summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adam Bookatz <bookatz@google.com> 2023-03-08 13:34:17 -0800
committer Adam Bookatz <bookatz@google.com> 2023-03-08 19:54:32 -0800
commitbd1e947f2f41c782b756d69f7e18653ecf7272fe (patch)
tree1006bd793b813425385311bec68e5ee2773a7898
parent3521df06db71c084bb7c132b84e6ad45ca240f77 (diff)
OTA only adds Main if isMainUserPermanentAdmin
On OTA to Android U, we bestow upon one user the MainUser title. Not all devices need to have a MainUser though, depnding on their configuration. Nonetheless, we were previously always adding MainUser on OTA. For HSUM devices that do NOT have config_isMainUserPermanentAdmin, we should not be setting a MainUser on OTA, so we fix this here. On non-HSUM, we continue to make user 0 the MainUser on OTA regardless of configuration; non-HSUM user 0 being Main is just an invariant. Moreover, we update the emulation logic to also take into account config_isMainUserPermanentAdmin and the invariance. The updated logic of emulation is: non-HSUM -> emulate HSUM Rule: in HSUM, we never have Sys be Main. We set a new main iff the config says to. Scenarios: * if main=Sys (usual phone case): Remove Main from system; if isMainUserPermanentAdmin(), switch/set a new Main. * if no main (severly aberrant case): if isMainUserPermanentAdmin(), set a new Main. * if main=other (aberrant case): leave as is HSUM -> emulate non-HSUM Rule: in non-HSUM, we always make Sys to be Main Scenarios: * if main=Sys (severely aberrant case): leave as is * if no main (usual for Auto):  always make Sys the Main * if main=other (usual for tablet): always switch Main to system Test: manual OTA from T to U Test: manual emulate different modes Bug: 272295293 Change-Id: Id915203fe07b65cdd0e7e08df92fe93454be4f6f
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java39
-rw-r--r--services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java1
2 files changed, 22 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index dd014ee637c7..0d9ab670cc2f 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3473,15 +3473,15 @@ public class UserManagerService extends IUserManager.Stub {
return;
}
final int oldMainUserId = getMainUserIdUnchecked();
- final int oldFlags = systemUserData.info.flags;
- final int newFlags;
+ final int oldSysFlags = systemUserData.info.flags;
+ final int newSysFlags;
final String newUserType;
if (newHeadlessSystemUserMode) {
newUserType = UserManager.USER_TYPE_SYSTEM_HEADLESS;
- newFlags = oldFlags & ~UserInfo.FLAG_FULL & ~UserInfo.FLAG_MAIN;
+ newSysFlags = oldSysFlags & ~UserInfo.FLAG_FULL & ~UserInfo.FLAG_MAIN;
} else {
newUserType = UserManager.USER_TYPE_FULL_SYSTEM;
- newFlags = oldFlags | UserInfo.FLAG_FULL;
+ newSysFlags = oldSysFlags | UserInfo.FLAG_FULL | UserInfo.FLAG_MAIN;
}
if (systemUserData.info.userType.equals(newUserType)) {
@@ -3492,18 +3492,19 @@ public class UserManagerService extends IUserManager.Stub {
Slogf.i(LOG_TAG, "Persisting emulated system user data: type changed from %s to "
+ "%s, flags changed from %s to %s",
systemUserData.info.userType, newUserType,
- UserInfo.flagsToString(oldFlags), UserInfo.flagsToString(newFlags));
+ UserInfo.flagsToString(oldSysFlags), UserInfo.flagsToString(newSysFlags));
systemUserData.info.userType = newUserType;
- systemUserData.info.flags = newFlags;
+ systemUserData.info.flags = newSysFlags;
writeUserLP(systemUserData);
- // Switch the MainUser to a reasonable choice if needed.
- // (But if there was no MainUser, we deliberately continue to have no MainUser.)
+ // Designate the MainUser to a reasonable choice if needed.
final UserData oldMain = getUserDataNoChecks(oldMainUserId);
if (newHeadlessSystemUserMode) {
- if (oldMain != null && (oldMain.info.flags & UserInfo.FLAG_SYSTEM) != 0) {
- // System was MainUser. So we need a new choice for Main. Pick the oldest.
+ final boolean mainIsAlreadyNonSystem =
+ oldMain != null && (oldMain.info.flags & UserInfo.FLAG_SYSTEM) == 0;
+ if (!mainIsAlreadyNonSystem && isMainUserPermanentAdmin()) {
+ // We need a new choice for Main. Pick the oldest.
// If no oldest, don't set any. Let the BootUserInitializer do that later.
final UserInfo newMainUser = getEarliestCreatedFullUser();
if (newMainUser != null) {
@@ -3513,16 +3514,16 @@ public class UserManagerService extends IUserManager.Stub {
}
}
} else {
+ // We already made user 0 Main above. Now strip it from the old Main user.
// TODO(b/256624031): For now, we demand the Main user (if there is one) is
// always the system in non-HSUM. In the future, when we relax this, change how
// we handle MAIN.
if (oldMain != null && (oldMain.info.flags & UserInfo.FLAG_SYSTEM) == 0) {
- // Someone else was the MainUser; transfer it to System.
Slogf.i(LOG_TAG, "Transferring Main to user 0 from " + oldMain.info.id);
oldMain.info.flags &= ~UserInfo.FLAG_MAIN;
- systemUserData.info.flags |= UserInfo.FLAG_MAIN;
writeUserLP(oldMain);
- writeUserLP(systemUserData);
+ } else {
+ Slogf.i(LOG_TAG, "Designated user 0 to be Main");
}
}
}
@@ -3779,12 +3780,14 @@ public class UserManagerService extends IUserManager.Stub {
if (userVersion < 11) {
// Add FLAG_MAIN
if (isHeadlessSystemUserMode()) {
- final UserInfo earliestCreatedUser = getEarliestCreatedFullUser();
- if (earliestCreatedUser != null) {
- earliestCreatedUser.flags |= UserInfo.FLAG_MAIN;
- userIdsToWrite.add(earliestCreatedUser.id);
+ if (isMainUserPermanentAdmin()) {
+ final UserInfo earliestCreatedUser = getEarliestCreatedFullUser();
+ if (earliestCreatedUser != null) {
+ earliestCreatedUser.flags |= UserInfo.FLAG_MAIN;
+ userIdsToWrite.add(earliestCreatedUser.id);
+ }
}
- } else {
+ } else { // not isHeadlessSystemUserMode
synchronized (mUsersLock) {
final UserData userData = mUsers.get(UserHandle.USER_SYSTEM);
userData.info.flags |= UserInfo.FLAG_MAIN;
diff --git a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
index eed2a7896fcd..fd41af38b612 100644
--- a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
+++ b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
@@ -376,6 +376,7 @@ public class UserManagerServiceShellCommand extends ShellCommand {
final int pid = Process.myPid();
Slogf.i(LOG_TAG, "Restarting Android runtime(PID=%d) to finalize changes", pid);
pw.println("Restarting Android runtime to finalize changes");
+ pw.println("The restart may trigger a 'Broken pipe' message; this is to be expected.");
pw.flush();
// Ideally there should be a cleaner / safer option to restart system_server, but