From ed10f0ab6f8124b12681d36ab3b260ff342b2cd6 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Thu, 20 May 2021 15:50:04 +0200 Subject: [PATCH] Add an extra colored layer when animating launches (1/2) This CL adds an extra layer with the same color as the app background color when animating an app launch (e.g. from notification, QS, media, etc). This allows to avoid a "flash effect" that could be caused when the background color of the expanding view is bright, which is often the case for QS tiles. See b/188185381#comment5 for before/after videos. Bug: 186189658 Test: Long press a quick settings tile Change-Id: Ifc0cda3b03795549ddd7c333a9302e7ea298ac6a --- .../SplashscreenContentDrawer.java | 28 ++-- packages/SystemUI/animation/Android.bp | 1 + .../animation/ActivityLaunchAnimator.kt | 134 +++++++++++++++--- .../GhostedViewLaunchAnimatorController.kt | 53 ++----- .../row/ExpandableNotificationRow.java | 14 +- .../row/NotificationBackgroundView.java | 10 -- .../animation/ActivityLaunchAnimatorTest.kt | 11 +- 7 files changed, 170 insertions(+), 81 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java index 093c272193a3e..84a9ce52ffdc1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java @@ -135,7 +135,7 @@ public class SplashscreenContentDrawer { com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length); } - private int getSystemBGColor() { + private static int getSystemBGColor() { final Context systemContext = ActivityThread.currentApplication(); if (systemContext == null) { Slog.e(TAG, "System context does not exist!"); @@ -145,17 +145,18 @@ public class SplashscreenContentDrawer { return res.getColor(com.android.wm.shell.R.color.splash_window_background_default); } - private Drawable createDefaultBackgroundDrawable() { + private static Drawable createDefaultBackgroundDrawable() { return new ColorDrawable(getSystemBGColor()); } - private @ColorInt int peekWindowBGColor(Context context) { + /** Extract the window background color from {@code attrs}. */ + public static int peekWindowBGColor(Context context, SplashScreenWindowAttrs attrs) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "peekWindowBGColor"); final Drawable themeBGDrawable; - if (mTmpAttrs.mWindowBgColor != 0) { - themeBGDrawable = new ColorDrawable(mTmpAttrs.mWindowBgColor); - } else if (mTmpAttrs.mWindowBgResId != 0) { - themeBGDrawable = context.getDrawable(mTmpAttrs.mWindowBgResId); + if (attrs.mWindowBgColor != 0) { + themeBGDrawable = new ColorDrawable(attrs.mWindowBgColor); + } else if (attrs.mWindowBgResId != 0) { + themeBGDrawable = context.getDrawable(attrs.mWindowBgResId); } else { themeBGDrawable = createDefaultBackgroundDrawable(); Slog.w(TAG, "Window background does not exist, using " + themeBGDrawable); @@ -165,7 +166,7 @@ public class SplashscreenContentDrawer { return estimatedWindowBGColor; } - private int estimateWindowBGColor(Drawable themeBGDrawable) { + private static int estimateWindowBGColor(Drawable themeBGDrawable) { final DrawableColorTester themeBGTester = new DrawableColorTester(themeBGDrawable, true /* filterTransparent */); if (themeBGTester.nonTransparentRatio() == 0) { @@ -183,7 +184,7 @@ public class SplashscreenContentDrawer { getWindowAttrs(context, mTmpAttrs); final StartingWindowViewBuilder builder = new StartingWindowViewBuilder(); - final int themeBGColor = peekWindowBGColor(context); + final int themeBGColor = peekWindowBGColor(context, this.mTmpAttrs); // TODO (b/173975965) Tracking the performance on improved splash screen. return builder .setContext(context) @@ -193,7 +194,11 @@ public class SplashscreenContentDrawer { .build(); } - private static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) { + /** + * Get the {@link SplashScreenWindowAttrs} from {@code context} and fill them into + * {@code attrs}. + */ + public static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) { final TypedArray typedArray = context.obtainStyledAttributes( com.android.internal.R.styleable.Window); attrs.mWindowBgResId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0); @@ -216,7 +221,8 @@ public class SplashscreenContentDrawer { } } - private static class SplashScreenWindowAttrs { + /** The configuration of the splash screen window. */ + public static class SplashScreenWindowAttrs { private int mWindowBgResId = 0; private int mWindowBgColor = Color.TRANSPARENT; private Drawable mReplaceIcon = null; diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp index 1b15d20d2c52d..761b1f460bb5c 100644 --- a/packages/SystemUI/animation/Android.bp +++ b/packages/SystemUI/animation/Android.bp @@ -36,6 +36,7 @@ android_library { static_libs: [ "PluginCoreLib", + "WindowManager-Shell", ], manifest: "AndroidManifest.xml", diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index 2b87737830481..307d2a35166c5 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -5,13 +5,18 @@ import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.app.ActivityManager import android.app.ActivityTaskManager +import android.app.AppGlobals import android.app.PendingIntent import android.content.Context import android.graphics.Matrix +import android.graphics.PorterDuff +import android.graphics.PorterDuffXfermode import android.graphics.Rect import android.graphics.RectF +import android.graphics.drawable.GradientDrawable import android.os.Looper import android.os.RemoteException +import android.os.UserHandle import android.util.Log import android.util.MathUtils import android.view.IRemoteAnimationFinishedCallback @@ -26,6 +31,8 @@ import android.view.animation.AnimationUtils import android.view.animation.PathInterpolator import com.android.internal.annotations.VisibleForTesting import com.android.internal.policy.ScreenDecorationsUtils +import com.android.wm.shell.startingsurface.SplashscreenContentDrawer +import com.android.wm.shell.startingsurface.SplashscreenContentDrawer.SplashScreenWindowAttrs import kotlin.math.roundToInt /** @@ -37,9 +44,9 @@ class ActivityLaunchAnimator(context: Context) { companion object { const val ANIMATION_DURATION = 500L - const val ANIMATION_DURATION_FADE_OUT_CONTENT = 183L - const val ANIMATION_DURATION_FADE_IN_WINDOW = 217L - const val ANIMATION_DELAY_FADE_IN_WINDOW = 167L + private const val ANIMATION_DURATION_FADE_OUT_CONTENT = 150L + private const val ANIMATION_DURATION_FADE_IN_WINDOW = 183L + private const val ANIMATION_DELAY_FADE_IN_WINDOW = ANIMATION_DURATION_FADE_OUT_CONTENT private const val ANIMATION_DURATION_NAV_FADE_IN = 266L private const val ANIMATION_DURATION_NAV_FADE_OUT = 133L private const val ANIMATION_DELAY_NAV_FADE_IN = @@ -51,6 +58,8 @@ class ActivityLaunchAnimator(context: Context) { private val NAV_FADE_IN_INTERPOLATOR = PathInterpolator(0f, 0f, 0f, 1f) private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f) + private val SRC_MODE = PorterDuffXfermode(PorterDuff.Mode.SRC) + /** * Given the [linearProgress] of a launch animation, return the linear progress of the * sub-animation starting [delay] ms after the launch animation and that lasts [duration]. @@ -65,6 +74,8 @@ class ActivityLaunchAnimator(context: Context) { } } + private val packageManager = AppGlobals.getPackageManager() + /** The interpolator used for the width, height, Y position and corner radius. */ private val animationInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.launch_animation_interpolator_y) @@ -73,6 +84,8 @@ class ActivityLaunchAnimator(context: Context) { private val animationInterpolatorX = AnimationUtils.loadInterpolator(context, R.interpolator.launch_animation_interpolator_x) + private val cornerRadii = FloatArray(8) + /** * Start an intent and animate the opening window. The intent will be started by running * [intentStarter], which should use the provided [RemoteAnimationAdapter] and return the launch @@ -260,10 +273,7 @@ class ActivityLaunchAnimator(context: Context) { var right: Int, var topCornerRadius: Float = 0f, - var bottomCornerRadius: Float = 0f, - - var contentAlpha: Float = 1f, - var backgroundAlpha: Float = 1f + var bottomCornerRadius: Float = 0f ) { private val startTop = top private val startBottom = bottom @@ -303,6 +313,9 @@ class ActivityLaunchAnimator(context: Context) { val centerY: Float get() = top + height / 2f + + /** Whether the expanded view should be visible or hidden. */ + var visible: Boolean = true } @VisibleForTesting @@ -425,22 +438,39 @@ class ActivityLaunchAnimator(context: Context) { 0f } + // We add an extra layer with the same color as the app splash screen background color, + // which is usually the same color of the app background. We first fade in this layer + // to hide the expanding view, then we fade it out with SRC mode to draw a hole in the + // launch container and reveal the opening window. + val windowBackgroundColor = extractSplashScreenBackgroundColor(window) + val windowBackgroundLayer = GradientDrawable().apply { + setColor(windowBackgroundColor) + alpha = 0 + } + // Update state. val animator = ValueAnimator.ofFloat(0f, 1f) this.animator = animator animator.duration = ANIMATION_DURATION animator.interpolator = Interpolators.LINEAR + val launchContainerOverlay = launchContainer.overlay animator.addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?, isReverse: Boolean) { Log.d(TAG, "Animation started") controller.onLaunchAnimationStart(isExpandingFullyAbove) + + // Add the drawable to the launch container overlay. Overlays always draw + // drawables after views, so we know that it will be drawn above any view added + // by the controller. + launchContainerOverlay.add(windowBackgroundLayer) } override fun onAnimationEnd(animation: Animator?) { Log.d(TAG, "Animation ended") invokeCallback(iCallback) controller.onLaunchAnimationEnd(isExpandingFullyAbove) + launchContainerOverlay.remove(windowBackgroundLayer) } }) @@ -464,24 +494,61 @@ class ActivityLaunchAnimator(context: Context) { state.bottomCornerRadius = MathUtils.lerp(startBottomCornerRadius, endRadius, progress) - val contentAlphaProgress = getProgress(linearProgress, 0, - ANIMATION_DURATION_FADE_OUT_CONTENT) - state.contentAlpha = - 1 - CONTENT_FADE_OUT_INTERPOLATOR.getInterpolation(contentAlphaProgress) - - val backgroundAlphaProgress = getProgress(linearProgress, - ANIMATION_DELAY_FADE_IN_WINDOW, ANIMATION_DURATION_FADE_IN_WINDOW) - state.backgroundAlpha = - 1 - WINDOW_FADE_IN_INTERPOLATOR.getInterpolation(backgroundAlphaProgress) + // The expanding view can/should be hidden once it is completely coverred by the + // windowBackgroundLayer. + state.visible = + getProgress(linearProgress, 0, ANIMATION_DURATION_FADE_OUT_CONTENT) < 1 applyStateToWindow(window, state) + applyStateToWindowBackgroundLayer(windowBackgroundLayer, state, linearProgress) navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) } + + // If we started expanding the view, we make it 1 pixel smaller on all sides to + // avoid artefacts on the corners caused by anti-aliasing of the view background and + // the window background layer. + if (state.top != startTop && state.left != startLeft && + state.bottom != startBottom && state.right != startRight) { + state.top += 1 + state.left += 1 + state.right -= 1 + state.bottom -= 1 + } controller.onLaunchAnimationProgress(state, progress, linearProgress) } animator.start() } + /** Extract the background color of the app splash screen. */ + private fun extractSplashScreenBackgroundColor(window: RemoteAnimationTarget): Int { + val taskInfo = window.taskInfo + val windowPackage = taskInfo.topActivity.packageName + val userId = taskInfo.userId + val windowContext = context.createPackageContextAsUser( + windowPackage, Context.CONTEXT_RESTRICTED, UserHandle.of(userId)) + val activityInfo = taskInfo.topActivityInfo + val splashScreenThemeName = packageManager.getSplashScreenTheme(windowPackage, userId) + val splashScreenThemeId = if (splashScreenThemeName != null) { + windowContext.resources.getIdentifier(splashScreenThemeName, null, null) + } else { + 0 + } + + val themeResId = when { + splashScreenThemeId != 0 -> splashScreenThemeId + activityInfo.themeResource != 0 -> activityInfo.themeResource + else -> com.android.internal.R.style.Theme_DeviceDefault_DayNight + } + + if (themeResId != windowContext.themeResId) { + windowContext.setTheme(themeResId) + } + + val windowAttrs = SplashScreenWindowAttrs() + SplashscreenContentDrawer.getWindowAttrs(windowContext, windowAttrs) + return SplashscreenContentDrawer.peekWindowBGColor(windowContext, windowAttrs) + } + private fun applyStateToWindow(window: RemoteAnimationTarget, state: State) { val screenBounds = window.screenSpaceBounds val centerX = (screenBounds.left + screenBounds.right) / 2f @@ -533,6 +600,41 @@ class ActivityLaunchAnimator(context: Context) { transactionApplier.scheduleApply(params) } + private fun applyStateToWindowBackgroundLayer( + drawable: GradientDrawable, + state: State, + linearProgress: Float + ) { + // Update position. + drawable.setBounds(state.left, state.top, state.right, state.bottom) + + // Update radius. + cornerRadii[0] = state.topCornerRadius + cornerRadii[1] = state.topCornerRadius + cornerRadii[2] = state.topCornerRadius + cornerRadii[3] = state.topCornerRadius + cornerRadii[4] = state.bottomCornerRadius + cornerRadii[5] = state.bottomCornerRadius + cornerRadii[6] = state.bottomCornerRadius + cornerRadii[7] = state.bottomCornerRadius + drawable.cornerRadii = cornerRadii + + // We first fade in the background layer to hide the expanding view, then fade it out + // with SRC mode to draw a hole punch in the status bar and reveal the opening window. + val fadeInProgress = getProgress(linearProgress, 0, ANIMATION_DURATION_FADE_OUT_CONTENT) + if (fadeInProgress < 1) { + val alpha = CONTENT_FADE_OUT_INTERPOLATOR.getInterpolation(fadeInProgress) + drawable.alpha = (alpha * 0xFF).roundToInt() + drawable.setXfermode(null) + } else { + val fadeOutProgress = getProgress(linearProgress, + ANIMATION_DELAY_FADE_IN_WINDOW, ANIMATION_DURATION_FADE_IN_WINDOW) + val alpha = 1 - WINDOW_FADE_IN_INTERPOLATOR.getInterpolation(fadeOutProgress) + drawable.alpha = (alpha * 0xFF).roundToInt() + drawable.setXfermode(SRC_MODE) + } + } + private fun applyStateToNavigationBar( navigationBar: RemoteAnimationTarget, state: State, diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt index ce9feede87592..4b655a1a1b02c 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt @@ -4,8 +4,6 @@ import android.graphics.Canvas import android.graphics.ColorFilter import android.graphics.Matrix import android.graphics.PixelFormat -import android.graphics.PorterDuff -import android.graphics.PorterDuffXfermode import android.graphics.Rect import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable @@ -111,9 +109,7 @@ open class GhostedViewLaunchAnimatorController( } override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) { - backgroundView = FrameLayout(launchContainer.context).apply { - forceHasOverlappingRendering(false) - } + backgroundView = FrameLayout(launchContainer.context) launchContainerOverlay.add(backgroundView) // We wrap the ghosted view background and use it to draw the expandable background. Its @@ -125,9 +121,7 @@ open class GhostedViewLaunchAnimatorController( // Create a ghost of the view that will be moving and fading out. This allows to fade out // the content before fading out the background. - ghostView = GhostView.addGhost(ghostedView, launchContainer).apply { - setLayerType(View.LAYER_TYPE_HARDWARE, null) - } + ghostView = GhostView.addGhost(ghostedView, launchContainer) val matrix = ghostView?.animationMatrix ?: Matrix.IDENTITY_MATRIX matrix.getValues(initialGhostViewMatrixValues) @@ -139,7 +133,18 @@ open class GhostedViewLaunchAnimatorController( linearProgress: Float ) { val ghostView = this.ghostView!! - ghostView.alpha = state.contentAlpha + val backgroundView = this.backgroundView!! + + if (!state.visible) { + if (ghostView.visibility == View.VISIBLE) { + // Making the ghost view invisible will make the ghosted view visible, so order is + // important here. + ghostView.visibility = View.INVISIBLE + ghostedView.visibility = View.INVISIBLE + backgroundView.visibility = View.INVISIBLE + } + return + } val scale = min(state.widthRatio, state.heightRatio) ghostViewMatrix.setValues(initialGhostViewMatrixValues) @@ -150,14 +155,12 @@ open class GhostedViewLaunchAnimatorController( ) ghostView.animationMatrix = ghostViewMatrix - val backgroundView = this.backgroundView!! backgroundView.top = state.top backgroundView.bottom = state.bottom backgroundView.left = state.left backgroundView.right = state.right val backgroundDrawable = backgroundDrawable!! - backgroundDrawable.alpha = (0xFF * state.backgroundAlpha).toInt() backgroundDrawable.wrapped?.let { setBackgroundCornerRadius(it, state.topCornerRadius, state.bottomCornerRadius) } @@ -168,6 +171,7 @@ open class GhostedViewLaunchAnimatorController( GhostView.removeGhost(ghostedView) launchContainerOverlay.remove(backgroundView) + ghostedView.visibility = View.VISIBLE ghostedView.invalidate() } @@ -203,10 +207,6 @@ open class GhostedViewLaunchAnimatorController( } private class WrappedDrawable(val wrapped: Drawable?) : Drawable() { - companion object { - private val SRC_MODE = PorterDuffXfermode(PorterDuff.Mode.SRC) - } - private var currentAlpha = 0xFF private var previousBounds = Rect() @@ -220,7 +220,6 @@ open class GhostedViewLaunchAnimatorController( wrapped.alpha = currentAlpha wrapped.bounds = bounds - setXfermode(wrapped, SRC_MODE) applyBackgroundRadii() wrapped.draw(canvas) @@ -230,7 +229,6 @@ open class GhostedViewLaunchAnimatorController( // background. wrapped.alpha = 0 wrapped.bounds = previousBounds - setXfermode(wrapped, null) restoreBackgroundRadii() } @@ -257,27 +255,6 @@ open class GhostedViewLaunchAnimatorController( wrapped?.colorFilter = filter } - private fun setXfermode(background: Drawable, mode: PorterDuffXfermode?) { - if (background is InsetDrawable) { - background.drawable?.let { setXfermode(it, mode) } - return - } - - if (background !is LayerDrawable) { - background.setXfermode(mode) - return - } - - // We set the xfermode on the first layer that is not a mask. Most of the time it will - // be the "background layer". - for (i in 0 until background.numberOfLayers) { - if (background.getId(i) != android.R.id.mask) { - background.getDrawable(i).setXfermode(mode) - break - } - } - } - fun setBackgroundRadius(topCornerRadius: Float, bottomCornerRadius: Float) { updateRadii(cornerRadii, topCornerRadius, bottomCornerRadius) invalidateSelf() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index ced284e219635..7a3b8a711a9d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -73,7 +73,6 @@ import com.android.internal.widget.CachingIconView; import com.android.internal.widget.CallLayout; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.Interpolators; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.plugins.FalsingManager; @@ -2020,6 +2019,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (params == null) { return; } + + if (!params.getVisible()) { + if (getVisibility() == View.VISIBLE) { + setVisibility(View.INVISIBLE); + } + return; + } + float zProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation( params.getProgress(0, 50)); float translationZ = MathUtils.lerp(params.getStartTranslationZ(), @@ -2077,10 +2084,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView contentView = mGuts; } if (expandAnimationRunning) { - contentView.animate() - .alpha(0f) - .setDuration(ActivityLaunchAnimator.ANIMATION_DURATION_FADE_OUT_CONTENT) - .setInterpolator(ActivityLaunchAnimator.CONTENT_FADE_OUT_INTERPOLATOR); setAboveShelf(true); mExpandAnimationRunning = true; getViewState().cancelAnimations(this); @@ -2088,6 +2091,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } else { mExpandAnimationRunning = false; setAboveShelf(isAboveShelf()); + setVisibility(View.VISIBLE); if (mGuts != null) { mGuts.setAlpha(1.0f); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java index f6ab409998bfd..4b1f679b88517 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Canvas; import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; @@ -30,8 +29,6 @@ import android.view.View; import com.android.internal.util.ArrayUtils; import com.android.systemui.R; -import com.android.systemui.animation.ActivityLaunchAnimator; -import com.android.systemui.animation.Interpolators; import com.android.systemui.statusbar.notification.ExpandAnimationParameters; /** @@ -281,11 +278,6 @@ public class NotificationBackgroundView extends View { public void setExpandAnimationParams(ExpandAnimationParameters params) { mActualHeight = params.getHeight(); mActualWidth = params.getWidth(); - float alphaProgress = Interpolators.ALPHA_IN.getInterpolation( - params.getProgress( - ActivityLaunchAnimator.ANIMATION_DELAY_FADE_IN_WINDOW /* delay */, - ActivityLaunchAnimator.ANIMATION_DURATION_FADE_IN_WINDOW /* duration */)); - mBackground.setAlpha((int) (mDrawableAlpha * (1.0f - alphaProgress))); invalidate(); } @@ -294,8 +286,6 @@ public class NotificationBackgroundView extends View { if (mBackground instanceof LayerDrawable) { GradientDrawable gradientDrawable = (GradientDrawable) ((LayerDrawable) mBackground).getDrawable(0); - gradientDrawable.setXfermode( - running ? new PorterDuffXfermode(PorterDuff.Mode.SRC) : null); // Speed optimization: disable AA if transfer mode is not SRC_OVER. AA is not easy to // spot during animation anyways. gradientDrawable.setAntiAlias(!running); diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index f2ef5c38e9b94..45bd74add2266 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -2,6 +2,9 @@ package com.android.systemui.animation import android.app.ActivityManager import android.app.WindowConfiguration +import android.content.ComponentName +import android.content.pm.ActivityInfo +import android.content.pm.ApplicationInfo import android.graphics.Point import android.graphics.Rect import android.os.Looper @@ -141,10 +144,16 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { private fun fakeWindow(): RemoteAnimationTarget { val bounds = Rect(10 /* left */, 20 /* top */, 30 /* right */, 40 /* bottom */) + val taskInfo = ActivityManager.RunningTaskInfo() + taskInfo.topActivity = ComponentName("com.android.systemui", "FakeActivity") + taskInfo.topActivityInfo = ActivityInfo().apply { + applicationInfo = ApplicationInfo() + } + return RemoteAnimationTarget( 0, RemoteAnimationTarget.MODE_OPENING, SurfaceControl(), false, Rect(), Rect(), 0, Point(), Rect(), bounds, WindowConfiguration(), false, SurfaceControl(), Rect(), - ActivityManager.RunningTaskInfo() + taskInfo ) } }