Merge "Dismiss keyguard when target user has no password"
This commit is contained in:
committed by
Android (Google) Code Review
commit
15cd688ea7
@@ -103,6 +103,7 @@ import android.util.proto.ProtoOutputStream;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.policy.IKeyguardDismissCallback;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
@@ -162,6 +163,7 @@ class UserController implements Handler.Callback {
|
||||
static final int USER_UNLOCKED_MSG = 105;
|
||||
static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
|
||||
static final int START_USER_SWITCH_FG_MSG = 120;
|
||||
static final int COMPLETE_USER_SWITCH_MSG = 130;
|
||||
|
||||
// Message constant to clear {@link UserJourneySession} from {@link mUserIdToUserJourneyMap} if
|
||||
// the user journey, defined in the UserLifecycleJourneyReported atom for statsd, is not
|
||||
@@ -385,6 +387,7 @@ class UserController implements Handler.Callback {
|
||||
@VisibleForTesting
|
||||
UserController(Injector injector) {
|
||||
mInjector = injector;
|
||||
// This should be called early to avoid a null mHandler inside the injector
|
||||
mHandler = mInjector.getHandler(this);
|
||||
mUiHandler = mInjector.getUiHandler(this);
|
||||
// User 0 is the first and only user that runs at boot.
|
||||
@@ -1535,7 +1538,10 @@ class UserController implements Handler.Callback {
|
||||
// with the option to show the user switcher on the keyguard.
|
||||
if (userSwitchUiEnabled) {
|
||||
mInjector.getWindowManager().setSwitchingUser(true);
|
||||
mInjector.getWindowManager().lockNow(null);
|
||||
// Only lock if the user has a secure keyguard PIN/Pattern/Pwd
|
||||
if (mInjector.getKeyguardManager().isDeviceSecure(userId)) {
|
||||
mInjector.getWindowManager().lockNow(null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final Integer currentUserIdInt = mCurrentUserId;
|
||||
@@ -1967,11 +1973,10 @@ class UserController implements Handler.Callback {
|
||||
|
||||
EventLog.writeEvent(EventLogTags.UC_CONTINUE_USER_SWITCH, oldUserId, newUserId);
|
||||
|
||||
if (isUserSwitchUiEnabled()) {
|
||||
t.traceBegin("stopFreezingScreen");
|
||||
mInjector.getWindowManager().stopFreezingScreen();
|
||||
t.traceEnd();
|
||||
}
|
||||
// Do the keyguard dismiss and unfreeze later
|
||||
mHandler.removeMessages(COMPLETE_USER_SWITCH_MSG);
|
||||
mHandler.sendMessage(mHandler.obtainMessage(COMPLETE_USER_SWITCH_MSG, newUserId, 0));
|
||||
|
||||
uss.switching = false;
|
||||
mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
|
||||
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG, newUserId, 0));
|
||||
@@ -1981,6 +1986,34 @@ class UserController implements Handler.Callback {
|
||||
t.traceEnd(); // end continueUserSwitch
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void completeUserSwitch(int newUserId) {
|
||||
if (isUserSwitchUiEnabled()) {
|
||||
// If there is no challenge set, dismiss the keyguard right away
|
||||
if (!mInjector.getKeyguardManager().isDeviceSecure(newUserId)) {
|
||||
// Wait until the keyguard is dismissed to unfreeze
|
||||
mInjector.dismissKeyguard(
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
unfreezeScreen();
|
||||
}
|
||||
},
|
||||
"User Switch");
|
||||
return;
|
||||
} else {
|
||||
unfreezeScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void unfreezeScreen() {
|
||||
TimingsTraceAndSlog t = new TimingsTraceAndSlog();
|
||||
t.traceBegin("stopFreezingScreen");
|
||||
mInjector.getWindowManager().stopFreezingScreen();
|
||||
t.traceEnd();
|
||||
}
|
||||
|
||||
private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
|
||||
boolean homeInFront = mInjector.taskSupervisorSwitchUser(newUserId, uss);
|
||||
if (homeInFront) {
|
||||
@@ -2772,6 +2805,9 @@ class UserController implements Handler.Callback {
|
||||
case CLEAR_USER_JOURNEY_SESSION_MSG:
|
||||
logAndClearSessionId(msg.arg1);
|
||||
break;
|
||||
case COMPLETE_USER_SWITCH_MSG:
|
||||
completeUserSwitch(msg.arg1);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2961,13 +2997,14 @@ class UserController implements Handler.Callback {
|
||||
private final ActivityManagerService mService;
|
||||
private UserManagerService mUserManager;
|
||||
private UserManagerInternal mUserManagerInternal;
|
||||
private Handler mHandler;
|
||||
|
||||
Injector(ActivityManagerService service) {
|
||||
mService = service;
|
||||
}
|
||||
|
||||
protected Handler getHandler(Handler.Callback callback) {
|
||||
return new Handler(mService.mHandlerThread.getLooper(), callback);
|
||||
return mHandler = new Handler(mService.mHandlerThread.getLooper(), callback);
|
||||
}
|
||||
|
||||
protected Handler getUiHandler(Handler.Callback callback) {
|
||||
@@ -3165,5 +3202,24 @@ class UserController implements Handler.Callback {
|
||||
protected IStorageManager getStorageManager() {
|
||||
return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
|
||||
}
|
||||
|
||||
protected void dismissKeyguard(Runnable runnable, String reason) {
|
||||
getWindowManager().dismissKeyguard(new IKeyguardDismissCallback.Stub() {
|
||||
@Override
|
||||
public void onDismissError() throws RemoteException {
|
||||
mHandler.post(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissSucceeded() throws RemoteException {
|
||||
mHandler.post(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissCancelled() throws RemoteException {
|
||||
mHandler.post(runnable);
|
||||
}
|
||||
}, reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareC
|
||||
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
import static com.android.server.am.UserController.COMPLETE_USER_SWITCH_MSG;
|
||||
import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
|
||||
import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
|
||||
import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
|
||||
@@ -59,6 +60,7 @@ import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.IUserSwitchObserver;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.IIntentReceiver;
|
||||
import android.content.Intent;
|
||||
@@ -325,8 +327,16 @@ public class UserControllerTest {
|
||||
assertWithMessage("No messages should be sent").that(actualCodes).isEmpty();
|
||||
}
|
||||
|
||||
private void continueAndCompleteUserSwitch(UserState userState, int oldUserId, int newUserId) {
|
||||
mUserController.continueUserSwitch(userState, oldUserId, newUserId);
|
||||
mInjector.mHandler.removeMessages(UserController.COMPLETE_USER_SWITCH_MSG);
|
||||
mUserController.completeUserSwitch(newUserId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContinueUserSwitch() throws RemoteException {
|
||||
mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
|
||||
/* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
|
||||
// Start user -- this will update state of mUserController
|
||||
mUserController.startUser(TEST_USER_ID, true);
|
||||
Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
|
||||
@@ -336,7 +346,28 @@ public class UserControllerTest {
|
||||
int newUserId = reportMsg.arg2;
|
||||
mInjector.mHandler.clearAllRecordedMessages();
|
||||
// Verify that continueUserSwitch worked as expected
|
||||
mUserController.continueUserSwitch(userState, oldUserId, newUserId);
|
||||
continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
|
||||
verify(mInjector, times(0)).dismissKeyguard(any(), anyString());
|
||||
verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
|
||||
continueUserSwitchAssertions(TEST_USER_ID, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContinueUserSwitchDismissKeyguard() throws RemoteException {
|
||||
when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(false);
|
||||
mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
|
||||
/* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
|
||||
// Start user -- this will update state of mUserController
|
||||
mUserController.startUser(TEST_USER_ID, true);
|
||||
Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
|
||||
assertNotNull(reportMsg);
|
||||
UserState userState = (UserState) reportMsg.obj;
|
||||
int oldUserId = reportMsg.arg1;
|
||||
int newUserId = reportMsg.arg2;
|
||||
mInjector.mHandler.clearAllRecordedMessages();
|
||||
// Verify that continueUserSwitch worked as expected
|
||||
continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
|
||||
verify(mInjector, times(1)).dismissKeyguard(any(), anyString());
|
||||
verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
|
||||
continueUserSwitchAssertions(TEST_USER_ID, false);
|
||||
}
|
||||
@@ -355,7 +386,7 @@ public class UserControllerTest {
|
||||
int newUserId = reportMsg.arg2;
|
||||
mInjector.mHandler.clearAllRecordedMessages();
|
||||
// Verify that continueUserSwitch worked as expected
|
||||
mUserController.continueUserSwitch(userState, oldUserId, newUserId);
|
||||
continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
|
||||
verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
|
||||
continueUserSwitchAssertions(TEST_USER_ID, false);
|
||||
}
|
||||
@@ -363,6 +394,7 @@ public class UserControllerTest {
|
||||
private void continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping)
|
||||
throws RemoteException {
|
||||
Set<Integer> expectedCodes = new LinkedHashSet<>();
|
||||
expectedCodes.add(COMPLETE_USER_SWITCH_MSG);
|
||||
expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG);
|
||||
if (backgroundUserStopping) {
|
||||
expectedCodes.add(0); // this is for directly posting in stopping.
|
||||
@@ -397,7 +429,7 @@ public class UserControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitSystenUserStartInBackground() {
|
||||
public void testExplicitSystemUserStartInBackground() {
|
||||
setUpUser(UserHandle.USER_SYSTEM, 0);
|
||||
assertFalse(mUserController.isSystemUserStarted());
|
||||
assertTrue(mUserController.startUser(UserHandle.USER_SYSTEM, false, null));
|
||||
@@ -646,7 +678,7 @@ public class UserControllerTest {
|
||||
mUserStates.put(newUserId, userState);
|
||||
mInjector.mHandler.clearAllRecordedMessages();
|
||||
// Verify that continueUserSwitch worked as expected
|
||||
mUserController.continueUserSwitch(userState, oldUserId, newUserId);
|
||||
continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
|
||||
verify(mInjector.getWindowManager(), times(expectedNumberOfCalls))
|
||||
.stopFreezingScreen();
|
||||
continueUserSwitchAssertions(newUserId, expectOldUserStopping);
|
||||
@@ -701,6 +733,7 @@ public class UserControllerTest {
|
||||
private final IStorageManager mStorageManagerMock;
|
||||
private final UserManagerInternal mUserManagerInternalMock;
|
||||
private final WindowManagerService mWindowManagerMock;
|
||||
private final KeyguardManager mKeyguardManagerMock;
|
||||
|
||||
private final Context mCtx;
|
||||
|
||||
@@ -715,6 +748,8 @@ public class UserControllerTest {
|
||||
mUserManagerInternalMock = mock(UserManagerInternal.class);
|
||||
mWindowManagerMock = mock(WindowManagerService.class);
|
||||
mStorageManagerMock = mock(IStorageManager.class);
|
||||
mKeyguardManagerMock = mock(KeyguardManager.class);
|
||||
when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -753,6 +788,11 @@ public class UserControllerTest {
|
||||
return mWindowManagerMock;
|
||||
}
|
||||
|
||||
@Override
|
||||
KeyguardManager getKeyguardManager() {
|
||||
return mKeyguardManagerMock;
|
||||
}
|
||||
|
||||
@Override
|
||||
void updateUserConfiguration() {
|
||||
Log.i(TAG, "updateUserConfiguration");
|
||||
@@ -787,6 +827,11 @@ public class UserControllerTest {
|
||||
protected IStorageManager getStorageManager() {
|
||||
return mStorageManagerMock;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dismissKeyguard(Runnable runnable, String reason) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestHandler extends Handler {
|
||||
|
||||
Reference in New Issue
Block a user