From 8e879f1fec1ca6c641f270b58447033ab4671851 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Wed, 25 May 2016 16:41:49 -0700 Subject: [PATCH] Enforce background fallback to be non-translucent To avoid screen garbage or wallpaper shining through, the background we use there for filling the whole needs to a) Be non-translucent in all cases except if the window is translucent. b) Don't infer it from the theme as it might be unexpected. Don't define it in the theme, and use black if it's not defined. Bug: 28763785 Change-Id: Ifb724b5c5feea3ed70d68e5bd7615fa91185e743 --- .../android/internal/policy/DecorView.java | 40 +++++++++++++++---- .../android/internal/policy/PhoneWindow.java | 7 ++++ core/res/res/values/themes.xml | 1 - 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index f5966362fdb29..a0652197d7b4d 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -45,6 +45,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Shader; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.RemoteException; import android.util.DisplayMetrics; @@ -907,10 +908,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind if (getBackground() != drawable) { setBackgroundDrawable(drawable); if (drawable != null) { - mResizingBackgroundDrawable = drawable; + mResizingBackgroundDrawable = enforceNonTranslucentBackground(drawable, + mWindow.isTranslucent() || mWindow.isShowingWallpaper()); } else { mResizingBackgroundDrawable = getResizingBackgroundDrawable( - getContext(), 0, mWindow.mBackgroundFallbackResource); + getContext(), 0, mWindow.mBackgroundFallbackResource, + mWindow.isTranslucent() || mWindow.isShowingWallpaper()); } if (mResizingBackgroundDrawable != null) { mResizingBackgroundDrawable.getPadding(mBackgroundPadding); @@ -1785,7 +1788,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind private void loadBackgroundDrawablesIfNeeded() { if (mResizingBackgroundDrawable == null) { mResizingBackgroundDrawable = getResizingBackgroundDrawable(getContext(), - mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource); + mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource, + mWindow.isTranslucent() || mWindow.isShowingWallpaper()); if (mResizingBackgroundDrawable == null) { // We shouldn't really get here as the background fallback should be always // available since it is defaulted by the system. @@ -1893,21 +1897,41 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind * user is resizing the window of an activity in multi-window mode. */ public static Drawable getResizingBackgroundDrawable(Context context, int backgroundRes, - int backgroundFallbackRes) { + int backgroundFallbackRes, boolean windowTranslucent) { if (backgroundRes != 0) { final Drawable drawable = context.getDrawable(backgroundRes); if (drawable != null) { - return drawable; + return enforceNonTranslucentBackground(drawable, windowTranslucent); } } if (backgroundFallbackRes != 0) { final Drawable fallbackDrawable = context.getDrawable(backgroundFallbackRes); if (fallbackDrawable != null) { - return fallbackDrawable; + return enforceNonTranslucentBackground(fallbackDrawable, windowTranslucent); } } - return null; + return new ColorDrawable(Color.BLACK); + } + + /** + * Enforces a drawable to be non-translucent to act as a background if needed, i.e. if the + * window is not translucent. + */ + private static Drawable enforceNonTranslucentBackground(Drawable drawable, + boolean windowTranslucent) { + if (!windowTranslucent && drawable instanceof ColorDrawable) { + ColorDrawable colorDrawable = (ColorDrawable) drawable; + int color = colorDrawable.getColor(); + if (Color.alpha(color) != 255) { + ColorDrawable copy = (ColorDrawable) colorDrawable.getConstantState().newDrawable() + .mutate(); + copy.setColor( + Color.argb(255, Color.red(color), Color.green(color), Color.blue(color))); + return copy; + } + } + return drawable; } /** @@ -2037,7 +2061,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind private void drawResizingShadowIfNeeded(DisplayListCanvas canvas) { if (mResizeMode != RESIZE_MODE_DOCKED_DIVIDER || mWindow.mIsFloating || mWindow.isTranslucent() - || (mWindow.getAttributes().flags & FLAG_SHOW_WALLPAPER) != 0) { + || mWindow.isShowingWallpaper()) { return; } canvas.save(); diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 4f15ece8e04e0..9ad750d3a5994 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -508,6 +508,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return mIsTranslucent; } + /** + * @return Whether the window is currently showing the wallpaper. + */ + boolean isShowingWallpaper() { + return (getAttributes().flags & FLAG_SHOW_WALLPAPER) != 0; + } + /** * Return a LayoutInflater instance that can be used to inflate XML view layout * resources for use in this Window. diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 998eea5ac9ab7..aecda44a6583e 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -174,7 +174,6 @@ please see themes_device_defaults.xml. @drawable/screen_background_selector_dark - ?attr/colorBackground false @null false