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

Commit 9dc33190 authored by Felipe Leme's avatar Felipe Leme
Browse files

Changed HsumBootUserInitializer to use UMS instead of UMI

Fixes: 414774023
Test: atest FrameworksMockingServicesTests --test-filter='.*HsumBootUserInitializer.*'
Test: manual verification
Flag: EXEMPT refactor

Change-Id: I6807d6ab12a16cc5a892d1bdca91a4fd3b761fe5
parent aae9202a
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(),
@@ -6010,7 +6039,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)
@@ -8595,32 +8624,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