diff options
Diffstat (limited to 'services/java')
| -rw-r--r-- | services/java/com/android/server/HsumBootUserInitializer.java (renamed from services/java/com/android/server/BootUserInitializer.java) | 80 | ||||
| -rw-r--r-- | services/java/com/android/server/SystemServer.java | 21 |
2 files changed, 87 insertions, 14 deletions
diff --git a/services/java/com/android/server/BootUserInitializer.java b/services/java/com/android/server/HsumBootUserInitializer.java index 3d71739924f7..cc6c36ef1ed5 100644 --- a/services/java/com/android/server/BootUserInitializer.java +++ b/services/java/com/android/server/HsumBootUserInitializer.java @@ -15,8 +15,10 @@ */ package com.android.server; +import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.ContentResolver; +import android.content.pm.UserInfo; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -30,22 +32,43 @@ import com.android.server.utils.TimingsTraceAndSlog; * Class responsible for booting the device in the proper user on headless system user mode. * */ -// TODO(b/204091126): STOPSHIP - provide proper APIs -final class BootUserInitializer { +final class HsumBootUserInitializer { - private static final String TAG = BootUserInitializer.class.getSimpleName(); - - // TODO(b/204091126): STOPSHIP - set to false or dynamic value - private static final boolean DEBUG = true; + private static final String TAG = HsumBootUserInitializer.class.getSimpleName(); + private final UserManagerInternal mUmi; private final ActivityManagerService mAms; private final ContentResolver mContentResolver; - BootUserInitializer(ActivityManagerService am, ContentResolver contentResolver) { + /** Whether this device should always have a non-removable MainUser, including at first boot. */ + private final boolean mShouldAlwaysHaveMainUser; + + /** Static factory method for creating a {@link HsumBootUserInitializer} instance. */ + public static @Nullable HsumBootUserInitializer createInstance(ActivityManagerService am, + ContentResolver contentResolver, boolean shouldAlwaysHaveMainUser) { + + if (!UserManager.isHeadlessSystemUserMode()) { + return null; + } + return new HsumBootUserInitializer( + LocalServices.getService(UserManagerInternal.class), + am, contentResolver, shouldAlwaysHaveMainUser); + } + + private HsumBootUserInitializer(UserManagerInternal umi, ActivityManagerService am, + ContentResolver contentResolver, boolean shouldAlwaysHaveMainUser) { + mUmi = umi; mAms = am; mContentResolver = contentResolver; + this.mShouldAlwaysHaveMainUser = shouldAlwaysHaveMainUser; } + /** + * Initialize this object, and create MainUser if needed. + * + * Should be called before PHASE_SYSTEM_SERVICES_READY as services' setups may require MainUser, + * but probably after PHASE_LOCK_SETTINGS_READY since that may be needed for user creation. + */ public void init(TimingsTraceAndSlog t) { Slogf.i(TAG, "init())"); @@ -53,17 +76,56 @@ final class BootUserInitializer { // this class or the setup wizard app provisionHeadlessSystemUser(); + if (mShouldAlwaysHaveMainUser) { + t.traceBegin("createMainUserIfNeeded"); + createMainUserIfNeeded(); + t.traceEnd(); + } + } + + private void createMainUserIfNeeded() { + int mainUser = mUmi.getMainUserId(); + if (mainUser != UserHandle.USER_NULL) { + Slogf.d(TAG, "Found existing MainUser, userId=%d", mainUser); + return; + } + + Slogf.d(TAG, "Creating a new MainUser"); + try { + final UserInfo newInitialUser = mUmi.createUserEvenWhenDisallowed( + /* name= */ null, // null will appear as "Owner" in on-demand localisation + UserManager.USER_TYPE_FULL_SECONDARY, + UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN, + /* disallowedPackages= */ null, + /* token= */ null); + if (newInitialUser == null) { + Slogf.wtf(TAG, "Initial bootable MainUser creation failed: returned null"); + } else { + Slogf.i(TAG, "Successfully created MainUser, userId=%d", newInitialUser.id); + } + } catch (UserManager.CheckedUserOperationException e) { + Slogf.wtf(TAG, "Initial bootable MainUser creation failed", e); + } + } + + /** + * Put the device into the correct user state: unlock the system and switch to the boot user. + * + * Should only call once PHASE_THIRD_PARTY_APPS_CAN_START is reached to ensure that privileged + * apps have had the chance to set the boot user, if applicable. + */ + public void systemRunning(TimingsTraceAndSlog t) { unlockSystemUser(t); try { t.traceBegin("getBootUser"); - int bootUser = LocalServices.getService(UserManagerInternal.class).getBootUser(); + final int bootUser = mUmi.getBootUser(); t.traceEnd(); t.traceBegin("switchToBootUser-" + bootUser); switchToBootUser(bootUser); t.traceEnd(); } catch (UserManager.CheckedUserOperationException e) { - Slogf.wtf(TAG, "Failed to created boot user", e); + Slogf.wtf(TAG, "Failed to switch to boot user since there isn't one."); } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index a15c6d288cfd..d22be9ec01d0 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -75,7 +75,6 @@ import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; -import android.os.UserManager; import android.os.storage.IStorageManager; import android.provider.DeviceConfig; import android.provider.Settings; @@ -2694,6 +2693,18 @@ public final class SystemServer implements Dumpable { mSystemServiceManager.startBootPhase(t, SystemService.PHASE_LOCK_SETTINGS_READY); t.traceEnd(); + // 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, mContentResolver, + context.getResources().getBoolean(R.bool.config_isMainUserPermanentAdmin)); + if (hsumBootUserInitializer != null) { + t.traceBegin("HsumBootUserInitializer.init"); + hsumBootUserInitializer.init(t); + t.traceEnd(); + } + t.traceBegin("StartBootPhaseSystemServicesReady"); mSystemServiceManager.startBootPhase(t, SystemService.PHASE_SYSTEM_SERVICES_READY); t.traceEnd(); @@ -2961,10 +2972,10 @@ public final class SystemServer implements Dumpable { mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); t.traceEnd(); - if (UserManager.isHeadlessSystemUserMode() && !isAutomotive) { - // TODO(b/204091126): remove isAutomotive check once the workflow is finalized - t.traceBegin("BootUserInitializer"); - new BootUserInitializer(mActivityManagerService, mContentResolver).init(t); + if (hsumBootUserInitializer != null && !isAutomotive) { + // TODO(b/261924826): remove isAutomotive check once the workflow is finalized + t.traceBegin("HsumBootUserInitializer.systemRunning"); + hsumBootUserInitializer.systemRunning(t); t.traceEnd(); } |