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

Commit cfbc9e02 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Changing hsum property in OTA won't alter mode"

parents a956334f aeffc9de
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ interface IUserManager {
    boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne);
    UserInfo getProfileParent(int userId);
    boolean isSameProfileGroup(int userId, int otherUserHandle);
    boolean isHeadlessSystemUserMode();
    boolean isUserOfType(int userId, in String userType);
    @UnsupportedAppUsage
    UserInfo getUserInfo(int userId);
+16 −22
Original line number Diff line number Diff line
@@ -91,7 +91,6 @@ import java.util.Set;
public class UserManager {

    private static final String TAG = "UserManager";
    private static final boolean VERBOSE = false;

    @UnsupportedAppUsage
    private final IUserManager mService;
@@ -104,6 +103,9 @@ public class UserManager {
    /** The userType of UserHandle.myUserId(); empty string if not a profile; null until cached. */
    private String mProfileTypeOfProcessUser = null;

    /** Whether the device is in headless system user mode; null until cached. */
    private static Boolean sIsHeadlessSystemUser = null;

    /**
     * User type representing a {@link UserHandle#USER_SYSTEM system} user that is a human user.
     * This type of user cannot be created; it can only pre-exist on first boot.
@@ -2068,28 +2070,20 @@ public class UserManager {
     * @return whether the device is running in a headless system user mode.
     */
    public static boolean isHeadlessSystemUserMode() {
        final boolean realMode = RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER;
        if (!Build.isDebuggable()) {
            return realMode;
        // No need for synchronization.  Once it becomes non-null, it'll be non-null forever.
        // (Its value is determined when UMS is constructed and cannot change.)
        // Worst case we might end up calling the AIDL method multiple times but that's fine.
        if (sIsHeadlessSystemUser == null) {
            // Unfortunately this API is static, but the property no longer is. So go fetch the UMS.
            try {
                final IUserManager service = IUserManager.Stub.asInterface(
                        ServiceManager.getService(Context.USER_SERVICE));
                sIsHeadlessSystemUser = service.isHeadlessSystemUserMode();
            } catch (RemoteException re) {
                throw re.rethrowFromSystemServer();
            }

        final String emulatedMode = SystemProperties.get(SYSTEM_USER_MODE_EMULATION_PROPERTY);
        switch (emulatedMode) {
            case SYSTEM_USER_MODE_EMULATION_FULL:
                if (VERBOSE) Log.v(TAG, "isHeadlessSystemUserMode(): emulating as false");
                return false;
            case SYSTEM_USER_MODE_EMULATION_HEADLESS:
                if (VERBOSE) Log.v(TAG, "isHeadlessSystemUserMode(): emulating as true");
                return true;
            case SYSTEM_USER_MODE_EMULATION_DEFAULT:
            case "": // property not set
                return realMode;
            default:
                Log.wtf(TAG, "isHeadlessSystemUserMode(): invalid value of property "
                        + SYSTEM_USER_MODE_EMULATION_PROPERTY + " (" + emulatedMode + "); using"
                                + " default value (headless=" + realMode + ")");
                return realMode;
        }
        return sIsHeadlessSystemUser;
    }

    /**
+9 −0
Original line number Diff line number Diff line
@@ -51,6 +51,15 @@ public class RoSystemProperties {
    // ------ ro.fw.* ------------ //
    public static final boolean FW_SYSTEM_USER_SPLIT =
            SystemProperties.getBoolean("ro.fw.system_user_split", false);
    /**
     * Indicates whether the device should run in headless system user mode,
     *   in which user 0 only runs the system, not a real user.
     * <p>WARNING about changing this value during an non-wiping update (OTA):
     *   <li>If this value is modified via an update, the change will have no effect, since an
     *       already-existing system user cannot change its mode.
     *   <li>Changing this value during an OTA from a pre-R device is not permitted; attempting to
     *       do so will corrupt the system user.
     */
    public static final boolean MULTIUSER_HEADLESS_SYSTEM_USER =
            SystemProperties.getBoolean("ro.fw.mu.headless_system_user", false);

+47 −30
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.pm;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.UserManager.DISALLOW_USER_SWITCH;
import static android.os.UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY;

import android.Manifest;
import android.accounts.Account;
@@ -314,7 +315,7 @@ public class UserManagerService extends IUserManager.Stub {
    @VisibleForTesting
    static class UserData {
        // Basic user information and properties
        UserInfo info;
        @NonNull UserInfo info;
        // Account name used when there is a strong association between a user and an account
        String account;
        // Account information for seeding into a newly created user. This could also be
@@ -3268,11 +3269,39 @@ public class UserManagerService extends IUserManager.Stub {
        }
    }

    /** Checks whether the device is currently in headless system user mode (for any reason). */
    @Override
    public boolean isHeadlessSystemUserMode() {
        synchronized (mUsersLock) {
            final UserData systemUserData = mUsers.get(UserHandle.USER_SYSTEM);
            return !systemUserData.info.isFull();
        }
    }

    /**
     * Checks whether the device is really headless system user mode, ignoring system user mode
     * emulation.
     * Checks whether the default state of the device is headless system user mode, i.e. what the
     * mode would be if we did a fresh factory reset.
     * If the mode is  being emulated (via SYSTEM_USER_MODE_EMULATION_PROPERTY) then that will be
     * returned instead.
     * Note that, even in the absence of emulation, a device might deviate from the current default
     * due to an OTA changing the default (which won't change the already-decided mode).
     */
    private boolean isReallyHeadlessSystemUserMode() {
    private boolean isDefaultHeadlessSystemUserMode() {
        if (!Build.isDebuggable()) {
            return RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER;
        }

        final String emulatedValue = SystemProperties.get(SYSTEM_USER_MODE_EMULATION_PROPERTY);
        if (!TextUtils.isEmpty(emulatedValue)) {
            if (UserManager.SYSTEM_USER_MODE_EMULATION_HEADLESS.equals(emulatedValue)) return true;
            if (UserManager.SYSTEM_USER_MODE_EMULATION_FULL.equals(emulatedValue)) return false;
            if (!UserManager.SYSTEM_USER_MODE_EMULATION_DEFAULT.equals(emulatedValue)) {
                Slogf.e(LOG_TAG, "isDefaultHeadlessSystemUserMode(): ignoring invalid valued of "
                                + "property %s: %s",
                        SYSTEM_USER_MODE_EMULATION_PROPERTY, emulatedValue);
            }
        }

        return RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER;
    }

@@ -3284,30 +3313,11 @@ public class UserManagerService extends IUserManager.Stub {
        if (!Build.isDebuggable()) {
            return;
        }

        final String emulatedValue = SystemProperties
                .get(UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY);
        if (TextUtils.isEmpty(emulatedValue)) {
        if (TextUtils.isEmpty(SystemProperties.get(SYSTEM_USER_MODE_EMULATION_PROPERTY))) {
            return;
        }

        final boolean newHeadlessSystemUserMode;
        switch (emulatedValue) {
            case UserManager.SYSTEM_USER_MODE_EMULATION_FULL:
                newHeadlessSystemUserMode = false;
                break;
            case UserManager.SYSTEM_USER_MODE_EMULATION_HEADLESS:
                newHeadlessSystemUserMode = true;
                break;
            case UserManager.SYSTEM_USER_MODE_EMULATION_DEFAULT:
                newHeadlessSystemUserMode = isReallyHeadlessSystemUserMode();
                break;
            default:
                Slogf.wtf(LOG_TAG, "emulateSystemUserModeIfNeeded(): ignoring invalid valued of "
                        + "property %s: %s", UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY,
                        emulatedValue);
                return;
        }
        final boolean newHeadlessSystemUserMode = isDefaultHeadlessSystemUserMode();

        // Update system user type
        synchronized (mPackagesLock) {
@@ -3343,7 +3353,7 @@ public class UserManagerService extends IUserManager.Stub {
            }
        }

        // Update emulated mode, which will used to triger an update on user packages
        // Update emulated mode, which will used to trigger an update on user packages
        mUpdatingSystemUserMode = true;
    }

@@ -3533,7 +3543,11 @@ public class UserManagerService extends IUserManager.Stub {
            synchronized (mUsersLock) {
                UserData userData = mUsers.get(UserHandle.USER_SYSTEM);
                userData.info.flags |= UserInfo.FLAG_SYSTEM;
                if (!UserManager.isHeadlessSystemUserMode()) {
                // We assume that isDefaultHeadlessSystemUserMode() does not change during the OTA
                // from userVersion < 8 since it is documented that pre-R devices do not support its
                // modification. Therefore, its current value should be the same as the pre-update
                // version.
                if (!isDefaultHeadlessSystemUserMode()) {
                    userData.info.flags |= UserInfo.FLAG_FULL;
                }
                userIdsToWrite.add(userData.info.id);
@@ -3742,7 +3756,7 @@ public class UserManagerService extends IUserManager.Stub {
        int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN
                | UserInfo.FLAG_PRIMARY;
        // Create the system user
        String systemUserType = UserManager.isHeadlessSystemUserMode()
        String systemUserType = isDefaultHeadlessSystemUserMode()
                ? UserManager.USER_TYPE_SYSTEM_HEADLESS
                : UserManager.USER_TYPE_FULL_SYSTEM;
        flags |= mUserTypes.get(systemUserType).getDefaultUserInfoFlags();
@@ -6210,9 +6224,12 @@ public class UserManagerService extends IUserManager.Stub {
                com.android.internal.R.bool.config_guestUserEphemeral));
        pw.println("  Force ephemeral users: " + mForceEphemeralUsers);
        pw.println("  Is split-system user: " + UserManager.isSplitSystemUser());
        final boolean isHeadlessSystemUserMode = UserManager.isHeadlessSystemUserMode();
        final boolean isHeadlessSystemUserMode = isHeadlessSystemUserMode();
        pw.println("  Is headless-system mode: " + isHeadlessSystemUserMode);
        if (isHeadlessSystemUserMode != isReallyHeadlessSystemUserMode()) {
        if (isHeadlessSystemUserMode != RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER) {
            pw.println("  (differs from the current default build value)");
        }
        if (!TextUtils.isEmpty(SystemProperties.get(SYSTEM_USER_MODE_EMULATION_PROPERTY))) {
            pw.println("  (emulated by 'cmd user set-system-user-mode-emulation')");
            if (mUpdatingSystemUserMode) {
                pw.println("  (and being updated after boot)");