Changes on am / cmd user for ITestDevice integration
- Added (optional) listener to startUserInBackgroundVisibleOnDisplay
- Added cmd user is-visible-background-users-supported
It will used by shell command and ITestDevice (which uses the cmd).
Test: adb shell cmd user is-visible-background-users-supported
Test: adb shell am start-user --display 2 -w 10
Test: atest -it com.android.server.am.ActivityManagerServiceTest UserControllerTest
Bug: 266851112
Change-Id: I04648a0ba91ec883273cf519c77b081eabfd5187
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c4d6ad7..b117bdd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4417,7 +4417,8 @@
"device does not support users on secondary displays");
}
try {
- return getService().startUserInBackgroundVisibleOnDisplay(userId, displayId);
+ return getService().startUserInBackgroundVisibleOnDisplay(userId, displayId,
+ /* unlockProgressListener= */ null);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 058c389..d26e6ed 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -803,7 +803,7 @@
*/
@JavaPassthrough(annotation=
"@android.annotation.RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional = true)")
- boolean startUserInBackgroundVisibleOnDisplay(int userid, int displayId);
+ boolean startUserInBackgroundVisibleOnDisplay(int userid, int displayId, IProgressListener unlockProgressListener);
/**
* Similar to {@link #startProfile(int userId)}, but with a listener to report user unlock
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b272502..b41f506 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -16629,7 +16629,8 @@
}
@Override
- public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId) {
+ public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId,
+ @Nullable IProgressListener unlockListener) {
int[] displayIds = getDisplayIdsForStartingVisibleBackgroundUsers();
boolean validDisplay = false;
if (displayIds != null) {
@@ -16646,11 +16647,11 @@
}
if (DEBUG_MU) {
- Slogf.d(TAG_MU, "Calling startUserOnSecondaryDisplay(%d, %d) using injector %s", userId,
- displayId, mInjector);
+ Slogf.d(TAG_MU, "Calling startUserOnSecondaryDisplay(%d, %d, %s) using injector %s",
+ userId, displayId, unlockListener, mInjector);
}
// Permission check done inside UserController.
- return mInjector.startUserInBackgroundVisibleOnDisplay(userId, displayId);
+ return mInjector.startUserInBackgroundVisibleOnDisplay(userId, displayId, unlockListener);
}
@Override
@@ -19031,8 +19032,10 @@
/**
* Called by {@code AMS.startUserInBackgroundVisibleOnDisplay()}.
*/
- public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId) {
- return mUserController.startUserVisibleOnDisplay(userId, displayId);
+ public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId,
+ @Nullable IProgressListener unlockProgressListener) {
+ return mUserController.startUserVisibleOnDisplay(userId, displayId,
+ unlockProgressListener);
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 3ab1cd7..0f36eb9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2243,9 +2243,10 @@
pw.println("Not supported");
return -1;
}
- Slogf.d(TAG, "calling startUserInBackgroundVisibleOnDisplay(%d,%d)", userId,
- displayId);
- success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId);
+ Slogf.d(TAG, "calling startUserInBackgroundVisibleOnDisplay(%d, %d, %s)", userId,
+ displayId, waiter);
+ success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId,
+ waiter);
displaySuffix = " on display " + displayId;
}
if (wait && success) {
@@ -3849,6 +3850,7 @@
int runListDisplaysForStartingUsers(PrintWriter pw) throws RemoteException {
int[] displayIds = mInterface.getDisplayIdsForStartingVisibleBackgroundUsers();
+ // NOTE: format below cannot be changed as it's used by ITestDevice
pw.println(displayIds == null || displayIds.length == 0
? "none"
: Arrays.toString(displayIds));
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index b2e4740..75f48a7 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1560,16 +1560,18 @@
*
* @param userId user to be started
* @param displayId display where the user will be visible
+ * @param unlockListener Listener to be informed when the user has started and unlocked.
*
* @return whether the user was started
*/
- boolean startUserVisibleOnDisplay(@UserIdInt int userId, int displayId) {
+ boolean startUserVisibleOnDisplay(@UserIdInt int userId, int displayId,
+ @Nullable IProgressListener unlockListener) {
checkCallingHasOneOfThosePermissions("startUserOnDisplay",
MANAGE_USERS, INTERACT_ACROSS_USERS);
try {
return startUserNoChecks(userId, displayId, USER_START_MODE_BACKGROUND_VISIBLE,
- /* unlockListener= */ null);
+ unlockListener);
} catch (RuntimeException e) {
Slogf.e(TAG, "startUserOnSecondaryDisplay(%d, %d) failed: %s", userId, displayId, e);
return false;
diff --git a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
index 50a1d90..165b009 100644
--- a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
+++ b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
@@ -111,6 +111,11 @@
pw.println(" It returns the effective mode, even when using emulation");
pw.println(" (to get the real mode as well, use -v or --verbose)");
pw.println();
+ pw.println(" is-visible-background-users-supported [-v | --verbose]");
+ pw.println(" Checks whether the device allows users to be start visible on background.");
+ pw.println(" It returns the effective mode, even when using emulation");
+ pw.println(" (to get the real mode as well, use -v or --verbose)");
+ pw.println();
pw.println(" is-user-visible [--display DISPLAY_ID] <USER_ID>");
pw.println(" Checks if the given user is visible in the given display.");
pw.println(" If the display option is not set, it uses the user's context to check");
@@ -134,6 +139,8 @@
return runSetSystemUserModeEmulation();
case "is-headless-system-user-mode":
return runIsHeadlessSystemUserMode();
+ case "is-visible-background-users-supported":
+ return runIsVisibleBackgroundUserSupported();
case "is-visible-background-users-on-default-display-supported":
return runIsVisibleBackgroundUserOnDefaultDisplaySupported();
case "is-user-visible":
@@ -418,6 +425,7 @@
} else {
isVisible = getUserManagerForUser(userId).isUserVisible();
}
+ // NOTE: do not change output below (or command name / args), as it's used by ITestDevice
pw.println(isVisible);
return 0;
}
@@ -450,6 +458,35 @@
return 0;
}
+ private int runIsVisibleBackgroundUserSupported() {
+ PrintWriter pw = getOutPrintWriter();
+
+ boolean verbose = false;
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "-v":
+ case "--verbose":
+ verbose = true;
+ break;
+ default:
+ pw.println("Invalid option: " + opt);
+ return -1;
+ }
+ }
+
+ boolean effective = UserManager.isVisibleBackgroundUsersEnabled();
+ if (!verbose) {
+ // NOTE: do not change output below, as it's used by ITestDevice
+ // (it's ok to change the verbose option though)
+ pw.println(effective);
+ } else {
+ pw.printf("effective=%b real=%b\n", effective, Resources.getSystem()
+ .getBoolean(R.bool.config_multiuserVisibleBackgroundUsers));
+ }
+ return 0;
+ }
+
private int runIsVisibleBackgroundUserOnDefaultDisplaySupported() {
PrintWriter pw = getOutPrintWriter();
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index e9dc082..37ed4ac 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -69,6 +69,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
+import android.os.IProgressListener;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
@@ -848,7 +849,8 @@
mInjector.secondaryDisplayIdsForStartingBackgroundUsers = new int[]{4, 8, 15, 16, 23, 42};
assertThrows(IllegalArgumentException.class,
- () -> mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 666));
+ () -> mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 666,
+ /* unlockProgressListener= */ null));
assertWithMessage("UserController.startUserOnSecondaryDisplay() calls")
.that(mInjector.usersStartedOnSecondaryDisplays).isEmpty();
@@ -859,7 +861,8 @@
mInjector.secondaryDisplayIdsForStartingBackgroundUsers = new int[]{ 4, 8, 15, 16, 23, 42 };
mInjector.returnValueForstartUserOnSecondaryDisplay = false;
- boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42);
+ boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42,
+ /* unlockProgressListener= */ null);
Log.v(TAG, "Started: " + started);
assertWithMessage("mAms.startUserInBackgroundOnDisplay(%s, 42)", USER_ID)
@@ -874,7 +877,8 @@
mInjector.secondaryDisplayIdsForStartingBackgroundUsers = new int[]{ 4, 8, 15, 16, 23, 42 };
mInjector.returnValueForstartUserOnSecondaryDisplay = true;
- boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42);
+ boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42,
+ /* unlockProgressListener= */ null);
Log.v(TAG, "Started: " + started);
assertWithMessage("mAms.startUserInBackgroundOnDisplay(%s, 42)", USER_ID)
@@ -1009,7 +1013,8 @@
}
@Override
- public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId) {
+ public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId,
+ IProgressListener unlockProgressListener) {
usersStartedOnSecondaryDisplays.add(new Pair<>(userId, displayId));
return returnValueForstartUserOnSecondaryDisplay;
}
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index b146c27..e969268 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -244,7 +244,8 @@
@Test
public void testStartUserVisibleOnDisplay() {
- boolean started = mUserController.startUserVisibleOnDisplay(TEST_USER_ID, 42);
+ boolean started = mUserController.startUserVisibleOnDisplay(TEST_USER_ID, 42,
+ /* unlockProgressListener= */ null);
assertWithMessage("startUserOnDisplay(%s, %s)", TEST_USER_ID, 42).that(started).isTrue();
verifyUserAssignedToDisplay(TEST_USER_ID, 42);