Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd1e947f authored by Adam Bookatz's avatar Adam Bookatz
Browse files

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
parent 3521df06
Loading
Loading
Loading
Loading
+21 −18
Original line number Diff line number Diff line
@@ -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()) {
                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;
+1 −0
Original line number Diff line number Diff line
@@ -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