OSDN Git Service

Colorize SystemUI
authorAdrian Roos <roosa@google.com>
Mon, 5 May 2014 11:33:03 +0000 (13:33 +0200)
committerAdrian Roos <roosa@google.com>
Thu, 15 May 2014 16:22:37 +0000 (18:22 +0200)
Makes the color of the status and navigation bars customizable by
the app.

Bug: 14564488
Change-Id: I036edc228cfe1b659c7f11a43cdc4598ee705ff8

13 files changed:
core/java/android/view/View.java
core/java/android/view/Window.java
packages/SystemUI/res/values/colors.xml
packages/SystemUI/res/values/styles.xml
packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
policy/src/com/android/internal/policy/impl/BarController.java
policy/src/com/android/internal/policy/impl/PhoneWindow.java
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
services/core/java/com/android/server/wm/WindowManagerService.java

index e829141..2008f9e 100644 (file)
@@ -2774,8 +2774,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
 
     /**
      * @hide
+     *
+     * Makes system ui transparent.
+     */
+    public static final int SYSTEM_UI_TRANSPARENT = 0x00008000;
+
+    /**
+     * @hide
      */
-    public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
+    public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00007FFF;
 
     /**
      * These are the system UI flags that can be cleared by events outside
index 4acc608..ecc4586 100644 (file)
@@ -642,9 +642,7 @@ public abstract class Window {
         final WindowManager.LayoutParams attrs = getAttributes();
         attrs.width = width;
         attrs.height = height;
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
 
     /**
@@ -661,9 +659,7 @@ public abstract class Window {
     {
         final WindowManager.LayoutParams attrs = getAttributes();
         attrs.gravity = gravity;
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
 
     /**
@@ -675,9 +671,7 @@ public abstract class Window {
     public void setType(int type) {
         final WindowManager.LayoutParams attrs = getAttributes();
         attrs.type = type;
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
 
     /**
@@ -700,9 +694,7 @@ public abstract class Window {
             attrs.format = mDefaultWindowFormat;
             mHaveWindowFormat = false;
         }
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
 
     /**
@@ -715,9 +707,7 @@ public abstract class Window {
     public void setWindowAnimations(int resId) {
         final WindowManager.LayoutParams attrs = getAttributes();
         attrs.windowAnimations = resId;
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
 
     /**
@@ -735,9 +725,7 @@ public abstract class Window {
         } else {
             mHasSoftInputMode = false;
         }
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
     
     /**
@@ -793,14 +781,19 @@ public abstract class Window {
             attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
         }
         mForcedWindowFlags |= mask;
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
 
     private void setPrivateFlags(int flags, int mask) {
         final WindowManager.LayoutParams attrs = getAttributes();
         attrs.privateFlags = (attrs.privateFlags & ~mask) | (flags & mask);
+        dispatchWindowAttributesChanged(attrs);
+    }
+
+    /**
+     * {@hide}
+     */
+    protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
         if (mCallback != null) {
             mCallback.onWindowAttributesChanged(attrs);
         }
