Show specific messages for why bouncer is shown before or after OTA update.

Test: 1. Restart the device,
      2. Run `adb setprop sys.boot.reason.last reboot,mainline_update` before unlock
      3. See message on bouncer
Test: atest KeyguardViewMediatorTest
Bug: 285956229
Bug: 285578578
Change-Id: I8623cce9e9eb4c321f377f262e9831e3c3a62e93
This commit is contained in:
Chandru S
2023-06-13 10:47:27 -07:00
parent 9a60d6d679
commit eacf34bc18
8 changed files with 63 additions and 11 deletions

View File

@@ -358,12 +358,12 @@
<!-- Message shown to prepare for an unattended update (OTA). Also known as an over-the-air (OTA) update. [CHAR LIMIT=70] --> <!-- Message shown to prepare for an unattended update (OTA). Also known as an over-the-air (OTA) update. [CHAR LIMIT=70] -->
<string name="kg_prompt_unattended_update_pattern">Draw pattern to install update later</string> <string name="kg_prompt_unattended_update_pattern">Draw pattern to install update later</string>
<!-- Message shown after an unattended update (OTA) asking the user to enter their PIN. Also known as an over-the-air (OTA) update. [CHAR LIMIT=70] --> <!-- Message shown after an unattended mainline (major) update asking the user to enter their PIN. [CHAR LIMIT=70] -->
<string name="kg_prompt_after_update_pin">Device updated. Enter PIN to continue.</string> <string name="kg_prompt_after_update_pin">Device updated. Enter PIN to continue.</string>
<!-- Message shown after an unattended update (OTA) asking the user to enter their password. Also known as an over-the-air (OTA) update. [CHAR LIMIT=70] --> <!-- Message shown after an unattended mainline (major) update asking the user to enter their password. [CHAR LIMIT=70] -->
<string name="kg_prompt_after_update_password">Device updated. Enter password to continue.</string> <string name="kg_prompt_after_update_password">Device updated. Enter password to continue.</string>
<!-- Message shown after an unattended update (OTA) asking the user to enter their pattern. Also known as an over-the-air (OTA) update. [CHAR LIMIT=70] --> <!-- Message shown after an unattended mainline (major) update asking the user to enter their pattern. [CHAR LIMIT=70] -->
<string name="kg_prompt_after_update_pattern">Device updated. Draw pattern to continue.</string> <string name="kg_prompt_after_update_pattern">Device updated. Draw pattern to continue.</string>
</resources> </resources>

View File

