Loading core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java→core/java/com/android/internal/colorextraction/drawable/ScrimDrawable.java +17 −104 Original line number Original line Diff line number Diff line Loading @@ -11,7 +11,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * See the License for the specific language governing permissions and * limitations under the License * limitations under the License. */ */ package com.android.internal.colorextraction.drawable; package com.android.internal.colorextraction.drawable; Loading @@ -21,64 +21,42 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.Context; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PixelFormat; import android.graphics.RadialGradient; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.Xfermode; import android.graphics.Xfermode; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.graphics.ColorUtils; import com.android.internal.graphics.ColorUtils; /** /** * Draws a gradient based on a Palette * Drawable used on SysUI scrims. */ */ public class GradientDrawable extends Drawable { public class ScrimDrawable extends Drawable { private static final String TAG = "GradientDrawable"; private static final String TAG = "ScrimDrawable"; private static final float CENTRALIZED_CIRCLE_1 = -2; private static final int GRADIENT_RADIUS = 480; // in dp private static final long COLOR_ANIMATION_DURATION = 2000; private static final long COLOR_ANIMATION_DURATION = 2000; private int mAlpha = 255; private float mDensity; private final Paint mPaint; private final Paint mPaint; private final Rect mWindowBounds; private int mAlpha = 255; private final Splat mSplat; private int mMainColor; private int mMainColor; private int mSecondaryColor; private ValueAnimator mColorAnimation; private ValueAnimator mColorAnimation; private int mMainColorTo; private int mMainColorTo; private int mSecondaryColorTo; public GradientDrawable(@NonNull Context context) { mDensity = context.getResources().getDisplayMetrics().density; mSplat = new Splat(0.50f, 1.00f, GRADIENT_RADIUS, CENTRALIZED_CIRCLE_1); mWindowBounds = new Rect(); public ScrimDrawable() { mPaint = new Paint(); mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); mPaint.setStyle(Paint.Style.FILL); } } public void setColors(@NonNull ColorExtractor.GradientColors colors) { /** setColors(colors.getMainColor(), colors.getSecondaryColor(), true); * Sets the background color. } * @param mainColor the color. * @param animated if transition should be interpolated. public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) { */ setColors(colors.getMainColor(), colors.getSecondaryColor(), animated); public void setColor(int mainColor, boolean animated) { } if (mainColor == mMainColorTo) { public void setColors(int mainColor, int secondaryColor, boolean animated) { if (mainColor == mMainColorTo && secondaryColor == mSecondaryColorTo) { return; return; } } Loading @@ -87,19 +65,15 @@ public class GradientDrawable extends Drawable { } } mMainColorTo = mainColor; mMainColorTo = mainColor; mSecondaryColorTo = mainColor; if (animated) { if (animated) { final int mainFrom = mMainColor; final int mainFrom = mMainColor; final int secFrom = mSecondaryColor; ValueAnimator anim = ValueAnimator.ofFloat(0, 1); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); anim.setDuration(COLOR_ANIMATION_DURATION); anim.setDuration(COLOR_ANIMATION_DURATION); anim.addUpdateListener(animation -> { anim.addUpdateListener(animation -> { float ratio = (float) animation.getAnimatedValue(); float ratio = (float) animation.getAnimatedValue(); mMainColor = ColorUtils.blendARGB(mainFrom, mainColor, ratio); mMainColor = ColorUtils.blendARGB(mainFrom, mainColor, ratio); mSecondaryColor = ColorUtils.blendARGB(secFrom, secondaryColor, ratio); buildPaints(); invalidateSelf(); invalidateSelf(); }); }); anim.addListener(new AnimatorListenerAdapter() { anim.addListener(new AnimatorListenerAdapter() { Loading @@ -115,8 +89,6 @@ public class GradientDrawable extends Drawable { mColorAnimation = anim; mColorAnimation = anim; } else { } else { mMainColor = mainColor; mMainColor = mainColor; mSecondaryColor = secondaryColor; buildPaints(); invalidateSelf(); invalidateSelf(); } } } } Loading @@ -125,7 +97,6 @@ public class GradientDrawable extends Drawable { public void setAlpha(int alpha) { public void setAlpha(int alpha) { if (alpha != mAlpha) { if (alpha != mAlpha) { mAlpha = alpha; mAlpha = alpha; mPaint.setAlpha(mAlpha); invalidateSelf(); invalidateSelf(); } } } } Loading Loading @@ -156,73 +127,15 @@ public class GradientDrawable extends Drawable { return PixelFormat.TRANSLUCENT; return PixelFormat.TRANSLUCENT; } } public void setScreenSize(int width, int height) { mWindowBounds.set(0, 0, width, height); setBounds(0, 0, width, height); buildPaints(); } private void buildPaints() { Rect bounds = mWindowBounds; if (bounds.width() == 0) { return; } float w = bounds.width(); float h = bounds.height(); float x = mSplat.x * w; float y = mSplat.y * h; float radius = mSplat.radius * mDensity; // When we have only a single alpha gradient, we increase quality // (avoiding banding) by merging the background solid color into // the gradient directly RadialGradient radialGradient = new RadialGradient(x, y, radius, mSecondaryColor, mMainColor, Shader.TileMode.CLAMP); mPaint.setShader(radialGradient); } @Override @Override public void draw(@NonNull Canvas canvas) { public void draw(@NonNull Canvas canvas) { Rect bounds = mWindowBounds; mPaint.setColor(mMainColor); if (bounds.width() == 0) { mPaint.setAlpha(mAlpha); throw new IllegalStateException("You need to call setScreenSize before drawing."); canvas.drawRect(getBounds(), mPaint); } // Splat each gradient float w = bounds.width(); float h = bounds.height(); float x = mSplat.x * w; float y = mSplat.y * h; float radius = Math.max(w, h); canvas.drawRect(x - radius, y - radius, x + radius, y + radius, mPaint); } } @VisibleForTesting @VisibleForTesting public int getMainColor() { public int getMainColor() { return mMainColor; return mMainColor; } } @VisibleForTesting public int getSecondaryColor() { return mSecondaryColor; } static final class Splat { final float x; final float y; final float radius; final float colorIndex; Splat(float x, float y, float radius, float colorIndex) { this.x = x; this.y = y; this.radius = radius; this.colorIndex = colorIndex; } } } } core/java/com/android/internal/colorextraction/types/Tonal.java +20 −3 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.WallpaperColors; import android.app.WallpaperColors; import android.content.Context; import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.Color; import android.util.Log; import android.util.Log; import android.util.MathUtils; import android.util.MathUtils; Loading Loading @@ -51,11 +52,13 @@ public class Tonal implements ExtractionType { private static final boolean DEBUG = true; private static final boolean DEBUG = true; public static final int MAIN_COLOR_LIGHT = 0xffe0e0e0; public static final int MAIN_COLOR_LIGHT = 0xffdadce0; public static final int MAIN_COLOR_DARK = 0xff212121; public static final int MAIN_COLOR_DARK = 0xff202124; public static final int MAIN_COLOR_REGULAR = 0xff000000; private final TonalPalette mGreyPalette; private final TonalPalette mGreyPalette; private final ArrayList<TonalPalette> mTonalPalettes; private final ArrayList<TonalPalette> mTonalPalettes; private final Context mContext; // Temporary variable to avoid allocations // Temporary variable to avoid allocations private float[] mTmpHSL = new float[3]; private float[] mTmpHSL = new float[3]; Loading @@ -64,6 +67,7 @@ public class Tonal implements ExtractionType { ConfigParser parser = new ConfigParser(context); ConfigParser parser = new ConfigParser(context); mTonalPalettes = parser.getTonalPalettes(); mTonalPalettes = parser.getTonalPalettes(); mContext = context; mGreyPalette = mTonalPalettes.get(0); mGreyPalette = mTonalPalettes.get(0); mTonalPalettes.remove(0); mTonalPalettes.remove(0); Loading Loading @@ -247,7 +251,20 @@ public class Tonal implements ExtractionType { boolean light = inWallpaperColors != null boolean light = inWallpaperColors != null && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0; != 0; final int color = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK; boolean dark = inWallpaperColors != null && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0; final int color; final boolean inNightMode = (mContext.getResources().getConfiguration().uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; if (light) { color = MAIN_COLOR_LIGHT; } else if (dark || inNightMode) { color = MAIN_COLOR_DARK; } else { color = MAIN_COLOR_REGULAR; } final float[] hsl = new float[3]; final float[] hsl = new float[3]; ColorUtils.colorToHSL(color, hsl); ColorUtils.colorToHSL(color, hsl); Loading packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java +4 −7 Original line number Original line Diff line number Diff line Loading @@ -87,13 +87,13 @@ import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.recents.model.RecentsTaskLoadPlan; import com.android.systemui.recents.model.RecentsTaskLoadPlan; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.recents.views.RecentsView; import com.android.systemui.recents.views.RecentsView; import com.android.systemui.recents.views.SystemBarScrimViews; import com.android.systemui.recents.views.SystemBarScrimViews; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.ActivityManagerWrapper; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading Loading @@ -370,8 +370,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY); MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY); // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. ColorExtractor.GradientColors systemColors = mColorExtractor.getColors( ColorExtractor.GradientColors systemColors = mColorExtractor.getNeutralColors(); ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true); // We don't want to interpolate colors because we're defining the initial state. // We don't want to interpolate colors because we're defining the initial state. // Gradient should be set/ready when you open "Recents". // Gradient should be set/ready when you open "Recents". mRecentsView.setScrimColors(systemColors, false); mRecentsView.setScrimColors(systemColors, false); Loading @@ -397,9 +396,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { // Recents doesn't care about the wallpaper being visible or not, it always // Recents doesn't care about the wallpaper being visible or not, it always // wants to scrim with wallpaper colors // wants to scrim with wallpaper colors ColorExtractor.GradientColors colors = mColorExtractor.getColors( ColorExtractor.GradientColors colors = mColorExtractor.getNeutralColors(); WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_DARK, true /* ignoreVis */); boolean darkText = colors.supportsDarkText(); boolean darkText = colors.supportsDarkText(); if (darkText != mUsingDarkText) { if (darkText != mUsingDarkText) { mUsingDarkText = darkText; mUsingDarkText = darkText; Loading packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/RecentsView.java +5 −7 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Handler; import android.os.IRemoteCallback; import android.util.ArraySet; import android.util.ArraySet; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; Loading @@ -50,7 +49,7 @@ import android.widget.FrameLayout; import android.widget.TextView; import android.widget.TextView; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.drawable.GradientDrawable; import com.android.internal.colorextraction.drawable.ScrimDrawable; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; import com.android.settingslib.Utils; Loading Loading @@ -87,9 +86,9 @@ import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent; import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture; import com.android.systemui.shared.recents.view.RecentsTransition; import com.android.systemui.shared.recents.view.RecentsTransition; Loading Loading @@ -134,7 +133,7 @@ public class RecentsView extends FrameLayout { private int mDividerSize; private int mDividerSize; private float mBusynessFactor; private float mBusynessFactor; private GradientDrawable mBackgroundScrim; private ScrimDrawable mBackgroundScrim; private ColorDrawable mMultiWindowBackgroundScrim; private ColorDrawable mMultiWindowBackgroundScrim; private ValueAnimator mBackgroundScrimAnimator; private ValueAnimator mBackgroundScrimAnimator; private Point mTmpDisplaySize = new Point(); private Point mTmpDisplaySize = new Point(); Loading Loading @@ -172,7 +171,7 @@ public class RecentsView extends FrameLayout { mDividerSize = ssp.getDockedDividerSize(context); mDividerSize = ssp.getDockedDividerSize(context); mTouchHandler = new RecentsViewTouchHandler(this); mTouchHandler = new RecentsViewTouchHandler(this); mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f); mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f); mBackgroundScrim = new GradientDrawable(context); mBackgroundScrim = new ScrimDrawable(); mMultiWindowBackgroundScrim = new ColorDrawable(); mMultiWindowBackgroundScrim = new ColorDrawable(); LayoutInflater inflater = LayoutInflater.from(context); LayoutInflater inflater = LayoutInflater.from(context); Loading Loading @@ -395,7 +394,7 @@ public class RecentsView extends FrameLayout { * @param animated Interpolate colors if true. * @param animated Interpolate colors if true. */ */ public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) { public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) { mBackgroundScrim.setColors(scrimColors, animated); mBackgroundScrim.setColor(scrimColors.getMainColor(), animated); int alpha = mMultiWindowBackgroundScrim.getAlpha(); int alpha = mMultiWindowBackgroundScrim.getAlpha(); mMultiWindowBackgroundScrim.setColor(scrimColors.getMainColor()); mMultiWindowBackgroundScrim.setColor(scrimColors.getMainColor()); mMultiWindowBackgroundScrim.setAlpha(alpha); mMultiWindowBackgroundScrim.setAlpha(alpha); Loading Loading @@ -467,7 +466,6 @@ public class RecentsView extends FrameLayout { // Needs to know the screen size since the gradient never scales up or down // Needs to know the screen size since the gradient never scales up or down // even when bounds change. // even when bounds change. mContext.getDisplay().getRealSize(mTmpDisplaySize); mContext.getDisplay().getRealSize(mTmpDisplaySize); mBackgroundScrim.setScreenSize(mTmpDisplaySize.x, mTmpDisplaySize.y); mBackgroundScrim.setBounds(left, top, right, bottom); mBackgroundScrim.setBounds(left, top, right, bottom); mMultiWindowBackgroundScrim.setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y); mMultiWindowBackgroundScrim.setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y); Loading packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +23 −6 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.Tonal; import com.android.internal.colorextraction.types.Tonal; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; import com.android.systemui.Dumpable; import com.android.systemui.statusbar.policy.ConfigurationController; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading @@ -46,7 +47,8 @@ import javax.inject.Singleton; * ColorExtractor aware of wallpaper visibility * ColorExtractor aware of wallpaper visibility */ */ @Singleton @Singleton public class SysuiColorExtractor extends ColorExtractor implements Dumpable { public class SysuiColorExtractor extends ColorExtractor implements Dumpable, ConfigurationController.ConfigurationListener { private static final String TAG = "SysuiColorExtractor"; private static final String TAG = "SysuiColorExtractor"; private final Tonal mTonal; private final Tonal mTonal; private boolean mWallpaperVisible; private boolean mWallpaperVisible; Loading @@ -55,15 +57,17 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { private final GradientColors mWpHiddenColors; private final GradientColors mWpHiddenColors; @Inject @Inject public SysuiColorExtractor(Context context) { public SysuiColorExtractor(Context context, ConfigurationController configurationController) { this(context, new Tonal(context), true); this(context, new Tonal(context), configurationController, true); } } @VisibleForTesting @VisibleForTesting public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) { public SysuiColorExtractor(Context context, ExtractionType type, ConfigurationController configurationController, boolean registerVisibility) { super(context, type, false /* immediately */); super(context, type, false /* immediately */); mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context); mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context); mWpHiddenColors = new GradientColors(); mWpHiddenColors = new GradientColors(); configurationController.addCallback(this); WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); updateDefaultGradients(systemColors); updateDefaultGradients(systemColors); Loading Loading @@ -113,8 +117,21 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { } } } } @VisibleForTesting @Override GradientColors getFallbackColors() { public void onUiModeChanged() { WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); updateDefaultGradients(systemColors); } /** * Colors the should be using for scrims. * * They will be: * - A light gray if the wallpaper is light * - A dark gray if the wallpaper is very dark or we're in night mode. * - Black otherwise */ public GradientColors getNeutralColors() { return mWpHiddenColors; return mWpHiddenColors; } } Loading Loading
core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java→core/java/com/android/internal/colorextraction/drawable/ScrimDrawable.java +17 −104 Original line number Original line Diff line number Diff line Loading @@ -11,7 +11,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * See the License for the specific language governing permissions and * limitations under the License * limitations under the License. */ */ package com.android.internal.colorextraction.drawable; package com.android.internal.colorextraction.drawable; Loading @@ -21,64 +21,42 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.Context; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PixelFormat; import android.graphics.RadialGradient; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.Xfermode; import android.graphics.Xfermode; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.graphics.ColorUtils; import com.android.internal.graphics.ColorUtils; /** /** * Draws a gradient based on a Palette * Drawable used on SysUI scrims. */ */ public class GradientDrawable extends Drawable { public class ScrimDrawable extends Drawable { private static final String TAG = "GradientDrawable"; private static final String TAG = "ScrimDrawable"; private static final float CENTRALIZED_CIRCLE_1 = -2; private static final int GRADIENT_RADIUS = 480; // in dp private static final long COLOR_ANIMATION_DURATION = 2000; private static final long COLOR_ANIMATION_DURATION = 2000; private int mAlpha = 255; private float mDensity; private final Paint mPaint; private final Paint mPaint; private final Rect mWindowBounds; private int mAlpha = 255; private final Splat mSplat; private int mMainColor; private int mMainColor; private int mSecondaryColor; private ValueAnimator mColorAnimation; private ValueAnimator mColorAnimation; private int mMainColorTo; private int mMainColorTo; private int mSecondaryColorTo; public GradientDrawable(@NonNull Context context) { mDensity = context.getResources().getDisplayMetrics().density; mSplat = new Splat(0.50f, 1.00f, GRADIENT_RADIUS, CENTRALIZED_CIRCLE_1); mWindowBounds = new Rect(); public ScrimDrawable() { mPaint = new Paint(); mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); mPaint.setStyle(Paint.Style.FILL); } } public void setColors(@NonNull ColorExtractor.GradientColors colors) { /** setColors(colors.getMainColor(), colors.getSecondaryColor(), true); * Sets the background color. } * @param mainColor the color. * @param animated if transition should be interpolated. public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) { */ setColors(colors.getMainColor(), colors.getSecondaryColor(), animated); public void setColor(int mainColor, boolean animated) { } if (mainColor == mMainColorTo) { public void setColors(int mainColor, int secondaryColor, boolean animated) { if (mainColor == mMainColorTo && secondaryColor == mSecondaryColorTo) { return; return; } } Loading @@ -87,19 +65,15 @@ public class GradientDrawable extends Drawable { } } mMainColorTo = mainColor; mMainColorTo = mainColor; mSecondaryColorTo = mainColor; if (animated) { if (animated) { final int mainFrom = mMainColor; final int mainFrom = mMainColor; final int secFrom = mSecondaryColor; ValueAnimator anim = ValueAnimator.ofFloat(0, 1); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); anim.setDuration(COLOR_ANIMATION_DURATION); anim.setDuration(COLOR_ANIMATION_DURATION); anim.addUpdateListener(animation -> { anim.addUpdateListener(animation -> { float ratio = (float) animation.getAnimatedValue(); float ratio = (float) animation.getAnimatedValue(); mMainColor = ColorUtils.blendARGB(mainFrom, mainColor, ratio); mMainColor = ColorUtils.blendARGB(mainFrom, mainColor, ratio); mSecondaryColor = ColorUtils.blendARGB(secFrom, secondaryColor, ratio); buildPaints(); invalidateSelf(); invalidateSelf(); }); }); anim.addListener(new AnimatorListenerAdapter() { anim.addListener(new AnimatorListenerAdapter() { Loading @@ -115,8 +89,6 @@ public class GradientDrawable extends Drawable { mColorAnimation = anim; mColorAnimation = anim; } else { } else { mMainColor = mainColor; mMainColor = mainColor; mSecondaryColor = secondaryColor; buildPaints(); invalidateSelf(); invalidateSelf(); } } } } Loading @@ -125,7 +97,6 @@ public class GradientDrawable extends Drawable { public void setAlpha(int alpha) { public void setAlpha(int alpha) { if (alpha != mAlpha) { if (alpha != mAlpha) { mAlpha = alpha; mAlpha = alpha; mPaint.setAlpha(mAlpha); invalidateSelf(); invalidateSelf(); } } } } Loading Loading @@ -156,73 +127,15 @@ public class GradientDrawable extends Drawable { return PixelFormat.TRANSLUCENT; return PixelFormat.TRANSLUCENT; } } public void setScreenSize(int width, int height) { mWindowBounds.set(0, 0, width, height); setBounds(0, 0, width, height); buildPaints(); } private void buildPaints() { Rect bounds = mWindowBounds; if (bounds.width() == 0) { return; } float w = bounds.width(); float h = bounds.height(); float x = mSplat.x * w; float y = mSplat.y * h; float radius = mSplat.radius * mDensity; // When we have only a single alpha gradient, we increase quality // (avoiding banding) by merging the background solid color into // the gradient directly RadialGradient radialGradient = new RadialGradient(x, y, radius, mSecondaryColor, mMainColor, Shader.TileMode.CLAMP); mPaint.setShader(radialGradient); } @Override @Override public void draw(@NonNull Canvas canvas) { public void draw(@NonNull Canvas canvas) { Rect bounds = mWindowBounds; mPaint.setColor(mMainColor); if (bounds.width() == 0) { mPaint.setAlpha(mAlpha); throw new IllegalStateException("You need to call setScreenSize before drawing."); canvas.drawRect(getBounds(), mPaint); } // Splat each gradient float w = bounds.width(); float h = bounds.height(); float x = mSplat.x * w; float y = mSplat.y * h; float radius = Math.max(w, h); canvas.drawRect(x - radius, y - radius, x + radius, y + radius, mPaint); } } @VisibleForTesting @VisibleForTesting public int getMainColor() { public int getMainColor() { return mMainColor; return mMainColor; } } @VisibleForTesting public int getSecondaryColor() { return mSecondaryColor; } static final class Splat { final float x; final float y; final float radius; final float colorIndex; Splat(float x, float y, float radius, float colorIndex) { this.x = x; this.y = y; this.radius = radius; this.colorIndex = colorIndex; } } } }
core/java/com/android/internal/colorextraction/types/Tonal.java +20 −3 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.WallpaperColors; import android.app.WallpaperColors; import android.content.Context; import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.Color; import android.util.Log; import android.util.Log; import android.util.MathUtils; import android.util.MathUtils; Loading Loading @@ -51,11 +52,13 @@ public class Tonal implements ExtractionType { private static final boolean DEBUG = true; private static final boolean DEBUG = true; public static final int MAIN_COLOR_LIGHT = 0xffe0e0e0; public static final int MAIN_COLOR_LIGHT = 0xffdadce0; public static final int MAIN_COLOR_DARK = 0xff212121; public static final int MAIN_COLOR_DARK = 0xff202124; public static final int MAIN_COLOR_REGULAR = 0xff000000; private final TonalPalette mGreyPalette; private final TonalPalette mGreyPalette; private final ArrayList<TonalPalette> mTonalPalettes; private final ArrayList<TonalPalette> mTonalPalettes; private final Context mContext; // Temporary variable to avoid allocations // Temporary variable to avoid allocations private float[] mTmpHSL = new float[3]; private float[] mTmpHSL = new float[3]; Loading @@ -64,6 +67,7 @@ public class Tonal implements ExtractionType { ConfigParser parser = new ConfigParser(context); ConfigParser parser = new ConfigParser(context); mTonalPalettes = parser.getTonalPalettes(); mTonalPalettes = parser.getTonalPalettes(); mContext = context; mGreyPalette = mTonalPalettes.get(0); mGreyPalette = mTonalPalettes.get(0); mTonalPalettes.remove(0); mTonalPalettes.remove(0); Loading Loading @@ -247,7 +251,20 @@ public class Tonal implements ExtractionType { boolean light = inWallpaperColors != null boolean light = inWallpaperColors != null && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0; != 0; final int color = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK; boolean dark = inWallpaperColors != null && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0; final int color; final boolean inNightMode = (mContext.getResources().getConfiguration().uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; if (light) { color = MAIN_COLOR_LIGHT; } else if (dark || inNightMode) { color = MAIN_COLOR_DARK; } else { color = MAIN_COLOR_REGULAR; } final float[] hsl = new float[3]; final float[] hsl = new float[3]; ColorUtils.colorToHSL(color, hsl); ColorUtils.colorToHSL(color, hsl); Loading
packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java +4 −7 Original line number Original line Diff line number Diff line Loading @@ -87,13 +87,13 @@ import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction; import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.recents.model.RecentsTaskLoadPlan; import com.android.systemui.recents.model.RecentsTaskLoadPlan; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.recents.views.RecentsView; import com.android.systemui.recents.views.RecentsView; import com.android.systemui.recents.views.SystemBarScrimViews; import com.android.systemui.recents.views.SystemBarScrimViews; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.ActivityManagerWrapper; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading Loading @@ -370,8 +370,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY); MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY); // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. ColorExtractor.GradientColors systemColors = mColorExtractor.getColors( ColorExtractor.GradientColors systemColors = mColorExtractor.getNeutralColors(); ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true); // We don't want to interpolate colors because we're defining the initial state. // We don't want to interpolate colors because we're defining the initial state. // Gradient should be set/ready when you open "Recents". // Gradient should be set/ready when you open "Recents". mRecentsView.setScrimColors(systemColors, false); mRecentsView.setScrimColors(systemColors, false); Loading @@ -397,9 +396,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { // Recents doesn't care about the wallpaper being visible or not, it always // Recents doesn't care about the wallpaper being visible or not, it always // wants to scrim with wallpaper colors // wants to scrim with wallpaper colors ColorExtractor.GradientColors colors = mColorExtractor.getColors( ColorExtractor.GradientColors colors = mColorExtractor.getNeutralColors(); WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_DARK, true /* ignoreVis */); boolean darkText = colors.supportsDarkText(); boolean darkText = colors.supportsDarkText(); if (darkText != mUsingDarkText) { if (darkText != mUsingDarkText) { mUsingDarkText = darkText; mUsingDarkText = darkText; Loading
packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/RecentsView.java +5 −7 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Handler; import android.os.IRemoteCallback; import android.util.ArraySet; import android.util.ArraySet; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; Loading @@ -50,7 +49,7 @@ import android.widget.FrameLayout; import android.widget.TextView; import android.widget.TextView; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.drawable.GradientDrawable; import com.android.internal.colorextraction.drawable.ScrimDrawable; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; import com.android.settingslib.Utils; Loading Loading @@ -87,9 +86,9 @@ import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent; import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.recents.utilities.Utilities; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture; import com.android.systemui.shared.recents.view.RecentsTransition; import com.android.systemui.shared.recents.view.RecentsTransition; Loading Loading @@ -134,7 +133,7 @@ public class RecentsView extends FrameLayout { private int mDividerSize; private int mDividerSize; private float mBusynessFactor; private float mBusynessFactor; private GradientDrawable mBackgroundScrim; private ScrimDrawable mBackgroundScrim; private ColorDrawable mMultiWindowBackgroundScrim; private ColorDrawable mMultiWindowBackgroundScrim; private ValueAnimator mBackgroundScrimAnimator; private ValueAnimator mBackgroundScrimAnimator; private Point mTmpDisplaySize = new Point(); private Point mTmpDisplaySize = new Point(); Loading Loading @@ -172,7 +171,7 @@ public class RecentsView extends FrameLayout { mDividerSize = ssp.getDockedDividerSize(context); mDividerSize = ssp.getDockedDividerSize(context); mTouchHandler = new RecentsViewTouchHandler(this); mTouchHandler = new RecentsViewTouchHandler(this); mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f); mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f); mBackgroundScrim = new GradientDrawable(context); mBackgroundScrim = new ScrimDrawable(); mMultiWindowBackgroundScrim = new ColorDrawable(); mMultiWindowBackgroundScrim = new ColorDrawable(); LayoutInflater inflater = LayoutInflater.from(context); LayoutInflater inflater = LayoutInflater.from(context); Loading Loading @@ -395,7 +394,7 @@ public class RecentsView extends FrameLayout { * @param animated Interpolate colors if true. * @param animated Interpolate colors if true. */ */ public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) { public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) { mBackgroundScrim.setColors(scrimColors, animated); mBackgroundScrim.setColor(scrimColors.getMainColor(), animated); int alpha = mMultiWindowBackgroundScrim.getAlpha(); int alpha = mMultiWindowBackgroundScrim.getAlpha(); mMultiWindowBackgroundScrim.setColor(scrimColors.getMainColor()); mMultiWindowBackgroundScrim.setColor(scrimColors.getMainColor()); mMultiWindowBackgroundScrim.setAlpha(alpha); mMultiWindowBackgroundScrim.setAlpha(alpha); Loading Loading @@ -467,7 +466,6 @@ public class RecentsView extends FrameLayout { // Needs to know the screen size since the gradient never scales up or down // Needs to know the screen size since the gradient never scales up or down // even when bounds change. // even when bounds change. mContext.getDisplay().getRealSize(mTmpDisplaySize); mContext.getDisplay().getRealSize(mTmpDisplaySize); mBackgroundScrim.setScreenSize(mTmpDisplaySize.x, mTmpDisplaySize.y); mBackgroundScrim.setBounds(left, top, right, bottom); mBackgroundScrim.setBounds(left, top, right, bottom); mMultiWindowBackgroundScrim.setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y); mMultiWindowBackgroundScrim.setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y); Loading
packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +23 −6 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.Tonal; import com.android.internal.colorextraction.types.Tonal; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; import com.android.systemui.Dumpable; import com.android.systemui.statusbar.policy.ConfigurationController; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading @@ -46,7 +47,8 @@ import javax.inject.Singleton; * ColorExtractor aware of wallpaper visibility * ColorExtractor aware of wallpaper visibility */ */ @Singleton @Singleton public class SysuiColorExtractor extends ColorExtractor implements Dumpable { public class SysuiColorExtractor extends ColorExtractor implements Dumpable, ConfigurationController.ConfigurationListener { private static final String TAG = "SysuiColorExtractor"; private static final String TAG = "SysuiColorExtractor"; private final Tonal mTonal; private final Tonal mTonal; private boolean mWallpaperVisible; private boolean mWallpaperVisible; Loading @@ -55,15 +57,17 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { private final GradientColors mWpHiddenColors; private final GradientColors mWpHiddenColors; @Inject @Inject public SysuiColorExtractor(Context context) { public SysuiColorExtractor(Context context, ConfigurationController configurationController) { this(context, new Tonal(context), true); this(context, new Tonal(context), configurationController, true); } } @VisibleForTesting @VisibleForTesting public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) { public SysuiColorExtractor(Context context, ExtractionType type, ConfigurationController configurationController, boolean registerVisibility) { super(context, type, false /* immediately */); super(context, type, false /* immediately */); mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context); mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context); mWpHiddenColors = new GradientColors(); mWpHiddenColors = new GradientColors(); configurationController.addCallback(this); WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); updateDefaultGradients(systemColors); updateDefaultGradients(systemColors); Loading Loading @@ -113,8 +117,21 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { } } } } @VisibleForTesting @Override GradientColors getFallbackColors() { public void onUiModeChanged() { WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); updateDefaultGradients(systemColors); } /** * Colors the should be using for scrims. * * They will be: * - A light gray if the wallpaper is light * - A dark gray if the wallpaper is very dark or we're in night mode. * - Black otherwise */ public GradientColors getNeutralColors() { return mWpHiddenColors; return mWpHiddenColors; } } Loading