Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +67 −35 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.Nullable; import android.app.ActivityManager; import android.graphics.Matrix; import android.graphics.Rect; Loading @@ -41,6 +42,8 @@ import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController; import java.util.concurrent.Executor; /** * A class that allows activities to be launched in a seamless way where the notification * transforms nicely into the starting window. Loading @@ -59,6 +62,7 @@ public class ActivityLaunchAnimator { private final float mWindowCornerRadius; private final NotificationShadeWindowViewController mNotificationShadeWindowViewController; private final NotificationShadeDepthController mDepthController; private final Executor mMainExecutor; private Callback mCallback; private final Runnable mTimeoutRunnable = () -> { setAnimationPending(false); Loading @@ -73,12 +77,14 @@ public class ActivityLaunchAnimator { Callback callback, NotificationPanelViewController notificationPanel, NotificationShadeDepthController depthController, NotificationListContainer container) { NotificationListContainer container, Executor mainExecutor) { mNotificationPanel = notificationPanel; mNotificationContainer = container; mDepthController = depthController; mNotificationShadeWindowViewController = notificationShadeWindowViewController; mCallback = callback; mMainExecutor = mainExecutor; mWindowCornerRadius = ScreenDecorationsUtils .getWindowCornerRadius(mNotificationShadeWindowViewController.getView() .getResources()); Loading @@ -91,7 +97,7 @@ public class ActivityLaunchAnimator { return null; } AnimationRunner animationRunner = new AnimationRunner( (ExpandableNotificationRow) sourceView); (ExpandableNotificationRow) sourceView, mMainExecutor); return new RemoteAnimationAdapter(animationRunner, ANIMATION_DURATION, ANIMATION_DURATION - 150 /* statusBarTransitionDelay */); } Loading Loading @@ -134,17 +140,18 @@ public class ActivityLaunchAnimator { class AnimationRunner extends IRemoteAnimationRunner.Stub { private final ExpandableNotificationRow mSourceNotification; private final ExpandAnimationParameters mParams; private final ExpandAnimationParameters mParams = new ExpandAnimationParameters(); private final Rect mWindowCrop = new Rect(); private final float mNotificationCornerRadius; private final Executor mMainExecutor; @Nullable private ExpandableNotificationRow mSourceNotification; @Nullable private SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier; private float mCornerRadius; private boolean mIsFullScreenLaunch = true; private final SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier; public AnimationRunner(ExpandableNotificationRow sourceNofitication) { mSourceNotification = sourceNofitication; mParams = new ExpandAnimationParameters(); AnimationRunner(ExpandableNotificationRow sourceNotification, Executor mainExecutor) { mMainExecutor = mainExecutor; mSourceNotification = sourceNotification; mSyncRtTransactionApplier = new SyncRtSurfaceTransactionApplier(mSourceNotification); mNotificationCornerRadius = Math.max(mSourceNotification.getCurrentTopRoundness(), mSourceNotification.getCurrentBottomRoundness()); Loading @@ -155,13 +162,15 @@ public class ActivityLaunchAnimator { RemoteAnimationTarget[] remoteAnimationWallpaperTargets, IRemoteAnimationFinishedCallback iRemoteAnimationFinishedCallback) throws RemoteException { mSourceNotification.post(() -> { mMainExecutor.execute(() -> { RemoteAnimationTarget primary = getPrimaryRemoteAnimationTarget( remoteAnimationTargets); if (primary == null) { if (primary == null || mSourceNotification == null) { setAnimationPending(false); invokeCallback(iRemoteAnimationFinishedCallback); mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */); mSourceNotification = null; mSyncRtTransactionApplier = null; return; } Loading @@ -172,28 +181,14 @@ public class ActivityLaunchAnimator { if (!mIsFullScreenLaunch) { mNotificationPanel.collapseWithDuration(ANIMATION_DURATION); } ValueAnimator anim = ValueAnimator.ofFloat(0, 1); mParams.startPosition = mSourceNotification.getLocationOnScreen(); mParams.startTranslationZ = mSourceNotification.getTranslationZ(); mParams.startClipTopAmount = mSourceNotification.getClipTopAmount(); if (mSourceNotification.isChildInGroup()) { int parentClip = mSourceNotification .getNotificationParent().getClipTopAmount(); mParams.parentStartClipTopAmount = parentClip; // We need to calculate how much the child is clipped by the parent // because children always have 0 clipTopAmount if (parentClip != 0) { float childClip = parentClip - mSourceNotification.getTranslationY(); if (childClip > 0.0f) { mParams.startClipTopAmount = (int) Math.ceil(childClip); } } } int targetWidth = primary.sourceContainerBounds.width(); int notificationHeight = mSourceNotification.getActualHeight() mParams.initFrom(mSourceNotification); final int targetWidth = primary.sourceContainerBounds.width(); final int notificationHeight; final int notificationWidth; notificationHeight = mSourceNotification.getActualHeight() - mSourceNotification.getClipBottomAmount(); int notificationWidth = mSourceNotification.getWidth(); notificationWidth = mSourceNotification.getWidth(); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); anim.setDuration(ANIMATION_DURATION); anim.setInterpolator(Interpolators.LINEAR); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Loading Loading @@ -231,6 +226,11 @@ public class ActivityLaunchAnimator { }); } @Nullable ExpandableNotificationRow getRow() { return mSourceNotification; } private void invokeCallback(IRemoteAnimationFinishedCallback callback) { try { callback.onAnimationFinished(); Loading @@ -253,7 +253,9 @@ public class ActivityLaunchAnimator { private void setExpandAnimationRunning(boolean running) { mNotificationPanel.setLaunchingNotification(running); if (mSourceNotification != null) { mSourceNotification.setExpandAnimationRunning(running); } mNotificationShadeWindowViewController.setExpandAnimationRunning(running); mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null); mAnimationRunning = running; Loading @@ -261,6 +263,8 @@ public class ActivityLaunchAnimator { mCallback.onExpandAnimationFinished(mIsFullScreenLaunch); applyParamsToNotification(null); applyParamsToNotificationShade(null); mSourceNotification = null; mSyncRtTransactionApplier = null; } } Loading @@ -272,8 +276,10 @@ public class ActivityLaunchAnimator { } private void applyParamsToNotification(ExpandAnimationParameters params) { if (mSourceNotification != null) { mSourceNotification.applyExpandAnimationParams(params); } } private void applyParamsToWindow(RemoteAnimationTarget app) { Matrix m = new Matrix(); Loading @@ -287,14 +293,18 @@ public class ActivityLaunchAnimator { .withCornerRadius(mCornerRadius) .withVisibility(true) .build(); if (mSyncRtTransactionApplier != null) { mSyncRtTransactionApplier.scheduleApply(true /* earlyWakeup */, params); } } @Override public void onAnimationCancelled() throws RemoteException { mSourceNotification.post(() -> { mMainExecutor.execute(() -> { setAnimationPending(false); mCallback.onLaunchAnimationCancelled(); mSourceNotification = null; mSyncRtTransactionApplier = null; }); } }; Loading Loading @@ -359,6 +369,28 @@ public class ActivityLaunchAnimator { public float getStartTranslationZ() { return startTranslationZ; } /** Initialize with data pulled from the row. */ void initFrom(@Nullable ExpandableNotificationRow row) { if (row == null) { return; } startPosition = row.getLocationOnScreen(); startTranslationZ = row.getTranslationZ(); startClipTopAmount = row.getClipTopAmount(); if (row.isChildInGroup()) { int parentClip = row.getNotificationParent().getClipTopAmount(); parentStartClipTopAmount = parentClip; // We need to calculate how much the child is clipped by the parent // because children always have 0 clipTopAmount if (parentClip != 0) { float childClip = parentClip - row.getTranslationY(); if (childClip > 0.0f) { startClipTopAmount = (int) Math.ceil(childClip); } } } } } public interface Callback { Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +6 −1 Original line number Diff line number Diff line Loading @@ -140,6 +140,7 @@ import com.android.systemui.bubbles.BubbleController; import com.android.systemui.charging.WirelessChargingAnimation; import com.android.systemui.classifier.FalsingLog; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.fragments.ExtensionFragmentListener; import com.android.systemui.fragments.FragmentHostManager; Loading Loading @@ -467,6 +468,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final ScrimController mScrimController; protected DozeScrimController mDozeScrimController; private final Executor mUiBgExecutor; private final Executor mMainExecutor; protected boolean mDozing; Loading Loading @@ -625,6 +627,7 @@ public class StatusBar extends SystemUI implements DemoMode, DisplayMetrics displayMetrics, MetricsLogger metricsLogger, @UiBackground Executor uiBgExecutor, @Main Executor mainExecutor, NotificationMediaManager notificationMediaManager, NotificationLockscreenUserManager lockScreenUserManager, NotificationRemoteInputManager remoteInputManager, Loading Loading @@ -705,6 +708,7 @@ public class StatusBar extends SystemUI implements DemoMode, mDisplayMetrics = displayMetrics; mMetricsLogger = metricsLogger; mUiBgExecutor = uiBgExecutor; mMainExecutor = mainExecutor; mMediaManager = notificationMediaManager; mLockscreenUserManager = lockScreenUserManager; mRemoteInputManager = remoteInputManager; Loading Loading @@ -1232,7 +1236,8 @@ public class StatusBar extends SystemUI implements DemoMode, mActivityLaunchAnimator = new ActivityLaunchAnimator( mNotificationShadeWindowViewController, this, mNotificationPanelViewController, mNotificationShadeDepthControllerLazy.get(), (NotificationListContainer) mStackScroller); (NotificationListContainer) mStackScroller, mMainExecutor); // TODO: inject this. mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanelViewController, Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.KeyguardViewMediator; Loading Loading @@ -145,6 +146,7 @@ public interface StatusBarPhoneModule { DisplayMetrics displayMetrics, MetricsLogger metricsLogger, @UiBackground Executor uiBgExecutor, @Main Executor mainExecutor, NotificationMediaManager notificationMediaManager, NotificationLockscreenUserManager lockScreenUserManager, NotificationRemoteInputManager remoteInputManager, Loading Loading @@ -224,6 +226,7 @@ public interface StatusBarPhoneModule { displayMetrics, metricsLogger, uiBgExecutor, mainExecutor, notificationMediaManager, lockScreenUserManager, remoteInputManager, Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java +33 −2 Original line number Diff line number Diff line Loading @@ -19,14 +19,18 @@ package com.android.systemui.statusbar.notification; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.os.RemoteException; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.IRemoteAnimationFinishedCallback; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.View; import com.android.systemui.SysuiTestCase; Loading @@ -36,6 +40,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; import org.junit.Assert; import org.junit.Before; Loading Loading @@ -68,9 +74,11 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase { private NotificationPanelViewController mNotificationPanelViewController; @Rule public MockitoRule rule = MockitoJUnit.rule(); private FakeExecutor mExecutor; @Before public void setUp() throws Exception { mExecutor = new FakeExecutor(new FakeSystemClock()); when(mNotificationShadeWindowViewController.getView()) .thenReturn(mNotificationShadeWindowView); when(mNotificationShadeWindowView.getResources()).thenReturn(mContext.getResources()); Loading @@ -80,8 +88,8 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase { mCallback, mNotificationPanelViewController, mNotificationShadeDepthController, mNotificationContainer); mNotificationContainer, mExecutor); } @Test Loading Loading @@ -113,6 +121,29 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase { verify(mCallback).onExpandAnimationTimedOut(); } @Test public void testRowLinkBrokenOnAnimationStartFail() throws RemoteException { ActivityLaunchAnimator.AnimationRunner runner = mLaunchAnimator.new AnimationRunner(mRow, mExecutor); // WHEN onAnimationStart with no valid remote target runner.onAnimationStart(new RemoteAnimationTarget[0], new RemoteAnimationTarget[0], mock(IRemoteAnimationFinishedCallback.class)); mExecutor.runAllReady(); // THEN the row is nulled out so that it won't be retained Assert.assertTrue("The row should be null", runner.getRow() == null); } @Test public void testRowLinkBrokenOnAnimationCancelled() throws RemoteException { ActivityLaunchAnimator.AnimationRunner runner = mLaunchAnimator.new AnimationRunner(mRow, mExecutor); // WHEN onAnimationCancelled runner.onAnimationCancelled(); mExecutor.runAllReady(); // THEN the row is nulled out so that it won't be retained Assert.assertTrue("The row should be null", runner.getRow() == null); } private void executePostsImmediately(View view) { doAnswer((i) -> { Runnable run = i.getArgument(0); Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy; private ShadeController mShadeController; private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); private FakeExecutor mMainExecutor = new FakeExecutor(new FakeSystemClock()); private InitController mInitController = new InitController(); @Before Loading Loading @@ -353,6 +354,7 @@ public class StatusBarTest extends SysuiTestCase { new DisplayMetrics(), mMetricsLogger, mUiBgExecutor, mMainExecutor, mNotificationMediaManager, mLockscreenUserManager, mRemoteInputManager, Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +67 −35 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.Nullable; import android.app.ActivityManager; import android.graphics.Matrix; import android.graphics.Rect; Loading @@ -41,6 +42,8 @@ import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController; import java.util.concurrent.Executor; /** * A class that allows activities to be launched in a seamless way where the notification * transforms nicely into the starting window. Loading @@ -59,6 +62,7 @@ public class ActivityLaunchAnimator { private final float mWindowCornerRadius; private final NotificationShadeWindowViewController mNotificationShadeWindowViewController; private final NotificationShadeDepthController mDepthController; private final Executor mMainExecutor; private Callback mCallback; private final Runnable mTimeoutRunnable = () -> { setAnimationPending(false); Loading @@ -73,12 +77,14 @@ public class ActivityLaunchAnimator { Callback callback, NotificationPanelViewController notificationPanel, NotificationShadeDepthController depthController, NotificationListContainer container) { NotificationListContainer container, Executor mainExecutor) { mNotificationPanel = notificationPanel; mNotificationContainer = container; mDepthController = depthController; mNotificationShadeWindowViewController = notificationShadeWindowViewController; mCallback = callback; mMainExecutor = mainExecutor; mWindowCornerRadius = ScreenDecorationsUtils .getWindowCornerRadius(mNotificationShadeWindowViewController.getView() .getResources()); Loading @@ -91,7 +97,7 @@ public class ActivityLaunchAnimator { return null; } AnimationRunner animationRunner = new AnimationRunner( (ExpandableNotificationRow) sourceView); (ExpandableNotificationRow) sourceView, mMainExecutor); return new RemoteAnimationAdapter(animationRunner, ANIMATION_DURATION, ANIMATION_DURATION - 150 /* statusBarTransitionDelay */); } Loading Loading @@ -134,17 +140,18 @@ public class ActivityLaunchAnimator { class AnimationRunner extends IRemoteAnimationRunner.Stub { private final ExpandableNotificationRow mSourceNotification; private final ExpandAnimationParameters mParams; private final ExpandAnimationParameters mParams = new ExpandAnimationParameters(); private final Rect mWindowCrop = new Rect(); private final float mNotificationCornerRadius; private final Executor mMainExecutor; @Nullable private ExpandableNotificationRow mSourceNotification; @Nullable private SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier; private float mCornerRadius; private boolean mIsFullScreenLaunch = true; private final SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier; public AnimationRunner(ExpandableNotificationRow sourceNofitication) { mSourceNotification = sourceNofitication; mParams = new ExpandAnimationParameters(); AnimationRunner(ExpandableNotificationRow sourceNotification, Executor mainExecutor) { mMainExecutor = mainExecutor; mSourceNotification = sourceNotification; mSyncRtTransactionApplier = new SyncRtSurfaceTransactionApplier(mSourceNotification); mNotificationCornerRadius = Math.max(mSourceNotification.getCurrentTopRoundness(), mSourceNotification.getCurrentBottomRoundness()); Loading @@ -155,13 +162,15 @@ public class ActivityLaunchAnimator { RemoteAnimationTarget[] remoteAnimationWallpaperTargets, IRemoteAnimationFinishedCallback iRemoteAnimationFinishedCallback) throws RemoteException { mSourceNotification.post(() -> { mMainExecutor.execute(() -> { RemoteAnimationTarget primary = getPrimaryRemoteAnimationTarget( remoteAnimationTargets); if (primary == null) { if (primary == null || mSourceNotification == null) { setAnimationPending(false); invokeCallback(iRemoteAnimationFinishedCallback); mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */); mSourceNotification = null; mSyncRtTransactionApplier = null; return; } Loading @@ -172,28 +181,14 @@ public class ActivityLaunchAnimator { if (!mIsFullScreenLaunch) { mNotificationPanel.collapseWithDuration(ANIMATION_DURATION); } ValueAnimator anim = ValueAnimator.ofFloat(0, 1); mParams.startPosition = mSourceNotification.getLocationOnScreen(); mParams.startTranslationZ = mSourceNotification.getTranslationZ(); mParams.startClipTopAmount = mSourceNotification.getClipTopAmount(); if (mSourceNotification.isChildInGroup()) { int parentClip = mSourceNotification .getNotificationParent().getClipTopAmount(); mParams.parentStartClipTopAmount = parentClip; // We need to calculate how much the child is clipped by the parent // because children always have 0 clipTopAmount if (parentClip != 0) { float childClip = parentClip - mSourceNotification.getTranslationY(); if (childClip > 0.0f) { mParams.startClipTopAmount = (int) Math.ceil(childClip); } } } int targetWidth = primary.sourceContainerBounds.width(); int notificationHeight = mSourceNotification.getActualHeight() mParams.initFrom(mSourceNotification); final int targetWidth = primary.sourceContainerBounds.width(); final int notificationHeight; final int notificationWidth; notificationHeight = mSourceNotification.getActualHeight() - mSourceNotification.getClipBottomAmount(); int notificationWidth = mSourceNotification.getWidth(); notificationWidth = mSourceNotification.getWidth(); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); anim.setDuration(ANIMATION_DURATION); anim.setInterpolator(Interpolators.LINEAR); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Loading Loading @@ -231,6 +226,11 @@ public class ActivityLaunchAnimator { }); } @Nullable ExpandableNotificationRow getRow() { return mSourceNotification; } private void invokeCallback(IRemoteAnimationFinishedCallback callback) { try { callback.onAnimationFinished(); Loading @@ -253,7 +253,9 @@ public class ActivityLaunchAnimator { private void setExpandAnimationRunning(boolean running) { mNotificationPanel.setLaunchingNotification(running); if (mSourceNotification != null) { mSourceNotification.setExpandAnimationRunning(running); } mNotificationShadeWindowViewController.setExpandAnimationRunning(running); mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null); mAnimationRunning = running; Loading @@ -261,6 +263,8 @@ public class ActivityLaunchAnimator { mCallback.onExpandAnimationFinished(mIsFullScreenLaunch); applyParamsToNotification(null); applyParamsToNotificationShade(null); mSourceNotification = null; mSyncRtTransactionApplier = null; } } Loading @@ -272,8 +276,10 @@ public class ActivityLaunchAnimator { } private void applyParamsToNotification(ExpandAnimationParameters params) { if (mSourceNotification != null) { mSourceNotification.applyExpandAnimationParams(params); } } private void applyParamsToWindow(RemoteAnimationTarget app) { Matrix m = new Matrix(); Loading @@ -287,14 +293,18 @@ public class ActivityLaunchAnimator { .withCornerRadius(mCornerRadius) .withVisibility(true) .build(); if (mSyncRtTransactionApplier != null) { mSyncRtTransactionApplier.scheduleApply(true /* earlyWakeup */, params); } } @Override public void onAnimationCancelled() throws RemoteException { mSourceNotification.post(() -> { mMainExecutor.execute(() -> { setAnimationPending(false); mCallback.onLaunchAnimationCancelled(); mSourceNotification = null; mSyncRtTransactionApplier = null; }); } }; Loading Loading @@ -359,6 +369,28 @@ public class ActivityLaunchAnimator { public float getStartTranslationZ() { return startTranslationZ; } /** Initialize with data pulled from the row. */ void initFrom(@Nullable ExpandableNotificationRow row) { if (row == null) { return; } startPosition = row.getLocationOnScreen(); startTranslationZ = row.getTranslationZ(); startClipTopAmount = row.getClipTopAmount(); if (row.isChildInGroup()) { int parentClip = row.getNotificationParent().getClipTopAmount(); parentStartClipTopAmount = parentClip; // We need to calculate how much the child is clipped by the parent // because children always have 0 clipTopAmount if (parentClip != 0) { float childClip = parentClip - row.getTranslationY(); if (childClip > 0.0f) { startClipTopAmount = (int) Math.ceil(childClip); } } } } } public interface Callback { Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +6 −1 Original line number Diff line number Diff line Loading @@ -140,6 +140,7 @@ import com.android.systemui.bubbles.BubbleController; import com.android.systemui.charging.WirelessChargingAnimation; import com.android.systemui.classifier.FalsingLog; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.fragments.ExtensionFragmentListener; import com.android.systemui.fragments.FragmentHostManager; Loading Loading @@ -467,6 +468,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final ScrimController mScrimController; protected DozeScrimController mDozeScrimController; private final Executor mUiBgExecutor; private final Executor mMainExecutor; protected boolean mDozing; Loading Loading @@ -625,6 +627,7 @@ public class StatusBar extends SystemUI implements DemoMode, DisplayMetrics displayMetrics, MetricsLogger metricsLogger, @UiBackground Executor uiBgExecutor, @Main Executor mainExecutor, NotificationMediaManager notificationMediaManager, NotificationLockscreenUserManager lockScreenUserManager, NotificationRemoteInputManager remoteInputManager, Loading Loading @@ -705,6 +708,7 @@ public class StatusBar extends SystemUI implements DemoMode, mDisplayMetrics = displayMetrics; mMetricsLogger = metricsLogger; mUiBgExecutor = uiBgExecutor; mMainExecutor = mainExecutor; mMediaManager = notificationMediaManager; mLockscreenUserManager = lockScreenUserManager; mRemoteInputManager = remoteInputManager; Loading Loading @@ -1232,7 +1236,8 @@ public class StatusBar extends SystemUI implements DemoMode, mActivityLaunchAnimator = new ActivityLaunchAnimator( mNotificationShadeWindowViewController, this, mNotificationPanelViewController, mNotificationShadeDepthControllerLazy.get(), (NotificationListContainer) mStackScroller); (NotificationListContainer) mStackScroller, mMainExecutor); // TODO: inject this. mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanelViewController, Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.KeyguardViewMediator; Loading Loading @@ -145,6 +146,7 @@ public interface StatusBarPhoneModule { DisplayMetrics displayMetrics, MetricsLogger metricsLogger, @UiBackground Executor uiBgExecutor, @Main Executor mainExecutor, NotificationMediaManager notificationMediaManager, NotificationLockscreenUserManager lockScreenUserManager, NotificationRemoteInputManager remoteInputManager, Loading Loading @@ -224,6 +226,7 @@ public interface StatusBarPhoneModule { displayMetrics, metricsLogger, uiBgExecutor, mainExecutor, notificationMediaManager, lockScreenUserManager, remoteInputManager, Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java +33 −2 Original line number Diff line number Diff line Loading @@ -19,14 +19,18 @@ package com.android.systemui.statusbar.notification; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.os.RemoteException; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.IRemoteAnimationFinishedCallback; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.View; import com.android.systemui.SysuiTestCase; Loading @@ -36,6 +40,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; import org.junit.Assert; import org.junit.Before; Loading Loading @@ -68,9 +74,11 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase { private NotificationPanelViewController mNotificationPanelViewController; @Rule public MockitoRule rule = MockitoJUnit.rule(); private FakeExecutor mExecutor; @Before public void setUp() throws Exception { mExecutor = new FakeExecutor(new FakeSystemClock()); when(mNotificationShadeWindowViewController.getView()) .thenReturn(mNotificationShadeWindowView); when(mNotificationShadeWindowView.getResources()).thenReturn(mContext.getResources()); Loading @@ -80,8 +88,8 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase { mCallback, mNotificationPanelViewController, mNotificationShadeDepthController, mNotificationContainer); mNotificationContainer, mExecutor); } @Test Loading Loading @@ -113,6 +121,29 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase { verify(mCallback).onExpandAnimationTimedOut(); } @Test public void testRowLinkBrokenOnAnimationStartFail() throws RemoteException { ActivityLaunchAnimator.AnimationRunner runner = mLaunchAnimator.new AnimationRunner(mRow, mExecutor); // WHEN onAnimationStart with no valid remote target runner.onAnimationStart(new RemoteAnimationTarget[0], new RemoteAnimationTarget[0], mock(IRemoteAnimationFinishedCallback.class)); mExecutor.runAllReady(); // THEN the row is nulled out so that it won't be retained Assert.assertTrue("The row should be null", runner.getRow() == null); } @Test public void testRowLinkBrokenOnAnimationCancelled() throws RemoteException { ActivityLaunchAnimator.AnimationRunner runner = mLaunchAnimator.new AnimationRunner(mRow, mExecutor); // WHEN onAnimationCancelled runner.onAnimationCancelled(); mExecutor.runAllReady(); // THEN the row is nulled out so that it won't be retained Assert.assertTrue("The row should be null", runner.getRow() == null); } private void executePostsImmediately(View view) { doAnswer((i) -> { Runnable run = i.getArgument(0); Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy; private ShadeController mShadeController; private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); private FakeExecutor mMainExecutor = new FakeExecutor(new FakeSystemClock()); private InitController mInitController = new InitController(); @Before Loading Loading @@ -353,6 +354,7 @@ public class StatusBarTest extends SysuiTestCase { new DisplayMetrics(), mMetricsLogger, mUiBgExecutor, mMainExecutor, mNotificationMediaManager, mLockscreenUserManager, mRemoteInputManager, Loading