Merge changes Ic62b7358,Ic3f7e62a into tm-qpr-dev am: 0c76ea59be am: 23c9b021be

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20237808

Change-Id: I3a3ff337869ac8fb4251c31754a6cf1303f4b4b1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Josh Tsuji
2022-10-25 21:12:01 +00:00
committed by Automerger Merge Worker
6 changed files with 157 additions and 10 deletions

View File

@@ -91,6 +91,7 @@ import android.view.animation.AnimationUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.jank.InteractionJankMonitor.Configuration;
@@ -322,6 +323,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// true if the keyguard is hidden by another window
private boolean mOccluded = false;
/**
* Whether the {@link #mOccludeAnimationController} is currently playing the occlusion
* animation.
*/
private boolean mOccludeAnimationPlaying = false;
private boolean mWakeAndUnlocking = false;
/**
@@ -837,15 +844,22 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
/**
* Animation launch controller for activities that occlude the keyguard.
*/
private final ActivityLaunchAnimator.Controller mOccludeAnimationController =
@VisibleForTesting
final ActivityLaunchAnimator.Controller mOccludeAnimationController =
new ActivityLaunchAnimator.Controller() {
@Override
public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {}
public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {
mOccludeAnimationPlaying = true;
}
@Override
public void onLaunchAnimationCancelled(@Nullable Boolean newKeyguardOccludedState) {
Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: "
+ mOccluded);
mOccludeAnimationPlaying = false;
// Ensure keyguard state is set correctly if we're cancelled.
mCentralSurfaces.updateIsKeyguard();
}
@Override
@@ -854,6 +868,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mCentralSurfaces.instantCollapseNotificationPanel();
}
mOccludeAnimationPlaying = false;
// Hide the keyguard now that we're done launching the occluding activity over
// it.
mCentralSurfaces.updateIsKeyguard();
mInteractionJankMonitor.end(CUJ_LOCKSCREEN_OCCLUSION);
}
@@ -1768,6 +1788,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
return mShowing && !mOccluded;
}
public boolean isOccludeAnimationPlaying() {
return mOccludeAnimationPlaying;
}
/**
* Notify us when the keyguard is occluded by another window
*/

View File

@@ -2960,7 +2960,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
// * When phone is unlocked: we still don't want to execute hiding of the keyguard
// as the animation could prepare 'fake AOD' interface (without actually
// transitioning to keyguard state) and this might reset the view states
if (!mScreenOffAnimationController.isKeyguardHideDelayed()) {
if (!mScreenOffAnimationController.isKeyguardHideDelayed()
// If we're animating occluded, there's an activity launching over the keyguard
// UI. Wait to hide it until after the animation concludes.
&& !mKeyguardViewMediator.isOccludeAnimationPlaying()) {
return hideKeyguardImpl(forceStateChange);
}
}

View File