@@ -818,9 +811,7 @@ public abstract class Window {
         final WindowManager.LayoutParams attrs = getAttributes();
         attrs.dimAmount = amount;
         mHaveDimAmount = true;
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(attrs);
-        }
+        dispatchWindowAttributesChanged(attrs);
     }
 
     /**
@@ -835,9 +826,7 @@ public abstract class Window {
      */
     public void setAttributes(WindowManager.LayoutParams a) {
         mWindowAttributes.copyFrom(a);
-        if (mCallback != null) {
-            mCallback.onWindowAttributesChanged(mWindowAttributes);
-        }
+        dispatchWindowAttributesChanged(mWindowAttributes);
     }
 
     /**
@@ -1269,9 +1258,7 @@ public abstract class Window {
         if (!mHaveWindowFormat) {
             final WindowManager.LayoutParams attrs = getAttributes();
             attrs.format = format;
-            if (mCallback != null) {
-                mCallback.onWindowAttributesChanged(attrs);
-            }
+            dispatchWindowAttributesChanged(attrs);
         }
     }
 
index 7de1bd0..9582b21 100644 (file)
@@ -22,6 +22,7 @@
     <drawable name="system_bar_background">@color/system_bar_background_opaque</drawable>
     <color name="system_bar_background_opaque">#ff000000</color>
     <color name="system_bar_background_semi_transparent">#66000000</color> <!-- 40% black -->
+    <color name="system_bar_background_transparent">#00000000</color>
     <color name="notification_panel_solid_background">#ff000000</color>
     <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
     <color name="status_bar_recents_app_label_color">#ffffffff</color>
index 1273e74..9536b12 100644 (file)
@@ -22,8 +22,9 @@
 
     <!-- Alternate Recents theme -->
     <style name="RecentsTheme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
-        <item name="android:windowTranslucentStatus">true</item>
-        <item name="android:windowTranslucentNavigation">true</item>
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
+        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
         <item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
     </style>
 
index eb63a54..a41ec22 100644 (file)
@@ -43,6 +43,7 @@ public class BarTransitions {
     public static final int MODE_SEMI_TRANSPARENT = 1;
     public static final int MODE_TRANSLUCENT = 2;
     public static final int MODE_LIGHTS_OUT = 3;
+    public static final int MODE_TRANSPARENT = 4;
 
     public static final int LIGHTS_IN_DURATION = 250;
     public static final int LIGHTS_OUT_DURATION = 750;
@@ -69,7 +70,8 @@ public class BarTransitions {
 
     public void transitionTo(int mode, boolean animate) {
         // low-end devices do not support translucent modes, fallback to opaque
-        if (!HIGH_END && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT)) {
+        if (!HIGH_END && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
+                || mode == MODE_TRANSPARENT)) {
             mode = MODE_OPAQUE;
         }
         if (mMode == mode) return;
@@ -97,6 +99,7 @@ public class BarTransitions {
         if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
         if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT";
         if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
+        if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
         throw new IllegalArgumentException("Unknown mode " + mode);
     }
 
@@ -111,6 +114,7 @@ public class BarTransitions {
     private static class BarBackgroundDrawable extends Drawable {
         private final int mOpaque;
         private final int mSemiTransparent;
+        private final int mTransparent;
         private final Drawable mGradient;
         private final TimeInterpolator mInterpolator;
 
@@ -130,9 +134,11 @@ public class BarTransitions {
             if (DEBUG_COLORS) {
                 mOpaque = 0xff0000ff;
                 mSemiTransparent = 0x7f0000ff;
+                mTransparent = 0x2f0000ff;
             } else {
                 mOpaque = res.getColor(R.color.system_bar_background_opaque);
                 mSemiTransparent = res.getColor(R.color.system_bar_background_semi_transparent);
+                mTransparent = res.getColor(R.color.system_bar_background_transparent);
             }
             mGradient = res.getDrawable(gradientResourceId);
             mInterpolator = new LinearInterpolator();
@@ -184,9 +190,11 @@ public class BarTransitions {
         public void draw(Canvas canvas) {
             int targetGradientAlpha = 0, targetColor = 0;
             if (mMode == MODE_TRANSLUCENT) {
-                targetGradientAlpha = 0xff;
+                targetColor = mSemiTransparent;
             } else if (mMode == MODE_SEMI_TRANSPARENT) {
                 targetColor = mSemiTransparent;
+            } else if (mMode == MODE_TRANSPARENT) {
+                targetColor = mTransparent;
             } else {
                 targetColor = mOpaque;
             }
index a0582ee..c83b479 100644 (file)
@@ -61,7 +61,7 @@ public final class NavigationBarTransitions extends BarTransitions {
     @Override
     public void transitionTo(int mode, boolean animate) {
         mRequestedMode = mode;
-        if (mVertical && mode == MODE_TRANSLUCENT) {
+        if (mVertical && (mode == MODE_TRANSLUCENT || mode == MODE_TRANSPARENT)) {
             // translucent mode not allowed when vertical
             mode = MODE_OPAQUE;
         }
index 23b0594..d3b5f96 100644 (file)
@@ -26,6 +26,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OU
 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_TRANSLUCENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -1870,6 +1871,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
     private int barMode(int vis, int transientFlag, int translucentFlag) {
         return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
                 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
+                : (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
                 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
                 : MODE_OPAQUE;
     }
index 8406565..8520f40 100644 (file)
@@ -68,7 +68,8 @@ public final class PhoneStatusBarTransitions extends BarTransitions {
     }
 
     private boolean isOpaque(int mode) {
-        return !(mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT);
+        return !(mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
+                || mode == MODE_TRANSPARENT);
     }
 
     @Override
index 46a637b..b7bf6cd 100644 (file)
@@ -75,8 +75,7 @@ public class StatusBarWindowManager {
                         | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                         | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                         | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
-                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
+                        | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
                 PixelFormat.TRANSLUCENT);
         mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
         mLp.gravity = Gravity.TOP;
index fc49a56..49e1072 100644 (file)
@@ -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;
index f6c8001..1b96f1f 100644 (file)
@@ -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;
index 4ee8103..8eed414 100644 (file)
@@ -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
index 836a19c..b61ba5c 100644 (file)
@@ -2806,18 +2806,10 @@ public class WindowManagerService extends IWindowManager.Stub
         boolean configChanged;
         boolean surfaceChanged = false;
         boolean animating;
+        boolean hasStatusBarPermission =
+                mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
+                        == PackageManager.PERMISSION_GRANTED;
 
-        // if they don't have this permission, mask out the status bar bits
-        int systemUiVisibility = 0;
-        if (attrs != null) {
-            systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
-            if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
-                if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
-                        != PackageManager.PERMISSION_GRANTED) {
-                    systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
-                }
-            }
-        }
         long origId = Binder.clearCallingIdentity();
 
         synchronized(mWindowMap) {
@@ -2832,14 +2824,26 @@ public class WindowManagerService extends IWindowManager.Stub
                 win.mRequestedWidth = requestedWidth;
                 win.mRequestedHeight = requestedHeight;
             }
-            if (attrs != null && seq == win.mSeq) {
-                win.mSystemUiVisibility = systemUiVisibility;
-            }
 
             if (attrs != null) {
                 mPolicy.adjustWindowParamsLw(attrs);
             }
 
+            // if they don't have the permission, mask out the status bar bits
+            int systemUiVisibility = 0;
+            if (attrs != null) {
+                systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
+                if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
+                    if (!hasStatusBarPermission) {
+                        systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
+                    }
+                }
+            }
+
+            if (attrs != null && seq == win.mSeq) {
+                win.mSystemUiVisibility = systemUiVisibility;
+            }
+
             winAnimator.mSurfaceDestroyDeferred =
                     (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;