OSDN Git Service

Promote lights-out to a bar transition mode.
authorJohn Spurlock <jspurlock@google.com>
Sat, 14 Sep 2013 15:58:55 +0000 (11:58 -0400)
committerJohn Spurlock <jspurlock@google.com>
Sat, 14 Sep 2013 20:58:57 +0000 (16:58 -0400)
Move all visual application of the legacy lights-out behind
a new mode managed by BarTransitions for better coordination.

Remove unused "hidden" state in NavigationBarView.

Improve window state (showing/hiding/hidden) calculation,
affecting whether or not sysui thinks it should animate.
Removes invalid interim mode changes causing needless
flashing during some transitions.

Consider WINDOW_STATE_HIDING a state in which we ought to animate,
since at least part of the window is visible throughout.

Make the status/nav bar transition helper classes real boys.

Animate KeyButtonView drawing alpha transition, cancel existing
animations when resetting to avoid needless and unsightly "recovery".

Bug:10746803
Change-Id: Ibd883da9041d071b6a4ff5b42cf96efba7696e9c

packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java [new file with mode: 0644]
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java [new file with mode: 0644]
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
policy/src/com/android/internal/policy/impl/BarController.java

index 6302244..212d704 100644 (file)
@@ -20,7 +20,6 @@ import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.ActivityManager;
-import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -35,6 +34,10 @@ public class BarTransitions {
     public static final int MODE_OPAQUE = 0;
     public static final int MODE_SEMI_TRANSPARENT = 1;
     public static final int MODE_TRANSPARENT = 2;
+    public static final int MODE_LIGHTS_OUT = 3;
+
+    protected static final int LIGHTS_IN_DURATION = 250;
+    protected static final int LIGHTS_OUT_DURATION = 750;
 
     private final String mTag;
     protected final View mTarget;
@@ -52,10 +55,10 @@ public class BarTransitions {
         }
     };
 
