Merge "Improve transient bar transitions." into klp-dev
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 1acac85..7bcf43e 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -66,8 +66,9 @@
public static final int WINDOW_STATUS_BAR = 1;
public static final int WINDOW_NAVIGATION_BAR = 2;
+ public static final int WINDOW_STATE_SHOWING = 0;
public static final int WINDOW_STATE_HIDING = 1;
- public static final int WINDOW_STATE_SHOWING = 2;
+ public static final int WINDOW_STATE_HIDDEN = 2;
private Context mContext;
private IStatusBarService mService;
@@ -185,4 +186,12 @@
throw new RuntimeException(ex);
}
}
+
+ /** @hide */
+ public static String windowStateToString(int state) {
+ if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
+ if (state == WINDOW_STATE_HIDDEN) return "WINDOW_STATE_HIDDEN";
+ if (state == WINDOW_STATE_SHOWING) return "WINDOW_STATE_SHOWING";
+ return "WINDOW_STATE_UNKNOWN";
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f05e372..5269ee3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2542,6 +2542,26 @@
/**
* @hide
+ *
+ * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+ * out of the public fields to keep the undefined bits out of the developer's way.
+ *
+ * Flag to specify that the hidden status bar would like to be shown.
+ */
+ public static final int STATUS_BAR_UNHIDE = 0x10000000;
+
+ /**
+ * @hide
+ *
+ * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+ * out of the public fields to keep the undefined bits out of the developer's way.
+ *
+ * Flag to specify that the hidden navigation bar would like to be shown.
+ */
+ public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;
+
+ /**
+ * @hide
*/
public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 53041b7..e8173b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -236,7 +236,7 @@
public void setWindowState(int window, int state) {
synchronized (mList) {
- mHandler.removeMessages(MSG_SET_WINDOW_STATE);
+ // don't coalesce these
mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index e40c4e5..292ea7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -37,12 +37,13 @@
public static final int MODE_TRANSPARENT = 2;
private final String mTag;
- private final View mTarget;
- private final int mOpaque;
- private final int mSemiTransparent;
+ protected final View mTarget;
+ protected final int mOpaque;
+ protected final int mSemiTransparent;
protected Drawable mTransparent;
private int mMode;
+ private ValueAnimator mBackgroundColorAnimator;
private final AnimatorUpdateListener mBackgroundColorListener = new AnimatorUpdateListener() {
@Override
@@ -80,10 +81,11 @@
}
protected void onTransition(int oldMode, int newMode, boolean animate) {
+ cancelBackgroundColorAnimation();
if (animate && oldMode == MODE_SEMI_TRANSPARENT && newMode == MODE_OPAQUE) {
- startColorAnimation(mSemiTransparent, mOpaque);
+ startBackgroundColorAnimation(mSemiTransparent, mOpaque);
} else if (animate && oldMode == MODE_OPAQUE && newMode == MODE_SEMI_TRANSPARENT) {
- startColorAnimation(mOpaque, mSemiTransparent);
+ startBackgroundColorAnimation(mOpaque, mSemiTransparent);
} else if (newMode == MODE_OPAQUE || newMode == MODE_SEMI_TRANSPARENT) {
mTarget.setBackgroundColor(newMode == MODE_OPAQUE ? mOpaque : mSemiTransparent);
} else {
@@ -93,10 +95,17 @@
}
}
- private void startColorAnimation(int from, int to) {
- ValueAnimator anim = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
- anim.addUpdateListener(mBackgroundColorListener);
- anim.start();
+ private void startBackgroundColorAnimation(int from, int to) {
+ mBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
+ mBackgroundColorAnimator.addUpdateListener(mBackgroundColorListener);
+ mBackgroundColorAnimator.start();
+ }
+
+ private void cancelBackgroundColorAnimation() {
+ if (mBackgroundColorAnimator != null && mBackgroundColorAnimator.isStarted()) {
+ mBackgroundColorAnimator.cancel();
+ mBackgroundColorAnimator = null;
+ }
}
public static String modeToString(int mode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ad53fea..b36bedd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1841,37 +1841,26 @@
@Override // CommandQueue
public void setWindowState(int window, int state) {
+ boolean showing = state == StatusBarManager.WINDOW_STATE_SHOWING;
if (mStatusBarWindow != null
&& window == StatusBarManager.WINDOW_STATUS_BAR
&& mStatusBarWindowState != state) {
mStatusBarWindowState = state;
- if (DEBUG) Log.d(TAG, "Status bar window " + stateString(state));
- if (state == StatusBarManager.WINDOW_STATE_HIDING) {
- mStatusBarWindow.setEnabled(false);
+ if (DEBUG) Log.d(TAG, "Status bar " + StatusBarManager.windowStateToString(state));
+ mStatusBarWindow.setEnabled(showing);
+ if (!showing) {
mStatusBarView.collapseAllPanels(false);
- } else if (state == StatusBarManager.WINDOW_STATE_SHOWING) {
- mStatusBarWindow.setEnabled(true);
}
}
if (mNavigationBarView != null
&& window == StatusBarManager.WINDOW_NAVIGATION_BAR
&& mNavigationBarWindowState != state) {
mNavigationBarWindowState = state;
- if (DEBUG) Log.d(TAG, "Navigation bar window " + stateString(state));
- if (state == StatusBarManager.WINDOW_STATE_HIDING) {
- mNavigationBarView.setEnabled(false);
- } else if (state == StatusBarManager.WINDOW_STATE_SHOWING) {
- mNavigationBarView.setEnabled(true);
- }
+ if (DEBUG) Log.d(TAG, "Navigation bar " + StatusBarManager.windowStateToString(state));
+ mNavigationBarView.setEnabled(showing);
}
}
- private static String stateString(int state) {
- if (state == StatusBarManager.WINDOW_STATE_HIDING) return "hiding";
- if (state == StatusBarManager.WINDOW_STATE_SHOWING) return "showing";
- return "unknown";
- }
-
@Override // CommandQueue
public void setSystemUiVisibility(int vis, int mask) {
final int oldVal = mSystemUiVisibility;
@@ -1904,11 +1893,13 @@
// update status bar mode
int sbMode = updateBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
- View.STATUS_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS);
+ View.STATUS_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS,
+ mStatusBarWindowState);
// update navigation bar mode
int nbMode = updateBarMode(oldVal, newVal, mNavigationBarView.getBarTransitions(),
- View.NAVIGATION_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION);
+ View.NAVIGATION_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION,
+ mNavigationBarWindowState);
if (sbMode != -1 || nbMode != -1) {
// update transient bar autohide
@@ -1919,19 +1910,29 @@
}
}
+ // ready to unhide
+ if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
+ mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
+ }
+ if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
+ mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
+ }
+
// send updated sysui visibility to window manager
notifyUiVisibilityChanged(mSystemUiVisibility);
}
}
private int updateBarMode(int oldVis, int newVis, BarTransitions transitions,
- int transientFlag, int transparentFlag) {
+ int transientFlag, int transparentFlag, int windowState) {
final int oldMode = barMode(oldVis, transientFlag, transparentFlag);
final int newMode = barMode(newVis, transientFlag, transparentFlag);
if (oldMode == newMode) {
return -1; // no mode change
}
- transitions.transitionTo(newMode);
+ boolean animate = windowState == StatusBarManager.WINDOW_STATE_SHOWING
+ && oldMode == MODE_SEMI_TRANSPARENT && newMode == MODE_OPAQUE;
+ transitions.transitionTo(newMode, animate);
return newMode;
}
@@ -1941,11 +1942,19 @@
: MODE_OPAQUE;
}
+ private final Runnable mResumeSemiTransparent = new Runnable() {
+ @Override
+ public void run() {
+ if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0) {
+ animateTransitionTo(BarTransitions.MODE_SEMI_TRANSPARENT);
+ }
+ }};
+
@Override
public void resumeAutohide() {
if (mAutohideSuspended) {
scheduleAutohide();
- animateTransitionTo(BarTransitions.MODE_SEMI_TRANSPARENT);
+ mHandler.postDelayed(mResumeSemiTransparent, 500); // longer than home -> launcher
}
}
@@ -1959,7 +1968,8 @@
@Override
public void suspendAutohide() {
mHandler.removeCallbacks(mAutohide);
- mAutohideSuspended = 0 != (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT);
+ mHandler.removeCallbacks(mResumeSemiTransparent);
+ mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
animateTransitionTo(BarTransitions.MODE_OPAQUE);
}
@@ -1984,7 +1994,7 @@
private void userAutohide() {
cancelAutohide();
- mHandler.postDelayed(mAutohide, 25);
+ mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
}
private void setStatusBarLowProfile(boolean lightsOut) {
diff --git a/policy/src/com/android/internal/policy/impl/BarController.java b/policy/src/com/android/internal/policy/impl/BarController.java
index fb76e20..bcecff2 100644
--- a/policy/src/com/android/internal/policy/impl/BarController.java
+++ b/policy/src/com/android/internal/policy/impl/BarController.java
@@ -40,18 +40,21 @@
private final String mTag;
private final int mTransientFlag;
+ private final int mUnhideFlag;
private final int mStatusBarManagerId;
private final Handler mHandler;
private final Object mServiceAquireLock = new Object();
private IStatusBarService mStatusBarService;
private WindowState mWin;
+ private int mState;
private int mTransientBarState;
private boolean mPendingShow;
- public BarController(String tag, int transientFlag, int statusBarManagerId) {
+ public BarController(String tag, int transientFlag, int unhideFlag, int statusBarManagerId) {
mTag = "BarController." + tag;
mTransientFlag = transientFlag;
+ mUnhideFlag = unhideFlag;
mStatusBarManagerId = statusBarManagerId;
mHandler = new Handler();
}
@@ -60,6 +63,10 @@
mWin = win;
}
+ public boolean isHidden() {
+ return mState == StatusBarManager.WINDOW_STATE_HIDDEN;
+ }
+
public void showTransient() {
if (mWin != null) {
setTransientBarState(TRANSIENT_BAR_SHOWING);
@@ -70,49 +77,75 @@
return mTransientBarState == TRANSIENT_BAR_SHOWING;
}
- public void adjustSystemUiVisibilityLw(int visibility) {
+ public void adjustSystemUiVisibilityLw(int oldVis, int vis) {
if (mWin != null && mTransientBarState == TRANSIENT_BAR_SHOWING &&
- (visibility & mTransientFlag) == 0) {
+ (vis & mTransientFlag) == 0) {
+ // sysui requests hide
setTransientBarState(TRANSIENT_BAR_HIDING);
setBarShowingLw(false);
+ } else if (mWin != null && (oldVis & mUnhideFlag) != 0 && (vis & mUnhideFlag) == 0) {
+ // sysui ready to unhide
+ setBarShowingLw(true);
}
}
public boolean setBarShowingLw(final boolean show) {
if (mWin == null) return false;
-
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.setWindowState(mStatusBarManagerId, show
- ? StatusBarManager.WINDOW_STATE_SHOWING
- : StatusBarManager.WINDOW_STATE_HIDING);
- }
- } catch (RemoteException e) {
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
- }
- }
- });
if (show && mTransientBarState == TRANSIENT_BAR_HIDING) {
mPendingShow = true;
return false;
}
- return show ? mWin.showLw(true) : mWin.hideLw(true);
+ 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) {
+ updateState(state);
+ }
+ 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;
+ }
+
+ private void updateState(final int state) {
+ if (state != mState) {
+ mState = state;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.setWindowState(mStatusBarManagerId, state);
+ }
+ } catch (RemoteException e) {
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
+ }
+ }
+ });
+ }
}
public boolean checkHiddenLw() {
- if (mWin != null && mTransientBarState == TRANSIENT_BAR_HIDING && !mWin.isVisibleLw()) {
- // Finished animating out, clean up and reset style
- setTransientBarState(TRANSIENT_BAR_NONE);
- if (mPendingShow) {
- setBarShowingLw(true);
- mPendingShow = false;
+ if (mWin != null) {
+ if (!mWin.isVisibleLw() && !mWin.isAnimatingLw()) {
+ updateState(StatusBarManager.WINDOW_STATE_HIDDEN);
}
- return true;
+ if (mTransientBarState == TRANSIENT_BAR_HIDING && !mWin.isVisibleLw()) {
+ // Finished animating out, clean up and reset style
+ setTransientBarState(TRANSIENT_BAR_NONE);
+ if (mPendingShow) {
+ setBarShowingLw(true);
+ mPendingShow = false;
+ }
+ return true;
+ }
}
return false;
}
@@ -134,12 +167,11 @@
public int updateVisibilityLw(boolean allowed, int oldVis, int vis) {
if (mWin == null) return vis;
-
if (mTransientBarState == TRANSIENT_BAR_SHOWING) { // transient bar requested
if (allowed) {
vis |= mTransientFlag;
if ((oldVis & mTransientFlag) == 0) {
- setBarShowingLw(true);
+ vis |= mUnhideFlag; // tell sysui we're ready to unhide
}
} else {
setTransientBarState(TRANSIENT_BAR_NONE); // request denied
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 11e33dc..f3e7f0a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -554,9 +554,15 @@
MyOrientationListener mOrientationListener;
private final BarController mStatusBarController = new BarController("StatusBar",
- View.STATUS_BAR_TRANSIENT, StatusBarManager.WINDOW_STATUS_BAR);
+ View.STATUS_BAR_TRANSIENT,
+ View.STATUS_BAR_UNHIDE,
+ StatusBarManager.WINDOW_STATUS_BAR);
+
private final BarController mNavigationBarController = new BarController("NavigationBar",
- View.NAVIGATION_BAR_TRANSIENT, StatusBarManager.WINDOW_NAVIGATION_BAR);
+ View.NAVIGATION_BAR_TRANSIENT,
+ View.NAVIGATION_BAR_UNHIDE,
+ StatusBarManager.WINDOW_NAVIGATION_BAR);
+
private TransientNavigationConfirmation mTransientNavigationConfirmation;
private SystemGesturesPointerEventListener mSystemGestures;
@@ -2551,8 +2557,8 @@
@Override
public int adjustSystemUiVisibilityLw(int visibility) {
- mStatusBarController.adjustSystemUiVisibilityLw(visibility);
- mNavigationBarController.adjustSystemUiVisibilityLw(visibility);
+ mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
+ mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
// Reset any bits in mForceClearingStatusBarVisibility that
// are now clear.
@@ -5084,6 +5090,10 @@
}
vis = mNavigationBarController.updateVisibilityLw(isTransientNav, oldVis, vis);
+ // don't send low profile updates if the system bars are hidden
+ if (mStatusBarController.isHidden() && mNavigationBarController.isHidden()) {
+ vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
+ }
return vis;
}