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

Commit 37f22f5c authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "Changed HsumBootUserInitializer to use UMS instead of UMI" into main

parents d60b2c00 9dc33190
Loading
Loading
Loading
Loading
+18 −16
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.os.UserManager;
import android.provider.Settings;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService;
import com.android.server.utils.Slogf;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -45,7 +44,7 @@ public final class HsumBootUserInitializer {

    private static final boolean DEBUG = false;

    private final UserManagerInternal mUmi;
    private final UserManagerService mUms;
    private final ActivityManagerService mAms;
    private final PackageManagerService mPms;
    private final ContentResolver mContentResolver;
@@ -72,24 +71,23 @@ public final class HsumBootUserInitializer {
    private final boolean mShouldCreateInitialUser;

    /** Static factory method for creating a {@link HsumBootUserInitializer} instance. */
    public static @Nullable HsumBootUserInitializer createInstance(ActivityManagerService am,
            PackageManagerService pms, ContentResolver contentResolver,
    public static @Nullable HsumBootUserInitializer createInstance(UserManagerService ums,
            ActivityManagerService ams, PackageManagerService pms, ContentResolver contentResolver,
            boolean shouldAlwaysHaveMainUser, boolean shouldCreateInitialUser) {

        if (!UserManager.isHeadlessSystemUserMode()) {
            return null;
        }
        return new HsumBootUserInitializer(
                LocalServices.getService(UserManagerInternal.class), am, pms, contentResolver,
        return new HsumBootUserInitializer(ums, ams, pms, contentResolver,
                shouldAlwaysHaveMainUser, shouldCreateInitialUser);
    }

    @VisibleForTesting
    HsumBootUserInitializer(UserManagerInternal umi, ActivityManagerService am,
    HsumBootUserInitializer(UserManagerService ums, ActivityManagerService ams,
            PackageManagerService pms, ContentResolver contentResolver,
            boolean shouldAlwaysHaveMainUser, boolean shouldCreateInitialUser) {
        mUmi = umi;
        mAms = am;
        mUms = ums;
        mAms = ams;
        mPms = pms;
        mContentResolver = contentResolver;
        mShouldAlwaysHaveMainUser = shouldAlwaysHaveMainUser;
@@ -114,7 +112,7 @@ public final class HsumBootUserInitializer {

    // TODO(b/409650316): remove after flag's completely pushed
    private void preCreateInitialUserCreateMainUserIfNeeded() {
        final int mainUser = mUmi.getMainUserId();
        final int mainUser = mUms.getMainUserId();
        if (mainUser != UserHandle.USER_NULL) {
            Slogf.d(TAG, "Found existing MainUser, userId=%d", mainUser);
            return;
@@ -122,10 +120,12 @@ public final class HsumBootUserInitializer {

        Slogf.d(TAG, "Creating a new MainUser");
        try {
            final UserInfo newInitialUser = mUmi.createUserEvenWhenDisallowed(
            final UserInfo newInitialUser = mUms.createUserInternalUnchecked(
                    /* name= */ null, // null will appear as "Owner" in on-demand localisation
                    UserManager.USER_TYPE_FULL_SECONDARY,
                    UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN,
                    /* parentId= */ UserHandle.USER_NULL,
                    /* preCreated= */ false,
                    /* disallowedPackages= */ null,
                    /* token= */ null);
            if (newInitialUser != null) {
@@ -171,7 +171,7 @@ public final class HsumBootUserInitializer {
        // Always tracing as it used to be done by the caller
        t.traceBegin("createMainUserIfNeeded");
        try {
            int mainUserId = mUmi.getMainUserId();
            int mainUserId = mUms.getMainUserId();
            if (mainUserId != UserHandle.USER_NULL) {
                Slogf.d(TAG, "createMainUserIfNeeded(): found MainUser (userId=%d)", mainUserId);
                return;
@@ -185,7 +185,7 @@ public final class HsumBootUserInitializer {
    private void createAdminUserIfNeeded(TimingsTraceAndSlog t) {
        t.traceBegin("createAdminUserIfNeeded");
        try {
            int[] userIds = mUmi.getUserIds();
            int[] userIds = mUms.getUserIds();
            if (userIds != null && userIds.length > 1) {
                if (DEBUG) {
                    Slogf.d(TAG, "createAdminUserIfNeeded(): already have more than 1 user (%s)",
@@ -210,14 +210,16 @@ public final class HsumBootUserInitializer {
        }
        Slogf.d(TAG, "Creating %s", logName);
        try {
            final UserInfo newInitialUser = mUmi.createUserEvenWhenDisallowed(
            final UserInfo newInitialUser = mUms.createUserInternalUnchecked(
                    /* name= */ null, // null will appear as "Owner" in on-demand localisation
                    UserManager.USER_TYPE_FULL_SECONDARY,
                    flags,
                    /* parentId= */ UserHandle.USER_NULL,
                    /* preCreated= */ false,
                    /* disallowedPackages= */ null,
                    /* token= */ null);
            Slogf.i(TAG, "Successfully created %s, userId=%d", logName, newInitialUser.id);
            mUmi.setBootUserId(newInitialUser.id);
            mUms.setBootUserIdUnchecked(newInitialUser.id);
        } catch (UserManager.CheckedUserOperationException e) {
            Slogf.wtf(TAG, e, "Initial bootable %s creation failed", logName);
        }
@@ -235,7 +237,7 @@ public final class HsumBootUserInitializer {

        try {
            t.traceBegin("getBootUser");
            final int bootUser = mUmi.getBootUser(/* waitUntilSet= */ mPms
            final int bootUser = mUms.getBootUser(/* waitUntilSet= */ mPms
                    .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, /* version= */0));
            t.traceEnd();
            t.traceBegin("switchToBootUser-" + bootUser);
+0 −8
Original line number Diff line number Diff line
@@ -600,14 +600,6 @@ public abstract class UserManagerInternal {
    public abstract @UserIdInt int getBootUser(boolean waitUntilSet)
            throws UserManager.CheckedUserOperationException;

    // NOTE: used only by HsumBootUserInitializer, ideally it should be package-protected, but it's
    // located in a different package.
    /**
     * Same as {@link UserManager#setBootUser(android.os.UserHandle)}, but without checking
     * permissions.
     */
    public abstract void setBootUserId(@UserIdInt int userId);

    /**
     * Returns the user id of the communal profile, or {@link android.os.UserHandle#USER_NULL}
     * if there is no such user.
+32 −28
Original line number Diff line number Diff line
@@ -1054,6 +1054,10 @@ public class UserManagerService extends IUserManager.Stub {
                }
            }
        }

        public UserManagerService getService() {
            return mUms;
        }
    }

    // TODO(b/28848102) Add support for test dependencies injection
@@ -1381,7 +1385,7 @@ public class UserManagerService extends IUserManager.Stub {
        setBootUserIdUnchecked(userId);
    }

    private void setBootUserIdUnchecked(@UserIdInt int userId) {
    void setBootUserIdUnchecked(@UserIdInt int userId) {
        synchronized (mUsersLock) {
            // TODO(b/263381643): Change to EventLog.
            Slogf.i(LOG_TAG, "setBootUser %d", userId);
@@ -1431,6 +1435,31 @@ public class UserManagerService extends IUserManager.Stub {
        return UserHandle.USER_SYSTEM;
    }

    @UserIdInt
    int getBootUser(boolean waitUntilSet) throws UserManager.CheckedUserOperationException {
        if (waitUntilSet) {
            final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
            t.traceBegin("wait-boot-user");
            try {
                if (mBootUserLatch.getCount() != 0) {
                    Slogf.d(LOG_TAG,
                            "Sleeping for boot user to be set. "
                            + "Max sleep for Time: %d", BOOT_USER_SET_TIMEOUT_MS);
                }
                if (!mBootUserLatch.await(BOOT_USER_SET_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                    Slogf.w(LOG_TAG, "Boot user not set. Timeout: %d",
                            BOOT_USER_SET_TIMEOUT_MS);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                Slogf.w(LOG_TAG, e, "InterruptedException during wait for boot user.");
            }
            t.traceEnd();
        }

        return getBootUserUnchecked();
    }

    private @UserIdInt int getBootUserBasedOnProvisioning()
            throws UserManager.CheckedUserOperationException {
        final boolean provisioned = Settings.Global.getInt(mContext.getContentResolver(),
@@ -6009,7 +6038,7 @@ public class UserManagerService extends IUserManager.Stub {
                /* preCreate= */ false, disallowedPackages, /* token= */ null);
    }

    private @NonNull UserInfo createUserInternalUnchecked(
    @NonNull UserInfo createUserInternalUnchecked(
            @Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
            @CanBeNULL @UserIdInt int parentId, boolean preCreate,
            @Nullable String[] disallowedPackages, @Nullable Object token)
@@ -8594,32 +8623,7 @@ public class UserManagerService extends IUserManager.Stub {
        @Override
        public @UserIdInt int getBootUser(boolean waitUntilSet)
                throws UserManager.CheckedUserOperationException {
            if (waitUntilSet) {
                final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
                t.traceBegin("wait-boot-user");
                try {
                    if (mBootUserLatch.getCount() != 0) {
                        Slogf.d(LOG_TAG,
                                "Sleeping for boot user to be set. "
                                + "Max sleep for Time: %d", BOOT_USER_SET_TIMEOUT_MS);
                    }
                    if (!mBootUserLatch.await(BOOT_USER_SET_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                        Slogf.w(LOG_TAG, "Boot user not set. Timeout: %d",
                                BOOT_USER_SET_TIMEOUT_MS);
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    Slogf.w(LOG_TAG, e, "InterruptedException during wait for boot user.");
                }
                t.traceEnd();
            }

            return getBootUserUnchecked();
        }

        @Override
        public void setBootUserId(@UserIdInt int userId) {
            setBootUserIdUnchecked(userId);
            return UserManagerService.this.getBootUser(waitUntilSet);
        }

        @Override
+5 −3
Original line number Diff line number Diff line
@@ -490,6 +490,7 @@ public final class SystemServer implements Dumpable {
    // TODO: remove all of these references by improving dependency resolution and boot phases
    private PowerManagerService mPowerManagerService;
    private ActivityManagerService mActivityManagerService;
    private UserManagerService mUserManagerService;
    private WindowManagerGlobalLock mWindowManagerGlobalLock;
    private WebViewUpdateService mWebViewUpdateService;
    private DisplayManagerService mDisplayManagerService;
@@ -1375,7 +1376,8 @@ public final class SystemServer implements Dumpable {
        }

        t.traceBegin("StartUserManagerService");
        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
        mUserManagerService = mSystemServiceManager
                .startService(UserManagerService.LifeCycle.class).getService();
        t.traceEnd();

        // Initialize attribute cache used to cache resources from packages.
@@ -3030,8 +3032,8 @@ public final class SystemServer implements Dumpable {
        // Create initial user if needed, which should be done early since some system services rely
        // on it in their setup, but likely needs to be done after LockSettingsService is ready.
        final HsumBootUserInitializer hsumBootUserInitializer =
                HsumBootUserInitializer.createInstance(
                        mActivityManagerService, mPackageManagerService, mContentResolver,
                HsumBootUserInitializer.createInstance(mUserManagerService, mActivityManagerService,
                        mPackageManagerService, mContentResolver,
                        context.getResources().getBoolean(R.bool.config_isMainUserPermanentAdmin),
                        context.getResources().getBoolean(R.bool.config_createInitialUser)
                        );
+14 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static com.android.server.pm.HsumBootUserInitializerTest.InitialUsers.SYS
import static com.android.server.pm.HsumBootUserInitializerTest.InitialUsers.SYSTEM_ONLY;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -87,7 +88,7 @@ public final class HsumBootUserInitializerTest {
            new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);

    @Mock
    private UserManagerInternal mMockUmi;
    private UserManagerService mMockUms;
    @Mock
    private ActivityManagerService mMockAms;
    @Mock
@@ -226,7 +227,7 @@ public final class HsumBootUserInitializerTest {
    private HsumBootUserInitializer createHsumBootUserInitializer(
            boolean shouldAlwaysHaveMainUser, boolean shouldCreateInitialUser) {
        mTracer = new TimingsTraceAndSlog(TAG);
        return new HsumBootUserInitializer(mMockUmi, mMockAms, mMockPms, mMockContentResolver,
        return new HsumBootUserInitializer(mMockUms, mMockAms, mMockPms, mMockContentResolver,
                shouldAlwaysHaveMainUser, shouldCreateInitialUser);
    }

@@ -240,8 +241,9 @@ public final class HsumBootUserInitializerTest {

    private void expectUserCreated(@UserInfoFlag int flags) {
        try {
            verify(mMockUmi).createUserEvenWhenDisallowed(null,
                    UserManager.USER_TYPE_FULL_SECONDARY, flags, null, null);
            verify(mMockUms).createUserInternalUnchecked(/* name= */ null,
                    UserManager.USER_TYPE_FULL_SECONDARY, flags, /* parentId= */ USER_NULL,
                    /* preCreated= */ false, /* disallowedPackages= */ null, /* token= */ null);
        } catch (Exception e) {
            String msg = "didn't create user with flags " + flags;
            Log.e(TAG, msg, e);
@@ -251,8 +253,8 @@ public final class HsumBootUserInitializerTest {

    private void expectNoUserCreated() {
        try {
            verify(mMockUmi, never()).createUserEvenWhenDisallowed(any(), any(), anyInt(), any(),
                    any());
            verify(mMockUms, never()).createUserInternalUnchecked(any(), any(), anyInt(), anyInt(),
                    anyBoolean(), any(), any());
        } catch (Exception e) {
            String msg = "shouldn't have created any user";
            Log.e(TAG, msg, e);
@@ -266,7 +268,7 @@ public final class HsumBootUserInitializerTest {

    private void expectSetBootUserId(@UserIdInt int userId) {
        try {
            verify(mMockUmi).setBootUserId(userId);
            verify(mMockUms).setBootUserIdUnchecked(userId);
        } catch (Exception e) {
            String msg = "didn't call setBootUserId(" +  userId + ")";
            Log.e(TAG, msg, e);
@@ -276,7 +278,7 @@ public final class HsumBootUserInitializerTest {

    private void expectSetBootUserIdNeverCalled() {
        try {
            verify(mMockUmi, never()).setBootUserId(anyInt());
            verify(mMockUms, never()).setBootUserIdUnchecked(anyInt());
        } catch (Exception e) {
            String msg = "setBootUserId() should never be called";
            Log.e(TAG, msg, e);
@@ -289,18 +291,18 @@ public final class HsumBootUserInitializerTest {
        UserInfo userInfo = new UserInfo();
        userInfo.id = userId;
        Log.d(TAG, "createUserEvenWhenDisallowed() will return " + userInfo);
        when(mMockUmi.createUserEvenWhenDisallowed(any(), any(), anyInt(), any(), any()))
                .thenReturn(userInfo);
        when(mMockUms.createUserInternalUnchecked(any(), any(), anyInt(), anyInt(), anyBoolean(),
                any(), any())).thenReturn(userInfo);
    }

    private void mockGetMainUserId(@CanBeNULL @UserIdInt int userId) {
        Log.d(TAG, "mockGetMainUserId(): " + userId);
        when(mMockUmi.getMainUserId()).thenReturn(userId);
        when(mMockUms.getMainUserId()).thenReturn(userId);
    }

    private void mockGetUserIds(@UserIdInt int... userIds) {
        Log.d(TAG, "mockGetUserIds(): " + Arrays.toString(userIds));
        when(mMockUmi.getUserIds()).thenReturn(userIds);
        when(mMockUms.getUserIds()).thenReturn(userIds);
    }

    // NOTE: enums below must be public to be static imported