From 75f224c673d13134381dab49ea8a95858f5d2c56 Mon Sep 17 00:00:00 2001 From: Chandru S Date: Fri, 19 May 2023 17:22:31 -0700 Subject: [PATCH] Inject system settings, secure settings & system clock to make it easily testable Add tests for verifying that we use user specific settings for timeout values. Bug: 265431505 Test: atest KeyguardViewMediatorTest Change-Id: Ibbd1a74f3e87ee8a5f003db90fcfbee9ca89d359 Merged-In: Ibbd1a74f3e87ee8a5f003db90fcfbee9ca89d359 --- .../keyguard/KeyguardViewMediator.java | 53 ++++++++------ .../keyguard/dagger/KeyguardModule.java | 13 +++- .../keyguard/KeyguardViewMediatorTest.java | 73 ++++++++++++++++++- 3 files changed, 113 insertions(+), 26 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 3b40d8602e6fe..81f325f53f1b6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -17,6 +17,8 @@ package com.android.systemui.keyguard; import static android.app.StatusBarManager.SESSION_KEYGUARD; +import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT; +import static android.provider.Settings.System.LOCKSCREEN_SOUNDS_ENABLED; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT; @@ -70,7 +72,6 @@ import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; @@ -93,7 +94,6 @@ import android.view.WindowManager; import android.view.WindowManagerPolicyConstants; import android.view.animation.Animation; import android.view.animation.AnimationUtils; -import android.window.IRemoteTransition; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -154,6 +154,9 @@ import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.DeviceConfigProxy; +import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.util.settings.SystemSettings; +import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.keyguard.KeyguardTransitions; import dagger.Lazy; @@ -161,7 +164,6 @@ import dagger.Lazy; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; -import java.util.Optional; import java.util.concurrent.Executor; /** @@ -215,7 +217,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, private final static String TAG = "KeyguardViewMediator"; - private static final String DELAYED_KEYGUARD_ACTION = + public static final String DELAYED_KEYGUARD_ACTION = "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"; private static final String DELAYED_LOCK_PROFILE_ACTION = "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK"; @@ -250,7 +252,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, * turning on the keyguard (i.e, the user has this much time to turn * the screen back on without having to face the keyguard). */ - private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000; + public static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000; /** * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()} @@ -306,6 +308,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, /** UserSwitcherController for creating guest user on boot complete */ private final UserSwitcherController mUserSwitcherController; + private final SecureSettings mSecureSettings; + private final SystemSettings mSystemSettings; + private final SystemClock mSystemClock; /** * Used to keep the device awake while to ensure the keyguard finishes opening before @@ -1253,7 +1258,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, Lazy notificationShadeWindowControllerLazy, Lazy activityLaunchAnimator, Lazy scrimControllerLazy, - FeatureFlags featureFlags) { + FeatureFlags featureFlags, + SecureSettings secureSettings, + SystemSettings systemSettings, + SystemClock systemClock) { mContext = context; mUserTracker = userTracker; mFalsingCollector = falsingCollector; @@ -1267,6 +1275,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, mPM = powerManager; mTrustManager = trustManager; mUserSwitcherController = userSwitcherController; + mSecureSettings = secureSettings; + mSystemSettings = systemSettings; + mSystemClock = systemClock; mStatusBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mKeyguardDisplayManager = keyguardDisplayManager; @@ -1316,7 +1327,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } public void userActivity() { - mPM.userActivity(SystemClock.uptimeMillis(), false); + mPM.userActivity(mSystemClock.uptimeMillis(), false); } private void setupLocked() { @@ -1502,7 +1513,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, if (cameraGestureTriggered) { // Just to make sure, make sure the device is awake. - mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(), + mContext.getSystemService(PowerManager.class).wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH, "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK"); setPendingLock(false); @@ -1599,12 +1610,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // to enable it a bit later (i.e, give the user a chance // to turn the screen back on within a certain window without // having to unlock the screen) - final ContentResolver cr = mContext.getContentResolver(); // From SecuritySettings - final long lockAfterTimeout = Settings.Secure.getIntForUser(cr, - Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, - KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, userId); + final long lockAfterTimeout = mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT, + KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, + userId); // From DevicePolicyAdmin final long policyTimeout = mLockPatternUtils.getDevicePolicyManager() @@ -1616,8 +1626,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, timeout = lockAfterTimeout; } else { // From DisplaySettings - long displayTimeout = Settings.System.getIntForUser(cr, SCREEN_OFF_TIMEOUT, - KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT, userId); + long displayTimeout = mSystemSettings.getIntForUser(SCREEN_OFF_TIMEOUT, + KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT, + userId); // policy in effect. Make sure we don't go beyond policy limit. displayTimeout = Math.max(displayTimeout, 0); // ignore negative values @@ -1638,7 +1649,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, private void doKeyguardLaterLocked(long timeout) { // Lock in the future - long when = SystemClock.elapsedRealtime() + timeout; + long when = mSystemClock.elapsedRealtime() + timeout; Intent intent = new Intent(DELAYED_KEYGUARD_ACTION); intent.setPackage(mContext.getPackageName()); intent.putExtra("seq", mDelayedShowingSequence); @@ -1660,7 +1671,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, if (userTimeout == 0) { doKeyguardForChildProfilesLocked(); } else { - long userWhen = SystemClock.elapsedRealtime() + userTimeout; + long userWhen = mSystemClock.elapsedRealtime() + userTimeout; Intent lockIntent = new Intent(DELAYED_LOCK_PROFILE_ACTION); lockIntent.setPackage(mContext.getPackageName()); lockIntent.putExtra("seq", mDelayedProfileShowingSequence); @@ -2468,9 +2479,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, private void playSound(int soundId) { if (soundId == 0) return; - final ContentResolver cr = mContext.getContentResolver(); - int lockscreenSoundsEnabled = Settings.System.getIntForUser(cr, - Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1, + int lockscreenSoundsEnabled = mSystemSettings.getIntForUser(LOCKSCREEN_SOUNDS_ENABLED, 1, KeyguardUpdateMonitor.getCurrentUser()); if (lockscreenSoundsEnabled == 1) { @@ -2647,7 +2656,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // It's possible that the device was unlocked (via BOUNCER) while dozing. It's time to // wake up. if (mAodShowing) { - mPM.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, + mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:BOUNCER_DOZING"); } @@ -2662,7 +2671,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // TODO(bc-unlock): Fill parameters mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(() -> { handleStartKeyguardExitAnimation( - SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), + mSystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */, null /* nonApps */, null /* finishedCallback */); }); @@ -2671,7 +2680,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // It's possible that the device was unlocked (via BOUNCER or Fingerprint) while // dreaming. It's time to wake up. if (mDreamOverlayShowing) { - mPM.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, + mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:UNLOCK_DREAMING"); } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index d7c039d9b519a..1c5bb5f4efaf4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -64,6 +64,9 @@ import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.DeviceConfigProxy; +import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.util.settings.SystemSettings; +import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.keyguard.KeyguardTransitions; import dagger.Lazy; @@ -128,7 +131,10 @@ public class KeyguardModule { Lazy notificationShadeWindowController, Lazy activityLaunchAnimator, Lazy scrimControllerLazy, - FeatureFlags featureFlags) { + FeatureFlags featureFlags, + SecureSettings secureSettings, + SystemSettings systemSettings, + SystemClock systemClock) { return new KeyguardViewMediator( context, uiEventLogger, @@ -162,7 +168,10 @@ public class KeyguardModule { notificationShadeWindowController, activityLaunchAnimator, scrimControllerLazy, - featureFlags); + featureFlags, + secureSettings, + systemSettings, + systemClock); } /** */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index f31ac00051f68..c4a0e7c6b7aba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -16,11 +16,16 @@ package com.android.systemui.keyguard; +import static android.os.PowerManager.WAKE_REASON_WAKE_MOTION; +import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; +import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT; import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT; +import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION; +import static com.android.systemui.keyguard.KeyguardViewMediator.KEYGUARD_LOCK_AFTER_DELAY_DEFAULT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -35,9 +40,12 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AlarmManager; import android.app.IActivityManager; +import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; +import android.content.Context; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.telephony.TelephonyManager; @@ -94,9 +102,12 @@ import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.FakeSystemClock; import com.android.wm.shell.keyguard.KeyguardTransitions; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -156,18 +167,24 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private @Mock CentralSurfaces mCentralSurfaces; private @Mock UiEventLogger mUiEventLogger; private @Mock SessionTracker mSessionTracker; + private @Mock SystemSettings mSystemSettings; + private @Mock SecureSettings mSecureSettings; + private @Mock AlarmManager mAlarmManager; + private FakeSystemClock mSystemClock; private FakeFeatureFlags mFeatureFlags; + private int mInitialUserId; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mFalsingCollector = new FalsingCollectorFake(); - + mSystemClock = new FakeSystemClock(); when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager); when(mPowerManager.newWakeLock(anyInt(), any())).thenReturn(mock(WakeLock.class)); when(mInteractionJankMonitor.begin(any(), anyInt())).thenReturn(true); when(mInteractionJankMonitor.end(anyInt())).thenReturn(true); + mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager); final ViewRootImpl testViewRoot = mock(ViewRootImpl.class); when(testViewRoot.getView()).thenReturn(mock(View.class)); when(mStatusBarKeyguardViewManager.getViewRootImpl()).thenReturn(testViewRoot); @@ -183,6 +200,12 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { DejankUtils.setImmediate(true); createAndStartViewMediator(); + mInitialUserId = KeyguardUpdateMonitor.getCurrentUser(); + } + + @After + public void teardown() { + KeyguardUpdateMonitor.setCurrentUser(mInitialUserId); } @Test @@ -368,6 +391,49 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.mViewMediatorCallback.getBouncerPromptReason()); } + @Test + public void lockAfterScreenTimeoutUsesValueFromSettings() { + int currentUserId = 99; + int userSpecificTimeout = 5999; + KeyguardUpdateMonitor.setCurrentUser(currentUserId); + + when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false); + when(mDevicePolicyManager.getMaximumTimeToLock(null, currentUserId)).thenReturn(0L); + when(mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT, + KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, currentUserId)).thenReturn(userSpecificTimeout); + mSystemClock.setElapsedRealtime(0L); + ArgumentCaptor pendingIntent = ArgumentCaptor.forClass(PendingIntent.class); + + mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_TIMEOUT); + + verify(mAlarmManager).setExactAndAllowWhileIdle(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + eq(Long.valueOf(userSpecificTimeout)), pendingIntent.capture()); + assertEquals(DELAYED_KEYGUARD_ACTION, pendingIntent.getValue().getIntent().getAction()); + } + + @Test + public void lockAfterSpecifiedAfterDreamStarted() { + int currentUserId = 99; + int userSpecificTimeout = 5999; + KeyguardUpdateMonitor.setCurrentUser(currentUserId); + + // set mDeviceInteractive to true + mViewMediator.onStartedWakingUp(WAKE_REASON_WAKE_MOTION, false); + mFeatureFlags.set(Flags.LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING, false); + when(mLockPatternUtils.isSecure(currentUserId)).thenReturn(true); + when(mDevicePolicyManager.getMaximumTimeToLock(null, currentUserId)).thenReturn(0L); + when(mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT, + KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, currentUserId)).thenReturn(userSpecificTimeout); + mSystemClock.setElapsedRealtime(0L); + ArgumentCaptor pendingIntent = ArgumentCaptor.forClass(PendingIntent.class); + + mViewMediator.onDreamingStarted(); + + verify(mAlarmManager).setExactAndAllowWhileIdle(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + eq(Long.valueOf(userSpecificTimeout)), pendingIntent.capture()); + assertEquals(DELAYED_KEYGUARD_ACTION, pendingIntent.getValue().getIntent().getAction()); + } + @Test public void testHideSurfaceBehindKeyguardMarksKeyguardNotGoingAway() { mViewMediator.hideSurfaceBehindKeyguard(); @@ -629,7 +695,10 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { () -> mNotificationShadeWindowController, () -> mActivityLaunchAnimator, () -> mScrimController, - mFeatureFlags); + mFeatureFlags, + mSecureSettings, + mSystemSettings, + mSystemClock); mViewMediator.start(); mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null);