1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server; 17 18 import android.annotation.Nullable; 19 import android.annotation.UserIdInt; 20 import android.content.ContentResolver; 21 import android.content.pm.PackageManager; 22 import android.content.pm.UserInfo; 23 import android.database.ContentObserver; 24 import android.os.Handler; 25 import android.os.Looper; 26 import android.os.UserHandle; 27 import android.os.UserManager; 28 import android.provider.Settings; 29 30 import com.android.server.am.ActivityManagerService; 31 import com.android.server.pm.PackageManagerService; 32 import com.android.server.pm.UserManagerInternal; 33 import com.android.server.utils.Slogf; 34 import com.android.server.utils.TimingsTraceAndSlog; 35 36 /** 37 * Class responsible for booting the device in the proper user on headless system user mode. 38 * 39 */ 40 final class HsumBootUserInitializer { 41 42 private static final String TAG = HsumBootUserInitializer.class.getSimpleName(); 43 44 private final UserManagerInternal mUmi; 45 private final ActivityManagerService mAms; 46 private final PackageManagerService mPms; 47 private final ContentResolver mContentResolver; 48 49 private final ContentObserver mDeviceProvisionedObserver = 50 new ContentObserver(new Handler(Looper.getMainLooper())) { 51 @Override 52 public void onChange(boolean selfChange) { 53 // Set USER_SETUP_COMPLETE for the (headless) system user only when the device 54 // has been set up at least once. 55 if (isDeviceProvisioned()) { 56 Slogf.i(TAG, "Marking USER_SETUP_COMPLETE for system user"); 57 Settings.Secure.putInt(mContentResolver, 58 Settings.Secure.USER_SETUP_COMPLETE, 1); 59 mContentResolver.unregisterContentObserver(mDeviceProvisionedObserver); 60 } 61 } 62 }; 63 64 /** Whether this device should always have a non-removable MainUser, including at first boot. */ 65 private final boolean mShouldAlwaysHaveMainUser; 66 67 /** Static factory method for creating a {@link HsumBootUserInitializer} instance. */ createInstance(ActivityManagerService am, PackageManagerService pms, ContentResolver contentResolver, boolean shouldAlwaysHaveMainUser)68 public static @Nullable HsumBootUserInitializer createInstance(ActivityManagerService am, 69 PackageManagerService pms, ContentResolver contentResolver, 70 boolean shouldAlwaysHaveMainUser) { 71 72 if (!UserManager.isHeadlessSystemUserMode()) { 73 return null; 74 } 75 return new HsumBootUserInitializer( 76 LocalServices.getService(UserManagerInternal.class), 77 am, pms, contentResolver, shouldAlwaysHaveMainUser); 78 } 79 HsumBootUserInitializer(UserManagerInternal umi, ActivityManagerService am, PackageManagerService pms, ContentResolver contentResolver, boolean shouldAlwaysHaveMainUser)80 private HsumBootUserInitializer(UserManagerInternal umi, ActivityManagerService am, 81 PackageManagerService pms, ContentResolver contentResolver, 82 boolean shouldAlwaysHaveMainUser) { 83 mUmi = umi; 84 mAms = am; 85 mPms = pms; 86 mContentResolver = contentResolver; 87 mShouldAlwaysHaveMainUser = shouldAlwaysHaveMainUser; 88 } 89 90 /** 91 * Initialize this object, and create MainUser if needed. 92 * 93 * <p>Should be called before PHASE_SYSTEM_SERVICES_READY as services' setups may require 94 * MainUser, but probably after PHASE_LOCK_SETTINGS_READY since that may be needed for user 95 * creation. 96 */ init(TimingsTraceAndSlog t)97 public void init(TimingsTraceAndSlog t) { 98 Slogf.i(TAG, "init())"); 99 100 if (mShouldAlwaysHaveMainUser) { 101 t.traceBegin("createMainUserIfNeeded"); 102 createMainUserIfNeeded(); 103 t.traceEnd(); 104 } 105 } 106 createMainUserIfNeeded()107 private void createMainUserIfNeeded() { 108 final int mainUser = mUmi.getMainUserId(); 109 if (mainUser != UserHandle.USER_NULL) { 110 Slogf.d(TAG, "Found existing MainUser, userId=%d", mainUser); 111 return; 112 } 113 114 Slogf.d(TAG, "Creating a new MainUser"); 115 try { 116 final UserInfo newInitialUser = mUmi.createUserEvenWhenDisallowed( 117 /* name= */ null, // null will appear as "Owner" in on-demand localisation 118 UserManager.USER_TYPE_FULL_SECONDARY, 119 UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN, 120 /* disallowedPackages= */ null, 121 /* token= */ null); 122 Slogf.i(TAG, "Successfully created MainUser, userId=%d", newInitialUser.id); 123 } catch (UserManager.CheckedUserOperationException e) { 124 Slogf.wtf(TAG, "Initial bootable MainUser creation failed", e); 125 } 126 } 127 128 /** 129 * Put the device into the correct user state: unlock the system and switch to the boot user. 130 * 131 * <p>Should only call once PHASE_THIRD_PARTY_APPS_CAN_START is reached to ensure that 132 * privileged apps have had the chance to set the boot user, if applicable. 133 */ systemRunning(TimingsTraceAndSlog t)134 public void systemRunning(TimingsTraceAndSlog t) { 135 observeDeviceProvisioning(); 136 unlockSystemUser(t); 137 138 try { 139 t.traceBegin("getBootUser"); 140 final int bootUser = mUmi.getBootUser(/* waitUntilSet= */ mPms 141 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, /* version= */0)); 142 t.traceEnd(); 143 t.traceBegin("switchToBootUser-" + bootUser); 144 switchToBootUser(bootUser); 145 t.traceEnd(); 146 } catch (UserManager.CheckedUserOperationException e) { 147 Slogf.wtf(TAG, "Failed to switch to boot user since there isn't one."); 148 } 149 } 150 observeDeviceProvisioning()151 private void observeDeviceProvisioning() { 152 if (isDeviceProvisioned()) { 153 return; 154 } 155 156 mContentResolver.registerContentObserver( 157 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), 158 false, 159 mDeviceProvisionedObserver 160 ); 161 } 162 isDeviceProvisioned()163 private boolean isDeviceProvisioned() { 164 try { 165 return Settings.Global.getInt(mContentResolver, 166 Settings.Global.DEVICE_PROVISIONED) == 1; 167 } catch (Exception e) { 168 Slogf.wtf(TAG, "DEVICE_PROVISIONED setting not found.", e); 169 return false; 170 } 171 } 172 173 // NOTE: Mostly copied from Automotive's InitialUserSetter 174 // TODO(b/266158156): Refactor how starting/unlocking works for the System. unlockSystemUser(TimingsTraceAndSlog t)175 private void unlockSystemUser(TimingsTraceAndSlog t) { 176 Slogf.i(TAG, "Unlocking system user"); 177 t.traceBegin("unlock-system-user"); 178 try { 179 // This is for force changing state into RUNNING_LOCKED. Otherwise unlock does not 180 // update the state and USER_SYSTEM unlock happens twice. 181 t.traceBegin("am.startUser"); 182 final boolean started = mAms.startUserInBackgroundWithListener(UserHandle.USER_SYSTEM, 183 /* listener= */ null); 184 t.traceEnd(); 185 if (!started) { 186 Slogf.w(TAG, "could not restart system user in background; trying unlock instead"); 187 t.traceBegin("am.unlockUser"); 188 final boolean unlocked = mAms.unlockUser(UserHandle.USER_SYSTEM, /* token= */ null, 189 /* secret= */ null, /* listener= */ null); 190 t.traceEnd(); 191 if (!unlocked) { 192 Slogf.w(TAG, "could not unlock system user either"); 193 } 194 } 195 } finally { 196 t.traceEnd(); 197 } 198 } 199 switchToBootUser(@serIdInt int bootUserId)200 private void switchToBootUser(@UserIdInt int bootUserId) { 201 Slogf.i(TAG, "Switching to boot user %d", bootUserId); 202 final boolean started = mAms.startUserInForegroundWithListener(bootUserId, 203 /* unlockListener= */ null); 204 if (!started) { 205 Slogf.wtf(TAG, "Failed to start user %d in foreground", bootUserId); 206 } 207 } 208 } 209