1 /*
2  * Copyright (C) 2018 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 
17 package com.android.car.user;
18 
19 import static android.Manifest.permission.CREATE_USERS;
20 import static android.Manifest.permission.MANAGE_USERS;
21 import static android.car.drivingstate.CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP;
22 
23 import static com.android.car.PermissionHelper.checkHasAtLeastOnePermissionGranted;
24 import static com.android.car.PermissionHelper.checkHasDumpPermissionGranted;
25 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DEPRECATED_CODE;
26 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
27 
28 import android.annotation.NonNull;
29 import android.annotation.Nullable;
30 import android.annotation.UserIdInt;
31 import android.app.ActivityManager;
32 import android.app.ActivityTaskManager.RootTaskInfo;
33 import android.app.IActivityManager;
34 import android.car.CarOccupantZoneManager;
35 import android.car.CarOccupantZoneManager.OccupantTypeEnum;
36 import android.car.CarOccupantZoneManager.OccupantZoneInfo;
37 import android.car.ICarUserService;
38 import android.car.drivingstate.CarUxRestrictions;
39 import android.car.drivingstate.ICarUxRestrictionsChangeListener;
40 import android.car.settings.CarSettings;
41 import android.car.user.CarUserManager;
42 import android.car.user.CarUserManager.UserIdentificationAssociationSetValue;
43 import android.car.user.CarUserManager.UserIdentificationAssociationType;
44 import android.car.user.CarUserManager.UserLifecycleEvent;
45 import android.car.user.CarUserManager.UserLifecycleListener;
46 import android.car.user.UserCreationResult;
47 import android.car.user.UserIdentificationAssociationResponse;
48 import android.car.user.UserRemovalResult;
49 import android.car.user.UserStartResult;
50 import android.car.user.UserStopResult;
51 import android.car.user.UserSwitchResult;
52 import android.car.userlib.HalCallback;
53 import android.car.userlib.UserHalHelper;
54 import android.car.userlib.UserHelper;
55 import android.content.ComponentName;
56 import android.content.Context;
57 import android.content.pm.PackageManager;
58 import android.content.pm.PackageManager.NameNotFoundException;
59 import android.content.pm.UserInfo;
60 import android.content.pm.UserInfo.UserInfoFlag;
61 import android.content.res.Resources;
62 import android.graphics.Bitmap;
63 import android.hardware.automotive.vehicle.V2_0.CreateUserRequest;
64 import android.hardware.automotive.vehicle.V2_0.CreateUserStatus;
65 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoRequestType;
66 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction;
67 import android.hardware.automotive.vehicle.V2_0.RemoveUserRequest;
68 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
69 import android.hardware.automotive.vehicle.V2_0.SwitchUserStatus;
70 import android.hardware.automotive.vehicle.V2_0.UserIdentificationGetRequest;
71 import android.hardware.automotive.vehicle.V2_0.UserIdentificationResponse;
72 import android.hardware.automotive.vehicle.V2_0.UserIdentificationSetAssociation;
73 import android.hardware.automotive.vehicle.V2_0.UserIdentificationSetRequest;
74 import android.hardware.automotive.vehicle.V2_0.UsersInfo;
75 import android.location.LocationManager;
76 import android.os.Binder;
77 import android.os.Bundle;
78 import android.os.Handler;
79 import android.os.HandlerThread;
80 import android.os.IBinder;
81 import android.os.Process;
82 import android.os.RemoteException;
83 import android.os.Trace;
84 import android.os.UserHandle;
85 import android.os.UserManager;
86 import android.provider.Settings;
87 import android.sysprop.CarProperties;
88 import android.text.TextUtils;
89 import android.util.ArrayMap;
90 import android.util.EventLog;
91 import android.util.IndentingPrintWriter;
92 import android.util.Log;
93 import android.util.Slog;
94 import android.util.SparseBooleanArray;
95 import android.util.TimingsTraceLog;
96 import android.view.Display;
97 
98 import com.android.car.CarLog;
99 import com.android.car.CarServiceBase;
100 import com.android.car.CarServiceUtils;
101 import com.android.car.CarUxRestrictionsManagerService;
102 import com.android.car.R;
103 import com.android.car.hal.UserHalService;
104 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
105 import com.android.car.internal.ICarServiceHelper;
106 import com.android.car.internal.common.CommonConstants.UserLifecycleEventType;
107 import com.android.car.internal.common.EventLogTags;
108 import com.android.car.internal.common.UserHelperLite;
109 import com.android.car.power.CarPowerManagementService;
110 import com.android.car.user.InitialUserSetter.InitialUserInfo;
111 import com.android.internal.annotations.GuardedBy;
112 import com.android.internal.annotations.VisibleForTesting;
113 import com.android.internal.infra.AndroidFuture;
114 import com.android.internal.os.IResultReceiver;
115 import com.android.internal.util.ArrayUtils;
116 import com.android.internal.util.FunctionalUtils;
117 import com.android.internal.util.Preconditions;
118 import com.android.internal.util.UserIcons;
119 import com.android.server.utils.Slogf;
120 
121 import java.io.PrintWriter;
122 import java.util.ArrayList;
123 import java.util.Arrays;
124 import java.util.Iterator;
125 import java.util.List;
126 import java.util.Objects;
127 import java.util.concurrent.CopyOnWriteArrayList;
128 import java.util.concurrent.CountDownLatch;
129 import java.util.concurrent.TimeUnit;
130 
131 /**
132  * User service for cars. Manages users at boot time. Including:
133  *
134  * <ol>
135  *   <li> Creates a user used as driver.
136  *   <li> Creates a user used as passenger.
137  *   <li> Creates a secondary admin user on first run.
138  *   <li> Switch drivers.
139  * <ol/>
140  */
141 public final class CarUserService extends ICarUserService.Stub implements CarServiceBase {
142 
143     private static final String TAG = CarLog.tagFor(CarUserService.class);
144 
145     /** {@code int} extra used to represent a user id in a {@link IResultReceiver} response. */
146     public static final String BUNDLE_USER_ID = "user.id";
147     /** {@code int} extra used to represent user flags in a {@link IResultReceiver} response. */
148     public static final String BUNDLE_USER_FLAGS = "user.flags";
149     /** {@code String} extra used to represent a user name in a {@link IResultReceiver} response. */
150     public static final String BUNDLE_USER_NAME = "user.name";
151     /**
152      * {@code int} extra used to represent the user locales in a {@link IResultReceiver} response.
153      */
154     public static final String BUNDLE_USER_LOCALES = "user.locales";
155     /**
156      * {@code int} extra used to represent the info action in a {@link IResultReceiver} response.
157      */
158     public static final String BUNDLE_INITIAL_INFO_ACTION = "initial_info.action";
159 
160     public static final String VEHICLE_HAL_NOT_SUPPORTED = "Vehicle Hal not supported.";
161 
162     public static final String HANDLER_THREAD_NAME = "UserService";
163 
164     private final Context mContext;
165     private final IActivityManager mAm;
166     private final UserManager mUserManager;
167     private final int mMaxRunningUsers;
168     private final InitialUserSetter mInitialUserSetter;
169     private final boolean mEnablePassengerSupport;
170     private final UserPreCreator mUserPreCreator;
171 
172     private final Object mLockUser = new Object();
173     @GuardedBy("mLockUser")
174     private boolean mUser0Unlocked;
175     @GuardedBy("mLockUser")
176     private final ArrayList<Runnable> mUser0UnlockTasks = new ArrayList<>();
177     // Only one passenger is supported.
178     @GuardedBy("mLockUser")
179     private @UserIdInt int mLastPassengerId;
180     /**
181      * Background users that will be restarted in garage mode. This list can include the
182      * current foreground user but the current foreground user should not be restarted.
183      */
184     @GuardedBy("mLockUser")
185     private final ArrayList<Integer> mBackgroundUsersToRestart = new ArrayList<>();
186     /**
187      * Keep the list of background users started here. This is wholly for debugging purpose.
188      */
189     @GuardedBy("mLockUser")
190     private final ArrayList<Integer> mBackgroundUsersRestartedHere = new ArrayList<>();
191 
192     private final UserHalService mHal;
193 
194     private final HandlerThread mHandlerThread = CarServiceUtils.getHandlerThread(
195             HANDLER_THREAD_NAME);
196     private final Handler mHandler;
197 
198     /**
199      * Internal listeners to be notified on new user activities events.
200      *
201      * <p>This collection should be accessed and manipulated by {@code mHandlerThread} only.
202      */
203     private final List<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>();
204 
205     /**
206      * App listeners to be notified on new user activities events.
207      *
208      * <p>This collection should be accessed and manipulated by {@code mHandlerThread} only.
209      */
210     private final ArrayMap<IBinder, AppLifecycleListener> mAppLifecycleListeners =
211             new ArrayMap<>();
212 
213     /**
214      * User Id for the user switch in process, if any.
215      */
216     @GuardedBy("mLockUser")
217     private int mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
218     /**
219      * Request Id for the user switch in process, if any.
220      */
221     @GuardedBy("mLockUser")
222     private int mRequestIdForUserSwitchInProcess;
223     private final int mHalTimeoutMs = CarProperties.user_hal_timeout().orElse(5_000);
224 
225     private final CopyOnWriteArrayList<PassengerCallback> mPassengerCallbacks =
226             new CopyOnWriteArrayList<>();
227 
228     // TODO(b/163566866): Use mSwitchGuestUserBeforeSleep for new create guest request
229     private final boolean mSwitchGuestUserBeforeSleep;
230 
231     @Nullable
232     @GuardedBy("mLockUser")
233     private UserHandle mInitialUser;
234 
235     private IResultReceiver mUserSwitchUiReceiver;
236 
237     private final CarUxRestrictionsManagerService mCarUxRestrictionService;
238 
239     /**
240      * Whether some operations - like user switch - are restricted by driving safety constraints.
241      */
242     @GuardedBy("mLockUser")
243     private boolean mUxRestricted;
244 
245     /**
246      * If {@code false}, garage mode operations (background users start at garage mode entry and
247      * background users stop at garage mode exit) will be skipped. Controlled using car shell
248      * command {@code adb shell set-start-bg-users-on-garage-mode [true|false]}
249      * Purpose: Garage mode testing and simulation
250      */
251     @GuardedBy("mLockUser")
252     private boolean mStartBackgroundUsersOnGarageMode = true;
253 
254     /**
255      * Callback to notify {@code CarServiceHelper} about driving safety changes (through
256      * {@link ICarServiceHelper#setSafetyMode(boolean).
257      *
258      * <p>NOTE: in theory, that logic should belong to {@code CarDevicePolicyService}, but it's
259      * simpler to do it here (and that service already depends on this one).
260      */
261     @GuardedBy("mLockUser")
262     private ICarServiceHelper mICarServiceHelper;
263 
264     private final ICarUxRestrictionsChangeListener mCarUxRestrictionsChangeListener =
265             new ICarUxRestrictionsChangeListener.Stub() {
266         @Override
267         public void onUxRestrictionsChanged(CarUxRestrictions restrictions) {
268             setUxRestrictions(restrictions);
269         }
270     };
271 
272     /** Interface for callbaks related to passenger activities. */
273     public interface PassengerCallback {
274         /** Called when passenger is started at a certain zone. */
onPassengerStarted(@serIdInt int passengerId, int zoneId)275         void onPassengerStarted(@UserIdInt int passengerId, int zoneId);
276         /** Called when passenger is stopped. */
onPassengerStopped(@serIdInt int passengerId)277         void onPassengerStopped(@UserIdInt int passengerId);
278     }
279 
280     /** Interface for delegating zone-related implementation to CarOccupantZoneService. */
281     public interface ZoneUserBindingHelper {
282         /** Gets occupant zones corresponding to the occupant type. */
283         @NonNull
getOccupantZones(@ccupantTypeEnum int occupantType)284         List<OccupantZoneInfo> getOccupantZones(@OccupantTypeEnum int occupantType);
285         /** Assigns the user to the occupant zone. */
assignUserToOccupantZone(@serIdInt int userId, int zoneId)286         boolean assignUserToOccupantZone(@UserIdInt int userId, int zoneId);
287         /** Makes the occupant zone unoccupied. */
unassignUserFromOccupantZone(@serIdInt int userId)288         boolean unassignUserFromOccupantZone(@UserIdInt int userId);
289         /** Returns whether there is a passenger display. */
isPassengerDisplayAvailable()290         boolean isPassengerDisplayAvailable();
291     }
292 
293     private final Object mLockHelper = new Object();
294     @GuardedBy("mLockHelper")
295     private ZoneUserBindingHelper mZoneUserBindingHelper;
296 
297     /** Map used to avoid calling UserHAL when a user was removed because HAL creation failed. */
298     @GuardedBy("mLockUser")
299     private final SparseBooleanArray mFailedToCreateUserIds = new SparseBooleanArray(1);
300 
CarUserService(@onNull Context context, @NonNull UserHalService hal, @NonNull UserManager userManager, @NonNull IActivityManager am, int maxRunningUsers, @NonNull CarUxRestrictionsManagerService uxRestrictionService)301     public CarUserService(@NonNull Context context, @NonNull UserHalService hal,
302             @NonNull UserManager userManager,
303             @NonNull IActivityManager am, int maxRunningUsers,
304             @NonNull CarUxRestrictionsManagerService uxRestrictionService) {
305         this(context, hal, userManager, am, maxRunningUsers,
306                 /* initialUserSetter= */ null, /* userPreCreator= */ null, uxRestrictionService,
307                 null);
308     }
309 
310     @VisibleForTesting
CarUserService(@onNull Context context, @NonNull UserHalService hal, @NonNull UserManager userManager, @NonNull IActivityManager am, int maxRunningUsers, @Nullable InitialUserSetter initialUserSetter, @Nullable UserPreCreator userPreCreator, @NonNull CarUxRestrictionsManagerService uxRestrictionService, @Nullable Handler handler)311     CarUserService(@NonNull Context context, @NonNull UserHalService hal,
312             @NonNull UserManager userManager,
313             @NonNull IActivityManager am, int maxRunningUsers,
314             @Nullable InitialUserSetter initialUserSetter,
315             @Nullable UserPreCreator userPreCreator,
316             @NonNull CarUxRestrictionsManagerService uxRestrictionService,
317             @Nullable Handler handler) {
318         if (Log.isLoggable(TAG, Log.DEBUG)) {
319             Slog.d(TAG, "constructed for user " + context.getUserId());
320         }
321         mContext = context;
322         mHal = hal;
323         mAm = am;
324         mMaxRunningUsers = maxRunningUsers;
325         mUserManager = userManager;
326         mLastPassengerId = UserHandle.USER_NULL;
327         mHandler = handler == null ? new Handler(mHandlerThread.getLooper()) : handler;
328         mInitialUserSetter =
329                 initialUserSetter == null ? new InitialUserSetter(context, this,
330                         (u) -> setInitialUser(u)) : initialUserSetter;
331         mUserPreCreator =
332                 userPreCreator == null ? new UserPreCreator(mUserManager) : userPreCreator;
333         Resources resources = context.getResources();
334         mEnablePassengerSupport = resources.getBoolean(R.bool.enablePassengerSupport);
335         mSwitchGuestUserBeforeSleep = resources.getBoolean(
336                 R.bool.config_switchGuestUserBeforeGoingSleep);
337         mCarUxRestrictionService = uxRestrictionService;
338     }
339 
340     @Override
init()341     public void init() {
342         if (Log.isLoggable(TAG, Log.DEBUG)) {
343             Slog.d(TAG, "init()");
344         }
345         mCarUxRestrictionService.registerUxRestrictionsChangeListener(
346                 mCarUxRestrictionsChangeListener, Display.DEFAULT_DISPLAY);
347 
348         setUxRestrictions(mCarUxRestrictionService.getCurrentUxRestrictions());
349     }
350 
351     @Override
release()352     public void release() {
353         if (Log.isLoggable(TAG, Log.DEBUG)) {
354             Slog.d(TAG, "release()");
355         }
356         mCarUxRestrictionService
357                 .unregisterUxRestrictionsChangeListener(mCarUxRestrictionsChangeListener);
358     }
359 
360     @Override
361     @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
dump(@onNull IndentingPrintWriter writer)362     public void dump(@NonNull IndentingPrintWriter writer) {
363         checkHasDumpPermissionGranted("dump()");
364 
365         writer.println("*CarUserService*");
366         handleDumpListeners(writer);
367         writer.printf("User switch UI receiver %s\n", mUserSwitchUiReceiver);
368         synchronized (mLockUser) {
369             writer.println("User0Unlocked: " + mUser0Unlocked);
370             writer.println("BackgroundUsersToRestart: " + mBackgroundUsersToRestart);
371             writer.println("BackgroundUsersRestarted: " + mBackgroundUsersRestartedHere);
372             if (mFailedToCreateUserIds.size() > 0) {
373                 writer.println("FailedToCreateUserIds: " + mFailedToCreateUserIds);
374             }
375             writer.printf("Is UX restricted: %b\n", mUxRestricted);
376             writer.printf("Start Background Users On Garage Mode=%s\n",
377                     mStartBackgroundUsersOnGarageMode);
378             writer.printf("Initial user: %s\n", mInitialUser);
379         }
380 
381         writer.println("SwitchGuestUserBeforeSleep: " + mSwitchGuestUserBeforeSleep);
382 
383         writer.println("MaxRunningUsers: " + mMaxRunningUsers);
384         List<UserInfo> allDrivers = getAllDrivers();
385         int driversSize = allDrivers.size();
386         writer.println("NumberOfDrivers: " + driversSize);
387         writer.increaseIndent();
388         for (int i = 0; i < driversSize; i++) {
389             int driverId = allDrivers.get(i).id;
390             writer.printf("#%d: id=%d", i, driverId);
391             List<UserInfo> passengers = getPassengers(driverId);
392             int passengersSize = passengers.size();
393             writer.print(" NumberPassengers: " + passengersSize);
394             if (passengersSize > 0) {
395                 writer.print(" [");
396                 for (int j = 0; j < passengersSize; j++) {
397                     writer.print(passengers.get(j).id);
398                     if (j < passengersSize - 1) {
399                         writer.print(" ");
400                     }
401                 }
402                 writer.print("]");
403             }
404             writer.println();
405         }
406         writer.decreaseIndent();
407         writer.printf("EnablePassengerSupport: %s\n", mEnablePassengerSupport);
408         writer.printf("User HAL: supported=%b, timeout=%dms\n", isUserHalSupported(),
409                 mHalTimeoutMs);
410 
411         writer.println("Relevant overlayable properties");
412         Resources res = mContext.getResources();
413         writer.increaseIndent();
414         writer.printf("owner_name=%s\n", res.getString(com.android.internal.R.string.owner_name));
415         writer.printf("default_guest_name=%s\n", res.getString(R.string.default_guest_name));
416         writer.decreaseIndent();
417         writer.printf("User switch in process=%d\n", mUserIdForUserSwitchInProcess);
418         writer.printf("Request Id for the user switch in process=%d\n ",
419                     mRequestIdForUserSwitchInProcess);
420         writer.printf("System UI package name=%s\n", getSystemUiPackageName());
421 
422         writer.println("Relevant Global settings");
423         writer.increaseIndent();
424         dumpGlobalProperty(writer, CarSettings.Global.LAST_ACTIVE_USER_ID);
425         dumpGlobalProperty(writer, CarSettings.Global.LAST_ACTIVE_PERSISTENT_USER_ID);
426         writer.decreaseIndent();
427 
428         mInitialUserSetter.dump(writer);
429     }
430 
dumpGlobalProperty(IndentingPrintWriter writer, String property)431     private void dumpGlobalProperty(IndentingPrintWriter writer, String property) {
432         String value = Settings.Global.getString(mContext.getContentResolver(), property);
433         writer.printf("%s=%s\n", property, value);
434     }
435 
handleDumpListeners(IndentingPrintWriter writer)436     private void handleDumpListeners(IndentingPrintWriter writer) {
437         writer.increaseIndent();
438         CountDownLatch latch = new CountDownLatch(1);
439         mHandler.post(() -> {
440             handleDumpServiceLifecycleListeners(writer);
441             handleDumpAppLifecycleListeners(writer);
442             latch.countDown();
443         });
444         int timeout = 5;
445         try {
446             if (!latch.await(timeout, TimeUnit.SECONDS)) {
447                 writer.printf("Handler thread didn't respond in %ds when dumping listeners\n",
448                         timeout);
449             }
450         } catch (InterruptedException e) {
451             Thread.currentThread().interrupt();
452             writer.println("Interrupted waiting for handler thread to dump app and user listeners");
453         }
454         writer.decreaseIndent();
455     }
456 
handleDumpServiceLifecycleListeners(PrintWriter writer)457     private void handleDumpServiceLifecycleListeners(PrintWriter writer) {
458         if (mUserLifecycleListeners.isEmpty()) {
459             writer.println("No lifecycle listeners for internal services");
460             return;
461         }
462         int size = mUserLifecycleListeners.size();
463         writer.printf("%d lifecycle listener%s for services\n", size, size == 1 ? "" : "s");
464         String indent = "  ";
465         for (int i = 0; i < size; i++) {
466             UserLifecycleListener listener = mUserLifecycleListeners.get(i);
467             writer.printf("%s%s\n", indent, FunctionalUtils.getLambdaName(listener));
468         }
469     }
470 
handleDumpAppLifecycleListeners(IndentingPrintWriter writer)471     private void handleDumpAppLifecycleListeners(IndentingPrintWriter writer) {
472         int size = mAppLifecycleListeners.size();
473         if (size == 0) {
474             writer.println("No lifecycle listeners for apps");
475             return;
476         }
477         writer.printf("%d lifecycle listener%s for apps\n", size, size == 1 ? "" : "s");
478         writer.increaseIndent();
479         for (int i = 0; i < size; i++) {
480             mAppLifecycleListeners.valueAt(i).dump(writer);
481         }
482         writer.decreaseIndent();
483     }
484 
485     /**
486      * @see ExperimentalCarUserManager.createDriver
487      */
488     @Override
489     @ExcludeFromCodeCoverageGeneratedReport(reason = DEPRECATED_CODE,
490             details = "TODO(b/172262561) remove annotation after refactoring")
createDriver(@onNull String name, boolean admin)491     public AndroidFuture<UserCreationResult> createDriver(@NonNull String name, boolean admin) {
492         checkManageUsersPermission("createDriver");
493         Objects.requireNonNull(name, "name cannot be null");
494 
495         AndroidFuture<UserCreationResult> future = new AndroidFuture<UserCreationResult>() {
496             @Override
497             protected void onCompleted(UserCreationResult result, Throwable err) {
498                 if (result == null) {
499                     Slog.w(TAG, "createDriver(" + name + "," + admin + ") failed: " + err);
500                 } else {
501                     if (result.getStatus() == UserCreationResult.STATUS_SUCCESSFUL) {
502                         assignDefaultIcon(result.getUser());
503                     }
504                 }
505                 super.onCompleted(result, err);
506             };
507         };
508         int flags = 0;
509         if (admin) {
510             if (!(mUserManager.isAdminUser() || mUserManager.isSystemUser())) {
511                 Slog.e(TAG, "Only admin users and system user can create other admins.");
512                 sendUserCreationResultFailure(future, UserCreationResult.STATUS_INVALID_REQUEST);
513                 return future;
514             }
515             flags = UserInfo.FLAG_ADMIN;
516         }
517         createUser(name, UserInfo.getDefaultUserType(flags), flags, mHalTimeoutMs, future);
518         return future;
519     }
520 
521     /**
522      * @see ExperimentalCarUserManager.createPassenger
523      */
524     @Override
525     @Nullable
526     @ExcludeFromCodeCoverageGeneratedReport(reason = DEPRECATED_CODE,
527             details = "TODO(b/172262561) remove annotation after refactoring")
createPassenger(@onNull String name, @UserIdInt int driverId)528     public UserInfo createPassenger(@NonNull String name, @UserIdInt int driverId) {
529         checkManageUsersPermission("createPassenger");
530         Objects.requireNonNull(name, "name cannot be null");
531         UserInfo driver = mUserManager.getUserInfo(driverId);
532         if (driver == null) {
533             Slog.w(TAG, "the driver is invalid");
534             return null;
535         }
536         if (driver.isGuest()) {
537             Slog.w(TAG, "a guest driver cannot create a passenger");
538             return null;
539         }
540         // createPassenger doesn't use user HAL because user HAL doesn't support profile user yet.
541         UserInfo user = mUserManager.createProfileForUser(name,
542                 UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, driverId);
543         if (user == null) {
544             // Couldn't create user, most likely because there are too many.
545             Slog.w(TAG, "can't create a profile for user" + driverId);
546             return null;
547         }
548         // Passenger user should be a non-admin user.
549         UserHelper.setDefaultNonAdminRestrictions(mContext, user, /* enable= */ true);
550         assignDefaultIcon(user);
551         return user;
552     }
553 
554     /**
555      * @see ExperimentalCarUserManager.switchDriver
556      */
557     @Override
558     @ExcludeFromCodeCoverageGeneratedReport(reason = DEPRECATED_CODE,
559             details = "TODO(b/172262561) remove annotation after refactoring")
switchDriver(@serIdInt int driverId, AndroidFuture<UserSwitchResult> receiver)560     public void switchDriver(@UserIdInt int driverId, AndroidFuture<UserSwitchResult> receiver) {
561         checkManageUsersPermission("switchDriver");
562         if (UserHelperLite.isHeadlessSystemUser(driverId)) {
563             // System user doesn't associate with real person, can not be switched to.
564             Slog.w(TAG, "switching to system user in headless system user mode is not allowed");
565             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_INVALID_REQUEST);
566             return;
567         }
568         int userSwitchable = mUserManager.getUserSwitchability();
569         if (userSwitchable != UserManager.SWITCHABILITY_STATUS_OK) {
570             Slog.w(TAG, "current process is not allowed to switch user");
571             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_INVALID_REQUEST);
572             return;
573         }
574         switchUser(driverId, mHalTimeoutMs, receiver);
575     }
576 
577     /**
578      * Returns all drivers who can occupy the driving zone. Guest users are included in the list.
579      *
580      * @return the list of {@link UserInfo} who can be a driver on the device.
581      */
582     @Override
583     @NonNull
getAllDrivers()584     public List<UserInfo> getAllDrivers() {
585         checkManageUsersOrDumpPermission("getAllDrivers");
586         return getUsers((user) -> !UserHelperLite.isHeadlessSystemUser(user.id) && user.isEnabled()
587                 && !user.isManagedProfile() && !user.isEphemeral());
588     }
589 
590     /**
591      * Returns all passengers under the given driver.
592      *
593      * @param driverId User id of a driver.
594      * @return the list of {@link UserInfo} who is a passenger under the given driver.
595      */
596     @Override
597     @NonNull
getPassengers(@serIdInt int driverId)598     public List<UserInfo> getPassengers(@UserIdInt int driverId) {
599         checkManageUsersOrDumpPermission("getPassengers");
600         return getUsers((user) -> {
601             return !UserHelperLite.isHeadlessSystemUser(user.id) && user.isEnabled()
602                     && user.isManagedProfile() && user.profileGroupId == driverId;
603         });
604     }
605 
606     /**
607      * @see CarUserManager.startPassenger
608      */
609     @Override
startPassenger(@serIdInt int passengerId, int zoneId)610     public boolean startPassenger(@UserIdInt int passengerId, int zoneId) {
611         checkManageUsersPermission("startPassenger");
612         synchronized (mLockUser) {
613             try {
614                 if (!mAm.startUserInBackgroundWithListener(passengerId, null)) {
615                     Slog.w(TAG, "could not start passenger");
616                     return false;
617                 }
618             } catch (RemoteException e) {
619                 // ignore
620                 Slog.w(TAG, "error while starting passenger", e);
621                 return false;
622             }
623             if (!assignUserToOccupantZone(passengerId, zoneId)) {
624                 Slog.w(TAG, "could not assign passenger to zone");
625                 return false;
626             }
627             mLastPassengerId = passengerId;
628         }
629         for (PassengerCallback callback : mPassengerCallbacks) {
630             callback.onPassengerStarted(passengerId, zoneId);
631         }
632         return true;
633     }
634 
635     /**
636      * @see CarUserManager.stopPassenger
637      */
638     @Override
stopPassenger(@serIdInt int passengerId)639     public boolean stopPassenger(@UserIdInt int passengerId) {
640         checkManageUsersPermission("stopPassenger");
641         return stopPassengerInternal(passengerId, true);
642     }
643 
stopPassengerInternal(@serIdInt int passengerId, boolean checkCurrentDriver)644     private boolean stopPassengerInternal(@UserIdInt int passengerId, boolean checkCurrentDriver) {
645         synchronized (mLockUser) {
646             UserInfo passenger = mUserManager.getUserInfo(passengerId);
647             if (passenger == null) {
648                 Slog.w(TAG, "passenger " + passengerId + " doesn't exist");
649                 return false;
650             }
651             if (mLastPassengerId != passengerId) {
652                 Slog.w(TAG, "passenger " + passengerId + " hasn't been started");
653                 return true;
654             }
655             if (checkCurrentDriver) {
656                 int currentUser = ActivityManager.getCurrentUser();
657                 if (passenger.profileGroupId != currentUser) {
658                     Slog.w(TAG, "passenger " + passengerId
659                             + " is not a profile of the current user");
660                     return false;
661                 }
662             }
663             // Passenger is a profile, so cannot be stopped through activity manager.
664             // Instead, activities started by the passenger are stopped and the passenger is
665             // unassigned from the zone.
666             stopAllTasks(passengerId);
667             if (!unassignUserFromOccupantZone(passengerId)) {
668                 Slog.w(TAG, "could not unassign user from occupant zone");
669                 return false;
670             }
671             mLastPassengerId = UserHandle.USER_NULL;
672         }
673         for (PassengerCallback callback : mPassengerCallbacks) {
674             callback.onPassengerStopped(passengerId);
675         }
676         return true;
677     }
678 
stopAllTasks(@serIdInt int userId)679     private void stopAllTasks(@UserIdInt int userId) {
680         try {
681             for (RootTaskInfo info : mAm.getAllRootTaskInfos()) {
682                 for (int i = 0; i < info.childTaskIds.length; i++) {
683                     if (info.childTaskUserIds[i] == userId) {
684                         int taskId = info.childTaskIds[i];
685                         if (!mAm.removeTask(taskId)) {
686                             Slog.w(TAG, "could not remove task " + taskId);
687                         }
688                     }
689                 }
690             }
691         } catch (RemoteException e) {
692             Slog.e(TAG, "could not get stack info", e);
693         }
694     }
695 
696     @Override
setLifecycleListenerForApp(String packageName, IResultReceiver receiver)697     public void setLifecycleListenerForApp(String packageName, IResultReceiver receiver) {
698         int uid = Binder.getCallingUid();
699         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SET_LIFECYCLE_LISTENER, uid, packageName);
700         checkInteractAcrossUsersPermission("setLifecycleListenerForApp-" + uid + "-" + packageName);
701 
702         IBinder receiverBinder = receiver.asBinder();
703         AppLifecycleListener listener = new AppLifecycleListener(uid, packageName, receiver,
704                 (l) -> onListenerDeath(l));
705         Slogf.d(TAG, "Adding %s (using binder %s)", listener, receiverBinder);
706         mHandler.post(() -> mAppLifecycleListeners.put(receiverBinder, listener));
707     }
708 
onListenerDeath(AppLifecycleListener listener)709     private void onListenerDeath(AppLifecycleListener listener) {
710         Slogf.i(TAG, "Removing listener %s on binder death", listener);
711         mHandler.post(() -> mAppLifecycleListeners.remove(listener.receiver.asBinder()));
712     }
713 
714     @Override
resetLifecycleListenerForApp(IResultReceiver receiver)715     public void resetLifecycleListenerForApp(IResultReceiver receiver) {
716         int uid = Binder.getCallingUid();
717         checkInteractAcrossUsersPermission("resetLifecycleListenerForApp-" + uid);
718         IBinder receiverBinder = receiver.asBinder();
719         mHandler.post(() -> {
720             AppLifecycleListener listener = mAppLifecycleListeners.get(receiverBinder);
721             if (listener == null) {
722                 Slogf.e(TAG, "resetLifecycleListenerForApp(uid=%d): no listener for receiver", uid);
723                 return;
724             }
725             if (listener.uid != uid) {
726                 Slogf.e(TAG, "resetLifecycleListenerForApp(): uid mismatch (called by %d) for "
727                         + "listener %s", uid, listener);
728             }
729             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_RESET_LIFECYCLE_LISTENER, uid,
730                     listener.packageName);
731             Slogf.d(TAG, "Removing %s (using binder %s)", listener, receiverBinder);
732             mAppLifecycleListeners.remove(receiverBinder);
733 
734             listener.onDestroy();
735         });
736     }
737 
738     /**
739      * Gets the initial foreground user after the device boots or resumes from suspension.
740      *
741      * <p>When the OEM supports the User HAL, the initial user won't be available until the HAL
742      * returns the initial value to {@code CarService} - if HAL takes too long or times out, this
743      * method returns {@code null}.
744      *
745      * <p>If the HAL eventually times out, {@code CarService} will fallback to its default behavior
746      * (like switching to the last active user), and this method will return the result of such
747      * operation.
748      *
749      * <p>Notice that if {@code CarService} crashes, subsequent calls to this method will return
750      * {@code null}.
751      *
752      * @hide
753      */
754     @Nullable
getInitialUser()755     public UserHandle getInitialUser() {
756         checkInteractAcrossUsersPermission("getInitialUser");
757         synchronized (mLockUser) {
758             return mInitialUser;
759         }
760     }
761 
762     /**
763      * Sets the initial foreground user after the device boots or resumes from suspension.
764      */
setInitialUser(@ullable UserInfo user)765     public void setInitialUser(@Nullable UserInfo user) {
766         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SET_INITIAL_USER,
767                 user == null ? UserHandle.USER_NULL : user.id);
768         synchronized (mLockUser) {
769             if (user == null) {
770                 // This mean InitialUserSetter failed and could not fallback, so the initial user
771                 // was not switched (and most likely is SYSTEM_USER).
772                 // TODO(b/153104378): should we set it to ActivityManager.getCurrentUser() instead?
773                 Slog.wtf(TAG, "Initial user set to null");
774                 mInitialUser = null;
775                 return;
776             }
777             mInitialUser = user.getUserHandle();
778         }
779         sendInitialUserToSystemServer(user.getUserHandle());
780     }
781 
782     /**
783      * Sets the initial foreground user after car service is crashed and reconnected.
784      */
setInitialUserFromSystemServer(@ullable UserHandle user)785     public void setInitialUserFromSystemServer(@Nullable UserHandle user) {
786         if (user == null || user.getIdentifier() == UserHandle.USER_NULL) {
787             Slogf.e(TAG,
788                     "setInitialUserFromSystemServer: Not setting initial user as user is NULL ");
789             return;
790         }
791 
792         if (Log.isLoggable(TAG, Log.DEBUG)) {
793             Slogf.d(TAG, "setInitialUserFromSystemServer: initial User: %s", user);
794         }
795 
796         synchronized (mLockUser) {
797             mInitialUser = user;
798         }
799     }
800 
sendInitialUserToSystemServer(UserHandle user)801     private void sendInitialUserToSystemServer(UserHandle user) {
802         ICarServiceHelper iCarServiceHelper;
803         synchronized (mLockUser) {
804             iCarServiceHelper = mICarServiceHelper;
805         }
806 
807         if (iCarServiceHelper == null) {
808             Slogf.e(TAG, "sendInitialUserToSystemServer: CarServiceHelper is NULL.");
809             return;
810         }
811 
812         try {
813             iCarServiceHelper.sendInitialUser(user);
814         } catch (RemoteException e) {
815             Slogf.e(TAG, "Error calling sendInitialUser.", e);
816         }
817     }
818 
initResumeReplaceGuest()819     private void initResumeReplaceGuest() {
820         int currentUserId = ActivityManager.getCurrentUser();
821         UserInfo currentUser = mUserManager.getUserInfo(currentUserId);
822 
823         if (!mInitialUserSetter.canReplaceGuestUser(currentUser)) return; // Not a guest
824 
825         InitialUserInfo info =
826                 new InitialUserSetter.Builder(InitialUserSetter.TYPE_REPLACE_GUEST).build();
827 
828         mInitialUserSetter.set(info);
829     }
830 
831     /**
832      * Calls to switch user at the power suspend.
833      *
834      * <p><b>Note:</b> Should be used only by {@link CarPowerManagementService}
835      *
836      */
onSuspend()837     public void onSuspend() {
838         if (Log.isLoggable(TAG, Log.DEBUG)) {
839             Slog.d(TAG, "onSuspend called.");
840         }
841 
842         if (mSwitchGuestUserBeforeSleep) {
843             initResumeReplaceGuest();
844         }
845 
846         preCreateUsersInternal();
847     }
848 
849     /**
850      * Calls to switch user at the power resume.
851      *
852      * <p>
853      * <b>Note:</b> Should be used only by {@link CarPowerManagementService}
854      *
855      */
onResume()856     public void onResume() {
857         if (Log.isLoggable(TAG, Log.DEBUG)) {
858             Slog.d(TAG, "onResume called.");
859         }
860 
861         mHandler.post(() -> initBootUser(InitialUserInfoRequestType.RESUME));
862     }
863 
864     /**
865      * Calls to start user at the android startup.
866      */
initBootUser()867     public void initBootUser() {
868         mHandler.post(() -> initBootUser(getInitialUserInfoRequestType()));
869     }
870 
initBootUser(int requestType)871     private void initBootUser(int requestType) {
872         boolean replaceGuest =
873                 requestType == InitialUserInfoRequestType.RESUME && !mSwitchGuestUserBeforeSleep;
874         checkManageUsersPermission("startInitialUser");
875 
876         if (!isUserHalSupported()) {
877             fallbackToDefaultInitialUserBehavior(/* userLocales= */ null, replaceGuest,
878                     /* supportsOverrideUserIdProperty= */ true);
879             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_REQ_COMPLETE,
880                     requestType);
881             return;
882         }
883 
884         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
885 
886         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_REQ, requestType,
887                 mHalTimeoutMs, usersInfo.currentUser.userId, usersInfo.currentUser.flags,
888                 usersInfo.numberUsers);
889 
890         mHal.getInitialUserInfo(requestType, mHalTimeoutMs, usersInfo, (status, resp) -> {
891             if (resp != null) {
892                 EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_RESP,
893                         status, resp.action, resp.userToSwitchOrCreate.userId,
894                         resp.userToSwitchOrCreate.flags, resp.userNameToCreate, resp.userLocales);
895 
896                 String userLocales = resp.userLocales;
897                 InitialUserInfo info;
898                 switch (resp.action) {
899                     case InitialUserInfoResponseAction.SWITCH:
900                         int userId = resp.userToSwitchOrCreate.userId;
901                         if (userId <= 0) {
902                             Slog.w(TAG, "invalid (or missing) user id sent by HAL: " + userId);
903                             fallbackToDefaultInitialUserBehavior(userLocales, replaceGuest,
904                                     /* supportsOverrideUserIdProperty= */ false);
905                             break;
906                         }
907                         info = new InitialUserSetter.Builder(InitialUserSetter.TYPE_SWITCH)
908                                 .setUserLocales(userLocales)
909                                 .setSwitchUserId(userId)
910                                 .setReplaceGuest(replaceGuest)
911                                 .build();
912                         mInitialUserSetter.set(info);
913                         break;
914 
915                     case InitialUserInfoResponseAction.CREATE:
916                         int halFlags = resp.userToSwitchOrCreate.flags;
917                         String userName =  resp.userNameToCreate;
918                         info = new InitialUserSetter.Builder(InitialUserSetter.TYPE_CREATE)
919                                 .setUserLocales(userLocales)
920                                 .setNewUserName(userName)
921                                 .setNewUserFlags(halFlags)
922                                 .build();
923                         mInitialUserSetter.set(info);
924                         break;
925 
926                     case InitialUserInfoResponseAction.DEFAULT:
927                         fallbackToDefaultInitialUserBehavior(userLocales, replaceGuest,
928                                 /* supportsOverrideUserIdProperty= */ false);
929                         break;
930                     default:
931                         Slog.w(TAG, "invalid response action on " + resp);
932                         fallbackToDefaultInitialUserBehavior(/* userLocales= */ null, replaceGuest,
933                                 /* supportsOverrideUserIdProperty= */ false);
934                         break;
935 
936                 }
937             } else {
938                 EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_RESP, status);
939                 fallbackToDefaultInitialUserBehavior(/* userLocales= */ null, replaceGuest,
940                         /* supportsOverrideUserIdProperty= */ false);
941             }
942             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_REQ_COMPLETE,
943                     requestType);
944         });
945     }
946 
fallbackToDefaultInitialUserBehavior(String userLocales, boolean replaceGuest, boolean supportsOverrideUserIdProperty)947     private void fallbackToDefaultInitialUserBehavior(String userLocales, boolean replaceGuest,
948             boolean supportsOverrideUserIdProperty) {
949         InitialUserInfo info = new InitialUserSetter.Builder(
950                 InitialUserSetter.TYPE_DEFAULT_BEHAVIOR)
951                 .setUserLocales(userLocales)
952                 .setReplaceGuest(replaceGuest)
953                 .setSupportsOverrideUserIdProperty(supportsOverrideUserIdProperty)
954                 .build();
955         mInitialUserSetter.set(info);
956     }
957 
958     @VisibleForTesting
getInitialUserInfoRequestType()959     int getInitialUserInfoRequestType() {
960         if (!mInitialUserSetter.hasInitialUser()) {
961             return InitialUserInfoRequestType.FIRST_BOOT;
962         }
963         if (mContext.getPackageManager().isDeviceUpgrading()) {
964             return InitialUserInfoRequestType.FIRST_BOOT_AFTER_OTA;
965         }
966         return InitialUserInfoRequestType.COLD_BOOT;
967     }
968 
969     /**
970      * Sets the {@link ICarServiceHelper} so it can receive UX restriction updates.
971      */
setCarServiceHelper(ICarServiceHelper helper)972     public void setCarServiceHelper(ICarServiceHelper helper) {
973         boolean restricted;
974         synchronized (mLockUser) {
975             mICarServiceHelper = helper;
976             restricted = mUxRestricted;
977         }
978         updateSafetyMode(helper, restricted);
979     }
980 
updateSafetyMode(@ullable ICarServiceHelper helper, boolean restricted)981     private void updateSafetyMode(@Nullable ICarServiceHelper helper, boolean restricted) {
982         if (helper == null) return;
983 
984         boolean isSafe = !restricted;
985         try {
986             helper.setSafetyMode(isSafe);
987         } catch (Exception e) {
988             Slog.e(TAG, "Exception calling helper.setDpmSafetyMode(" + isSafe + ")", e);
989         }
990     }
991 
setUxRestrictions(@ullable CarUxRestrictions restrictions)992     private void setUxRestrictions(@Nullable CarUxRestrictions restrictions) {
993         boolean restricted = restrictions != null
994                 && (restrictions.getActiveRestrictions() & UX_RESTRICTIONS_NO_SETUP)
995                         == UX_RESTRICTIONS_NO_SETUP;
996         if (Log.isLoggable(TAG, Log.DEBUG)) {
997             Slog.d(TAG, "setUxRestrictions(" + restrictions + "): restricted=" + restricted);
998         } else {
999             Slog.i(TAG, "Setting UX restricted to " + restricted);
1000         }
1001 
1002         ICarServiceHelper helper = null;
1003 
1004         synchronized (mLockUser) {
1005             mUxRestricted = restricted;
1006             if (mICarServiceHelper == null) {
1007                 Slog.e(TAG, "onUxRestrictionsChanged(): no mICarServiceHelper");
1008             }
1009             helper = mICarServiceHelper;
1010         }
1011         updateSafetyMode(helper, restricted);
1012     }
1013 
isUxRestricted()1014     private boolean isUxRestricted() {
1015         synchronized (mLockUser) {
1016             return mUxRestricted;
1017         }
1018     }
1019 
1020     /**
1021      * Calls the {@link UserHalService} and {@link IActivityManager} for user switch.
1022      *
1023      * <p>
1024      * When everything works well, the workflow is:
1025      * <ol>
1026      *   <li> {@link UserHalService} is called for HAL user switch with ANDROID_SWITCH request
1027      *   type, current user id, target user id, and a callback.
1028      *   <li> HAL called back with SUCCESS.
1029      *   <li> {@link IActivityManager} is called for Android user switch.
1030      *   <li> Receiver would receive {@code STATUS_SUCCESSFUL}.
1031      *   <li> Once user is unlocked, {@link UserHalService} is again called with ANDROID_POST_SWITCH
1032      *   request type, current user id, and target user id. In this case, the current and target
1033      *   user IDs would be same.
1034      * <ol/>
1035      *
1036      * <p>
1037      * Corner cases:
1038      * <ul>
1039      *   <li> If target user is already the current user, no user switch is performed and receiver
1040      *   would receive {@code STATUS_OK_USER_ALREADY_IN_FOREGROUND} right away.
1041      *   <li> If HAL user switch call fails, no Android user switch. Receiver would receive
1042      *   {@code STATUS_HAL_INTERNAL_FAILURE}.
1043      *   <li> If HAL user switch call is successful, but android user switch call fails,
1044      *   {@link UserHalService} is again called with request type POST_SWITCH, current user id, and
1045      *   target user id, but in this case the current and target user IDs would be different.
1046      *   <li> If another user switch request for the same target user is received while previous
1047      *   request is in process, receiver would receive
1048      *   {@code STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO} for the new request right away.
1049      *   <li> If a user switch request is received while another user switch request for different
1050      *   target user is in process, the previous request would be abandoned and new request will be
1051      *   processed. No POST_SWITCH would be sent for the previous request.
1052      * <ul/>
1053      *
1054      * @param targetUserId - target user Id
1055      * @param timeoutMs - timeout for HAL to wait
1056      * @param receiver - receiver for the results
1057      */
1058     @Override
switchUser(@serIdInt int targetUserId, int timeoutMs, @NonNull AndroidFuture<UserSwitchResult> receiver)1059     public void switchUser(@UserIdInt int targetUserId, int timeoutMs,
1060             @NonNull AndroidFuture<UserSwitchResult> receiver) {
1061         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_REQ, targetUserId, timeoutMs);
1062         checkManageOrCreateUsersPermission("switchUser");
1063         Objects.requireNonNull(receiver);
1064         UserInfo targetUser = mUserManager.getUserInfo(targetUserId);
1065         Preconditions.checkArgument(targetUser != null, "Target user doesn't exist");
1066         if (mUserManager.getUserSwitchability() != UserManager.SWITCHABILITY_STATUS_OK) {
1067             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_NOT_SWITCHABLE);
1068             return;
1069         }
1070         mHandler.post(() -> handleSwitchUser(targetUser, timeoutMs, receiver));
1071     }
1072 
handleSwitchUser(@onNull UserInfo targetUser, int timeoutMs, @NonNull AndroidFuture<UserSwitchResult> receiver)1073     private void handleSwitchUser(@NonNull UserInfo targetUser, int timeoutMs,
1074             @NonNull AndroidFuture<UserSwitchResult> receiver) {
1075         int currentUser = ActivityManager.getCurrentUser();
1076         int targetUserId = targetUser.id;
1077         if (currentUser == targetUserId) {
1078             if (Log.isLoggable(TAG, Log.DEBUG)) {
1079                 Slog.d(TAG, "Current user is same as requested target user: " + targetUserId);
1080             }
1081             int resultStatus = UserSwitchResult.STATUS_OK_USER_ALREADY_IN_FOREGROUND;
1082             sendUserSwitchResult(receiver, resultStatus);
1083             return;
1084         }
1085 
1086         if (isUxRestricted()) {
1087             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_UX_RESTRICTION_FAILURE);
1088             return;
1089         }
1090 
1091         // If User Hal is not supported, just android user switch.
1092         if (!isUserHalSupported()) {
1093             try {
1094                 if (mAm.switchUser(targetUserId)) {
1095                     sendUserSwitchResult(receiver, UserSwitchResult.STATUS_SUCCESSFUL);
1096                     return;
1097                 }
1098             } catch (RemoteException e) {
1099                 // ignore
1100                 Slog.w(TAG, "error while switching user " + targetUser.toFullString(), e);
1101             }
1102             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_ANDROID_FAILURE);
1103             return;
1104         }
1105 
1106         synchronized (mLockUser) {
1107             if (Log.isLoggable(TAG, Log.DEBUG)) {
1108                 Slog.d(TAG, "switchUser(" + targetUserId + "): currentuser=" + currentUser
1109                         + ", mUserIdForUserSwitchInProcess=" + mUserIdForUserSwitchInProcess);
1110             }
1111 
1112             // If there is another request for the same target user, return another request in
1113             // process, else {@link mUserIdForUserSwitchInProcess} is updated and {@link
1114             // mRequestIdForUserSwitchInProcess} is reset. It is possible that there may be another
1115             // user switch request in process for different target user, but that request is now
1116             // ignored.
1117             if (mUserIdForUserSwitchInProcess == targetUserId) {
1118                 if (Log.isLoggable(TAG, Log.DEBUG)) {
1119                     Slog.d(TAG,
1120                             "Another user switch request in process for the requested target user: "
1121                                     + targetUserId);
1122                 }
1123 
1124                 int resultStatus = UserSwitchResult.STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO;
1125                 sendUserSwitchResult(receiver, resultStatus);
1126                 return;
1127             } else {
1128                 mUserIdForUserSwitchInProcess = targetUserId;
1129                 mRequestIdForUserSwitchInProcess = 0;
1130             }
1131         }
1132 
1133         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
1134         SwitchUserRequest request = createUserSwitchRequest(targetUserId, usersInfo);
1135 
1136         mHal.switchUser(request, timeoutMs, (halCallbackStatus, resp) -> {
1137             if (Log.isLoggable(TAG, Log.DEBUG)) {
1138                 Slog.d(TAG, "switch response: status="
1139                         + UserHalHelper.halCallbackStatusToString(halCallbackStatus)
1140                         + ", resp=" + resp);
1141             }
1142 
1143             int resultStatus = UserSwitchResult.STATUS_HAL_INTERNAL_FAILURE;
1144 
1145             synchronized (mLockUser) {
1146                 if (halCallbackStatus != HalCallback.STATUS_OK) {
1147                     Slog.w(TAG, "invalid callback status ("
1148                             + UserHalHelper.halCallbackStatusToString(halCallbackStatus)
1149                             + ") for response " + resp);
1150                     sendUserSwitchResult(receiver, resultStatus);
1151                     mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
1152                     return;
1153                 }
1154 
1155                 if (mUserIdForUserSwitchInProcess != targetUserId) {
1156                     // Another user switch request received while HAL responded. No need to process
1157                     // this request further
1158                     if (Log.isLoggable(TAG, Log.DEBUG)) {
1159                         Slog.d(TAG, "Another user switch received while HAL responsed. Request"
1160                                 + " abondoned for : " + targetUserId + ". Current user in process: "
1161                                 + mUserIdForUserSwitchInProcess);
1162                     }
1163                     resultStatus =
1164                             UserSwitchResult.STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST;
1165                     sendUserSwitchResult(receiver, resultStatus);
1166                     mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
1167                     return;
1168                 }
1169 
1170                 switch (resp.status) {
1171                     case SwitchUserStatus.SUCCESS:
1172                         boolean switched;
1173                         try {
1174                             switched = mAm.switchUser(targetUserId);
1175                             if (switched) {
1176                                 sendUserSwitchUiCallback(targetUserId);
1177                                 resultStatus = UserSwitchResult.STATUS_SUCCESSFUL;
1178                                 mRequestIdForUserSwitchInProcess = resp.requestId;
1179                             } else {
1180                                 resultStatus = UserSwitchResult.STATUS_ANDROID_FAILURE;
1181                                 postSwitchHalResponse(resp.requestId, targetUserId);
1182                             }
1183                         } catch (RemoteException e) {
1184                             // ignore
1185                             Slog.w(TAG,
1186                                     "error while switching user " + targetUser.toFullString(), e);
1187                         }
1188                         break;
1189                     case SwitchUserStatus.FAILURE:
1190                         // HAL failed to switch user
1191                         resultStatus = UserSwitchResult.STATUS_HAL_FAILURE;
1192                         break;
1193                     default:
1194                         // Shouldn't happen because UserHalService validates the status
1195                         Slog.wtf(TAG, "Received invalid user switch status from HAL: " + resp);
1196                 }
1197 
1198                 if (mRequestIdForUserSwitchInProcess == 0) {
1199                     mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
1200                 }
1201             }
1202             sendUserSwitchResult(receiver, halCallbackStatus, resultStatus, resp.errorMessage);
1203         });
1204     }
1205 
1206     @Override
removeUser(@serIdInt int userId, AndroidFuture<UserRemovalResult> receiver)1207     public void removeUser(@UserIdInt int userId, AndroidFuture<UserRemovalResult> receiver) {
1208         removeUser(userId, /* hasCallerRestrictions= */ false, receiver);
1209     }
1210 
1211     /**
1212      * Internal implementation of {@code removeUser()}, which is used by both
1213      * {@code ICarUserService} and {@code ICarDevicePolicyService}.
1214      *
1215      * @param userId user to be removed
1216      * @param hasCallerRestrictions when {@code true}, if the caller user is not an admin, it can
1217      * only remove itself.
1218      * @param receiver to post results
1219      */
removeUser(@serIdInt int userId, boolean hasCallerRestrictions, AndroidFuture<UserRemovalResult> receiver)1220     public void removeUser(@UserIdInt int userId, boolean hasCallerRestrictions,
1221             AndroidFuture<UserRemovalResult> receiver) {
1222         checkManageOrCreateUsersPermission("removeUser");
1223         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_REQ, userId,
1224                 hasCallerRestrictions ? 1 : 0);
1225 
1226         if (hasCallerRestrictions) {
1227             // Restrictions: non-admin user can only remove itself, admins have no restrictions
1228             int callingUserId = Binder.getCallingUserHandle().getIdentifier();
1229             UserInfo callingUser = mUserManager.getUserInfo(callingUserId);
1230             if (!callingUser.isAdmin() && userId != callingUserId) {
1231                 throw new SecurityException("Non-admin user " + callingUserId
1232                         + " can only remove itself");
1233             }
1234         }
1235         mHandler.post(() -> handleRemoveUser(userId, hasCallerRestrictions, receiver));
1236     }
1237 
handleRemoveUser(@serIdInt int userId, boolean hasCallerRestrictions, AndroidFuture<UserRemovalResult> receiver)1238     private void handleRemoveUser(@UserIdInt int userId, boolean hasCallerRestrictions,
1239             AndroidFuture<UserRemovalResult> receiver) {
1240         UserInfo userInfo = mUserManager.getUserInfo(userId);
1241         if (userInfo == null) {
1242             sendUserRemovalResult(userId, UserRemovalResult.STATUS_USER_DOES_NOT_EXIST, receiver);
1243             return;
1244         }
1245         android.hardware.automotive.vehicle.V2_0.UserInfo halUser =
1246                 new android.hardware.automotive.vehicle.V2_0.UserInfo();
1247         halUser.userId = userInfo.id;
1248         halUser.flags = UserHalHelper.convertFlags(userInfo);
1249         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
1250 
1251         // check if the user is last admin user.
1252         boolean isLastAdmin = false;
1253         if (UserHalHelper.isAdmin(halUser.flags)) {
1254             int size = usersInfo.existingUsers.size();
1255             int totalAdminUsers = 0;
1256             for (int i = 0; i < size; i++) {
1257                 if (UserHalHelper.isAdmin(usersInfo.existingUsers.get(i).flags)) {
1258                     totalAdminUsers++;
1259                 }
1260             }
1261             if (totalAdminUsers == 1) {
1262                 isLastAdmin = true;
1263             }
1264         }
1265 
1266         // First remove user from android and then remove from HAL because HAL remove user is one
1267         // way call.
1268         // TODO(b/170887769): rename hasCallerRestrictions to fromCarDevicePolicyManager (or use an
1269         // int / enum to indicate if it's called from CarUserManager or CarDevicePolicyManager), as
1270         // it's counter-intuitive that it's "allowed even when disallowed" when it
1271         // "has caller restrictions"
1272         boolean evenWhenDisallowed = hasCallerRestrictions;
1273         int result = mUserManager.removeUserOrSetEphemeral(userId, evenWhenDisallowed);
1274         if (result == UserManager.REMOVE_RESULT_ERROR) {
1275             sendUserRemovalResult(userId, UserRemovalResult.STATUS_ANDROID_FAILURE, receiver);
1276             return;
1277         }
1278 
1279         if (isLastAdmin) {
1280             Slog.w(TAG,
1281                     "Last admin user successfully removed or set ephemeral. User Id: " + userId);
1282         }
1283 
1284         switch (result) {
1285             case UserManager.REMOVE_RESULT_REMOVED:
1286             case UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED:
1287                 sendUserRemovalResult(userId,
1288                         isLastAdmin ? UserRemovalResult.STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED
1289                                 : UserRemovalResult.STATUS_SUCCESSFUL, receiver);
1290             case UserManager.REMOVE_RESULT_SET_EPHEMERAL:
1291                 sendUserRemovalResult(userId,
1292                         isLastAdmin ? UserRemovalResult.STATUS_SUCCESSFUL_LAST_ADMIN_SET_EPHEMERAL
1293                                 : UserRemovalResult.STATUS_SUCCESSFUL_SET_EPHEMERAL, receiver);
1294             default:
1295                 sendUserRemovalResult(userId, UserRemovalResult.STATUS_ANDROID_FAILURE, receiver);
1296         }
1297     }
1298 
1299     /**
1300      * Should be called by {@code ICarImpl} only.
1301      */
onUserRemoved(@onNull UserInfo user)1302     public void onUserRemoved(@NonNull UserInfo user) {
1303         if (Log.isLoggable(TAG, Log.DEBUG)) {
1304             Slog.d(TAG, "onUserRemoved: " + user.toFullString());
1305         }
1306         notifyHalUserRemoved(user);
1307     }
1308 
notifyHalUserRemoved(@onNull UserInfo user)1309     private void notifyHalUserRemoved(@NonNull UserInfo user) {
1310         if (!isUserHalSupported()) return;
1311 
1312         if (user == null) {
1313             Slog.wtf(TAG, "notifyHalUserRemoved() called for null user");
1314             return;
1315         }
1316 
1317         int userId = user.id;
1318 
1319         if (userId == UserHandle.USER_NULL) {
1320             Slog.wtf(TAG, "notifyHalUserRemoved() called for UserHandle.USER_NULL");
1321             return;
1322         }
1323 
1324         synchronized (mLockUser) {
1325             if (mFailedToCreateUserIds.get(userId)) {
1326                 if (Log.isLoggable(TAG, Log.DEBUG)) {
1327                     Slog.d(TAG, "notifyHalUserRemoved(): skipping " + userId);
1328                 }
1329                 mFailedToCreateUserIds.delete(userId);
1330                 return;
1331             }
1332         }
1333 
1334         android.hardware.automotive.vehicle.V2_0.UserInfo halUser =
1335                 new android.hardware.automotive.vehicle.V2_0.UserInfo();
1336         halUser.userId = userId;
1337         halUser.flags = UserHalHelper.convertFlags(user);
1338 
1339         RemoveUserRequest request = new RemoveUserRequest();
1340         request.removedUserInfo = halUser;
1341         request.usersInfo = UserHalHelper.newUsersInfo(mUserManager);
1342         mHal.removeUser(request);
1343     }
1344 
sendUserRemovalResult(@serIdInt int userId, @UserRemovalResult.Status int result, AndroidFuture<UserRemovalResult> receiver)1345     private void sendUserRemovalResult(@UserIdInt int userId, @UserRemovalResult.Status int result,
1346             AndroidFuture<UserRemovalResult> receiver) {
1347         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_RESP, userId, result);
1348         receiver.complete(new UserRemovalResult(result));
1349     }
1350 
sendUserSwitchUiCallback(@serIdInt int targetUserId)1351     private void sendUserSwitchUiCallback(@UserIdInt int targetUserId) {
1352         if (mUserSwitchUiReceiver == null) {
1353             Slog.w(TAG, "No User switch UI receiver.");
1354             return;
1355         }
1356 
1357         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_UI_REQ, targetUserId);
1358         try {
1359             mUserSwitchUiReceiver.send(targetUserId, null);
1360         } catch (RemoteException e) {
1361             Slog.e(TAG, "Error calling user switch UI receiver.", e);
1362         }
1363     }
1364 
1365     /**
1366      * Used to create the initial user, even when it's disallowed by {@code DevicePolicyManager}.
1367      */
1368     @Nullable
createUserEvenWhenDisallowed(@ullable String name, @NonNull String userType, @UserInfoFlag int flags)1369     UserInfo createUserEvenWhenDisallowed(@Nullable String name, @NonNull String userType,
1370             @UserInfoFlag int flags) {
1371         if (mICarServiceHelper == null) {
1372             Slog.wtf(TAG, "createUserEvenWhenDisallowed(): mICarServiceHelper not set yet",
1373                     new Exception());
1374             return null;
1375         }
1376         try {
1377             return mICarServiceHelper.createUserEvenWhenDisallowed(name, userType, flags);
1378         } catch (RemoteException e) {
1379             Slog.e(TAG, "createUserEvenWhenDisallowed(" + UserHelperLite.safeName(name) + ", "
1380                     + userType + ", " + UserInfo.flagsToString(flags) + ") failed", e);
1381             return null;
1382         }
1383     }
1384 
1385     @Override
createUser(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, int timeoutMs, @NonNull AndroidFuture<UserCreationResult> receiver)1386     public void createUser(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
1387             int timeoutMs, @NonNull AndroidFuture<UserCreationResult> receiver) {
1388         createUser(name, userType, flags, timeoutMs, receiver, /* hasCallerRestrictions= */ false);
1389     }
1390 
1391     /**
1392      * Internal implementation of {@code createUser()}, which is used by both
1393      * {@code ICarUserService} and {@code ICarDevicePolicyService}.
1394      *
1395      * @param hasCallerRestrictions when {@code true}, if the caller user is not an admin, it can
1396      * only create admin users
1397      */
createUser(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, int timeoutMs, @NonNull AndroidFuture<UserCreationResult> receiver, boolean hasCallerRestrictions)1398     public void createUser(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
1399             int timeoutMs, @NonNull AndroidFuture<UserCreationResult> receiver,
1400             boolean hasCallerRestrictions) {
1401         Objects.requireNonNull(userType, "user type cannot be null");
1402         Objects.requireNonNull(receiver, "receiver cannot be null");
1403         checkManageOrCreateUsersPermission(flags);
1404         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_REQ,
1405                 UserHelperLite.safeName(name), userType, flags, timeoutMs,
1406                 hasCallerRestrictions ? 1 : 0);
1407         mHandler.post(() -> handleCreateUser(name, userType, flags, timeoutMs, receiver,
1408                 hasCallerRestrictions));
1409 
1410     }
1411 
handleCreateUser(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, int timeoutMs, @NonNull AndroidFuture<UserCreationResult> receiver, boolean hasCallerRestrictions)1412     private void handleCreateUser(@Nullable String name, @NonNull String userType,
1413             @UserInfoFlag int flags, int timeoutMs,
1414             @NonNull AndroidFuture<UserCreationResult> receiver,
1415             boolean hasCallerRestrictions) {
1416         if (hasCallerRestrictions) {
1417             // Restrictions:
1418             // - type/flag can only be normal user, admin, or guest
1419             // - non-admin user can only create non-admin users
1420 
1421             boolean validCombination;
1422             switch (userType) {
1423                 case UserManager.USER_TYPE_FULL_SECONDARY:
1424                     validCombination = flags == 0
1425                         || (flags & UserInfo.FLAG_ADMIN) == UserInfo.FLAG_ADMIN;
1426                     break;
1427                 case UserManager.USER_TYPE_FULL_GUEST:
1428                     validCombination = flags == 0;
1429                     break;
1430                 default:
1431                     validCombination = false;
1432             }
1433             if (!validCombination) {
1434                 if (Log.isLoggable(TAG, Log.DEBUG)) {
1435                     Slog.d(TAG, "Invalid combination of user type(" + userType
1436                             + ") and flags (" + UserInfo.flagsToString(flags)
1437                             + ") for caller with restrictions");
1438                 }
1439                 sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_INVALID_REQUEST);
1440                 return;
1441 
1442             }
1443 
1444             int callingUserId = Binder.getCallingUserHandle().getIdentifier();
1445             UserInfo callingUser = mUserManager.getUserInfo(callingUserId);
1446             if (!callingUser.isAdmin() && (flags & UserInfo.FLAG_ADMIN) == UserInfo.FLAG_ADMIN) {
1447                 if (Log.isLoggable(TAG, Log.DEBUG)) {
1448                     Slog.d(TAG, "Non-admin user " + callingUserId
1449                             + " can only create non-admin users");
1450                 }
1451                 sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_INVALID_REQUEST);
1452                 return;
1453             }
1454 
1455         }
1456 
1457         UserInfo newUser;
1458         try {
1459             newUser = mUserManager.createUser(name, userType, flags);
1460             if (newUser == null) {
1461                 Slog.w(TAG, "um.createUser() returned null for user of type " + userType
1462                         + " and flags " + UserInfo.flagsToString(flags));
1463                 sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_ANDROID_FAILURE);
1464                 return;
1465             }
1466             if (Log.isLoggable(TAG, Log.DEBUG)) {
1467                 Slog.d(TAG, "Created user: " + newUser.toFullString());
1468             }
1469             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_USER_CREATED, newUser.id,
1470                     UserHelperLite.safeName(newUser.name), newUser.userType, newUser.flags);
1471         } catch (RuntimeException e) {
1472             Slog.e(TAG, "Error creating user of type " + userType + " and flags"
1473                     + UserInfo.flagsToString(flags), e);
1474             sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_ANDROID_FAILURE);
1475             return;
1476         }
1477 
1478         if (!isUserHalSupported()) {
1479             sendUserCreationResult(receiver, UserCreationResult.STATUS_SUCCESSFUL, newUser, null);
1480             return;
1481         }
1482 
1483         CreateUserRequest request = new CreateUserRequest();
1484         request.usersInfo = UserHalHelper.newUsersInfo(mUserManager);
1485         if (!TextUtils.isEmpty(name)) {
1486             request.newUserName = name;
1487         }
1488         request.newUserInfo.userId = newUser.id;
1489         request.newUserInfo.flags = UserHalHelper.convertFlags(newUser);
1490         if (Log.isLoggable(TAG, Log.DEBUG)) {
1491             Slog.d(TAG, "Create user request: " + request);
1492         }
1493 
1494         try {
1495             mHal.createUser(request, timeoutMs, (status, resp) -> {
1496                 int resultStatus = UserCreationResult.STATUS_HAL_INTERNAL_FAILURE;
1497                 if (Log.isLoggable(TAG, Log.DEBUG)) {
1498                     Slog.d(TAG, "createUserResponse: status="
1499                             + UserHalHelper.halCallbackStatusToString(status) + ", resp=" + resp);
1500                 }
1501                 UserInfo user = null; // user returned in the result
1502                 if (status != HalCallback.STATUS_OK) {
1503                     Slog.w(TAG, "invalid callback status ("
1504                             + UserHalHelper.halCallbackStatusToString(status) + ") for response "
1505                             + resp);
1506                     EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_RESP, status,
1507                             resultStatus, resp.errorMessage);
1508                     removeCreatedUser(newUser, "HAL call failed with "
1509                             + UserHalHelper.halCallbackStatusToString(status));
1510                     sendUserCreationResult(receiver, resultStatus, user, /* errorMsg= */ null);
1511                     return;
1512                 }
1513 
1514                 switch (resp.status) {
1515                     case CreateUserStatus.SUCCESS:
1516                         resultStatus = UserCreationResult.STATUS_SUCCESSFUL;
1517                         user = newUser;
1518                         break;
1519                     case CreateUserStatus.FAILURE:
1520                         // HAL failed to switch user
1521                         resultStatus = UserCreationResult.STATUS_HAL_FAILURE;
1522                         break;
1523                     default:
1524                         // Shouldn't happen because UserHalService validates the status
1525                         Slog.wtf(TAG, "Received invalid user switch status from HAL: " + resp);
1526                 }
1527                 EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_RESP, status,
1528                         resultStatus, resp.errorMessage);
1529                 if (user == null) {
1530                     removeCreatedUser(newUser, "HAL returned "
1531                             + UserCreationResult.statusToString(resultStatus));
1532                 }
1533                 sendUserCreationResult(receiver, resultStatus, user, resp.errorMessage);
1534             });
1535         } catch (Exception e) {
1536             Slog.w(TAG, "mHal.createUser(" + request + ") failed", e);
1537             removeCreatedUser(newUser, "mHal.createUser() failed");
1538             sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_HAL_INTERNAL_FAILURE);
1539         }
1540     }
1541 
removeCreatedUser(@onNull UserInfo user, @NonNull String reason)1542     private void removeCreatedUser(@NonNull UserInfo user, @NonNull String reason) {
1543         Slog.i(TAG, "removing " + user.toFullString() + "; reason: " + reason);
1544 
1545         int userId = user.id;
1546         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_USER_REMOVED, userId, reason);
1547 
1548         synchronized (mLockUser) {
1549             mFailedToCreateUserIds.put(userId, true);
1550         }
1551 
1552         try {
1553             if (!mUserManager.removeUser(userId)) {
1554                 Slog.w(TAG, "Failed to remove user " + user.toFullString());
1555             }
1556         } catch (Exception e) {
1557             Slog.e(TAG, "Failed to remove user " + user.toFullString(), e);
1558         }
1559     }
1560 
1561     @Override
getUserIdentificationAssociation( @serIdentificationAssociationType int[] types)1562     public UserIdentificationAssociationResponse getUserIdentificationAssociation(
1563             @UserIdentificationAssociationType int[] types) {
1564         if (!isUserHalUserAssociationSupported()) {
1565             return UserIdentificationAssociationResponse.forFailure(VEHICLE_HAL_NOT_SUPPORTED);
1566         }
1567 
1568         Preconditions.checkArgument(!ArrayUtils.isEmpty(types), "must have at least one type");
1569         checkManageOrCreateUsersPermission("getUserIdentificationAssociation");
1570 
1571         int uid = getCallingUid();
1572         int userId = UserHandle.getUserId(uid);
1573         EventLog.writeEvent(EventLogTags.CAR_USER_MGR_GET_USER_AUTH_REQ, uid, userId);
1574 
1575         UserIdentificationGetRequest request = new UserIdentificationGetRequest();
1576         request.userInfo.userId = userId;
1577         request.userInfo.flags = getHalUserInfoFlags(userId);
1578 
1579         request.numberAssociationTypes = types.length;
1580         for (int i = 0; i < types.length; i++) {
1581             request.associationTypes.add(types[i]);
1582         }
1583 
1584         UserIdentificationResponse halResponse = mHal.getUserAssociation(request);
1585         if (halResponse == null) {
1586             Slog.w(TAG, "getUserIdentificationAssociation(): HAL returned null for "
1587                     + Arrays.toString(types));
1588             return UserIdentificationAssociationResponse.forFailure();
1589         }
1590 
1591         int[] values = new int[halResponse.associations.size()];
1592         for (int i = 0; i < values.length; i++) {
1593             values[i] = halResponse.associations.get(i).value;
1594         }
1595         EventLog.writeEvent(EventLogTags.CAR_USER_MGR_GET_USER_AUTH_RESP, values.length);
1596 
1597         return UserIdentificationAssociationResponse.forSuccess(values, halResponse.errorMessage);
1598     }
1599 
1600     @Override
setUserIdentificationAssociation(int timeoutMs, @UserIdentificationAssociationType int[] types, @UserIdentificationAssociationSetValue int[] values, AndroidFuture<UserIdentificationAssociationResponse> result)1601     public void setUserIdentificationAssociation(int timeoutMs,
1602             @UserIdentificationAssociationType int[] types,
1603             @UserIdentificationAssociationSetValue int[] values,
1604             AndroidFuture<UserIdentificationAssociationResponse> result) {
1605         if (!isUserHalUserAssociationSupported()) {
1606             result.complete(
1607                     UserIdentificationAssociationResponse.forFailure(VEHICLE_HAL_NOT_SUPPORTED));
1608             return;
1609         }
1610 
1611         Preconditions.checkArgument(!ArrayUtils.isEmpty(types), "must have at least one type");
1612         Preconditions.checkArgument(!ArrayUtils.isEmpty(values), "must have at least one value");
1613         if (types.length != values.length) {
1614             throw new IllegalArgumentException("types (" + Arrays.toString(types) + ") and values ("
1615                     + Arrays.toString(values) + ") should have the same length");
1616         }
1617         checkManageOrCreateUsersPermission("setUserIdentificationAssociation");
1618 
1619         int uid = getCallingUid();
1620         int userId = UserHandle.getUserId(uid);
1621         EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_REQ, uid, userId, types.length);
1622 
1623         UserIdentificationSetRequest request = new UserIdentificationSetRequest();
1624         request.userInfo.userId = userId;
1625         request.userInfo.flags = getHalUserInfoFlags(userId);
1626 
1627         request.numberAssociations = types.length;
1628         for (int i = 0; i < types.length; i++) {
1629             UserIdentificationSetAssociation association = new UserIdentificationSetAssociation();
1630             association.type = types[i];
1631             association.value = values[i];
1632             request.associations.add(association);
1633         }
1634 
1635         mHal.setUserAssociation(timeoutMs, request, (status, resp) -> {
1636             if (status != HalCallback.STATUS_OK) {
1637                 Slog.w(TAG, "setUserIdentificationAssociation(): invalid callback status ("
1638                         + UserHalHelper.halCallbackStatusToString(status) + ") for response "
1639                         + resp);
1640                 if (resp == null || TextUtils.isEmpty(resp.errorMessage)) {
1641                     EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_RESP, 0);
1642                     result.complete(UserIdentificationAssociationResponse.forFailure());
1643                     return;
1644                 }
1645                 EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_RESP, 0,
1646                         resp.errorMessage);
1647                 result.complete(
1648                         UserIdentificationAssociationResponse.forFailure(resp.errorMessage));
1649                 return;
1650             }
1651             int respSize = resp.associations.size();
1652             EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_RESP, respSize,
1653                     resp.errorMessage);
1654 
1655             int[] responseTypes = new int[respSize];
1656             for (int i = 0; i < respSize; i++) {
1657                 responseTypes[i] = resp.associations.get(i).value;
1658             }
1659             UserIdentificationAssociationResponse response = UserIdentificationAssociationResponse
1660                     .forSuccess(responseTypes, resp.errorMessage);
1661             if (Log.isLoggable(TAG, Log.DEBUG)) {
1662                 Slog.d(TAG, "setUserIdentificationAssociation(): resp= " + resp
1663                         + ", converted=" + response);
1664             }
1665             result.complete(response);
1666         });
1667     }
1668 
1669     /**
1670      * Gets the User HAL flags for the given user.
1671      *
1672      * @throws IllegalArgumentException if the user does not exist.
1673      */
getHalUserInfoFlags(@serIdInt int userId)1674     private int getHalUserInfoFlags(@UserIdInt int userId) {
1675         UserInfo user = mUserManager.getUserInfo(userId);
1676         Preconditions.checkArgument(user != null, "no user for id %d", userId);
1677         return UserHalHelper.convertFlags(user);
1678     }
1679 
sendResult(@onNull IResultReceiver receiver, int resultCode, @Nullable Bundle resultData)1680     private void sendResult(@NonNull IResultReceiver receiver, int resultCode,
1681             @Nullable Bundle resultData) {
1682         try {
1683             receiver.send(resultCode, resultData);
1684         } catch (RemoteException e) {
1685             // ignore
1686             Slog.w(TAG, "error while sending results", e);
1687         }
1688     }
1689 
sendUserSwitchResult(@onNull AndroidFuture<UserSwitchResult> receiver, @UserSwitchResult.Status int userSwitchStatus)1690     private void sendUserSwitchResult(@NonNull AndroidFuture<UserSwitchResult> receiver,
1691             @UserSwitchResult.Status int userSwitchStatus) {
1692         sendUserSwitchResult(receiver, HalCallback.STATUS_INVALID, userSwitchStatus,
1693                 /* errorMessage= */ null);
1694     }
1695 
sendUserSwitchResult(@onNull AndroidFuture<UserSwitchResult> receiver, @HalCallback.HalCallbackStatus int halCallbackStatus, @UserSwitchResult.Status int userSwitchStatus, @Nullable String errorMessage)1696     private void sendUserSwitchResult(@NonNull AndroidFuture<UserSwitchResult> receiver,
1697             @HalCallback.HalCallbackStatus int halCallbackStatus,
1698             @UserSwitchResult.Status int userSwitchStatus, @Nullable String errorMessage) {
1699         if (errorMessage != null) {
1700             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_RESP, halCallbackStatus,
1701                     userSwitchStatus, errorMessage);
1702         } else {
1703             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_RESP, halCallbackStatus,
1704                     userSwitchStatus);
1705         }
1706         receiver.complete(new UserSwitchResult(userSwitchStatus, errorMessage));
1707     }
1708 
sendUserCreationResultFailure(@onNull AndroidFuture<UserCreationResult> receiver, @UserCreationResult.Status int status)1709     private void sendUserCreationResultFailure(@NonNull AndroidFuture<UserCreationResult> receiver,
1710             @UserCreationResult.Status int status) {
1711         sendUserCreationResult(receiver, status, /* user= */ null, /* errorMessage= */ null);
1712     }
1713 
sendUserCreationResult(@onNull AndroidFuture<UserCreationResult> receiver, @UserCreationResult.Status int status, @NonNull UserInfo user, @Nullable String errorMessage)1714     private void sendUserCreationResult(@NonNull AndroidFuture<UserCreationResult> receiver,
1715             @UserCreationResult.Status int status, @NonNull UserInfo user,
1716             @Nullable String errorMessage) {
1717         if (TextUtils.isEmpty(errorMessage)) {
1718             errorMessage = null;
1719         }
1720         receiver.complete(new UserCreationResult(status, user, errorMessage));
1721     }
1722 
1723     /**
1724      * Calls activity manager for user switch.
1725      *
1726      * <p><b>NOTE</b> This method is meant to be called just by UserHalService.
1727      *
1728      * @param requestId for the user switch request
1729      * @param targetUserId of the target user
1730      *
1731      * @hide
1732      */
switchAndroidUserFromHal(int requestId, @UserIdInt int targetUserId)1733     public void switchAndroidUserFromHal(int requestId, @UserIdInt int targetUserId) {
1734         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_FROM_HAL_REQ, requestId,
1735                 targetUserId);
1736         Slog.i(TAG, "User hal requested a user switch. Target user id " + targetUserId);
1737 
1738         try {
1739             boolean result = mAm.switchUser(targetUserId);
1740             if (result) {
1741                 updateUserSwitchInProcess(requestId, targetUserId);
1742             } else {
1743                 postSwitchHalResponse(requestId, targetUserId);
1744             }
1745         } catch (RemoteException e) {
1746             // ignore
1747             Slog.w(TAG, "error while switching user " + targetUserId, e);
1748         }
1749     }
1750 
updateUserSwitchInProcess(int requestId, @UserIdInt int targetUserId)1751     private void updateUserSwitchInProcess(int requestId, @UserIdInt int targetUserId) {
1752         synchronized (mLockUser) {
1753             if (mUserIdForUserSwitchInProcess != UserHandle.USER_NULL) {
1754                 // Some other user switch is in process.
1755                 if (Log.isLoggable(TAG, Log.DEBUG)) {
1756                     Slog.d(TAG, "User switch for user: " + mUserIdForUserSwitchInProcess
1757                             + " is in process. Abandoning it as a new user switch is requested"
1758                             + " for the target user: " + targetUserId);
1759                 }
1760             }
1761             mUserIdForUserSwitchInProcess = targetUserId;
1762             mRequestIdForUserSwitchInProcess = requestId;
1763         }
1764     }
1765 
postSwitchHalResponse(int requestId, @UserIdInt int targetUserId)1766     private void postSwitchHalResponse(int requestId, @UserIdInt int targetUserId) {
1767         if (!isUserHalSupported()) return;
1768 
1769         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
1770         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_POST_SWITCH_USER_REQ, requestId,
1771                 targetUserId, usersInfo.currentUser.userId);
1772         SwitchUserRequest request = createUserSwitchRequest(targetUserId, usersInfo);
1773         request.requestId = requestId;
1774         mHal.postSwitchResponse(request);
1775     }
1776 
createUserSwitchRequest(@serIdInt int targetUserId, @NonNull UsersInfo usersInfo)1777     private SwitchUserRequest createUserSwitchRequest(@UserIdInt int targetUserId,
1778             @NonNull UsersInfo usersInfo) {
1779         UserInfo targetUser = mUserManager.getUserInfo(targetUserId);
1780         android.hardware.automotive.vehicle.V2_0.UserInfo halTargetUser =
1781                 new android.hardware.automotive.vehicle.V2_0.UserInfo();
1782         halTargetUser.userId = targetUser.id;
1783         halTargetUser.flags = UserHalHelper.convertFlags(targetUser);
1784         SwitchUserRequest request = new SwitchUserRequest();
1785         request.targetUser = halTargetUser;
1786         request.usersInfo = usersInfo;
1787         return request;
1788     }
1789 
1790     /**
1791      * Checks if the User HAL is supported.
1792      */
isUserHalSupported()1793     public boolean isUserHalSupported() {
1794         return mHal.isSupported();
1795     }
1796 
1797     /**
1798      * Checks if the User HAL user association is supported.
1799      */
1800     @Override
isUserHalUserAssociationSupported()1801     public boolean isUserHalUserAssociationSupported() {
1802         return mHal.isUserAssociationSupported();
1803     }
1804 
1805     /**
1806      * Sets a callback which is invoked before user switch.
1807      *
1808      * <p>
1809      * This method should only be called by the Car System UI. The purpose of this call is to notify
1810      * Car System UI to show the user switch UI before the user switch.
1811      */
1812     @Override
setUserSwitchUiCallback(@onNull IResultReceiver receiver)1813     public void setUserSwitchUiCallback(@NonNull IResultReceiver receiver) {
1814         checkManageUsersPermission("setUserSwitchUiCallback");
1815 
1816         // Confirm that caller is system UI.
1817         String systemUiPackageName = getSystemUiPackageName();
1818         if (systemUiPackageName == null) {
1819             throw new IllegalStateException("System UI package not found.");
1820         }
1821 
1822         try {
1823             int systemUiUid = mContext
1824                     .createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0).getPackageManager()
1825                     .getPackageUid(systemUiPackageName, PackageManager.MATCH_SYSTEM_ONLY);
1826             int callerUid = Binder.getCallingUid();
1827             if (systemUiUid != callerUid) {
1828                 throw new SecurityException("Invalid caller. Only" + systemUiPackageName
1829                         + " is allowed to make this call");
1830             }
1831         } catch (NameNotFoundException e) {
1832             throw new IllegalStateException("Package " + systemUiPackageName + " not found.");
1833         }
1834 
1835         mUserSwitchUiReceiver = receiver;
1836     }
1837 
1838     // TODO(157082995): This information can be taken from
1839     // PackageManageInternalImpl.getSystemUiServiceComponent
1840     @Nullable
getSystemUiPackageName()1841     private String getSystemUiPackageName() {
1842         try {
1843             ComponentName componentName = ComponentName.unflattenFromString(mContext.getResources()
1844                     .getString(com.android.internal.R.string.config_systemUIServiceComponent));
1845             return componentName.getPackageName();
1846         } catch (RuntimeException e) {
1847             Slog.w(TAG, "error while getting system UI package name.", e);
1848             return null;
1849         }
1850     }
1851 
updateDefaultUserRestriction()1852     private void updateDefaultUserRestriction() {
1853         // We want to set restrictions on system and guest users only once. These are persisted
1854         // onto disk, so it's sufficient to do it once + we minimize the number of disk writes.
1855         if (Settings.Global.getInt(mContext.getContentResolver(),
1856                 CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, /* default= */ 0) != 0) {
1857             return;
1858         }
1859         // Only apply the system user restrictions if the system user is headless.
1860         if (UserManager.isHeadlessSystemUserMode()) {
1861             setSystemUserRestrictions();
1862         }
1863         Settings.Global.putInt(mContext.getContentResolver(),
1864                 CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, 1);
1865     }
1866 
isPersistentUser(@serIdInt int userId)1867     private boolean isPersistentUser(@UserIdInt int userId) {
1868         return !mUserManager.getUserInfo(userId).isEphemeral();
1869     }
1870 
1871     /**
1872      * Adds a new {@link UserLifecycleListener} to listen to user activity events.
1873      */
addUserLifecycleListener(@onNull UserLifecycleListener listener)1874     public void addUserLifecycleListener(@NonNull UserLifecycleListener listener) {
1875         Objects.requireNonNull(listener, "listener cannot be null");
1876         mHandler.post(() -> mUserLifecycleListeners.add(listener));
1877     }
1878 
1879     /**
1880      * Removes previously added {@link UserLifecycleListener}.
1881      */
removeUserLifecycleListener(@onNull UserLifecycleListener listener)1882     public void removeUserLifecycleListener(@NonNull UserLifecycleListener listener) {
1883         Objects.requireNonNull(listener, "listener cannot be null");
1884         mHandler.post(() -> mUserLifecycleListeners.remove(listener));
1885     }
1886 
1887     /** Adds callback to listen to passenger activity events. */
addPassengerCallback(@onNull PassengerCallback callback)1888     public void addPassengerCallback(@NonNull PassengerCallback callback) {
1889         Objects.requireNonNull(callback, "callback cannot be null");
1890         mPassengerCallbacks.add(callback);
1891     }
1892 
1893     /** Removes previously added callback to listen passenger events. */
removePassengerCallback(@onNull PassengerCallback callback)1894     public void removePassengerCallback(@NonNull PassengerCallback callback) {
1895         Objects.requireNonNull(callback, "callback cannot be null");
1896         mPassengerCallbacks.remove(callback);
1897     }
1898 
1899     /** Sets the implementation of ZoneUserBindingHelper. */
setZoneUserBindingHelper(@onNull ZoneUserBindingHelper helper)1900     public void setZoneUserBindingHelper(@NonNull ZoneUserBindingHelper helper) {
1901         synchronized (mLockHelper) {
1902             mZoneUserBindingHelper = helper;
1903         }
1904     }
1905 
onUserUnlocked(@serIdInt int userId)1906     private void onUserUnlocked(@UserIdInt int userId) {
1907         ArrayList<Runnable> tasks = null;
1908         synchronized (mLockUser) {
1909             sendPostSwitchToHalLocked(userId);
1910             if (userId == UserHandle.USER_SYSTEM) {
1911                 if (!mUser0Unlocked) { // user 0, unlocked, do this only once
1912                     updateDefaultUserRestriction();
1913                     tasks = new ArrayList<>(mUser0UnlockTasks);
1914                     mUser0UnlockTasks.clear();
1915                     mUser0Unlocked = true;
1916                 }
1917             } else { // none user0
1918                 Integer user = userId;
1919                 if (isPersistentUser(userId)) {
1920                     // current foreground user should stay in top priority.
1921                     if (userId == ActivityManager.getCurrentUser()) {
1922                         mBackgroundUsersToRestart.remove(user);
1923                         mBackgroundUsersToRestart.add(0, user);
1924                     }
1925                     // -1 for user 0
1926                     if (mBackgroundUsersToRestart.size() > (mMaxRunningUsers - 1)) {
1927                         int userToDrop = mBackgroundUsersToRestart.get(
1928                                 mBackgroundUsersToRestart.size() - 1);
1929                         Slog.i(TAG, "New user unlocked:" + userId
1930                                 + ", dropping least recently user from restart list:" + userToDrop);
1931                         // Drop the least recently used user.
1932                         mBackgroundUsersToRestart.remove(mBackgroundUsersToRestart.size() - 1);
1933                     }
1934                 }
1935             }
1936         }
1937         if (tasks != null && tasks.size() > 0) {
1938             Slog.d(TAG, "User0 unlocked, run queued tasks:" + tasks.size());
1939             for (Runnable r : tasks) {
1940                 r.run();
1941             }
1942         }
1943     }
1944 
1945     /**
1946      * Starts the specified user in the background.
1947      *
1948      * @param userId user to start in background
1949      * @param receiver to post results
1950      */
startUserInBackground(@serIdInt int userId, @NonNull AndroidFuture<UserStartResult> receiver)1951     public void startUserInBackground(@UserIdInt int userId,
1952             @NonNull AndroidFuture<UserStartResult> receiver) {
1953         checkManageOrCreateUsersPermission("startUserInBackground");
1954         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_START_USER_IN_BACKGROUND_REQ, userId);
1955 
1956         mHandler.post(() -> handleStartUserInBackground(userId, receiver));
1957     }
1958 
handleStartUserInBackground(@serIdInt int userId, @NonNull AndroidFuture<UserStartResult> receiver)1959     private void handleStartUserInBackground(@UserIdInt int userId,
1960             @NonNull AndroidFuture<UserStartResult> receiver) {
1961         // If the requested user is the current user, do nothing and return success.
1962         if (ActivityManager.getCurrentUser() == userId) {
1963             sendUserStartResult(
1964                     userId, UserStartResult.STATUS_SUCCESSFUL_USER_IS_CURRENT_USER, receiver);
1965             return;
1966         }
1967         // If requested user does not exist, return error.
1968         if (mUserManager.getUserInfo(userId) == null) {
1969             Slogf.w(TAG, "User %d does not exist", userId);
1970             sendUserStartResult(userId, UserStartResult.STATUS_USER_DOES_NOT_EXIST, receiver);
1971             return;
1972         }
1973 
1974         try {
1975             if (!mAm.startUserInBackground(userId)) {
1976                 Slogf.w(TAG, "Failed to start user %d in background", userId);
1977                 sendUserStartResult(userId, UserStartResult.STATUS_ANDROID_FAILURE, receiver);
1978                 return;
1979             }
1980         } catch (RemoteException e) {
1981             Slogf.w(TAG, e, "Failed to start user %d in background", userId);
1982         }
1983 
1984         // TODO(b/181331178): We are not updating mBackgroundUsersToRestart or
1985         // mBackgroundUsersRestartedHere, which were only used for the garage mode. Consider
1986         // renaming them to make it more clear.
1987         sendUserStartResult(userId, UserStartResult.STATUS_SUCCESSFUL, receiver);
1988     }
1989 
sendUserStartResult(@serIdInt int userId, @UserStartResult.Status int result, @NonNull AndroidFuture<UserStartResult> receiver)1990     private void sendUserStartResult(@UserIdInt int userId, @UserStartResult.Status int result,
1991             @NonNull AndroidFuture<UserStartResult> receiver) {
1992         EventLog.writeEvent(
1993                 EventLogTags.CAR_USER_SVC_START_USER_IN_BACKGROUND_RESP, userId, result);
1994         receiver.complete(new UserStartResult(result));
1995     }
1996 
1997     /**
1998      * Starts all background users that were active in system.
1999      *
2000      * @return list of background users started successfully.
2001      */
2002     @NonNull
startAllBackgroundUsersInGarageMode()2003     public ArrayList<Integer> startAllBackgroundUsersInGarageMode() {
2004         synchronized (mLockUser) {
2005             if (!mStartBackgroundUsersOnGarageMode) {
2006                 Slogf.i(TAG, "Background users are not started as mStartBackgroundUsersOnGarageMode"
2007                         + " is false.");
2008                 return new ArrayList<>();
2009             }
2010         }
2011 
2012         ArrayList<Integer> users;
2013         synchronized (mLockUser) {
2014             users = new ArrayList<>(mBackgroundUsersToRestart);
2015             mBackgroundUsersRestartedHere.clear();
2016             mBackgroundUsersRestartedHere.addAll(mBackgroundUsersToRestart);
2017         }
2018         ArrayList<Integer> startedUsers = new ArrayList<>();
2019         for (Integer user : users) {
2020             if (user == ActivityManager.getCurrentUser()) {
2021                 continue;
2022             }
2023             try {
2024                 if (mAm.startUserInBackground(user)) {
2025                     if (mUserManager.isUserUnlockingOrUnlocked(user)) {
2026                         // already unlocked / unlocking. No need to unlock.
2027                         startedUsers.add(user);
2028                     } else if (mAm.unlockUser(user, null, null, null)) {
2029                         startedUsers.add(user);
2030                     } else { // started but cannot unlock
2031                         Slog.w(TAG, "Background user started but cannot be unlocked:" + user);
2032                         if (mUserManager.isUserRunning(user)) {
2033                             // add to started list so that it can be stopped later.
2034                             startedUsers.add(user);
2035                         }
2036                     }
2037                 }
2038             } catch (RemoteException e) {
2039                 // ignore
2040                 Slog.w(TAG, "error while starting user in background", e);
2041             }
2042         }
2043         // Keep only users that were re-started in mBackgroundUsersRestartedHere
2044         synchronized (mLockUser) {
2045             ArrayList<Integer> usersToRemove = new ArrayList<>();
2046             for (Integer user : mBackgroundUsersToRestart) {
2047                 if (!startedUsers.contains(user)) {
2048                     usersToRemove.add(user);
2049                 }
2050             }
2051             mBackgroundUsersRestartedHere.removeAll(usersToRemove);
2052         }
2053         return startedUsers;
2054     }
2055 
2056     /**
2057      * Stops the specified background user.
2058      *
2059      * @param userId user to stop
2060      * @param receiver to post results
2061      */
stopUser(@serIdInt int userId, @NonNull AndroidFuture<UserStopResult> receiver)2062     public void stopUser(@UserIdInt int userId, @NonNull AndroidFuture<UserStopResult> receiver) {
2063         checkManageOrCreateUsersPermission("stopUser");
2064         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_STOP_USER_REQ, userId);
2065 
2066         mHandler.post(() -> handleStopUser(userId, receiver));
2067     }
2068 
handleStopUser( @serIdInt int userId, @NonNull AndroidFuture<UserStopResult> receiver)2069     private void handleStopUser(
2070             @UserIdInt int userId, @NonNull AndroidFuture<UserStopResult> receiver) {
2071         @UserStopResult.Status int userStopStatus = stopBackgroundUserInternal(userId);
2072         sendUserStopResult(userId, userStopStatus, receiver);
2073     }
2074 
sendUserStopResult(@serIdInt int userId, @UserStopResult.Status int result, @NonNull AndroidFuture<UserStopResult> receiver)2075     private void sendUserStopResult(@UserIdInt int userId, @UserStopResult.Status int result,
2076             @NonNull AndroidFuture<UserStopResult> receiver) {
2077         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_STOP_USER_RESP, userId, result);
2078         receiver.complete(new UserStopResult(result));
2079     }
2080 
stopBackgroundUserInternal(@serIdInt int userId)2081     private @UserStopResult.Status int stopBackgroundUserInternal(@UserIdInt int userId) {
2082         try {
2083             int r = mAm.stopUserWithDelayedLocking(userId, true, null);
2084             switch(r) {
2085                 case ActivityManager.USER_OP_SUCCESS:
2086                     return UserStopResult.STATUS_SUCCESSFUL;
2087                 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
2088                     Slogf.w(TAG, "Cannot stop the system user: %d", userId);
2089                     return UserStopResult.STATUS_FAILURE_SYSTEM_USER;
2090                 case ActivityManager.USER_OP_IS_CURRENT:
2091                     Slogf.w(TAG, "Cannot stop the current user: %d", userId);
2092                     return UserStopResult.STATUS_FAILURE_CURRENT_USER;
2093                 case ActivityManager.USER_OP_UNKNOWN_USER:
2094                     Slogf.w(TAG, "Cannot stop the user that does not exist: %d", userId);
2095                     return UserStopResult.STATUS_USER_DOES_NOT_EXIST;
2096                 default:
2097                     Slogf.w(TAG, "stopUser failed, user: %d, err: %d", userId, r);
2098             }
2099         } catch (RemoteException e) {
2100             // ignore the exception
2101             Slogf.w(TAG, e, "error while stopping user: %d", userId);
2102         }
2103         return UserStopResult.STATUS_ANDROID_FAILURE;
2104     }
2105 
2106     /**
2107      * Sets boolean to control background user operations during garage mode.
2108      */
setStartBackgroundUsersOnGarageMode(boolean enable)2109     public void setStartBackgroundUsersOnGarageMode(boolean enable) {
2110         synchronized (mLockUser) {
2111             mStartBackgroundUsersOnGarageMode = enable;
2112         }
2113     }
2114 
2115     /**
2116      * Stops a background user.
2117      *
2118      * @return whether stopping succeeds.
2119      */
stopBackgroundUserInGagageMode(@serIdInt int userId)2120     public boolean stopBackgroundUserInGagageMode(@UserIdInt int userId) {
2121         synchronized (mLockUser) {
2122             if (!mStartBackgroundUsersOnGarageMode) {
2123                 Slogf.i(TAG, "Background users are not stopped as mStartBackgroundUsersOnGarageMode"
2124                         + " is false.");
2125                 return false;
2126             }
2127         }
2128 
2129         @UserStopResult.Status int userStopStatus = stopBackgroundUserInternal(userId);
2130         if (UserStopResult.isSuccess(userStopStatus)) {
2131             // Remove the stopped user from the mBackgroundUserRestartedHere list.
2132             synchronized (mLockUser) {
2133                 mBackgroundUsersRestartedHere.remove(Integer.valueOf(userId));
2134             }
2135             return true;
2136         }
2137         return false;
2138     }
2139 
2140     /**
2141      * Notifies all registered {@link UserLifecycleListener} with the event passed as argument.
2142      */
onUserLifecycleEvent(@serLifecycleEventType int eventType, @UserIdInt int fromUserId, @UserIdInt int toUserId)2143     public void onUserLifecycleEvent(@UserLifecycleEventType int eventType,
2144             @UserIdInt int fromUserId, @UserIdInt int toUserId) {
2145         int userId = toUserId;
2146 
2147         // Handle special cases first...
2148         if (eventType == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
2149             onUserSwitching(fromUserId, toUserId);
2150         } else if (eventType == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) {
2151             onUserUnlocked(userId);
2152         }
2153 
2154         // ...then notify listeners.
2155         UserLifecycleEvent event = new UserLifecycleEvent(eventType, fromUserId, userId);
2156 
2157         mHandler.post(() -> {
2158             handleNotifyServiceUserLifecycleListeners(event);
2159             handleNotifyAppUserLifecycleListeners(event);
2160         });
2161     }
2162 
sendPostSwitchToHalLocked(@serIdInt int userId)2163     private void sendPostSwitchToHalLocked(@UserIdInt int userId) {
2164         if (mUserIdForUserSwitchInProcess == UserHandle.USER_NULL
2165                 || mUserIdForUserSwitchInProcess != userId
2166                 || mRequestIdForUserSwitchInProcess == 0) {
2167             if (Log.isLoggable(TAG, Log.DEBUG)) {
2168                 Slog.d(TAG, "No user switch request Id. No android post switch sent.");
2169             }
2170             return;
2171         }
2172         postSwitchHalResponse(mRequestIdForUserSwitchInProcess, mUserIdForUserSwitchInProcess);
2173         mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
2174         mRequestIdForUserSwitchInProcess = 0;
2175     }
2176 
handleNotifyAppUserLifecycleListeners(UserLifecycleEvent event)2177     private void handleNotifyAppUserLifecycleListeners(UserLifecycleEvent event) {
2178         int listenersSize = mAppLifecycleListeners.size();
2179         if (listenersSize == 0) {
2180             Slogf.d(TAG, "No app listener to be notified of %s", event);
2181             return;
2182         }
2183         // Must use a different TimingsTraceLog because it's another thread
2184         Slogf.d(TAG, "Notifying %d app listeners of %s", listenersSize, event);
2185         int userId = event.getUserId();
2186         TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
2187         int eventType = event.getEventType();
2188         t.traceBegin("notify-app-listeners-user-" + userId + "-event-" + eventType);
2189         for (int i = 0; i < listenersSize; i++) {
2190             AppLifecycleListener listener = mAppLifecycleListeners.valueAt(i);
2191             Bundle data = new Bundle();
2192             data.putInt(CarUserManager.BUNDLE_PARAM_ACTION, eventType);
2193 
2194             int fromUserId = event.getPreviousUserId();
2195             if (fromUserId != UserHandle.USER_NULL) {
2196                 data.putInt(CarUserManager.BUNDLE_PARAM_PREVIOUS_USER_ID, fromUserId);
2197             }
2198             Slogf.d(TAG, "Notifying listener %s", listener);
2199             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_NOTIFY_APP_LIFECYCLE_LISTENER,
2200                     listener.uid, listener.packageName, eventType, fromUserId, userId);
2201             try {
2202                 t.traceBegin("notify-app-listener-" + listener.toShortString());
2203                 listener.receiver.send(userId, data);
2204             } catch (RemoteException e) {
2205                 Slogf.e(TAG, e, "Error calling lifecycle listener %s", listener);
2206             } finally {
2207                 t.traceEnd();
2208             }
2209         }
2210         t.traceEnd(); // notify-app-listeners-user-USERID-event-EVENT_TYPE
2211     }
2212 
handleNotifyServiceUserLifecycleListeners(UserLifecycleEvent event)2213     private void handleNotifyServiceUserLifecycleListeners(UserLifecycleEvent event) {
2214         TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
2215         if (mUserLifecycleListeners.isEmpty()) {
2216             Slog.w(TAG, "Not notifying internal UserLifecycleListeners");
2217             return;
2218         } else if (Log.isLoggable(TAG, Log.DEBUG)) {
2219             Slog.d(TAG, "Notifying " + mUserLifecycleListeners.size()
2220                     + " service listeners of " + event);
2221         }
2222 
2223         int userId = event.getUserId();
2224         int eventType = event.getEventType();
2225         t.traceBegin("notify-listeners-user-" + userId + "-event-" + eventType);
2226         for (UserLifecycleListener listener : mUserLifecycleListeners) {
2227             String listenerName = FunctionalUtils.getLambdaName(listener);
2228             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_NOTIFY_INTERNAL_LIFECYCLE_LISTENER,
2229                     listenerName, eventType, event.getPreviousUserId(), userId);
2230             try {
2231                 t.traceBegin("notify-listener-" + listenerName);
2232                 listener.onEvent(event);
2233             } catch (RuntimeException e) {
2234                 Slog.e(TAG,
2235                         "Exception raised when invoking onEvent for " + listenerName, e);
2236             } finally {
2237                 t.traceEnd();
2238             }
2239         }
2240         t.traceEnd(); // notify-listeners-user-USERID-event-EVENT_TYPE
2241     }
2242 
onUserSwitching(@serIdInt int fromUserId, @UserIdInt int toUserId)2243     private void onUserSwitching(@UserIdInt int fromUserId, @UserIdInt int toUserId) {
2244         Slog.i(TAG, "onUserSwitching() callback for user " + toUserId);
2245         TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
2246         t.traceBegin("onUserSwitching-" + toUserId);
2247 
2248         // Switch HAL users if user switch is not requested by CarUserService
2249         notifyHalLegacySwitch(fromUserId, toUserId);
2250 
2251         mInitialUserSetter.setLastActiveUser(toUserId);
2252 
2253         if (mLastPassengerId != UserHandle.USER_NULL) {
2254             stopPassengerInternal(mLastPassengerId, false);
2255         }
2256         if (mEnablePassengerSupport && isPassengerDisplayAvailable()) {
2257             setupPassengerUser();
2258             startFirstPassenger(toUserId);
2259         }
2260         t.traceEnd();
2261     }
2262 
notifyHalLegacySwitch(@serIdInt int fromUserId, @UserIdInt int toUserId)2263     private void notifyHalLegacySwitch(@UserIdInt int fromUserId, @UserIdInt int toUserId) {
2264         synchronized (mLockUser) {
2265             if (mUserIdForUserSwitchInProcess != UserHandle.USER_NULL) {
2266                 if (Log.isLoggable(TAG, Log.DEBUG)) {
2267                     Slog.d(TAG, "notifyHalLegacySwitch(" + fromUserId + ", " + toUserId
2268                             + "): not needed, normal switch for " + mUserIdForUserSwitchInProcess);
2269                 }
2270                 return;
2271             }
2272         }
2273 
2274         if (!isUserHalSupported()) return;
2275 
2276         // switch HAL user
2277         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager, fromUserId);
2278         SwitchUserRequest request = createUserSwitchRequest(toUserId, usersInfo);
2279         mHal.legacyUserSwitch(request);
2280     }
2281 
2282     /**
2283      * Runs the given runnable when user 0 is unlocked. If user 0 is already unlocked, it is
2284      * run inside this call.
2285      *
2286      * @param r Runnable to run.
2287      */
runOnUser0Unlock(@onNull Runnable r)2288     public void runOnUser0Unlock(@NonNull Runnable r) {
2289         Objects.requireNonNull(r, "runnable cannot be null");
2290         boolean runNow = false;
2291         synchronized (mLockUser) {
2292             if (mUser0Unlocked) {
2293                 runNow = true;
2294             } else {
2295                 mUser0UnlockTasks.add(r);
2296             }
2297         }
2298         if (runNow) {
2299             r.run();
2300         }
2301     }
2302 
2303     @VisibleForTesting
2304     @NonNull
getBackgroundUsersToRestart()2305     ArrayList<Integer> getBackgroundUsersToRestart() {
2306         ArrayList<Integer> backgroundUsersToRestart = null;
2307         synchronized (mLockUser) {
2308             backgroundUsersToRestart = new ArrayList<>(mBackgroundUsersToRestart);
2309         }
2310         return backgroundUsersToRestart;
2311     }
2312 
setSystemUserRestrictions()2313     private void setSystemUserRestrictions() {
2314         // Disable Location service for system user.
2315         LocationManager locationManager =
2316                 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2317         locationManager.setLocationEnabledForUser(
2318                 /* enabled= */ false, UserHandle.of(UserHandle.USER_SYSTEM));
2319         locationManager.setAdasGnssLocationEnabled(false);
2320     }
2321 
2322     /**
2323      * Assigns a default icon to a user according to the user's id.
2324      *
2325      * @param userInfo User whose avatar is set to default icon.
2326      */
assignDefaultIcon(UserInfo userInfo)2327     private void assignDefaultIcon(UserInfo userInfo) {
2328         int idForIcon = userInfo.isGuest() ? UserHandle.USER_NULL : userInfo.id;
2329         Bitmap bitmap = UserIcons.convertToBitmap(
2330                 UserIcons.getDefaultUserIcon(mContext.getResources(), idForIcon, false));
2331         mUserManager.setUserIcon(userInfo.id, bitmap);
2332     }
2333 
2334     private interface UserFilter {
isEligibleUser(UserInfo user)2335         boolean isEligibleUser(UserInfo user);
2336     }
2337 
2338     /** Returns all users who are matched by the given filter. */
getUsers(UserFilter filter)2339     private List<UserInfo> getUsers(UserFilter filter) {
2340         List<UserInfo> users = mUserManager.getAliveUsers();
2341 
2342         for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) {
2343             UserInfo user = iterator.next();
2344             if (!filter.isEligibleUser(user)) {
2345                 iterator.remove();
2346             }
2347         }
2348         return users;
2349     }
2350 
checkManageUsersOrDumpPermission(String message)2351     private static void checkManageUsersOrDumpPermission(String message) {
2352         checkHasAtLeastOnePermissionGranted(message,
2353                 android.Manifest.permission.MANAGE_USERS,
2354                 android.Manifest.permission.DUMP);
2355     }
2356 
checkInteractAcrossUsersPermission(String message)2357     private void checkInteractAcrossUsersPermission(String message) {
2358         checkHasAtLeastOnePermissionGranted(message,
2359                 android.Manifest.permission.INTERACT_ACROSS_USERS,
2360                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
2361     }
2362 
getNumberOfManagedProfiles(@serIdInt int userId)2363     private int getNumberOfManagedProfiles(@UserIdInt int userId) {
2364         List<UserInfo> users = mUserManager.getAliveUsers();
2365         // Count all users that are managed profiles of the given user.
2366         int managedProfilesCount = 0;
2367         for (UserInfo user : users) {
2368             if (user.isManagedProfile() && user.profileGroupId == userId) {
2369                 managedProfilesCount++;
2370             }
2371         }
2372         return managedProfilesCount;
2373     }
2374 
2375     /**
2376      * Starts the first passenger of the given driver and assigns the passenger to the front
2377      * passenger zone.
2378      *
2379      * @param driverId User id of the driver.
2380      * @return whether it succeeds.
2381      */
startFirstPassenger(@serIdInt int driverId)2382     private boolean startFirstPassenger(@UserIdInt int driverId) {
2383         int zoneId = getAvailablePassengerZone();
2384         if (zoneId == OccupantZoneInfo.INVALID_ZONE_ID) {
2385             Slog.w(TAG, "passenger occupant zone is not found");
2386             return false;
2387         }
2388         List<UserInfo> passengers = getPassengers(driverId);
2389         if (passengers.size() < 1) {
2390             Slog.w(TAG, "passenger is not found");
2391             return false;
2392         }
2393         // Only one passenger is supported. If there are two or more passengers, the first passenger
2394         // is chosen.
2395         int passengerId = passengers.get(0).id;
2396         if (!startPassenger(passengerId, zoneId)) {
2397             Slog.w(TAG, "cannot start passenger " + passengerId);
2398             return false;
2399         }
2400         return true;
2401     }
2402 
getAvailablePassengerZone()2403     private int getAvailablePassengerZone() {
2404         int[] occupantTypes = new int[] {CarOccupantZoneManager.OCCUPANT_TYPE_FRONT_PASSENGER,
2405                 CarOccupantZoneManager.OCCUPANT_TYPE_REAR_PASSENGER};
2406         for (int occupantType : occupantTypes) {
2407             int zoneId = getZoneId(occupantType);
2408             if (zoneId != OccupantZoneInfo.INVALID_ZONE_ID) {
2409                 return zoneId;
2410             }
2411         }
2412         return OccupantZoneInfo.INVALID_ZONE_ID;
2413     }
2414 
2415     /**
2416      * Creates a new passenger user when there is no passenger user.
2417      */
setupPassengerUser()2418     private void setupPassengerUser() {
2419         int currentUser = ActivityManager.getCurrentUser();
2420         int profileCount = getNumberOfManagedProfiles(currentUser);
2421         if (profileCount > 0) {
2422             Slog.w(TAG, "max profile of user" + currentUser
2423                     + " is exceeded: current profile count is " + profileCount);
2424             return;
2425         }
2426         // TODO(b/140311342): Use resource string for the default passenger name.
2427         UserInfo passenger = createPassenger("Passenger", currentUser);
2428         if (passenger == null) {
2429             // Couldn't create user, most likely because there are too many.
2430             Slog.w(TAG, "cannot create a passenger user");
2431             return;
2432         }
2433     }
2434 
2435     @NonNull
getOccupantZones(@ccupantTypeEnum int occupantType)2436     private List<OccupantZoneInfo> getOccupantZones(@OccupantTypeEnum int occupantType) {
2437         ZoneUserBindingHelper helper = null;
2438         synchronized (mLockHelper) {
2439             if (mZoneUserBindingHelper == null) {
2440                 Slog.w(TAG, "implementation is not delegated");
2441                 return new ArrayList<OccupantZoneInfo>();
2442             }
2443             helper = mZoneUserBindingHelper;
2444         }
2445         return helper.getOccupantZones(occupantType);
2446     }
2447 
assignUserToOccupantZone(@serIdInt int userId, int zoneId)2448     private boolean assignUserToOccupantZone(@UserIdInt int userId, int zoneId) {
2449         ZoneUserBindingHelper helper = null;
2450         synchronized (mLockHelper) {
2451             if (mZoneUserBindingHelper == null) {
2452                 Slog.w(TAG, "implementation is not delegated");
2453                 return false;
2454             }
2455             helper = mZoneUserBindingHelper;
2456         }
2457         return helper.assignUserToOccupantZone(userId, zoneId);
2458     }
2459 
unassignUserFromOccupantZone(@serIdInt int userId)2460     private boolean unassignUserFromOccupantZone(@UserIdInt int userId) {
2461         ZoneUserBindingHelper helper = null;
2462         synchronized (mLockHelper) {
2463             if (mZoneUserBindingHelper == null) {
2464                 Slog.w(TAG, "implementation is not delegated");
2465                 return false;
2466             }
2467             helper = mZoneUserBindingHelper;
2468         }
2469         return helper.unassignUserFromOccupantZone(userId);
2470     }
2471 
isPassengerDisplayAvailable()2472     private boolean isPassengerDisplayAvailable() {
2473         ZoneUserBindingHelper helper = null;
2474         synchronized (mLockHelper) {
2475             if (mZoneUserBindingHelper == null) {
2476                 Slog.w(TAG, "implementation is not delegated");
2477                 return false;
2478             }
2479             helper = mZoneUserBindingHelper;
2480         }
2481         return helper.isPassengerDisplayAvailable();
2482     }
2483 
2484     /**
2485      * Gets the zone id of the given occupant type. If there are two or more zones, the first found
2486      * zone is returned.
2487      *
2488      * @param occupantType The type of an occupant.
2489      * @return The zone id of the given occupant type. {@link OccupantZoneInfo.INVALID_ZONE_ID},
2490      *         if not found.
2491      */
getZoneId(@ccupantTypeEnum int occupantType)2492     private int getZoneId(@OccupantTypeEnum int occupantType) {
2493         List<OccupantZoneInfo> zoneInfos = getOccupantZones(occupantType);
2494         return (zoneInfos.size() > 0) ? zoneInfos.get(0).zoneId : OccupantZoneInfo.INVALID_ZONE_ID;
2495     }
2496 
2497     /**
2498      * Manages the required number of pre-created users.
2499      */
2500     @Override
updatePreCreatedUsers()2501     public void updatePreCreatedUsers() {
2502         checkManageOrCreateUsersPermission("preCreateUsers");
2503         preCreateUsersInternal();
2504     }
2505 
preCreateUsersInternal()2506     private void preCreateUsersInternal() {
2507         mHandler.post(() -> mUserPreCreator.managePreCreatedUsers());
2508     }
2509 
2510     // TODO(b/167698977): members below were copied from UserManagerService; it would be better to
2511     // move them to some internal android.os class instead.
2512 
2513     private static final int ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION =
2514             UserInfo.FLAG_MANAGED_PROFILE
2515             | UserInfo.FLAG_PROFILE
2516             | UserInfo.FLAG_EPHEMERAL
2517             | UserInfo.FLAG_RESTRICTED
2518             | UserInfo.FLAG_GUEST
2519             | UserInfo.FLAG_DEMO
2520             | UserInfo.FLAG_FULL;
2521 
checkManageUsersPermission(String message)2522     private static void checkManageUsersPermission(String message) {
2523         if (!hasManageUsersPermission()) {
2524             throw new SecurityException("You need " + MANAGE_USERS + " permission to: " + message);
2525         }
2526     }
2527 
checkManageOrCreateUsersPermission(String message)2528     private static void checkManageOrCreateUsersPermission(String message) {
2529         if (!hasManageOrCreateUsersPermission()) {
2530             throw new SecurityException(
2531                     "You either need " + MANAGE_USERS + " or " + CREATE_USERS + " permission to: "
2532             + message);
2533         }
2534     }
2535 
checkManageOrCreateUsersPermission(int creationFlags)2536     private static void checkManageOrCreateUsersPermission(int creationFlags) {
2537         if ((creationFlags & ~ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION) == 0) {
2538             if (!hasManageOrCreateUsersPermission()) {
2539                 throw new SecurityException("You either need " + MANAGE_USERS + " or "
2540                         + CREATE_USERS + "permission to create a user with flags "
2541                         + creationFlags);
2542             }
2543         } else if (!hasManageUsersPermission()) {
2544             throw new SecurityException("You need " + MANAGE_USERS + " permission to create a user"
2545                     + " with flags " + creationFlags);
2546         }
2547     }
2548 
hasManageUsersPermission()2549     private static boolean hasManageUsersPermission() {
2550         final int callingUid = Binder.getCallingUid();
2551         return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
2552                 || callingUid == Process.ROOT_UID
2553                 || hasPermissionGranted(MANAGE_USERS, callingUid);
2554     }
2555 
hasManageUsersOrPermission(String alternativePermission)2556     private static boolean hasManageUsersOrPermission(String alternativePermission) {
2557         final int callingUid = Binder.getCallingUid();
2558         return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
2559                 || callingUid == Process.ROOT_UID
2560                 || hasPermissionGranted(MANAGE_USERS, callingUid)
2561                 || hasPermissionGranted(alternativePermission, callingUid);
2562     }
2563 
hasManageOrCreateUsersPermission()2564     private static boolean hasManageOrCreateUsersPermission() {
2565         return hasManageUsersOrPermission(CREATE_USERS);
2566     }
2567 
hasPermissionGranted(String permission, int uid)2568     private static boolean hasPermissionGranted(String permission, int uid) {
2569         return ActivityManager.checkComponentPermission(permission, uid, /* owningUid= */ -1,
2570                 /* exported= */ true) == PackageManager.PERMISSION_GRANTED;
2571     }
2572 }
2573