@@ -23,6 +23,7 @@ import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
@@ -99,6 +100,8 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
switch (reason) { switch (reason) {
case PROMPT_REASON_RESTART: case PROMPT_REASON_RESTART:
return R.string.kg_prompt_reason_restart_password; return R.string.kg_prompt_reason_restart_password;
case PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE:
return R.string.kg_prompt_after_update_password;
case PROMPT_REASON_TIMEOUT: case PROMPT_REASON_TIMEOUT:
return R.string.kg_prompt_reason_timeout_password; return R.string.kg_prompt_reason_timeout_password;
case PROMPT_REASON_DEVICE_ADMIN: case PROMPT_REASON_DEVICE_ADMIN:
@@ -106,7 +109,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
case PROMPT_REASON_USER_REQUEST: case PROMPT_REASON_USER_REQUEST:
return R.string.kg_prompt_after_user_lockdown_password; return R.string.kg_prompt_after_user_lockdown_password;
case PROMPT_REASON_PREPARE_FOR_UPDATE: case PROMPT_REASON_PREPARE_FOR_UPDATE:
return R.string.kg_prompt_reason_timeout_password; return R.string.kg_prompt_unattended_update_password;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT: case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
return R.string.kg_prompt_reason_timeout_password; return R.string.kg_prompt_reason_timeout_password;
case PROMPT_REASON_TRUSTAGENT_EXPIRED: case PROMPT_REASON_TRUSTAGENT_EXPIRED:

View File

@@ -304,6 +304,9 @@ public class KeyguardPatternViewController
case PROMPT_REASON_RESTART: case PROMPT_REASON_RESTART:
resId = R.string.kg_prompt_reason_restart_pattern; resId = R.string.kg_prompt_reason_restart_pattern;
break; break;
case PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE:
resId = R.string.kg_prompt_after_update_pattern;
break;
case PROMPT_REASON_TIMEOUT: case PROMPT_REASON_TIMEOUT:
resId = R.string.kg_prompt_reason_timeout_pattern; resId = R.string.kg_prompt_reason_timeout_pattern;
break; break;
@@ -314,7 +317,7 @@ public class KeyguardPatternViewController
resId = R.string.kg_prompt_after_user_lockdown_pattern; resId = R.string.kg_prompt_after_user_lockdown_pattern;
break; break;
case PROMPT_REASON_PREPARE_FOR_UPDATE: case PROMPT_REASON_PREPARE_FOR_UPDATE:
resId = R.string.kg_prompt_reason_timeout_pattern; resId = R.string.kg_prompt_unattended_update_pattern;
break; break;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT: case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
resId = R.string.kg_prompt_reason_timeout_pattern; resId = R.string.kg_prompt_reason_timeout_pattern;

View File

@@ -21,6 +21,7 @@ import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
@@ -113,6 +114,8 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
switch (reason) { switch (reason) {
case PROMPT_REASON_RESTART: case PROMPT_REASON_RESTART:
return R.string.kg_prompt_reason_restart_pin; return R.string.kg_prompt_reason_restart_pin;
case PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE:
return R.string.kg_prompt_after_update_pin;
case PROMPT_REASON_TIMEOUT: case PROMPT_REASON_TIMEOUT:
return R.string.kg_prompt_reason_timeout_pin; return R.string.kg_prompt_reason_timeout_pin;
case PROMPT_REASON_DEVICE_ADMIN: case PROMPT_REASON_DEVICE_ADMIN:
@@ -120,7 +123,7 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
case PROMPT_REASON_USER_REQUEST: case PROMPT_REASON_USER_REQUEST:
return R.string.kg_prompt_after_user_lockdown_pin; return R.string.kg_prompt_after_user_lockdown_pin;
case PROMPT_REASON_PREPARE_FOR_UPDATE: case PROMPT_REASON_PREPARE_FOR_UPDATE:
return R.string.kg_prompt_reason_timeout_pin; return R.string.kg_prompt_unattended_update_pin;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT: case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
return R.string.kg_prompt_reason_timeout_pin; return R.string.kg_prompt_reason_timeout_pin;
case PROMPT_REASON_TRUSTAGENT_EXPIRED: case PROMPT_REASON_TRUSTAGENT_EXPIRED:

View File

@@ -102,6 +102,12 @@ public interface KeyguardSecurityView {
*/ */
int PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT = 15; int PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT = 15;
/**
* Strong auth is required because the device has just booted because of an automatic
* mainline update.
*/
int PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE = 16;
/** /**
* Reset the view and prepare to take input. This should do things like clearing the * Reset the view and prepare to take input. This should do things like clearing the
* password or pattern and clear error messages. * password or pattern and clear error messages.

View File

@@ -138,6 +138,7 @@ import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags; import com.android.systemui.flags.Flags;
import com.android.systemui.flags.SystemPropertiesHelper;
import com.android.systemui.keyguard.dagger.KeyguardModule; import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.log.SessionTracker; import com.android.systemui.log.SessionTracker;
@@ -171,6 +172,7 @@ import dagger.Lazy;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -284,6 +286,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
* keyguard to show even if it is disabled for the current user. * keyguard to show even if it is disabled for the current user.
*/ */
public static final String OPTION_FORCE_SHOW = "force_show"; public static final String OPTION_FORCE_SHOW = "force_show";
public static final String SYS_BOOT_REASON_PROP = "sys.boot.reason.last";
public static final String REBOOT_MAINLINE_UPDATE = "reboot,mainline_update";
private final DreamOverlayStateController mDreamOverlayStateController; private final DreamOverlayStateController mDreamOverlayStateController;
/** The stream type that the lock sounds are tied to. */ /** The stream type that the lock sounds are tied to. */
@@ -322,6 +326,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private final SecureSettings mSecureSettings; private final SecureSettings mSecureSettings;
private final SystemSettings mSystemSettings; private final SystemSettings mSystemSettings;
private final SystemClock mSystemClock; private final SystemClock mSystemClock;
private SystemPropertiesHelper mSystemPropertiesHelper;
/** /**
* Used to keep the device awake while to ensure the keyguard finishes opening before * Used to keep the device awake while to ensure the keyguard finishes opening before
@@ -853,7 +858,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
strongAuthTracker.isNonStrongBiometricAllowedAfterIdleTimeout(currentUser); strongAuthTracker.isNonStrongBiometricAllowedAfterIdleTimeout(currentUser);
if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) { if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
return KeyguardSecurityView.PROMPT_REASON_RESTART; String reasonForReboot = mSystemPropertiesHelper.get(SYS_BOOT_REASON_PROP);
if (Objects.equals(reasonForReboot, REBOOT_MAINLINE_UPDATE)) {
return KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE;
} else {
return KeyguardSecurityView.PROMPT_REASON_RESTART;
}
} else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) { } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
return KeyguardSecurityView.PROMPT_REASON_TIMEOUT; return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
} else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0) { } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0) {
@@ -1314,7 +1324,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
SystemSettings systemSettings, SystemSettings systemSettings,
SystemClock systemClock, SystemClock systemClock,
@Main CoroutineDispatcher mainDispatcher, @Main CoroutineDispatcher mainDispatcher,
Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel) { Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel,
SystemPropertiesHelper systemPropertiesHelper) {
mContext = context; mContext = context;
mUserTracker = userTracker; mUserTracker = userTracker;
mFalsingCollector = falsingCollector; mFalsingCollector = falsingCollector;
@@ -1331,6 +1342,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mSecureSettings = secureSettings; mSecureSettings = secureSettings;
mSystemSettings = systemSettings; mSystemSettings = systemSettings;
mSystemClock = systemClock; mSystemClock = systemClock;
mSystemPropertiesHelper = systemPropertiesHelper;
mStatusBarService = IStatusBarService.Stub.asInterface( mStatusBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE)); ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mKeyguardDisplayManager = keyguardDisplayManager; mKeyguardDisplayManager = keyguardDisplayManager;

View File

@@ -42,6 +42,7 @@ import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.SystemPropertiesHelper;
import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -140,7 +141,8 @@ public class KeyguardModule {
SystemSettings systemSettings, SystemSettings systemSettings,
SystemClock systemClock, SystemClock systemClock,
@Main CoroutineDispatcher mainDispatcher, @Main CoroutineDispatcher mainDispatcher,
Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel) { Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel,
SystemPropertiesHelper systemPropertiesHelper) {
return new KeyguardViewMediator( return new KeyguardViewMediator(
context, context,
uiEventLogger, uiEventLogger,
@@ -179,7 +181,8 @@ public class KeyguardModule {
systemSettings, systemSettings,
systemClock, systemClock,
mainDispatcher, mainDispatcher,
dreamingToLockscreenTransitionViewModel); dreamingToLockscreenTransitionViewModel,
systemPropertiesHelper);
} }
/** */ /** */

View File

@@ -27,6 +27,8 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION; import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION;
import static com.android.systemui.keyguard.KeyguardViewMediator.KEYGUARD_LOCK_AFTER_DELAY_DEFAULT; import static com.android.systemui.keyguard.KeyguardViewMediator.KEYGUARD_LOCK_AFTER_DELAY_DEFAULT;
import static com.android.systemui.keyguard.KeyguardViewMediator.REBOOT_MAINLINE_UPDATE;
import static com.android.systemui.keyguard.KeyguardViewMediator.SYS_BOOT_REASON_PROP;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@@ -80,6 +82,7 @@ import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.Flags; import com.android.systemui.flags.Flags;
import com.android.systemui.flags.SystemPropertiesHelper;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.log.SessionTracker; import com.android.systemui.log.SessionTracker;
import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.NavigationModeController;
@@ -179,6 +182,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock CoroutineDispatcher mDispatcher; private @Mock CoroutineDispatcher mDispatcher;
private @Mock DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel; private @Mock DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
private @Mock SystemPropertiesHelper mSystemPropertiesHelper;
private FakeFeatureFlags mFeatureFlags; private FakeFeatureFlags mFeatureFlags;
private int mInitialUserId; private int mInitialUserId;
@@ -380,6 +384,23 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mViewMediator.mViewMediatorCallback.getBouncerPromptReason()); mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
} }
@Test
public void testBouncerPrompt_deviceRestartedDueToMainlineUpdate() {
// GIVEN biometrics enrolled
when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(true);
// WHEN reboot caused by ota update
KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(false);
when(mSystemPropertiesHelper.get(SYS_BOOT_REASON_PROP)).thenReturn(REBOOT_MAINLINE_UPDATE);
// THEN the bouncer prompt reason should return PROMPT_REASON_RESTART_FOR_OTA
assertEquals(KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE,
mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
}
@Test @Test
public void testBouncerPrompt_afterUserLockDown() { public void testBouncerPrompt_afterUserLockDown() {
// GIVEN biometrics enrolled // GIVEN biometrics enrolled
@@ -747,7 +768,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mSystemSettings, mSystemSettings,
mSystemClock, mSystemClock,
mDispatcher, mDispatcher,
() -> mDreamingToLockscreenTransitionViewModel); () -> mDreamingToLockscreenTransitionViewModel,
mSystemPropertiesHelper);
mViewMediator.start(); mViewMediator.start();
mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null); mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null);