-    public BarTransitions(Context context, View target) {
+    public BarTransitions(View target) {
         mTag = "BarTransitions." + target.getClass().getSimpleName();
         mTarget = target;
-        final Resources res = context.getResources();
+        final Resources res = target.getContext().getResources();
         mOpaque = res.getColor(R.drawable.status_bar_background);
         mSemiTransparent = res.getColor(R.color.status_bar_background_semi_transparent);
     }
@@ -76,6 +79,7 @@ public class BarTransitions {
     protected Integer getBackgroundColor(int mode) {
         if (mode == MODE_SEMI_TRANSPARENT) return mSemiTransparent;
         if (mode == MODE_OPAQUE) return mOpaque;
+        if (mode == MODE_LIGHTS_OUT) return mOpaque;
         return null;
     }
 
@@ -113,6 +117,7 @@ public class BarTransitions {
         if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
         if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
         if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
+        if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
         throw new IllegalArgumentException("Unknown mode " + mode);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
new file mode 100644 (file)
index 0000000..085130b
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.GradientDrawable.Orientation;
+import android.os.ServiceManager;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.KeyButtonView;
+
+public final class NavigationBarTransitions extends BarTransitions {
+    private static final boolean ENABLE_GRADIENT = false;  // until we can smooth transition
+
+    private final NavigationBarView mView;
+    private final Drawable mTransparentBottom;
+    private final Drawable mTransparentRight;
+    private final int mTransparentColor;
+    private final IStatusBarService mBarService;
+
+    private boolean mLightsOut;
+
+    public NavigationBarTransitions(NavigationBarView view) {
+        super(view);
+        mView = view;
+        final Resources res = mView.getContext().getResources();
+        final int[] gradientColors = new int[] {
+                res.getColor(R.color.navigation_bar_background_transparent_start),
+                res.getColor(R.color.navigation_bar_background_transparent_end)
+        };
+        mTransparentBottom = new GradientDrawable(Orientation.BOTTOM_TOP, gradientColors);
+        mTransparentRight = new GradientDrawable(Orientation.RIGHT_LEFT, gradientColors);
+        mTransparentColor = res.getColor(R.color.status_bar_background_transparent);
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+    }
+
+    public void setVertical(boolean isVertical) {
+        if (!ENABLE_GRADIENT) return;
+        mTransparent = isVertical ? mTransparentRight : mTransparentBottom;
+    }
+
+    @Override
+    protected Integer getBackgroundColor(int mode) {
+        if (!ENABLE_GRADIENT && mode == MODE_TRANSPARENT) return mTransparentColor;
+        return super.getBackgroundColor(mode);
+    }
+
+    @Override
+    protected void onTransition(int oldMode, int newMode, boolean animate) {
+        super.onTransition(oldMode, newMode, animate);
+        applyMode(newMode, animate, false /*force*/);
+    }
+
+    public void reapplyMode() {
+        applyMode(getMode(), false /*animate*/, true /*force*/);
+    }
+
+    private void applyMode(int mode, boolean animate, boolean force) {
+        // apply to key buttons
+        final boolean isOpaque = mode == MODE_OPAQUE || mode == MODE_LIGHTS_OUT;
+        final float alpha = isOpaque ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f;
+        setKeyButtonViewQuiescentAlpha(mView.getBackButton(), alpha, animate);
+        setKeyButtonViewQuiescentAlpha(mView.getHomeButton(), alpha, animate);
+        setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate);
+        setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate);
+
+        // apply to lights out
+        applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
+    }
+
+    private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) {
+        if (button instanceof KeyButtonView) {
+            ((KeyButtonView) button).setQuiescentAlpha(alpha, animate);
+        }
+    }
+
+    private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
+        if (!force && lightsOut == mLightsOut) return;
+
+        mLightsOut = lightsOut;
+
+        final View navButtons = mView.getCurrentView().findViewById(R.id.nav_buttons);
+        final View lowLights = mView.getCurrentView().findViewById(R.id.lights_out);
+
+        // ok, everyone, stop it right there
+        navButtons.animate().cancel();
+        lowLights.animate().cancel();
+
+        final float navButtonsAlpha = lightsOut ? 0f : 1f;
+        final float lowLightsAlpha = lightsOut ? 1f : 0f;
+
+        if (!animate) {
+            navButtons.setAlpha(navButtonsAlpha);
+            lowLights.setAlpha(lowLightsAlpha);
+            lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
+        } else {
+            final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
+            navButtons.animate()
+                .alpha(navButtonsAlpha)
+                .setDuration(duration)
+                .start();
+
+            lowLights.setOnTouchListener(mLightsOutListener);
+            if (lowLights.getVisibility() == View.GONE) {
+                lowLights.setAlpha(0f);
+                lowLights.setVisibility(View.VISIBLE);
+            }
+            lowLights.animate()
+                .alpha(lowLightsAlpha)
+                .setDuration(duration)
+                .setInterpolator(new AccelerateInterpolator(2.0f))
+                .setListener(lightsOut ? null : new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator _a) {
+                        lowLights.setVisibility(View.GONE);
+                    }
+                })
+                .start();
+        }
+    }
+
+    private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
+        @Override
+        public boolean onTouch(View v, MotionEvent ev) {
+            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+                // even though setting the systemUI visibility below will turn these views
+                // on, we need them to come up faster so that they can catch this motion
+                // event
+                applyLightsOut(false, false, false);
+
+                try {
+                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
+                } catch (android.os.RemoteException ex) {
+                }
+            }
+            return false;
+        }
+    };
+}
\ No newline at end of file
index 850f94d..4683030 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.LayoutTransition;
 import android.app.StatusBarManager;
 import android.content.Context;
@@ -25,11 +23,8 @@ import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.GradientDrawable.Orientation;
 import android.os.Handler;
 import android.os.Message;
-import android.os.ServiceManager;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Display;
@@ -38,16 +33,13 @@ import android.view.Surface;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.animation.AccelerateInterpolator;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.DelegateViewHelper;
 import com.android.systemui.statusbar.policy.DeadZone;
