summaryrefslogtreecommitdiff
path: root/services/java
diff options
context:
space:
mode:
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.java21
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();
}