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, 78 shouldAlwaysHaveMainUser); 79 } 80 HsumBootUserInitializer(UserManagerInternal umi, ActivityManagerService am, PackageManagerService pms, ContentResolver contentResolver, boolean shouldAlwaysHaveMainUser)81 private HsumBootUserInitializer(UserManagerInternal umi, ActivityManagerService am, 82 PackageManagerService pms, ContentResolver contentResolver, 83 boolean shouldAlwaysHaveMainUser) { 84 mUmi = umi; 85 mAms = am; 86 mPms = pms; 87 mContentResolver = contentResolver; 88 mShouldAlwaysHaveMainUser = shouldAlwaysHaveMainUser; 89 } 90 91 /** 92 * Initialize this object, and create MainUser if needed. 93 * 94 * <p>Should be called before PHASE_SYSTEM_SERVICES_READY as services' setups may require 95 * MainUser, but probably after PHASE_LOCK_SETTINGS_READY since that may be needed for user 96 * creation. 97 */ init(TimingsTraceAndSlog t)98 public void init(TimingsTraceAndSlog t) { 99 Slogf.i(TAG, "init())"); 100 101 if (mShouldAlwaysHaveMainUser) { 102 t.traceBegin("createMainUserIfNeeded"); 103 createMainUserIfNeeded(); 104 t.traceEnd(); 105 } 106 } 107 createMainUserIfNeeded()108 private void createMainUserIfNeeded() { 109 final int mainUser = mUmi.getMainUserId(); 110 if (mainUser != UserHandle.USER_NULL) { 111 Slogf.d(TAG, "Found existing MainUser, userId=%d", mainUser); 112 return; 113 } 114 115 Slogf.d(TAG, "Creating a new MainUser"); 116 try { 117 final UserInfo newInitialUser = mUmi.createUserEvenWhenDisallowed( 118 /* name= */ null, // null will appear as "Owner" in on-demand localisation 119 UserManager.USER_TYPE_FULL_SECONDARY, 120 UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN, 121 /* disallowedPackages= */ null, 122 /* token= */ null); 123 Slogf.i(TAG, "Successfully created MainUser, userId=%d", newInitialUser.id); 124 } catch (UserManager.CheckedUserOperationException e) { 125 Slogf.wtf(TAG, "Initial bootable MainUser creation failed", e); 126 } 127 } 128 129 /** 130 * Put the device into the correct user state: unlock the system and switch to the boot user. 131 * 132 * <p>Should only call once PHASE_THIRD_PARTY_APPS_CAN_START is reached to ensure that 133 * privileged apps have had the chance to set the boot user, if applicable. 134 */ systemRunning(TimingsTraceAndSlog t)135 public void systemRunning(TimingsTraceAndSlog t) { 136 observeDeviceProvisioning(); 137 unlockSystemUser(t); 138 139 try { 140 t.traceBegin("getBootUser"); 141 final int bootUser = mUmi.getBootUser(/* waitUntilSet= */ mPms 142 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, /* version= */0)); 143 t.traceEnd(); 144 t.traceBegin("switchToBootUser-" + bootUser); 145 switchToBootUser(bootUser); 146 t.traceEnd(); 147 } catch (UserManager.CheckedUserOperationException e) { 148 Slogf.wtf(TAG, "Failed to switch to boot user since there isn't one."); 149 } 150 } 151 observeDeviceProvisioning()152 private void observeDeviceProvisioning() { 153 if (isDeviceProvisioned()) { 154 return; 155 } 156 157 mContentResolver.registerContentObserver( 158 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), 159 false, 160 mDeviceProvisionedObserver 161 ); 162 } 163 isDeviceProvisioned()164 private boolean isDeviceProvisioned() { 165 try { 166 return Settings.Global.getInt(mContentResolver, 167 Settings.Global.DEVICE_PROVISIONED) == 1; 168 } catch (Exception e) { 169 Slogf.wtf(TAG, "DEVICE_PROVISIONED setting not found.", e); 170 return false; 171 } 172 } 173 174 // NOTE: Mostly copied from Automotive's InitialUserSetter 175 // TODO(b/266158156): Refactor how starting/unlocking works for the System. unlockSystemUser(TimingsTraceAndSlog t)176 private void unlockSystemUser(TimingsTraceAndSlog t) { 177 Slogf.i(TAG, "Unlocking system user"); 178 t.traceBegin("unlock-system-user"); 179 try { 180 // This is for force changing state into RUNNING_LOCKED. Otherwise unlock does not 181 // update the state and USER_SYSTEM unlock happens twice. 182 t.traceBegin("am.startUser"); 183 final boolean started = mAms.startUserInBackgroundWithListener(UserHandle.USER_SYSTEM, 184 /* listener= */ null); 185 t.traceEnd(); 186 if (!started) { 187 Slogf.w(TAG, "could not restart system user in background; trying unlock instead"); 188 t.traceBegin("am.unlockUser"); 189 final boolean unlocked = mAms.unlockUser(UserHandle.USER_SYSTEM, /* token= */ null, 190 /* secret= */ null, /* listener= */ null); 191 t.traceEnd(); 192 if (!unlocked) { 193 Slogf.w(TAG, "could not unlock system user either"); 194 } 195 } 196 } finally { 197 t.traceEnd(); 198 } 199 } 200 switchToBootUser(@serIdInt int bootUserId)201 private void switchToBootUser(@UserIdInt int bootUserId) { 202 Slogf.i(TAG, "Switching to boot user %d", bootUserId); 203 final boolean started = mAms.startUserInForegroundWithListener(bootUserId, 204 /* unlockListener= */ null); 205 if (!started) { 206 Slogf.wtf(TAG, "Failed to start user %d in foreground", bootUserId); 207 } 208 } 209 } 210