-import com.android.systemui.statusbar.policy.KeyButtonView;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -59,11 +51,8 @@ public class NavigationBarView extends LinearLayout {
     final static boolean NAVBAR_ALWAYS_AT_RIGHT = true;
 
     // slippery nav bar when everything is disabled, e.g. during setup
-    final static boolean SLIPPERY_WHEN_DISABLED= true;
+    final static boolean SLIPPERY_WHEN_DISABLED = true;
 
-    final static boolean ANIMATE_HIDE_TRANSITION = false; // turned off because it introduces unsightly delay when videos goes to full screen
-
-    protected IStatusBarService mBarService;
     final Display mDisplay;
     View mCurrentView = null;
     View[] mRotatedViews = new View[4];
@@ -72,7 +61,7 @@ public class NavigationBarView extends LinearLayout {
     boolean mVertical;
     boolean mScreenOn;
 
-    boolean mHidden, mLowProfile, mShowMenu;
+    boolean mShowMenu;
     int mDisabledFlags = 0;
     int mNavigationIconHints = 0;
 
@@ -111,62 +100,11 @@ public class NavigationBarView extends LinearLayout {
         }
     }
 
-    private final class NavigationBarTransitions extends BarTransitions {
-        private static final boolean ENABLE_GRADIENT = false;  // until we can smooth transition
-
-        private final Drawable mTransparentBottom;
-        private final Drawable mTransparentRight;
-        private final int mTransparentColor;
-
-        public NavigationBarTransitions(Context context) {
-            super(context, NavigationBarView.this);
-            final Resources res = mContext.getResources();
-            final int[] gradientColors = new int[] {
-                    res.getColor(R.color.navigation_bar_background_transparent_start),
-                    res.getColor(R.color.navigation_bar_background_transparent_end)
-            };
-            mTransparentBottom = new GradientDrawable(Orientation.BOTTOM_TOP, gradientColors);
-            mTransparentRight = new GradientDrawable(Orientation.RIGHT_LEFT, gradientColors);
-            mTransparentColor = res.getColor(R.color.status_bar_background_transparent);
-        }
-
-        public void setVertical(boolean isVertical) {
-            if (!ENABLE_GRADIENT) return;
-            mTransparent = isVertical ? mTransparentRight : mTransparentBottom;
-        }
-
-        @Override
-        protected Integer getBackgroundColor(int mode) {
-            if (!ENABLE_GRADIENT && mode == MODE_TRANSPARENT) return mTransparentColor;
-            return super.getBackgroundColor(mode);
-        }
-
-        @Override
-        protected void onTransition(int oldMode, int newMode, boolean animate) {
-            super.onTransition(oldMode, newMode, animate);
-            final float alpha = newMode == MODE_OPAQUE ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f;
-            setKeyButtonViewQuiescentAlpha(getBackButton(), alpha);
-            setKeyButtonViewQuiescentAlpha(getHomeButton(), alpha);
-            setKeyButtonViewQuiescentAlpha(getRecentsButton(), alpha);
-            setKeyButtonViewQuiescentAlpha(getMenuButton(), alpha);
-        }
-
-        private void setKeyButtonViewQuiescentAlpha(View button, float alpha) {
-            if (button instanceof KeyButtonView) {
-                ((KeyButtonView) button).setQuiescentAlpha(alpha);
-            }
-        }
-    }
-
     public NavigationBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        mHidden = false;
-
         mDisplay = ((WindowManager)context.getSystemService(
                 Context.WINDOW_SERVICE)).getDefaultDisplay();
-        mBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
 
         final Resources res = mContext.getResources();
         mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
@@ -176,7 +114,7 @@ public class NavigationBarView extends LinearLayout {
 
         getIcons(res);
 
-        mBarTransitions = new NavigationBarTransitions(context);
+        mBarTransitions = new NavigationBarTransitions(this);
     }
 
     public BarTransitions getBarTransitions() {
@@ -210,6 +148,10 @@ public class NavigationBarView extends LinearLayout {
 
     private H mHandler = new H();
 
+    public View getCurrentView() {
+        return mCurrentView;
+    }
+
     public View getRecentsButton() {
         return mCurrentView.findViewById(R.id.recent_apps);
     }
@@ -252,24 +194,6 @@ public class NavigationBarView extends LinearLayout {
         setDisabledFlags(mDisabledFlags, true);
     }
 
-    View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
-        @Override
-        public boolean onTouch(View v, MotionEvent ev) {
-            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-                // even though setting the systemUI visibility below will turn these views
-                // on, we need them to come up faster so that they can catch this motion
-                // event
-                setLowProfile(false, false, false);
-
-                try {
-                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
-                } catch (android.os.RemoteException ex) {
-                }
-            }
-            return false;
-        }
-    };
-
     public void setNavigationIconHints(int hints) {
         setNavigationIconHints(hints, false);
     }
@@ -366,65 +290,6 @@ public class NavigationBarView extends LinearLayout {
         getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
     }
 
-    public void setLowProfile(final boolean lightsOut) {
-        setLowProfile(lightsOut, true, false);
-    }
-
-    public void setLowProfile(final boolean lightsOut, final boolean animate, final boolean force) {
-        if (!force && lightsOut == mLowProfile) return;
-
-        mLowProfile = lightsOut;
-
-        if (DEBUG) Log.d(TAG, "setting lights " + (lightsOut?"out":"on"));
-
-        final View navButtons = mCurrentView.findViewById(R.id.nav_buttons);
-        final View lowLights = mCurrentView.findViewById(R.id.lights_out);
-
-        // ok, everyone, stop it right there
-        navButtons.animate().cancel();
-        lowLights.animate().cancel();
-
-        if (!animate) {
-            navButtons.setAlpha(lightsOut ? 0f : 1f);
-
-            lowLights.setAlpha(lightsOut ? 1f : 0f);
-            lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
-        } else {
-            navButtons.animate()
-                .alpha(lightsOut ? 0f : 1f)
-                .setDuration(lightsOut ? 750 : 250)
-                .start();
-
-            lowLights.setOnTouchListener(mLightsOutListener);
-            if (lowLights.getVisibility() == View.GONE) {
-                lowLights.setAlpha(0f);
-                lowLights.setVisibility(View.VISIBLE);
-            }
-            lowLights.animate()
-                .alpha(lightsOut ? 1f : 0f)
-                .setDuration(lightsOut ? 750 : 250)
-                .setInterpolator(new AccelerateInterpolator(2.0f))
-                .setListener(lightsOut ? null : new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator _a) {
-                        lowLights.setVisibility(View.GONE);
-                    }
-                })
-                .start();
-        }
-    }
-
-    public void setHidden(final boolean hide) {
-        if (hide == mHidden) return;
-
-        mHidden = hide;
-        Log.d(TAG,
-            (hide ? "HIDING" : "SHOWING") + " navigation bar");
-
-        // bring up the lights no matter what
-        setLowProfile(false);
-    }
-
     @Override
     public void onFinishInflate() {
         mRotatedViews[Surface.ROTATION_0] =
@@ -454,7 +319,7 @@ public class NavigationBarView extends LinearLayout {
         mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
 
         // force the low profile & disabled states into compliance
-        setLowProfile(mLowProfile, false, true /* force */);
+        mBarTransitions.reapplyMode();
         setDisabledFlags(mDisabledFlags, true /* force */);
         setMenuVisibility(mShowMenu, true /* force */);
 
@@ -562,8 +427,6 @@ public class NavigationBarView extends LinearLayout {
         pw.println(String.format("      disabled=0x%08x vertical=%s hidden=%s low=%s menu=%s",
                         mDisabledFlags,
                         mVertical ? "true" : "false",
-                        mHidden ? "true" : "false",
-                        mLowProfile ? "true" : "false",
                         mShowMenu ? "true" : "false"));
 
         final View back = getBackButton();
index 64d4c7f..a3e6e38 100644 (file)
 package com.android.systemui.statusbar.phone;
 
 import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
+import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.app.ActivityManager;
@@ -251,9 +252,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
     int[] mAbsPos = new int[2];
     Runnable mPostCollapseCleanup = null;
 
-    private Animator mLightsOutAnimation;
-    private Animator mLightsOnAnimation;
-
     // for disabling the status bar
     int mDisabled = 0;
 
@@ -1808,11 +1806,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
                     }
                 }
 
-                if (mNavigationBarView != null) {
-                    mNavigationBarView.setLowProfile(lightsOut);
-                }
-
-                setStatusBarLowProfile(lightsOut);
+                setAreThereNotifications();
             }
 
             // update status bar mode
