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