@@ -53,6 +53,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -204,6 +205,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private final ScreenOffAnimationController mScreenOffAnimationController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private KeyguardViewMediator mKeyguardViewMediator;
private GradientColors mColors;
private boolean mNeedsDrawableColorUpdate;
@@ -273,7 +275,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
@Main Executor mainExecutor,
ScreenOffAnimationController screenOffAnimationController,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardViewMediator keyguardViewMediator) {
mScrimStateListener = lightBarController::setScrimState;
mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
@@ -312,6 +315,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
});
mColors = new GradientColors();
mKeyguardViewMediator = keyguardViewMediator;
}
/**
@@ -807,6 +812,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mBehindTint,
interpolatedFraction);
}
// If we're unlocked but still playing the occlude animation, remain at the keyguard
// alpha temporarily.
if (mKeyguardViewMediator.isOccludeAnimationPlaying()
|| mState.mLaunchingAffordanceWithPreview) {
mNotificationsAlpha = KEYGUARD_SCRIM_ALPHA;
}
} else if (mState == ScrimState.AUTH_SCRIMMED_SHADE) {
float behindFraction = getInterpolatedFraction();
behindFraction = (float) Math.pow(behindFraction, 0.8f);

View File

@@ -60,6 +60,7 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -112,6 +113,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private FalsingCollectorFake mFalsingCollector;
private @Mock CentralSurfaces mCentralSurfaces;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -258,6 +261,26 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
verify(mKeyguardStateController).notifyKeyguardGoingAway(false);
}
@Test
public void testUpdateIsKeyguardAfterOccludeAnimationEnds() {
mViewMediator.mOccludeAnimationController.onLaunchAnimationEnd(
false /* isExpandingFullyAbove */);
// Since the updateIsKeyguard call is delayed during the animation, ensure it's called once
// it ends.
verify(mCentralSurfaces).updateIsKeyguard();
}
@Test
public void testUpdateIsKeyguardAfterOccludeAnimationIsCancelled() {
mViewMediator.mOccludeAnimationController.onLaunchAnimationCancelled(
null /* newKeyguardOccludedState */);
// Since the updateIsKeyguard call is delayed during the animation, ensure it's called if
// it's cancelled.
verify(mCentralSurfaces).updateIsKeyguard();
}
private void createAndStartViewMediator() {
mViewMediator = new KeyguardViewMediator(
mContext,
@@ -287,5 +310,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mNotificationShadeWindowControllerLazy,
() -> mActivityLaunchAnimator);
mViewMediator.start();
mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null);
}
}

View File