@@ -1872,6 +1866,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
     private int barMode(int vis, int transientFlag, int transparentFlag) {
         return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
                 : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
+                : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
                 : MODE_OPAQUE;
     }
 
@@ -1888,7 +1883,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
     private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
         final boolean imeVisible = (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0;
         final int finalMode = imeVisible ? MODE_OPAQUE : mode;
-        final boolean animate = windowState == WINDOW_STATE_SHOWING;
+        final boolean animate = windowState != WINDOW_STATE_HIDDEN;
         transitions.transitionTo(finalMode, animate);
     }
 
@@ -1948,47 +1943,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
         mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
     }
 
-    private void setStatusBarLowProfile(boolean lightsOut) {
-        if (mLightsOutAnimation == null) {
-            final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
-            final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
-            final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
-            final View battery = mStatusBarView.findViewById(R.id.battery);
-            final View clock = mStatusBarView.findViewById(R.id.clock);
-
-            final AnimatorSet lightsOutAnim = new AnimatorSet();
-            lightsOutAnim.playTogether(
-                    ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
-                    ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
-                    ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
-                    ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
-                    ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
-                );
-            lightsOutAnim.setDuration(750);
-
-            final AnimatorSet lightsOnAnim = new AnimatorSet();
-            lightsOnAnim.playTogether(
-                    ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
-                );
-            lightsOnAnim.setDuration(250);
-
-            mLightsOutAnimation = lightsOutAnim;
-            mLightsOnAnimation = lightsOnAnim;
-        }
-
-        mLightsOutAnimation.cancel();
-        mLightsOnAnimation.cancel();
-
-        final Animator a = lightsOut ? mLightsOutAnimation : mLightsOnAnimation;
-        a.start();
-
-        setAreThereNotifications();
-    }
-
     private boolean areLightsOn() {
         return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
new file mode 100644 (file)
index 0000000..b9ffd6e
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.res.Resources;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.R;
+
+public final class PhoneStatusBarTransitions extends BarTransitions {
+    private static final float ALPHA_WHEN_TRANSPARENT = 1;
+    private static final float ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK = 0.5f;
+    private static final float ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK = 0;
+
+    private final PhoneStatusBarView mView;
+    private final int mTransparent;
+    private final float mAlphaWhenOpaque;
+
+    private View mLeftSide, mStatusIcons, mSignalCluster, mBattery, mClock;
+    private Animator mCurrentAnimation;
+
+    public PhoneStatusBarTransitions(PhoneStatusBarView view) {
+        super(view);
+        mView = view;
+        final Resources res = mView.getContext().getResources();
+        mTransparent = res.getColor(R.color.status_bar_background_transparent);
+        mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
+    }
+
+    public void init() {
+        mLeftSide = mView.findViewById(R.id.notification_icon_area);
+        mStatusIcons = mView.findViewById(R.id.statusIcons);
+        mSignalCluster = mView.findViewById(R.id.signal_cluster);
+        mBattery = mView.findViewById(R.id.battery);
+        mClock = mView.findViewById(R.id.clock);
+        applyMode(getMode(), false /*animate*/);
+    }
+
+    @Override
+    protected Integer getBackgroundColor(int mode) {
+        if (mode == MODE_TRANSPARENT) return mTransparent;
+        return super.getBackgroundColor(mode);
+    }
+
+    public ObjectAnimator animateTransitionTo(View v, float toAlpha) {
+        return ObjectAnimator.ofFloat(v, "alpha", v.getAlpha(), toAlpha);
+    }
+
+    private float getNonBatteryClockAlphaFor(int mode) {
+        return mode == MODE_LIGHTS_OUT ? ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
+                : isTransparent(mode) ? ALPHA_WHEN_TRANSPARENT
+                : mAlphaWhenOpaque;
+    }
+
+    private float getBatteryClockAlpha(int mode) {
+        return mode == MODE_LIGHTS_OUT ? ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
+                : getNonBatteryClockAlphaFor(mode);
+    }
+
+    private boolean isTransparent(int mode) {
+        return mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
+    }
+
+    @Override
+    protected void onTransition(int oldMode, int newMode, boolean animate) {
+        super.onTransition(oldMode, newMode, animate);
+        applyMode(newMode, animate);
+    }
+
+    private void applyMode(int mode, boolean animate) {
+        if (mLeftSide == null) return; // pre-init
+        float newAlpha = getNonBatteryClockAlphaFor(mode);
+        float newAlphaBC = getBatteryClockAlpha(mode);
+        if (mCurrentAnimation != null) {
+            mCurrentAnimation.cancel();
+        }
+        if (animate) {
+            AnimatorSet anims = new AnimatorSet();
+            anims.playTogether(
+                    animateTransitionTo(mLeftSide, newAlpha),
+                    animateTransitionTo(mStatusIcons, newAlpha),
+                    animateTransitionTo(mSignalCluster, newAlpha),
+                    animateTransitionTo(mBattery, newAlphaBC),
+                    animateTransitionTo(mClock, newAlphaBC)
+                    );
+            if (mode == MODE_LIGHTS_OUT) {
+                anims.setDuration(LIGHTS_OUT_DURATION);
+            }
+            anims.start();
+            mCurrentAnimation = anims;
+        } else {
+            mLeftSide.setAlpha(newAlpha);
+            mStatusIcons.setAlpha(newAlpha);
+            mSignalCluster.setAlpha(newAlpha);
+            mBattery.setAlpha(newAlphaBC);
+            mClock.setAlpha(newAlphaBC);
+        }
+    }
+}
\ No newline at end of file
index b263a6e..d9ac7e4 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.Resources;
@@ -47,73 +45,7 @@ public class PhoneStatusBarView extends PanelBar {
     PanelView mLastFullyOpenedPanel = null;
     PanelView mNotificationPanel, mSettingsPanel;
     private boolean mShouldFade;
-    private final StatusBarTransitions mBarTransitions;
-
-    private final class StatusBarTransitions extends BarTransitions {
-        private final int mTransparent;
-        private final float mAlphaWhenOpaque;
-        private final float mAlphaWhenTransparent = 1;
-        private View mLeftSide, mStatusIcons, mSignalCluster, mClock;
-
-        public StatusBarTransitions(Context context) {
-            super(context, PhoneStatusBarView.this);
-            final Resources res = context.getResources();
-            mTransparent = res.getColor(R.color.status_bar_background_transparent);
-            mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
-        }
-
-        public void init() {
-            mLeftSide = findViewById(R.id.notification_icon_area);
-            mStatusIcons = findViewById(R.id.statusIcons);
-            mSignalCluster = findViewById(R.id.signal_battery_cluster);
-            mClock = findViewById(R.id.clock);
-            applyMode(getMode(), false /*animate*/);
-        }
-
-        @Override
-        protected Integer getBackgroundColor(int mode) {
-            if (mode == MODE_TRANSPARENT) return mTransparent;
-            return super.getBackgroundColor(mode);
-        }
-
-        public ObjectAnimator animateTransitionTo(View v, float toAlpha) {
-            return ObjectAnimator.ofFloat(v, "alpha", v.getAlpha(), toAlpha);
-        }
-
-        public float getAlphaFor(int mode) {
-            return isTransparent(mode) ? mAlphaWhenTransparent : mAlphaWhenOpaque;
-        }
-
-        private boolean isTransparent(int mode) {
-            return mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
-        }
-
-        @Override
-        protected void onTransition(int oldMode, int newMode, boolean animate) {
-            super.onTransition(oldMode, newMode, animate);
-            applyMode(newMode, animate);
-        }
-
-        private void applyMode(int mode, boolean animate) {
-            if (mLeftSide == null) return; // pre-init
-            float newAlpha = getAlphaFor(mode);
-            if (animate) {
-                AnimatorSet anims = new AnimatorSet();
-                anims.playTogether(
-                        animateTransitionTo(mLeftSide, newAlpha),
-                        animateTransitionTo(mStatusIcons, newAlpha),
-                        animateTransitionTo(mSignalCluster, newAlpha),
-                        animateTransitionTo(mClock, newAlpha)
-                        );
-                anims.start();
-            } else {
-                mLeftSide.setAlpha(newAlpha);
-                mStatusIcons.setAlpha(newAlpha);
-                mSignalCluster.setAlpha(newAlpha);
-                mClock.setAlpha(newAlpha);
-            }
-        }
-    }
+    private final PhoneStatusBarTransitions mBarTransitions;
 
     public PhoneStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -127,7 +59,7 @@ public class PhoneStatusBarView extends PanelBar {
             mSettingsPanelDragzoneFrac = 0f;
         }
         mFullWidthNotifications = mSettingsPanelDragzoneFrac <= 0f;
-        mBarTransitions = new StatusBarTransitions(context);
+        mBarTransitions = new PhoneStatusBarTransitions(this);
     }
 
     public BarTransitions getBarTransitions() {
index 924478c..55fb95d 100644 (file)
@@ -17,8 +17,6 @@
 package com.android.systemui.statusbar.policy;
 
 import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
@@ -60,6 +58,7 @@ public class KeyButtonView extends ImageView {
     boolean mSupportsLongpress = true;
     RectF mRect = new RectF(0f,0f,0f,0f);
     AnimatorSet mPressedAnim;
+    Animator mAnimateToQuiescent = new ObjectAnimator();
 
     Runnable mCheckLongPress = new Runnable() {
         public void run() {
@@ -76,15 +75,6 @@ public class KeyButtonView extends ImageView {
         }
     };
 
-    private final AnimatorListener mRecoverToQuiescentListener = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (mQuiescentAlpha != mDrawingAlpha) {
-                animateToQuiescent().setDuration(200).start();
-            }
-        }
-    };
-
     public KeyButtonView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -133,16 +123,26 @@ public class KeyButtonView extends ImageView {
         super.onDraw(canvas);
     }
 
-    public void setQuiescentAlpha(float alpha) {
+    public void setQuiescentAlpha(float alpha, boolean animate) {
+        mAnimateToQuiescent.cancel();
         alpha = Math.min(Math.max(alpha, 0), 1);
         if (alpha == mQuiescentAlpha) return;
         mQuiescentAlpha = alpha;
         if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha);
         if (mGlowBG != null) {
-            setDrawingAlpha(mQuiescentAlpha);
+            if (animate) {
+                mAnimateToQuiescent = animateToQuiescent();
+                mAnimateToQuiescent.start();
+            } else {
+                setDrawingAlpha(mQuiescentAlpha);
+            }
         }
     }
 
+    private ObjectAnimator animateToQuiescent() {
+        return ObjectAnimator.ofFloat(this, "drawingAlpha", mQuiescentAlpha);
+    }
+
     public float getDrawingAlpha() {
         if (mGlowBG == null) return 0;
         return mDrawingAlpha;
@@ -197,12 +197,6 @@ public class KeyButtonView extends ImageView {
         }
     }
 
-    private ObjectAnimator animateToQuiescent() {
-        ObjectAnimator anim = ObjectAnimator.ofFloat(this, "drawingAlpha", mQuiescentAlpha);
-        anim.addListener(mRecoverToQuiescentListener);  // mQuiescentAlpha may change mid-animation
-        return anim;
-    }
-
     public void setPressed(boolean pressed) {
         if (mGlowBG != null) {
             if (pressed != isPressed()) {
@@ -222,10 +216,12 @@ public class KeyButtonView extends ImageView {
                     );
                     as.setDuration(50);
                 } else {
+                    mAnimateToQuiescent.cancel();
+                    mAnimateToQuiescent = animateToQuiescent();
                     as.playTogether(
                         ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
                         ObjectAnimator.ofFloat(this, "glowScale", 1f),
-                        animateToQuiescent()
+                        mAnimateToQuiescent
                     );
                     as.setDuration(500);
                 }
index 41b2fd1..57c9675 100644 (file)
@@ -33,7 +33,7 @@ import java.io.PrintWriter;
  * Controls state/behavior specific to a system bar window.
  */
 public class BarController {
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private static final int TRANSIENT_BAR_NONE = 0;
     private static final int TRANSIENT_BAR_SHOWING = 1;
@@ -106,24 +106,32 @@ public class BarController {
             mPendingShow = true;
             return false;
         }
-        final boolean oldVis = mWin.isVisibleLw();
-        final boolean oldAnim = mWin.isAnimatingLw();
-        final boolean rt = show ? mWin.showLw(true) : mWin.hideLw(true);
-        final int state = computeState(oldVis, oldAnim, mWin.isVisibleLw(), mWin.isAnimatingLw());
-        if (state > -1 && mWin.hasDrawnLw()) {
-            updateState(state);
+        final boolean wasVis = mWin.isVisibleLw();
+        final boolean wasAnim = mWin.isAnimatingLw();
+        final boolean change = show ? mWin.showLw(true) : mWin.hideLw(true);
+        final int state = computeStateLw(wasVis, wasAnim, mWin, change);
+        updateStateLw(state);
+        return change;
+    }
+
+    private int computeStateLw(boolean wasVis, boolean wasAnim, WindowState win, boolean change) {
+        if (win.hasDrawnLw()) {
+            final boolean vis = win.isVisibleLw();
+            final boolean anim = win.isAnimatingLw();
+            if (mState == StatusBarManager.WINDOW_STATE_HIDING && !change && !vis) {
+                return StatusBarManager.WINDOW_STATE_HIDDEN;
+            } else if (change) {
+                if (wasVis && vis && !wasAnim && anim) {
+                    return StatusBarManager.WINDOW_STATE_HIDING;
+                } else {
+                    return StatusBarManager.WINDOW_STATE_SHOWING;
+                }
+            }
         }
-        return rt;
-    }
-
-    private int computeState(boolean oldVis, boolean oldAnim, boolean newVis, boolean newAnim) {
-        return (!newVis && !newAnim) ? StatusBarManager.WINDOW_STATE_HIDDEN
-                : (!oldVis && newVis && newAnim) ? StatusBarManager.WINDOW_STATE_SHOWING
-                : (oldVis && newVis && !oldAnim && newAnim) ? StatusBarManager.WINDOW_STATE_HIDING
-                : -1;
+        return mState;
     }
 
-    private void updateState(final int state) {
+    private void updateStateLw(final int state) {
         if (state != mState) {
             mState = state;
             if (DEBUG) Slog.d(mTag, "mState: " + StatusBarManager.windowStateToString(state));
@@ -148,7 +156,7 @@ public class BarController {
     public boolean checkHiddenLw() {
         if (mWin != null && mWin.hasDrawnLw()) {
             if (!mWin.isVisibleLw() && !mWin.isAnimatingLw()) {
-                updateState(StatusBarManager.WINDOW_STATE_HIDDEN);
+                updateStateLw(StatusBarManager.WINDOW_STATE_HIDDEN);
             }
             if (mTransientBarState == TRANSIENT_BAR_HIDING && !mWin.isVisibleLw()) {
                 // Finished animating out, clean up and reset style