From bd95740648372449a4d5c164d7050eee352d4c24 Mon Sep 17 00:00:00 2001 From: John Spurlock Date: Thu, 3 Oct 2013 11:38:39 -0400 Subject: Transparent system ui flags -> Translucent WM flags. Migrate View.SYSTEM_UI_FLAG_TRANSPARENT_(STATUS/NAVIGATION) to WindowManager.LayoutParams.FLAG_TRANSLUCENT_(STATUS|NAVIGATION). Add associated public attrs for both new window flags: windowTranslucentStatus windowTranslucentNavigation Introduce convenient four new themes that set translucent decor: Theme.Holo.NoActionBar.TranslucentDecor Theme.Holo.Light.NoActionBar.TranslucentDecor Theme.DeviceDefault.NoActionBar.TranslucentDecor Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor Update PhoneWindowManager mechanism to plumb these values back to SystemUI to drive bar mode state. The new translucent flags come from the top fullscreen window, not the focused window, so translucency does not change when opening dialogs. Imply some window-level system-ui visibility if one or both of these new flags are present, specifically: FLAG_TRANSLUCENT_STATUS implies LAYOUT_STABLE, LAYOUT_FULLSCREEN FLAG_TRANSLUCENT_NAVIGATION implies LAYOUT STABLE, LAYOUT_HIDE_NAV Rename all associated variable & resource names to use the term translucent instead of transparent. (Retain the term semi-transparent for the transient bar style). Recents activity allowed to inherit translucent decor state via the new PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR. Compensating changes to use the full screen area more appropriately. Update keyguard to use new WM flags. Update docs and various api artifacts. Sanity-check fixes: - Toasts and alerts given stable layout. - Suppress nu-gradient when in transient (hidey) mode. - New translucent flags use top-fullscreen window, dialogs don't clear. Bug:10674960 Bug:11062108 Bug:10987178 Bug:10786445 Bug:10781433 Change-Id: If667a55bea4cf5e008549524b9899197fab55ebe --- .../internal/policy/impl/BarController.java | 45 ++++++++++---- .../android/internal/policy/impl/PhoneWindow.java | 12 ++++ .../internal/policy/impl/PhoneWindowManager.java | 71 ++++++++++++++-------- 3 files changed, 88 insertions(+), 40 deletions(-) (limited to 'policy') diff --git a/policy/src/com/android/internal/policy/impl/BarController.java b/policy/src/com/android/internal/policy/impl/BarController.java index 57c9675..8d97fc8 100644 --- a/policy/src/com/android/internal/policy/impl/BarController.java +++ b/policy/src/com/android/internal/policy/impl/BarController.java @@ -23,6 +23,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.util.Slog; import android.view.View; +import android.view.WindowManager; import android.view.WindowManagerPolicy.WindowState; import com.android.internal.statusbar.IStatusBarService; @@ -39,13 +40,14 @@ public class BarController { private static final int TRANSIENT_BAR_SHOWING = 1; private static final int TRANSIENT_BAR_HIDING = 2; - private static final int TRANSPARENT_ANIMATION_DELAY_MS = 1000; + private static final int TRANSLUCENT_ANIMATION_DELAY_MS = 1000; private final String mTag; private final int mTransientFlag; private final int mUnhideFlag; - private final int mTransparentFlag; + private final int mTranslucentFlag; private final int mStatusBarManagerId; + private final int mTranslucentWmFlag; private final Handler mHandler; private final Object mServiceAquireLock = new Object(); private IStatusBarService mStatusBarService; @@ -54,15 +56,16 @@ public class BarController { private int mState = StatusBarManager.WINDOW_STATE_SHOWING; private int mTransientBarState; private boolean mPendingShow; - private long mLastTransparent; + private long mLastTranslucent; - public BarController(String tag, int transientFlag, int unhideFlag, int transparentFlag, - int statusBarManagerId) { + public BarController(String tag, int transientFlag, int unhideFlag, int translucentFlag, + int statusBarManagerId, int translucentWmFlag) { mTag = "BarController." + tag; mTransientFlag = transientFlag; mUnhideFlag = unhideFlag; - mTransparentFlag = transparentFlag; + mTranslucentFlag = translucentFlag; mStatusBarManagerId = statusBarManagerId; + mTranslucentWmFlag = translucentWmFlag; mHandler = new Handler(); } @@ -84,8 +87,8 @@ public class BarController { return mTransientBarState == TRANSIENT_BAR_SHOWING; } - public boolean wasRecentlyTransparent() { - return (SystemClock.uptimeMillis() - mLastTransparent) < TRANSPARENT_ANIMATION_DELAY_MS; + public boolean wasRecentlyTranslucent() { + return (SystemClock.uptimeMillis() - mLastTranslucent) < TRANSLUCENT_ANIMATION_DELAY_MS; } public void adjustSystemUiVisibilityLw(int oldVis, int vis) { @@ -100,6 +103,22 @@ public class BarController { } } + public int applyTranslucentFlagLw(WindowState win, int vis, int oldVis) { + if (mWin != null) { + if (win != null && (win.getAttrs().privateFlags + & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) == 0) { + if ((win.getAttrs().flags & mTranslucentWmFlag) != 0) { + vis |= mTranslucentFlag; + } else { + vis &= ~mTranslucentFlag; + } + } else { + vis = (vis & ~mTranslucentFlag) | (oldVis & mTranslucentFlag); + } + } + return vis; + } + public boolean setBarShowingLw(final boolean show) { if (mWin == null) return false; if (show && mTransientBarState == TRANSIENT_BAR_HIDING) { @@ -186,10 +205,10 @@ public class BarController { } } - public int updateVisibilityLw(boolean allowed, int oldVis, int vis) { + public int updateVisibilityLw(boolean transientAllowed, int oldVis, int vis) { if (mWin == null) return vis; if (mTransientBarState == TRANSIENT_BAR_SHOWING) { // transient bar requested - if (allowed) { + if (transientAllowed) { vis |= mTransientFlag; if ((oldVis & mTransientFlag) == 0) { vis |= mUnhideFlag; // tell sysui we're ready to unhide @@ -202,8 +221,8 @@ public class BarController { vis |= mTransientFlag; // ignore clear requests until transition completes vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE; // never show transient bars in low profile } - if ((vis & mTransparentFlag) != 0 || (oldVis & mTransparentFlag) != 0) { - mLastTransparent = SystemClock.uptimeMillis(); + if ((vis & mTranslucentFlag) != 0 || (oldVis & mTranslucentFlag) != 0) { + mLastTranslucent = SystemClock.uptimeMillis(); } return vis; } @@ -211,7 +230,7 @@ public class BarController { private void setTransientBarState(int state) { if (mWin != null && state != mTransientBarState) { if (mTransientBarState == TRANSIENT_BAR_SHOWING || state == TRANSIENT_BAR_SHOWING) { - mLastTransparent = SystemClock.uptimeMillis(); + mLastTranslucent = SystemClock.uptimeMillis(); } mTransientBarState = state; if (DEBUG) Slog.d(mTag, "mTransientBarState: " + transientBarStateToString(state)); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 11913ee..d8af007 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -2750,6 +2750,18 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags())); } + if (a.getBoolean(com.android.internal.R.styleable.Window_windowTranslucentStatus, + false)) { + setFlags(FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_STATUS + & (~getForcedWindowFlags())); + } + + if (a.getBoolean(com.android.internal.R.styleable.Window_windowTranslucentNavigation, + false)) { + setFlags(FLAG_TRANSLUCENT_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION + & (~getForcedWindowFlags())); + } + if (a.getBoolean(com.android.internal.R.styleable.Window_windowOverscan, false)) { setFlags(FLAG_LAYOUT_IN_OVERSCAN, FLAG_LAYOUT_IN_OVERSCAN&(~getForcedWindowFlags())); } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 3232a1e..dd4f3d1 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -163,9 +163,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { */ static final int SYSTEM_UI_CHANGING_LAYOUT = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS - | View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION; + | View.SYSTEM_UI_FLAG_FULLSCREEN; /** * Keyguard stuff @@ -557,14 +555,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { private final BarController mStatusBarController = new BarController("StatusBar", View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_UNHIDE, - View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS, - StatusBarManager.WINDOW_STATUS_BAR); + View.STATUS_BAR_TRANSLUCENT, + StatusBarManager.WINDOW_STATUS_BAR, + WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); private final BarController mNavigationBarController = new BarController("NavigationBar", View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_UNHIDE, - View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION, - StatusBarManager.WINDOW_NAVIGATION_BAR); + View.NAVIGATION_BAR_TRANSLUCENT, + StatusBarManager.WINDOW_NAVIGATION_BAR, + WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); private TransientNavigationConfirmation mTransientNavigationConfirmation; @@ -2694,9 +2694,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { // drive nav being hidden only by whether it is requested. final int sysui = mLastSystemUiFlags; boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; - boolean navTransparent = (sysui & View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION) != 0; + boolean navTranslucent = (sysui & View.NAVIGATION_BAR_TRANSLUCENT) != 0; boolean transientAllowed = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; - navTransparent &= !transientAllowed; // transient trumps transparent + navTranslucent &= !transientAllowed; // transient trumps translucent // When the navigation bar isn't visible, we put up a fake // input window to catch all touch events. This way we can @@ -2733,7 +2733,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { - mNavigationBarHeightForRotation[displayRotation]; mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom); mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top; - if (transientNavBarShowing || navTransparent) { + if (transientNavBarShowing || navTranslucent) { mNavigationBarController.setBarShowingLw(true); } else if (navVisible) { mNavigationBarController.setBarShowingLw(true); @@ -2744,8 +2744,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { // We currently want to hide the navigation UI. mNavigationBarController.setBarShowingLw(false); } - if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw() - && !mNavigationBarController.wasRecentlyTransparent()) { + if (navVisible && !navTranslucent && !mNavigationBar.isAnimatingLw() + && !mNavigationBarController.wasRecentlyTranslucent()) { // If the opaque nav bar is currently requested to be visible, // and not in the process of animating on or off, then // we can tell the app that it is covered by it. @@ -2757,7 +2757,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { - mNavigationBarWidthForRotation[displayRotation]; mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight); mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left; - if (transientNavBarShowing || navTransparent) { + if (transientNavBarShowing || navTranslucent) { mNavigationBarController.setBarShowingLw(true); } else if (navVisible) { mNavigationBarController.setBarShowingLw(true); @@ -2768,8 +2768,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { // We currently want to hide the navigation UI. mNavigationBarController.setBarShowingLw(false); } - if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw() - && !mNavigationBarController.wasRecentlyTransparent()) { + if (navVisible && !navTranslucent && !mNavigationBar.isAnimatingLw() + && !mNavigationBarController.wasRecentlyTranslucent()) { // If the nav bar is currently requested to be visible, // and not in the process of animating on or off, then // we can tell the app that it is covered by it. @@ -2816,7 +2816,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStableTop = mUnrestrictedScreenTop + mStatusBarHeight; boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0; - boolean statusBarTransparent = (sysui & View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS) != 0; + boolean statusBarTranslucent = (sysui & View.STATUS_BAR_TRANSLUCENT) != 0; // If the status bar is hidden, we don't want to cause // windows behind it to scroll. @@ -2839,8 +2839,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mCurLeft, mCurTop, mCurRight, mCurBottom)); } if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw() - && !statusBarTransient && !statusBarTransparent - && !mStatusBarController.wasRecentlyTransparent()) { + && !statusBarTransient && !statusBarTranslucent + && !mStatusBarController.wasRecentlyTranslucent()) { // If the opaque status bar is currently requested to be visible, // and not in the process of animating on or off, then // we can tell the app that it is covered by it. @@ -2999,15 +2999,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { dcf.top = mSystemTop; dcf.right = mSystemRight; dcf.bottom = mSystemBottom; + final boolean inheritTranslucentDecor = (attrs.privateFlags + & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) != 0; if (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW - && attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW) { - if ((attrs.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0 - && (sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 - && (sysUiFl & View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS) == 0) { + && attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW + && !inheritTranslucentDecor) { + if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 + && (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0 + && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0) { // Ensure policy decor includes status bar dcf.top = mStableTop; } - if ((sysUiFl & View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION) == 0 + if ((fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == 0 && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { // Ensure policy decor includes navigation bar dcf.bottom = mStableBottom; @@ -3257,6 +3260,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { + mRestrictedScreenWidth; pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop + mRestrictedScreenHeight; + } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT) { + // Toasts are stable to interim decor changes. + pf.left = df.left = of.left = cf.left = mStableLeft; + pf.top = df.top = of.top = cf.top = mStableTop; + pf.right = df.right = of.right = cf.right = mStableRight; + pf.bottom = df.bottom = of.bottom = cf.bottom = mStableBottom; } else { pf.left = mContentLeft; pf.top = mContentTop; @@ -5061,22 +5070,30 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private int updateSystemBarsLw(WindowState win, int oldVis, int vis) { + // apply translucent bar vis flags + WindowState transWin = mKeyguard != null && mKeyguard.isVisibleLw() && !mHideLockScreen + ? mKeyguard + : mTopFullscreenOpaqueWindowState; + vis = mStatusBarController.applyTranslucentFlagLw(transWin, vis, oldVis); + vis = mNavigationBarController.applyTranslucentFlagLw(transWin, vis, oldVis); + // prevent status bar interaction from clearing certain flags boolean statusBarHasFocus = win.getAttrs().type == TYPE_STATUS_BAR; if (statusBarHasFocus) { int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE - | View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS - | View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION; - vis = (vis & ~flags) | (mLastSystemUiFlags & flags); + | View.STATUS_BAR_TRANSLUCENT + | View.NAVIGATION_BAR_TRANSLUCENT; + vis = (vis & ~flags) | (oldVis & flags); } // update status bar boolean transientAllowed = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; boolean hideStatusBarWM = - (win.getAttrs().flags + mTopFullscreenOpaqueWindowState != null && + (mTopFullscreenOpaqueWindowState.getAttrs().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; boolean hideStatusBarSysui = (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; -- cgit v1.1