diff options
author | Adrian Roos <roosa@google.com> | 2014-05-05 13:33:03 +0200 |
---|---|---|
committer | Adrian Roos <roosa@google.com> | 2014-05-15 18:22:37 +0200 |
commit | ea56251d92050e9a672d1f66d0d4621e4dd4136e (patch) | |
tree | eb1bc2025ba63e64de7f422140e64c6045604e09 /policy | |
parent | 217ccd2f82031f05d111bce7308a65136f278c7a (diff) | |
download | frameworks_base-ea56251d92050e9a672d1f66d0d4621e4dd4136e.zip frameworks_base-ea56251d92050e9a672d1f66d0d4621e4dd4136e.tar.gz frameworks_base-ea56251d92050e9a672d1f66d0d4621e4dd4136e.tar.bz2 |
Colorize SystemUI
Makes the color of the status and navigation bars customizable by
the app.
Bug: 14564488
Change-Id: I036edc228cfe1b659c7f11a43cdc4598ee705ff8
Diffstat (limited to 'policy')
3 files changed, 126 insertions, 27 deletions
diff --git a/policy/src/com/android/internal/policy/impl/BarController.java b/policy/src/com/android/internal/policy/impl/BarController.java index fc49a569..49e1072 100644 --- a/policy/src/com/android/internal/policy/impl/BarController.java +++ b/policy/src/com/android/internal/policy/impl/BarController.java @@ -108,13 +108,20 @@ public class BarController { if (mWin != null) { if (win != null && (win.getAttrs().privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) == 0) { - if ((PolicyControl.getWindowFlags(win, null) & mTranslucentWmFlag) != 0) { + int fl = PolicyControl.getWindowFlags(win, null); + if ((fl & mTranslucentWmFlag) != 0) { vis |= mTranslucentFlag; } else { vis &= ~mTranslucentFlag; } + if ((fl & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) { + vis |= View.SYSTEM_UI_TRANSPARENT; + } else { + vis &= ~View.SYSTEM_UI_TRANSPARENT; + } } else { vis = (vis & ~mTranslucentFlag) | (oldVis & mTranslucentFlag); + vis = (vis & View.SYSTEM_UI_TRANSPARENT) | (oldVis & View.SYSTEM_UI_TRANSPARENT); } } return vis; @@ -230,7 +237,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 & mTranslucentFlag) != 0 || (oldVis & mTranslucentFlag) != 0) { + if ((vis & mTranslucentFlag) != 0 || (oldVis & mTranslucentFlag) != 0 || + ((vis | oldVis) & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) { mLastTranslucent = SystemClock.uptimeMillis(); } return vis; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index f6c8001..1b96f1f 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -38,9 +38,7 @@ import com.android.internal.widget.ActionBarOverlayLayout; import com.android.internal.widget.ActionBarView; import com.android.internal.widget.SwipeDismissLayout; -import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.app.ActivityOptions; +import android.app.ActivityManager; import android.app.KeyguardManager; import android.content.Context; import android.content.pm.ActivityInfo; @@ -49,6 +47,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -56,22 +55,15 @@ import android.media.AudioManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; -import android.os.Looper; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; -import android.transition.ChangeBounds; -import android.transition.Explode; -import android.transition.Fade; -import android.transition.MoveImage; import android.transition.Scene; import android.transition.Transition; import android.transition.TransitionInflater; import android.transition.TransitionManager; -import android.transition.TransitionSet; import android.util.AndroidRuntimeException; -import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; @@ -98,7 +90,6 @@ import android.view.ViewManager; import android.view.ViewParent; import android.view.ViewRootImpl; import android.view.ViewStub; -import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; @@ -113,8 +104,6 @@ import android.widget.TextView; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; /** * Android-specific Window. @@ -213,6 +202,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private int mFrameResource = 0; private int mTextColor = 0; + private int mStatusBarColor = 0; + private int mNavigationBarColor = 0; private CharSequence mTitle = null; @@ -1987,7 +1978,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } - private final class DecorView extends FrameLayout implements RootViewSurfaceTaker { + private final class DecorView extends FrameLayout implements RootViewSurfaceTaker, + View.OnSystemUiVisibilityChangeListener { /* package */int mDefaultOpacity = PixelFormat.OPAQUE; /** The feature ID of the panel, or -1 if this is the application's DecorView */ @@ -2017,6 +2009,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { // View added at runtime to draw under the navigation bar area private View mNavigationGuard; + private View mStatusColorView; + private View mNavigationColorView; + + private int mLastTopInset = 0; + private int mLastBottomInset = 0; + private int mLastSystemUiVisibility = 0; + + public DecorView(Context context, int featureId) { super(context); mFeatureId = featureId; @@ -2582,8 +2582,15 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } @Override + public void onSystemUiVisibilityChange(int visible) { + mLastSystemUiVisibility = visible; + updateColorViews(null /* insets */); + } + + @Override protected boolean fitSystemWindows(Rect insets) { mFrameOffsets.set(insets); + updateColorViews(insets); updateStatusGuard(insets); updateNavigationGuard(insets); if (getForeground() != null) { @@ -2597,6 +2604,52 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return false; } + private void updateColorViews(Rect insets) { + if (mIsFloating || !ActivityManager.isHighEndGfx()) { + // No colors on floating windows or low end devices :( + return; + } + if (insets != null) { + mLastTopInset = insets.top; + mLastBottomInset = insets.bottom; + } + mStatusColorView = updateColorViewInt(mStatusColorView, + SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS, + mStatusBarColor, mLastTopInset, Gravity.TOP); + mNavigationColorView = updateColorViewInt(mNavigationColorView, + SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION, + mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM); + } + + private View updateColorViewInt(View view, int systemUiHideFlag, int translucentFlag, + int color, int height, int verticalGravity) { + boolean show = height > 0 && (mLastSystemUiVisibility & systemUiHideFlag) == 0 + && (getAttributes().flags & translucentFlag) == 0 + && (color & Color.BLACK) != 0 + && (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; + + if (view == null) { + if (show) { + view = new View(mContext); + view.setBackgroundColor(color); + addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height, + Gravity.START | verticalGravity)); + } + } else { + int vis = show ? VISIBLE : INVISIBLE; + view.setVisibility(vis); + if (show) { + LayoutParams lp = (LayoutParams) view.getLayoutParams(); + if (lp.height != height) { + lp.height = height; + view.setLayoutParams(lp); + } + view.setBackgroundColor(color); + } + } + return view; + } + private void updateStatusGuard(Rect insets) { boolean showStatusGuard = false; // Show the status guard when the non-overlay contextual action bar is showing @@ -2616,9 +2669,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mStatusGuard = new View(mContext); mStatusGuard.setBackgroundColor(mContext.getResources() .getColor(R.color.input_method_navigation_guard)); - addView(mStatusGuard, new LayoutParams( - LayoutParams.MATCH_PARENT, mlp.topMargin, - Gravity.START | Gravity.TOP)); + addView(mStatusGuard, indexOfChild(mStatusColorView), + new LayoutParams(LayoutParams.MATCH_PARENT, mlp.topMargin, + Gravity.START | Gravity.TOP)); } else { LayoutParams lp = (LayoutParams) mStatusGuard.getLayoutParams(); if (lp.height != mlp.topMargin) { @@ -2663,7 +2716,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mNavigationGuard = new View(mContext); mNavigationGuard.setBackgroundColor(mContext.getResources() .getColor(R.color.input_method_navigation_guard)); - addView(mNavigationGuard, new LayoutParams( + addView(mNavigationGuard, indexOfChild(mNavigationColorView), new LayoutParams( LayoutParams.MATCH_PARENT, insets.bottom, Gravity.START | Gravity.BOTTOM)); } else { @@ -3009,6 +3062,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { final int targetSdk = context.getApplicationInfo().targetSdkVersion; final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB; final boolean targetPreIcs = targetSdk < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH; + final boolean targetPreL = targetSdk < android.os.Build.VERSION_CODES.L; final boolean targetHcNeedsOptions = context.getResources().getBoolean( com.android.internal.R.bool.target_honeycomb_needs_options_menu); final boolean noActionBar = !hasFeature(FEATURE_ACTION_BAR) || hasFeature(FEATURE_NO_TITLE); @@ -3018,7 +3072,21 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } else { clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); } - + + // Non-floating windows on high end devices must put up decor beneath the system bars and + // therefore must know about visibility changes of those. + if (!mIsFloating && ActivityManager.isHighEndGfx()) { + if (!targetPreL && a.getBoolean( + com.android.internal.R.styleable.Window_windowDrawsSystemBarBackgrounds, + false)) { + setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, + FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags()); + } + decor.setOnSystemUiVisibilityChangeListener(decor); + } + mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000); + mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000); + if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { if (a.getBoolean( @@ -3522,6 +3590,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return (mLeftIconView = (ImageView)findViewById(com.android.internal.R.id.left_icon)); } + @Override + protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) { + super.dispatchWindowAttributesChanged(attrs); + if (mDecor != null) { + mDecor.updateColorViews(null /* insets */); + } + } + private ProgressBar getCircularProgressBar(boolean shouldInstallDecor) { if (mCircularProgressBar != null) { return mCircularProgressBar; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 4ee8103..8eed414 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -170,7 +170,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.STATUS_BAR_TRANSLUCENT - | View.NAVIGATION_BAR_TRANSLUCENT; + | View.NAVIGATION_BAR_TRANSLUCENT + | View.SYSTEM_UI_TRANSPARENT; /** * Keyguard stuff @@ -1368,6 +1369,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { // The status bar is the only window allowed to exhibit keyguard behavior. attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; } + + if (ActivityManager.isHighEndGfx() + && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) { + attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + } } void readLidState() { @@ -2708,7 +2716,8 @@ 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 navTranslucent = (sysui & View.NAVIGATION_BAR_TRANSLUCENT) != 0; + boolean navTranslucent = (sysui + & (View.NAVIGATION_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT)) != 0; boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; boolean navAllowedHidden = immersive || immersiveSticky; @@ -2834,7 +2843,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStableTop = mUnrestrictedScreenTop + mStatusBarHeight; boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0; - boolean statusBarTranslucent = (sysui & View.STATUS_BAR_TRANSLUCENT) != 0; + boolean statusBarTranslucent = (sysui + & (View.STATUS_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT)) != 0; statusBarTranslucent &= areTranslucentBarsAllowed(); // If the status bar is hidden, we don't want to cause @@ -3030,12 +3040,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (isAppWindow && !inheritTranslucentDecor && !topAtRest) { if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 && (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0 - && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0) { + && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0 + && (fl & WindowManager.LayoutParams. + FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) { // Ensure policy decor includes status bar dcf.top = mStableTop; } if ((fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == 0 - && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { + && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 + && (fl & WindowManager.LayoutParams. + FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) { // Ensure policy decor includes navigation bar dcf.bottom = mStableBottom; dcf.right = mStableRight; @@ -5232,7 +5246,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if (!areTranslucentBarsAllowed()) { - vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT); + vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT + | View.SYSTEM_UI_TRANSPARENT); } // update status bar |