@@ -235,6 +235,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private NavigationBarController mNavigationBarController;
@Mock private AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
@Mock private SysuiColorExtractor mColorExtractor;
private WakefulnessLifecycle mWakefulnessLifecycle;
@Mock private ColorExtractor.GradientColors mGradientColors;
@Mock private PulseExpansionHandler mPulseExpansionHandler;
@Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
@@ -366,10 +367,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
return null;
}).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
WakefulnessLifecycle wakefulnessLifecycle =
mWakefulnessLifecycle =
new WakefulnessLifecycle(mContext, mIWallpaperManager, mDumpManager);
wakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
wakefulnessLifecycle.dispatchFinishedWakingUp();
mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
mWakefulnessLifecycle.dispatchFinishedWakingUp();
when(mGradientColors.supportsDarkText()).thenReturn(true);
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
@@ -428,7 +429,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mBatteryController,
mColorExtractor,
new ScreenLifecycle(mDumpManager),
wakefulnessLifecycle,
mWakefulnessLifecycle,
mStatusBarStateController,
Optional.of(mBubbles),
mDeviceProvisionedController,
@@ -507,6 +508,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController;
mCentralSurfaces.mBarService = mBarService;
mCentralSurfaces.mStackScroller = mStackScroller;
mCentralSurfaces.mGestureWakeLock = mPowerManager.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "sysui:GestureWakeLock");
mCentralSurfaces.startKeyguard();
mInitController.executePostInitTasks();
notificationLogger.setUpWithContainer(mNotificationListContainer);
@@ -1125,6 +1128,55 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
assertThat(onDismissActionCaptor.getValue().onDismiss()).isFalse();
}
@Test
public void testKeyguardHideDelayedIfOcclusionAnimationRunning() {
// Show the keyguard and verify we've done so.
setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
verify(mStatusBarStateController).setState(StatusBarState.KEYGUARD);
// Request to hide the keyguard, but while the occlude animation is playing. We should delay
// this hide call, since we're playing the occlude animation over the keyguard and thus want
// it to remain visible.
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(true);
setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
verify(mStatusBarStateController, never()).setState(StatusBarState.SHADE);
// Once the animation ends, verify that the keyguard is actually hidden.
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
verify(mStatusBarStateController).setState(StatusBarState.SHADE);
}
@Test
public void testKeyguardHideNotDelayedIfOcclusionAnimationNotRunning() {
// Show the keyguard and verify we've done so.
setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
verify(mStatusBarStateController).setState(StatusBarState.KEYGUARD);
// Hide the keyguard while the occlusion animation is not running. Verify that we
// immediately hide the keyguard.
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
verify(mStatusBarStateController).setState(StatusBarState.SHADE);
}
/**
* Configures the appropriate mocks and then calls {@link CentralSurfacesImpl#updateIsKeyguard}
* to reconfigure the keyguard to reflect the requested showing/occluded states.
*/
private void setKeyguardShowingAndOccluded(boolean showing, boolean occluded) {
when(mStatusBarStateController.isKeyguardRequested()).thenReturn(showing);
when(mKeyguardStateController.isOccluded()).thenReturn(occluded);
// If we want to show the keyguard, make sure that we think we're awake and not unlocking.
if (showing) {
when(mBiometricUnlockController.isWakeAndUnlock()).thenReturn(false);
mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
}
mCentralSurfaces.updateIsKeyguard(false /* forceStateChange */);
}
private void setDeviceState(int state) {
ArgumentCaptor<DeviceStateManager.DeviceStateCallback> callbackCaptor =
ArgumentCaptor.forClass(DeviceStateManager.DeviceStateCallback.class);

View File

@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.statusbar.phone.ScrimController.KEYGUARD_SCRIM_ALPHA;
import static com.android.systemui.statusbar.phone.ScrimController.OPAQUE;
import static com.android.systemui.statusbar.phone.ScrimController.SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.ScrimController.TRANSPARENT;
@@ -58,6 +59,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.policy.FakeConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -117,6 +119,7 @@ public class ScrimControllerTest extends SysuiTestCase {
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private KeyguardViewMediator mKeyguardViewMediator;
private static class AnimatorListener implements Animator.AnimatorListener {
private int mNumStarts;
@@ -230,7 +233,8 @@ public class ScrimControllerTest extends SysuiTestCase {
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
mScreenOffAnimationController,
mKeyguardUnlockAnimationController,
mStatusBarKeyguardViewManager);
mStatusBarKeyguardViewManager,
mKeyguardViewMediator);
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
mScrimController.setAnimatorListener(mAnimatorListener);
@@ -239,6 +243,8 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setWallpaperSupportsAmbientMode(false);
mScrimController.transitionTo(ScrimState.KEYGUARD);
finishAnimationsImmediately();
mScrimController.setLaunchingAffordanceWithPreview(false);
}
@After
@@ -852,7 +858,8 @@ public class ScrimControllerTest extends SysuiTestCase {
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
mScreenOffAnimationController,
mKeyguardUnlockAnimationController,
mStatusBarKeyguardViewManager);
mStatusBarKeyguardViewManager,
mKeyguardViewMediator);
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
mScrimController.setAnimatorListener(mAnimatorListener);
@@ -1592,6 +1599,30 @@ public class ScrimControllerTest extends SysuiTestCase {
assertScrimAlpha(mScrimBehind, 0);
}
@Test
public void keyguardAlpha_whenUnlockedForOcclusion_ifPlayingOcclusionAnimation() {
mScrimController.transitionTo(ScrimState.KEYGUARD);
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(true);
mScrimController.transitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
assertScrimAlpha(mNotificationsScrim, (int) (KEYGUARD_SCRIM_ALPHA * 255f));
}
@Test
public void keyguardAlpha_whenUnlockedForLaunch_ifLaunchingAffordance() {
mScrimController.transitionTo(ScrimState.KEYGUARD);
when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(true);
mScrimController.setLaunchingAffordanceWithPreview(true);
mScrimController.transitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
assertScrimAlpha(mNotificationsScrim, (int) (KEYGUARD_SCRIM_ALPHA * 255f));
}
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
mScrimController.setRawPanelExpansionFraction(expansion);
finishAnimationsImmediately();