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 com.android.car.CarLog.TAG_USER;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.UserIdInt;
24 import android.app.ActivityManager;
25 import android.app.ActivityManager.StackInfo;
26 import android.app.IActivityManager;
27 import android.car.CarOccupantZoneManager;
28 import android.car.CarOccupantZoneManager.OccupantTypeEnum;
29 import android.car.CarOccupantZoneManager.OccupantZoneInfo;
30 import android.car.ICarUserService;
31 import android.car.settings.CarSettings;
32 import android.car.user.CarUserManager;
33 import android.car.user.CarUserManager.UserLifecycleEvent;
34 import android.car.user.CarUserManager.UserLifecycleEventType;
35 import android.car.user.CarUserManager.UserLifecycleListener;
36 import android.car.user.UserCreationResult;
37 import android.car.user.UserIdentificationAssociationResponse;
38 import android.car.user.UserRemovalResult;
39 import android.car.user.UserSwitchResult;
40 import android.car.userlib.CarUserManagerHelper;
41 import android.car.userlib.CommonConstants.CarUserServiceConstants;
42 import android.car.userlib.HalCallback;
43 import android.car.userlib.UserHalHelper;
44 import android.car.userlib.UserHelper;
45 import android.content.ComponentName;
46 import android.content.Context;
47 import android.content.pm.PackageManager;
48 import android.content.pm.PackageManager.NameNotFoundException;
49 import android.content.pm.UserInfo;
50 import android.content.pm.UserInfo.UserInfoFlag;
51 import android.content.res.Resources;
52 import android.graphics.Bitmap;
53 import android.hardware.automotive.vehicle.V2_0.CreateUserRequest;
54 import android.hardware.automotive.vehicle.V2_0.CreateUserStatus;
55 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponse;
56 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction;
57 import android.hardware.automotive.vehicle.V2_0.RemoveUserRequest;
58 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
59 import android.hardware.automotive.vehicle.V2_0.SwitchUserStatus;
60 import android.hardware.automotive.vehicle.V2_0.UserIdentificationGetRequest;
61 import android.hardware.automotive.vehicle.V2_0.UserIdentificationResponse;
62 import android.hardware.automotive.vehicle.V2_0.UserIdentificationSetAssociation;
63 import android.hardware.automotive.vehicle.V2_0.UserIdentificationSetRequest;
64 import android.hardware.automotive.vehicle.V2_0.UsersInfo;
65 import android.location.LocationManager;
66 import android.os.Binder;
67 import android.os.Bundle;
68 import android.os.Handler;
69 import android.os.HandlerThread;
70 import android.os.RemoteException;
71 import android.os.Trace;
72 import android.os.UserHandle;
73 import android.os.UserManager;
74 import android.provider.Settings;
75 import android.sysprop.CarProperties;
76 import android.text.TextUtils;
77 import android.util.EventLog;
78 import android.util.Log;
79 import android.util.SparseArray;
80 import android.util.TimingsTraceLog;
81 
82 import com.android.car.CarServiceBase;
83 import com.android.car.CarServiceUtils;
84 import com.android.car.R;
85 import com.android.car.hal.UserHalService;
86 import com.android.internal.annotations.GuardedBy;
87 import com.android.internal.annotations.VisibleForTesting;
88 import com.android.internal.car.EventLogTags;
89 import com.android.internal.infra.AndroidFuture;
90 import com.android.internal.os.IResultReceiver;
91 import com.android.internal.util.ArrayUtils;
92 import com.android.internal.util.FunctionalUtils;
93 import com.android.internal.util.Preconditions;
94 import com.android.internal.util.UserIcons;
95 
96 import java.io.PrintWriter;
97 import java.util.ArrayList;
98 import java.util.Arrays;
99 import java.util.Iterator;
100 import java.util.List;
101 import java.util.Objects;
102 import java.util.concurrent.CopyOnWriteArrayList;
103 import java.util.concurrent.CountDownLatch;
104 import java.util.concurrent.TimeUnit;
105 
106 /**
107  * User service for cars. Manages users at boot time. Including:
108  *
109  * <ol>
110  *   <li> Creates a user used as driver.
111  *   <li> Creates a user used as passenger.
112  *   <li> Creates a secondary admin user on first run.
113  *   <li> Switch drivers.
114  * <ol/>
115  */
116 public final class CarUserService extends ICarUserService.Stub implements CarServiceBase {
117 
118     private static final String TAG = TAG_USER;
119 
120     /** {@code int} extra used to represent a user id in a {@link IResultReceiver} response. */
121     public static final String BUNDLE_USER_ID = CarUserServiceConstants.BUNDLE_USER_ID;
122     /** {@code int} extra used to represent user flags in a {@link IResultReceiver} response. */
123     public static final String BUNDLE_USER_FLAGS = CarUserServiceConstants.BUNDLE_USER_FLAGS;
124     /** {@code String} extra used to represent a user name in a {@link IResultReceiver} response. */
125     public static final String BUNDLE_USER_NAME = CarUserServiceConstants.BUNDLE_USER_NAME;
126     /**
127      * {@code int} extra used to represent the user locales in a {@link IResultReceiver} response.
128      */
129     public static final String BUNDLE_USER_LOCALES =
130             CarUserServiceConstants.BUNDLE_USER_LOCALES;
131     /**
132      * {@code int} extra used to represent the info action in a {@link IResultReceiver} response.
133      */
134     public static final String BUNDLE_INITIAL_INFO_ACTION =
135             CarUserServiceConstants.BUNDLE_INITIAL_INFO_ACTION;
136 
137     public static final String VEHICLE_HAL_NOT_SUPPORTED = "Vehicle Hal not supported.";
138 
139     private final Context mContext;
140     private final CarUserManagerHelper mCarUserManagerHelper;
141     private final IActivityManager mAm;
142     private final UserManager mUserManager;
143     private final int mMaxRunningUsers;
144     private final boolean mEnablePassengerSupport;
145 
146     private final Object mLockUser = new Object();
147     @GuardedBy("mLockUser")
148     private boolean mUser0Unlocked;
149     @GuardedBy("mLockUser")
150     private final ArrayList<Runnable> mUser0UnlockTasks = new ArrayList<>();
151     // Only one passenger is supported.
152     @GuardedBy("mLockUser")
153     private @UserIdInt int mLastPassengerId;
154     /**
155      * Background users that will be restarted in garage mode. This list can include the
156      * current foreground user but the current foreground user should not be restarted.
157      */
158     @GuardedBy("mLockUser")
159     private final ArrayList<Integer> mBackgroundUsersToRestart = new ArrayList<>();
160     /**
161      * Keep the list of background users started here. This is wholly for debugging purpose.
162      */
163     @GuardedBy("mLockUser")
164     private final ArrayList<Integer> mBackgroundUsersRestartedHere = new ArrayList<>();
165 
166     private final UserHalService mHal;
167 
168     // HandlerThread and Handler used when notifying app listeners (mAppLifecycleListeners).
169     private final HandlerThread mHandlerThread = CarServiceUtils.getHandlerThread(
170             getClass().getSimpleName());
171     private final Handler mHandler = new Handler(mHandlerThread.getLooper());
172 
173     /**
174      * List of listeners to be notified on new user activities events.
175      * This collection should be accessed and manipulated by mHandlerThread only.
176      */
177     private final List<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>();
178 
179     /**
180      * List of lifecycle listeners by uid.
181      * This collection should be accessed and manipulated by mHandlerThread only.
182      */
183     private final SparseArray<IResultReceiver> mAppLifecycleListeners = new SparseArray<>();
184 
185     /**
186      * User Id for the user switch in process, if any.
187      */
188     @GuardedBy("mLockUser")
189     private int mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
190     /**
191      * Request Id for the user switch in process, if any.
192      */
193     @GuardedBy("mLockUser")
194     private int mRequestIdForUserSwitchInProcess;
195     private final int mHalTimeoutMs = CarProperties.user_hal_timeout().orElse(5_000);
196 
197     private final CopyOnWriteArrayList<PassengerCallback> mPassengerCallbacks =
198             new CopyOnWriteArrayList<>();
199 
200     @Nullable
201     @GuardedBy("mLockUser")
202     private UserInfo mInitialUser;
203 
204     private UserMetrics mUserMetrics;
205 
206     private IResultReceiver mUserSwitchUiReceiver;
207 
208     /** Interface for callbaks related to passenger activities. */
209     public interface PassengerCallback {
210         /** Called when passenger is started at a certain zone. */
onPassengerStarted(@serIdInt int passengerId, int zoneId)211         void onPassengerStarted(@UserIdInt int passengerId, int zoneId);
212         /** Called when passenger is stopped. */
onPassengerStopped(@serIdInt int passengerId)213         void onPassengerStopped(@UserIdInt int passengerId);
214     }
215 
216     /** Interface for delegating zone-related implementation to CarOccupantZoneService. */
217     public interface ZoneUserBindingHelper {
218         /** Gets occupant zones corresponding to the occupant type. */
219         @NonNull
getOccupantZones(@ccupantTypeEnum int occupantType)220         List<OccupantZoneInfo> getOccupantZones(@OccupantTypeEnum int occupantType);
221         /** Assigns the user to the occupant zone. */
assignUserToOccupantZone(@serIdInt int userId, int zoneId)222         boolean assignUserToOccupantZone(@UserIdInt int userId, int zoneId);
223         /** Makes the occupant zone unoccupied. */
unassignUserFromOccupantZone(@serIdInt int userId)224         boolean unassignUserFromOccupantZone(@UserIdInt int userId);
225         /** Returns whether there is a passenger display. */
isPassengerDisplayAvailable()226         boolean isPassengerDisplayAvailable();
227     }
228 
229     private final Object mLockHelper = new Object();
230     @GuardedBy("mLockHelper")
231     private ZoneUserBindingHelper mZoneUserBindingHelper;
232 
CarUserService(@onNull Context context, @NonNull UserHalService hal, @NonNull CarUserManagerHelper carUserManagerHelper, @NonNull UserManager userManager, @NonNull IActivityManager am, int maxRunningUsers)233     public CarUserService(@NonNull Context context, @NonNull UserHalService hal,
234             @NonNull CarUserManagerHelper carUserManagerHelper, @NonNull UserManager userManager,
235             @NonNull IActivityManager am, int maxRunningUsers) {
236         this(context, hal, carUserManagerHelper, userManager, am, maxRunningUsers,
237                 new UserMetrics());
238     }
239 
240     @VisibleForTesting
CarUserService(@onNull Context context, @NonNull UserHalService hal, @NonNull CarUserManagerHelper carUserManagerHelper, @NonNull UserManager userManager, @NonNull IActivityManager am, int maxRunningUsers, UserMetrics userMetrics)241     CarUserService(@NonNull Context context, @NonNull UserHalService hal,
242             @NonNull CarUserManagerHelper carUserManagerHelper, @NonNull UserManager userManager,
243             @NonNull IActivityManager am, int maxRunningUsers, UserMetrics userMetrics) {
244         if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
245             Log.d(TAG_USER, "constructed");
246         }
247         mContext = context;
248         mHal = hal;
249         mCarUserManagerHelper = carUserManagerHelper;
250         mAm = am;
251         mMaxRunningUsers = maxRunningUsers;
252         mUserManager = userManager;
253         mLastPassengerId = UserHandle.USER_NULL;
254         mEnablePassengerSupport = context.getResources().getBoolean(R.bool.enablePassengerSupport);
255         mUserMetrics = userMetrics;
256     }
257 
258     @Override
init()259     public void init() {
260         if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
261             Log.d(TAG_USER, "init");
262         }
263     }
264 
265     @Override
release()266     public void release() {
267         if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
268             Log.d(TAG_USER, "release");
269         }
270     }
271 
272     @Override
dump(@onNull PrintWriter writer)273     public void dump(@NonNull PrintWriter writer) {
274         checkAtLeastOnePermission("dump()", android.Manifest.permission.DUMP);
275         writer.println("*CarUserService*");
276         String indent = "  ";
277         handleDumpListeners(writer, indent);
278         writer.printf("User switch UI receiver %s\n", mUserSwitchUiReceiver);
279         synchronized (mLockUser) {
280             writer.println("User0Unlocked: " + mUser0Unlocked);
281             writer.println("BackgroundUsersToRestart: " + mBackgroundUsersToRestart);
282             writer.println("BackgroundUsersRestarted: " + mBackgroundUsersRestartedHere);
283         }
284         writer.println("MaxRunningUsers: " + mMaxRunningUsers);
285         List<UserInfo> allDrivers = getAllDrivers();
286         int driversSize = allDrivers.size();
287         writer.println("NumberOfDrivers: " + driversSize);
288         for (int i = 0; i < driversSize; i++) {
289             int driverId = allDrivers.get(i).id;
290             writer.print(indent + "#" + i + ": id=" + driverId);
291             List<UserInfo> passengers = getPassengers(driverId);
292             int passengersSize = passengers.size();
293             writer.print(" NumberPassengers: " + passengersSize);
294             if (passengersSize > 0) {
295                 writer.print(" [");
296                 for (int j = 0; j < passengersSize; j++) {
297                     writer.print(passengers.get(j).id);
298                     if (j < passengersSize - 1) {
299                         writer.print(" ");
300                     }
301                 }
302                 writer.print("]");
303             }
304             writer.println();
305         }
306         writer.printf("EnablePassengerSupport: %s\n", mEnablePassengerSupport);
307         writer.printf("User HAL timeout: %dms\n",  mHalTimeoutMs);
308         writer.printf("Initial user: %s\n", mInitialUser);
309 
310         writer.println("Relevant overlayable properties");
311         Resources res = mContext.getResources();
312         writer.printf("%sowner_name=%s\n", indent,
313                 res.getString(com.android.internal.R.string.owner_name));
314         writer.printf("%sdefault_guest_name=%s\n", indent,
315                 res.getString(R.string.default_guest_name));
316         writer.printf("User switch in process=%d\n", mUserIdForUserSwitchInProcess);
317         writer.printf("Request Id for the user switch in process=%d\n ",
318                     mRequestIdForUserSwitchInProcess);
319         writer.printf("System UI package name=%s\n", getSystemUiPackageName());
320 
321         writer.println("Relevant Global settings");
322         dumpGlobalProperty(writer, indent, CarSettings.Global.LAST_ACTIVE_USER_ID);
323         dumpGlobalProperty(writer, indent, CarSettings.Global.LAST_ACTIVE_PERSISTENT_USER_ID);
324 
325         dumpUserMetrics(writer);
326     }
327 
dumpGlobalProperty(PrintWriter writer, String indent, String property)328     private void dumpGlobalProperty(PrintWriter writer, String indent, String property) {
329         String value = Settings.Global.getString(mContext.getContentResolver(), property);
330         writer.printf("%s%s=%s\n", indent, property, value);
331     }
332 
333     /**
334      * Dumps user metrics.
335      */
dumpUserMetrics(@onNull PrintWriter writer)336     public void dumpUserMetrics(@NonNull PrintWriter writer) {
337         mUserMetrics.dump(writer);
338     }
339 
340     /**
341      * Dumps first user unlocking time.
342      */
dumpFirstUserUnlockDuration(PrintWriter writer)343     public void dumpFirstUserUnlockDuration(PrintWriter writer) {
344         mUserMetrics.dumpFirstUserUnlockDuration(writer);
345     }
346 
handleDumpListeners(@onNull PrintWriter writer, String indent)347     private void handleDumpListeners(@NonNull PrintWriter writer, String indent) {
348         CountDownLatch latch = new CountDownLatch(1);
349         mHandler.post(() -> {
350             handleDumpServiceLifecycleListeners(writer);
351             handleDumpAppLifecycleListeners(writer, indent);
352             latch.countDown();
353         });
354         int timeout = 5;
355         try {
356             if (!latch.await(timeout, TimeUnit.SECONDS)) {
357                 writer.printf("Handler thread didn't respond in %ds when dumping listeners\n",
358                         timeout);
359             }
360         } catch (InterruptedException e) {
361             Thread.currentThread().interrupt();
362             writer.println("Interrupted waiting for handler thread to dump app and user listeners");
363         }
364     }
365 
handleDumpServiceLifecycleListeners(@onNull PrintWriter writer)366     private void handleDumpServiceLifecycleListeners(@NonNull PrintWriter writer) {
367         if (mUserLifecycleListeners.isEmpty()) {
368             writer.println("No lifecycle listeners for internal services");
369             return;
370         }
371         int size = mUserLifecycleListeners.size();
372         writer.printf("%d lifecycle listener%s for services\n", size, size == 1 ? "" : "s");
373         String indent = "  ";
374         for (UserLifecycleListener listener : mUserLifecycleListeners) {
375             writer.printf("%s%s\n", indent, FunctionalUtils.getLambdaName(listener));
376         }
377     }
378 
handleDumpAppLifecycleListeners(@onNull PrintWriter writer, String indent)379     private void handleDumpAppLifecycleListeners(@NonNull PrintWriter writer, String indent) {
380         int size = mAppLifecycleListeners.size();
381         if (size == 0) {
382             writer.println("No lifecycle listeners for apps");
383             return;
384         }
385         writer.printf("%d lifecycle listener%s for apps \n", size, size == 1 ? "" : "s");
386         for (int i = 0; i < size; i++) {
387             int uid = mAppLifecycleListeners.keyAt(i);
388             IResultReceiver listener = mAppLifecycleListeners.valueAt(i);
389             writer.printf("%suid: %d\n", indent, uid);
390         }
391     }
392 
393     /**
394      * @see ExperimentalCarUserManager.createDriver
395      */
396     @Override
createDriver(@onNull String name, boolean admin)397     public AndroidFuture<UserCreationResult> createDriver(@NonNull String name, boolean admin) {
398         checkManageUsersPermission("createDriver");
399         Objects.requireNonNull(name, "name cannot be null");
400 
401         AndroidFuture<UserCreationResult> future = new AndroidFuture<UserCreationResult>() {
402             @Override
403             protected void onCompleted(UserCreationResult result, Throwable err) {
404                 if (result == null) {
405                     Log.w(TAG, "createDriver(" + name + "," + admin + ") failed: " + err);
406                 } else {
407                     if (result.getStatus() == UserCreationResult.STATUS_SUCCESSFUL) {
408                         assignDefaultIcon(result.getUser());
409                     }
410                 }
411                 super.onCompleted(result, err);
412             };
413         };
414         int flags = 0;
415         if (admin) {
416             if (!(mUserManager.isAdminUser() || mUserManager.isSystemUser())) {
417                 Log.e(TAG_USER, "Only admin users and system user can create other admins.");
418                 sendUserCreationResultFailure(future, UserCreationResult.STATUS_INVALID_REQUEST);
419                 return future;
420             }
421             flags = UserInfo.FLAG_ADMIN;
422         }
423         createUser(name, UserInfo.getDefaultUserType(flags), flags, mHalTimeoutMs, future);
424         return future;
425     }
426 
427     /**
428      * @see ExperimentalCarUserManager.createPassenger
429      */
430     @Override
431     @Nullable
createPassenger(@onNull String name, @UserIdInt int driverId)432     public UserInfo createPassenger(@NonNull String name, @UserIdInt int driverId) {
433         checkManageUsersPermission("createPassenger");
434         Objects.requireNonNull(name, "name cannot be null");
435         UserInfo driver = mUserManager.getUserInfo(driverId);
436         if (driver == null) {
437             Log.w(TAG_USER, "the driver is invalid");
438             return null;
439         }
440         if (driver.isGuest()) {
441             Log.w(TAG_USER, "a guest driver cannot create a passenger");
442             return null;
443         }
444         // createPassenger doesn't use user HAL because user HAL doesn't support profile user yet.
445         UserInfo user = mUserManager.createProfileForUser(name,
446                 UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, driverId);
447         if (user == null) {
448             // Couldn't create user, most likely because there are too many.
449             Log.w(TAG_USER, "can't create a profile for user" + driverId);
450             return null;
451         }
452         // Passenger user should be a non-admin user.
453         mCarUserManagerHelper.setDefaultNonAdminRestrictions(user, /* enable= */ true);
454         assignDefaultIcon(user);
455         return user;
456     }
457 
458     /**
459      * @see ExperimentalCarUserManager.switchDriver
460      */
461     @Override
switchDriver(@serIdInt int driverId, AndroidFuture<UserSwitchResult> receiver)462     public void switchDriver(@UserIdInt int driverId, AndroidFuture<UserSwitchResult> receiver) {
463         checkManageUsersPermission("switchDriver");
464         if (UserHelper.isHeadlessSystemUser(driverId)) {
465             // System user doesn't associate with real person, can not be switched to.
466             Log.w(TAG_USER, "switching to system user in headless system user mode is not allowed");
467             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_INVALID_REQUEST);
468             return;
469         }
470         int userSwitchable = mUserManager.getUserSwitchability();
471         if (userSwitchable != UserManager.SWITCHABILITY_STATUS_OK) {
472             Log.w(TAG_USER, "current process is not allowed to switch user");
473             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_INVALID_REQUEST);
474             return;
475         }
476         switchUser(driverId, mHalTimeoutMs, receiver);
477     }
478 
479     /**
480      * Returns all drivers who can occupy the driving zone. Guest users are included in the list.
481      *
482      * @return the list of {@link UserInfo} who can be a driver on the device.
483      */
484     @Override
485     @NonNull
getAllDrivers()486     public List<UserInfo> getAllDrivers() {
487         checkManageUsersOrDumpPermission("getAllDrivers");
488         return getUsers((user) -> !UserHelper.isHeadlessSystemUser(user.id) && user.isEnabled()
489                 && !user.isManagedProfile() && !user.isEphemeral());
490     }
491 
492     /**
493      * Returns all passengers under the given driver.
494      *
495      * @param driverId User id of a driver.
496      * @return the list of {@link UserInfo} who is a passenger under the given driver.
497      */
498     @Override
499     @NonNull
getPassengers(@serIdInt int driverId)500     public List<UserInfo> getPassengers(@UserIdInt int driverId) {
501         checkManageUsersOrDumpPermission("getPassengers");
502         return getUsers((user) -> {
503             return !UserHelper.isHeadlessSystemUser(user.id) && user.isEnabled()
504                     && user.isManagedProfile() && user.profileGroupId == driverId;
505         });
506     }
507 
508     /**
509      * @see CarUserManager.startPassenger
510      */
511     @Override
startPassenger(@serIdInt int passengerId, int zoneId)512     public boolean startPassenger(@UserIdInt int passengerId, int zoneId) {
513         checkManageUsersPermission("startPassenger");
514         synchronized (mLockUser) {
515             try {
516                 if (!mAm.startUserInBackgroundWithListener(passengerId, null)) {
517                     Log.w(TAG_USER, "could not start passenger");
518                     return false;
519                 }
520             } catch (RemoteException e) {
521                 // ignore
522                 Log.w(TAG_USER, "error while starting passenger", e);
523                 return false;
524             }
525             if (!assignUserToOccupantZone(passengerId, zoneId)) {
526                 Log.w(TAG_USER, "could not assign passenger to zone");
527                 return false;
528             }
529             mLastPassengerId = passengerId;
530         }
531         for (PassengerCallback callback : mPassengerCallbacks) {
532             callback.onPassengerStarted(passengerId, zoneId);
533         }
534         return true;
535     }
536 
537     /**
538      * @see CarUserManager.stopPassenger
539      */
540     @Override
stopPassenger(@serIdInt int passengerId)541     public boolean stopPassenger(@UserIdInt int passengerId) {
542         checkManageUsersPermission("stopPassenger");
543         return stopPassengerInternal(passengerId, true);
544     }
545 
stopPassengerInternal(@serIdInt int passengerId, boolean checkCurrentDriver)546     private boolean stopPassengerInternal(@UserIdInt int passengerId, boolean checkCurrentDriver) {
547         synchronized (mLockUser) {
548             UserInfo passenger = mUserManager.getUserInfo(passengerId);
549             if (passenger == null) {
550                 Log.w(TAG_USER, "passenger " + passengerId + " doesn't exist");
551                 return false;
552             }
553             if (mLastPassengerId != passengerId) {
554                 Log.w(TAG_USER, "passenger " + passengerId + " hasn't been started");
555                 return true;
556             }
557             if (checkCurrentDriver) {
558                 int currentUser = ActivityManager.getCurrentUser();
559                 if (passenger.profileGroupId != currentUser) {
560                     Log.w(TAG_USER, "passenger " + passengerId
561                             + " is not a profile of the current user");
562                     return false;
563                 }
564             }
565             // Passenger is a profile, so cannot be stopped through activity manager.
566             // Instead, activities started by the passenger are stopped and the passenger is
567             // unassigned from the zone.
568             stopAllTasks(passengerId);
569             if (!unassignUserFromOccupantZone(passengerId)) {
570                 Log.w(TAG_USER, "could not unassign user from occupant zone");
571                 return false;
572             }
573             mLastPassengerId = UserHandle.USER_NULL;
574         }
575         for (PassengerCallback callback : mPassengerCallbacks) {
576             callback.onPassengerStopped(passengerId);
577         }
578         return true;
579     }
580 
stopAllTasks(@serIdInt int userId)581     private void stopAllTasks(@UserIdInt int userId) {
582         try {
583             for (StackInfo info : mAm.getAllStackInfos()) {
584                 for (int i = 0; i < info.taskIds.length; i++) {
585                     if (info.taskUserIds[i] == userId) {
586                         int taskId = info.taskIds[i];
587                         if (!mAm.removeTask(taskId)) {
588                             Log.w(TAG_USER, "could not remove task " + taskId);
589                         }
590                     }
591                 }
592             }
593         } catch (RemoteException e) {
594             Log.e(TAG_USER, "could not get stack info", e);
595         }
596     }
597 
598     @Override
setLifecycleListenerForUid(IResultReceiver listener)599     public void setLifecycleListenerForUid(IResultReceiver listener) {
600         int uid = Binder.getCallingUid();
601         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SET_LIFECYCLE_LISTENER, uid);
602         checkInteractAcrossUsersPermission("setLifecycleListenerForUid" + uid);
603 
604         try {
605             listener.asBinder().linkToDeath(() -> onListenerDeath(uid), 0);
606         } catch (RemoteException e) {
607             Log.wtf(TAG_USER, "Cannot listen to death of " + uid);
608         }
609         mHandler.post(() -> mAppLifecycleListeners.append(uid, listener));
610     }
611 
onListenerDeath(int uid)612     private void onListenerDeath(int uid) {
613         Log.i(TAG_USER, "Removing listeners for uid " + uid + " on binder death");
614         mHandler.post(() -> mAppLifecycleListeners.remove(uid));
615     }
616 
617     @Override
resetLifecycleListenerForUid()618     public void resetLifecycleListenerForUid() {
619         int uid = Binder.getCallingUid();
620         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_RESET_LIFECYCLE_LISTENER, uid);
621         checkInteractAcrossUsersPermission("resetLifecycleListenerForUid-" + uid);
622         mHandler.post(() -> mAppLifecycleListeners.remove(uid));
623     }
624 
625     @Override
getInitialUserInfo(int requestType, int timeoutMs, @NonNull IResultReceiver receiver)626     public void getInitialUserInfo(int requestType, int timeoutMs,
627             @NonNull IResultReceiver receiver) {
628         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_REQ, requestType,
629                 timeoutMs);
630         Objects.requireNonNull(receiver, "receiver cannot be null");
631         checkManageUsersPermission("getInitialInfo");
632         if (!isUserHalSupported()) {
633             sendResult(receiver, HalCallback.STATUS_HAL_NOT_SUPPORTED, null);
634             return;
635         }
636         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
637         mHal.getInitialUserInfo(requestType, timeoutMs, usersInfo, (status, resp) -> {
638             Bundle resultData = null;
639             if (resp != null) {
640                 EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_RESP,
641                         status, resp.action, resp.userToSwitchOrCreate.userId,
642                         resp.userToSwitchOrCreate.flags, resp.userNameToCreate, resp.userLocales);
643                 switch (resp.action) {
644                     case InitialUserInfoResponseAction.SWITCH:
645                         resultData = new Bundle();
646                         resultData.putInt(BUNDLE_INITIAL_INFO_ACTION, resp.action);
647                         resultData.putInt(BUNDLE_USER_ID, resp.userToSwitchOrCreate.userId);
648                         break;
649                     case InitialUserInfoResponseAction.CREATE:
650                         resultData = new Bundle();
651                         resultData.putInt(BUNDLE_INITIAL_INFO_ACTION, resp.action);
652                         resultData.putInt(BUNDLE_USER_FLAGS, resp.userToSwitchOrCreate.flags);
653                         resultData.putString(BUNDLE_USER_NAME, resp.userNameToCreate);
654                         break;
655                     case InitialUserInfoResponseAction.DEFAULT:
656                         resultData = new Bundle();
657                         resultData.putInt(BUNDLE_INITIAL_INFO_ACTION, resp.action);
658                         break;
659                     default:
660                         // That's ok, it will be the same as DEFAULT...
661                         Log.w(TAG_USER, "invalid response action on " + resp);
662                 }
663             } else {
664                 EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_RESP, status);
665             }
666             if (resultData != null && !TextUtils.isEmpty(resp.userLocales)) {
667                 resultData.putString(BUNDLE_USER_LOCALES, resp.userLocales);
668             }
669 
670             sendResult(receiver, status, resultData);
671         });
672     }
673 
674     /**
675      * Gets the initial foreground user after the device boots or resumes from suspension.
676      *
677      * <p>When the OEM supports the User HAL, the initial user won't be available until the HAL
678      * returns the initial value to {@code CarService} - if HAL takes too long or times out, this
679      * method returns {@code null}.
680      *
681      * <p>If the HAL eventually times out, {@code CarService} will fallback to its default behavior
682      * (like switching to the last active user), and this method will return the result of such
683      * operation.
684      *
685      * <p>Notice that if {@code CarService} crashes, subsequent calls to this method will return
686      * {@code null}.
687      *
688      * @hide
689      */
690     @Nullable
getInitialUser()691     public UserInfo getInitialUser() {
692         checkInteractAcrossUsersPermission("getInitialUser");
693         synchronized (mLockUser) {
694             return mInitialUser;
695         }
696     }
697 
698     // TODO(b/150413515): temporary method called by ICarImpl.setInitialUser(int userId), as for
699     // some reason passing the whole UserInfo through a raw binder transaction  is not working.
700     /**
701      * Sets the initial foreground user after the device boots or resumes from suspension.
702      */
setInitialUser(@serIdInt int userId)703     public void setInitialUser(@UserIdInt int userId) {
704         UserInfo initialUser = userId == UserHandle.USER_NULL ? null
705                 : mUserManager.getUserInfo(userId);
706         setInitialUser(initialUser);
707     }
708 
709     /**
710      * Sets the initial foreground user after the device boots or resumes from suspension.
711      */
setInitialUser(@ullable UserInfo user)712     public void setInitialUser(@Nullable UserInfo user) {
713         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SET_INITIAL_USER,
714                 user == null ? UserHandle.USER_NULL : user.id);
715         synchronized (mLockUser) {
716             mInitialUser = user;
717         }
718         if (user == null) {
719             // This mean InitialUserSetter failed and could not fallback, so the initial user was
720             // not switched (and most likely is SYSTEM_USER).
721             // TODO(b/153104378): should we set it to ActivityManager.getCurrentUser() instead?
722             Log.wtf(TAG_USER, "Initial user set to null");
723         }
724     }
725 
726     /**
727      * Calls the User HAL to get the initial user info.
728      *
729      * @param requestType type as defined by {@code InitialUserInfoRequestType}.
730      * @param callback callback to receive the results.
731      */
getInitialUserInfo(int requestType, HalCallback<InitialUserInfoResponse> callback)732     public void getInitialUserInfo(int requestType,
733             HalCallback<InitialUserInfoResponse> callback) {
734         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_REQ, requestType,
735                 mHalTimeoutMs);
736         Objects.requireNonNull(callback, "callback cannot be null");
737         checkManageUsersPermission("getInitialUserInfo");
738         if (!isUserHalSupported()) {
739             callback.onResponse(HalCallback.STATUS_HAL_NOT_SUPPORTED, null);
740             return;
741         }
742         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
743         mHal.getInitialUserInfo(requestType, mHalTimeoutMs, usersInfo, callback);
744     }
745 
746     /**
747      * Calls the {@link UserHalService} and {@link IActivityManager} for user switch.
748      *
749      * <p>
750      * When everything works well, the workflow is:
751      * <ol>
752      *   <li> {@link UserHalService} is called for HAL user switch with ANDROID_SWITCH request
753      *   type, current user id, target user id, and a callback.
754      *   <li> HAL called back with SUCCESS.
755      *   <li> {@link IActivityManager} is called for Android user switch.
756      *   <li> Receiver would receive {@code STATUS_SUCCESSFUL}.
757      *   <li> Once user is unlocked, {@link UserHalService} is again called with ANDROID_POST_SWITCH
758      *   request type, current user id, and target user id. In this case, the current and target
759      *   user IDs would be same.
760      * <ol/>
761      *
762      * <p>
763      * Corner cases:
764      * <ul>
765      *   <li> If target user is already the current user, no user switch is performed and receiver
766      *   would receive {@code STATUS_OK_USER_ALREADY_IN_FOREGROUND} right away.
767      *   <li> If HAL user switch call fails, no Android user switch. Receiver would receive
768      *   {@code STATUS_HAL_INTERNAL_FAILURE}.
769      *   <li> If HAL user switch call is successful, but android user switch call fails,
770      *   {@link UserHalService} is again called with request type POST_SWITCH, current user id, and
771      *   target user id, but in this case the current and target user IDs would be different.
772      *   <li> If another user switch request for the same target user is received while previous
773      *   request is in process, receiver would receive
774      *   {@code STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO} for the new request right away.
775      *   <li> If a user switch request is received while another user switch request for different
776      *   target user is in process, the previous request would be abandoned and new request will be
777      *   processed. No POST_SWITCH would be sent for the previous request.
778      * <ul/>
779      *
780      * @param targetUserId - target user Id
781      * @param timeoutMs - timeout for HAL to wait
782      * @param receiver - receiver for the results
783      */
784     @Override
switchUser(@serIdInt int targetUserId, int timeoutMs, @NonNull AndroidFuture<UserSwitchResult> receiver)785     public void switchUser(@UserIdInt int targetUserId, int timeoutMs,
786             @NonNull AndroidFuture<UserSwitchResult> receiver) {
787         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_REQ, targetUserId, timeoutMs);
788         checkManageUsersPermission("switchUser");
789         Objects.requireNonNull(receiver);
790         UserInfo targetUser = mUserManager.getUserInfo(targetUserId);
791         Preconditions.checkArgument(targetUser != null, "Target user doesn't exist");
792 
793         int currentUser = ActivityManager.getCurrentUser();
794         if (currentUser == targetUserId) {
795             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
796                 Log.d(TAG_USER, "Current user is same as requested target user: " + targetUserId);
797             }
798             int resultStatus = UserSwitchResult.STATUS_OK_USER_ALREADY_IN_FOREGROUND;
799             sendUserSwitchResult(receiver, resultStatus);
800             return;
801         }
802 
803         // If User Hal is not supported, just android user switch.
804         if (!isUserHalSupported()) {
805             try {
806                 if (mAm.switchUser(targetUserId)) {
807                     sendUserSwitchResult(receiver, UserSwitchResult.STATUS_SUCCESSFUL);
808                     return;
809                 }
810             } catch (RemoteException e) {
811                 // ignore
812                 Log.w(TAG_USER,
813                         "error while switching user " + targetUser.toFullString(), e);
814             }
815             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_ANDROID_FAILURE);
816             return;
817         }
818 
819         synchronized (mLockUser) {
820             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
821                 Log.d(TAG_USER, "switchUser(" + targetUserId + "): currentuser=" + currentUser
822                         + ", mUserIdForUserSwitchInProcess=" + mUserIdForUserSwitchInProcess);
823             }
824 
825             // If there is another request for the same target user, return another request in
826             // process, else {@link mUserIdForUserSwitchInProcess} is updated and {@link
827             // mRequestIdForUserSwitchInProcess} is reset. It is possible that there may be another
828             // user switch request in process for different target user, but that request is now
829             // ignored.
830             if (mUserIdForUserSwitchInProcess == targetUserId) {
831                 if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
832                     Log.d(TAG_USER,
833                             "Another user switch request in process for the requested target user: "
834                                     + targetUserId);
835                 }
836 
837                 int resultStatus = UserSwitchResult.STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO;
838                 sendUserSwitchResult(receiver, resultStatus);
839                 return;
840             }
841             else {
842                 mUserIdForUserSwitchInProcess = targetUserId;
843                 mRequestIdForUserSwitchInProcess = 0;
844             }
845         }
846 
847         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
848         SwitchUserRequest request = createUserSwitchRequest(targetUserId, usersInfo);
849 
850         mHal.switchUser(request, timeoutMs, (status, resp) -> {
851             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
852                 Log.d(TAG, "switch response: status="
853                         + UserHalHelper.halCallbackStatusToString(status) + ", resp=" + resp);
854             }
855 
856             int resultStatus = UserSwitchResult.STATUS_HAL_INTERNAL_FAILURE;
857 
858             synchronized (mLockUser) {
859                 if (status != HalCallback.STATUS_OK) {
860                     EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_RESP, status);
861                     Log.w(TAG, "invalid callback status ("
862                             + UserHalHelper.halCallbackStatusToString(status) + ") for response "
863                             + resp);
864                     sendUserSwitchResult(receiver, resultStatus);
865                     mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
866                     return;
867                 }
868 
869                 EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_RESP, status, resp.status,
870                         resp.errorMessage);
871 
872                 if (mUserIdForUserSwitchInProcess != targetUserId) {
873                     // Another user switch request received while HAL responded. No need to process
874                     // this request further
875                     if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
876                         Log.d(TAG_USER, "Another user switch received while HAL responsed. Request "
877                                 + "abondoned for : " + targetUserId + ". Current user in process: "
878                                 + mUserIdForUserSwitchInProcess);
879                     }
880                     resultStatus =
881                             UserSwitchResult.STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST;
882                     sendUserSwitchResult(receiver, resultStatus);
883                     mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
884                     return;
885                 }
886 
887                 switch (resp.status) {
888                     case SwitchUserStatus.SUCCESS:
889                         boolean switched;
890                         try {
891                             switched = mAm.switchUser(targetUserId);
892                             if (switched) {
893                                 sendUserSwitchUiCallback(targetUserId);
894                                 resultStatus = UserSwitchResult.STATUS_SUCCESSFUL;
895                                 mRequestIdForUserSwitchInProcess = resp.requestId;
896                             } else {
897                                 resultStatus = UserSwitchResult.STATUS_ANDROID_FAILURE;
898                                 postSwitchHalResponse(resp.requestId, targetUserId);
899                             }
900                         } catch (RemoteException e) {
901                             // ignore
902                             Log.w(TAG_USER,
903                                     "error while switching user " + targetUser.toFullString(), e);
904                         }
905                         break;
906                     case SwitchUserStatus.FAILURE:
907                         // HAL failed to switch user
908                         resultStatus = UserSwitchResult.STATUS_HAL_FAILURE;
909                         break;
910                     default:
911                         // Shouldn't happen because UserHalService validates the status
912                         Log.wtf(TAG, "Received invalid user switch status from HAL: " + resp);
913                 }
914 
915                 if (mRequestIdForUserSwitchInProcess == 0) {
916                     mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
917                 }
918             }
919             sendUserSwitchResult(receiver, resultStatus, resp.errorMessage);
920         });
921     }
922 
923     @Override
removeUser(@serIdInt int userId)924     public UserRemovalResult removeUser(@UserIdInt int userId) {
925         checkManageUsersPermission("removeUser");
926         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_REQ, userId);
927         // If the requested user is the current user, return error.
928         if (ActivityManager.getCurrentUser() == userId) {
929             return logAndGetResults(userId,
930                     UserRemovalResult.STATUS_TARGET_USER_IS_CURRENT_USER);
931         }
932 
933         // If requested user is the only admin user, return error.
934         UserInfo userInfo = mUserManager.getUserInfo(userId);
935         if (userInfo == null) {
936             return logAndGetResults(userId, UserRemovalResult.STATUS_USER_DOES_NOT_EXIST);
937         }
938 
939         android.hardware.automotive.vehicle.V2_0.UserInfo halUser =
940                 new android.hardware.automotive.vehicle.V2_0.UserInfo();
941         halUser.userId = userInfo.id;
942         halUser.flags = UserHalHelper.convertFlags(userInfo);
943         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
944 
945         // Do not delete last admin user.
946         if (UserHalHelper.isAdmin(halUser.flags)) {
947             int size = usersInfo.existingUsers.size();
948             int totalAdminUsers = 0;
949             for (int i = 0; i < size; i++) {
950                 if (UserHalHelper.isAdmin(usersInfo.existingUsers.get(i).flags)) {
951                     totalAdminUsers++;
952                 }
953             }
954             if (totalAdminUsers == 1) {
955                 return logAndGetResults(userId,
956                         UserRemovalResult.STATUS_TARGET_USER_IS_LAST_ADMIN_USER);
957             }
958         }
959 
960         // First remove user from android and then remove from HAL because HAL remove user is one
961         // way call.
962         if (!mUserManager.removeUser(userId)) {
963             return logAndGetResults(userId, UserRemovalResult.STATUS_ANDROID_FAILURE);
964         }
965 
966         if (isUserHalSupported()) {
967             RemoveUserRequest request = new RemoveUserRequest();
968             request.removedUserInfo = halUser;
969             request.usersInfo = UserHalHelper.newUsersInfo(mUserManager);
970             mHal.removeUser(request);
971         }
972 
973         return logAndGetResults(userId, UserRemovalResult.STATUS_SUCCESSFUL);
974     }
975 
logAndGetResults(@serIdInt int userId, @UserRemovalResult.Status int result)976     private UserRemovalResult logAndGetResults(@UserIdInt int userId,
977             @UserRemovalResult.Status int result) {
978         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_RESP, userId, result);
979         return new UserRemovalResult(result);
980     }
981 
sendUserSwitchUiCallback(@serIdInt int targetUserId)982     private void sendUserSwitchUiCallback(@UserIdInt int targetUserId) {
983         if (mUserSwitchUiReceiver == null) {
984             Log.w(TAG_USER, "No User switch UI receiver.");
985             return;
986         }
987 
988         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_UI_REQ, targetUserId);
989         try {
990             mUserSwitchUiReceiver.send(targetUserId, null);
991         } catch (RemoteException e) {
992             Log.e(TAG_USER, "Error calling user switch UI receiver.", e);
993         }
994     }
995 
996     @Override
createUser(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, int timeoutMs, @NonNull AndroidFuture<UserCreationResult> receiver)997     public void createUser(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
998             int timeoutMs, @NonNull AndroidFuture<UserCreationResult> receiver) {
999         Objects.requireNonNull(userType, "user type cannot be null");
1000         Objects.requireNonNull(receiver, "receiver cannot be null");
1001         checkManageOrCreateUsersPermission("createUser");
1002         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_REQ, UserHelper.safeName(name),
1003                 userType, flags, timeoutMs);
1004 
1005         UserInfo newUser;
1006         try {
1007             newUser = mUserManager.createUser(name, userType, flags);
1008             if (newUser == null) {
1009                 Log.w(TAG, "um.createUser() returned null for user of type " + userType
1010                         + " and flags " + UserInfo.flagsToString(flags));
1011                 sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_ANDROID_FAILURE);
1012                 return;
1013             }
1014             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1015                 Log.d(TAG, "Created user: " + newUser.toFullString());
1016             }
1017             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_USER_CREATED, newUser.id,
1018                     UserHelper.safeName(newUser.name), newUser.userType, newUser.flags);
1019         } catch (RuntimeException e) {
1020             Log.e(TAG_USER, "Error creating user of type " + userType + " and flags"
1021                     + UserInfo.flagsToString(flags), e);
1022             sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_ANDROID_FAILURE);
1023             return;
1024         }
1025 
1026         if (!isUserHalSupported()) {
1027             sendUserCreationResult(receiver, UserCreationResult.STATUS_SUCCESSFUL, newUser, null);
1028             return;
1029         }
1030 
1031         CreateUserRequest request = new CreateUserRequest();
1032         request.usersInfo = UserHalHelper.newUsersInfo(mUserManager);
1033         if (!TextUtils.isEmpty(name)) {
1034             request.newUserName = name;
1035         }
1036         request.newUserInfo.userId = newUser.id;
1037         request.newUserInfo.flags = UserHalHelper.convertFlags(newUser);
1038         if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1039             Log.d(TAG, "Create user request: " + request);
1040         }
1041 
1042         try {
1043             mHal.createUser(request, timeoutMs, (status, resp) -> {
1044                 int resultStatus = UserCreationResult.STATUS_HAL_INTERNAL_FAILURE;
1045                 if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1046                     Log.d(TAG, "createUserResponse: status="
1047                             + UserHalHelper.halCallbackStatusToString(status) + ", resp=" + resp);
1048                 }
1049                 UserInfo user = null; // user returned in the result
1050                 if (status != HalCallback.STATUS_OK) {
1051                     Log.w(TAG, "invalid callback status ("
1052                             + UserHalHelper.halCallbackStatusToString(status) + ") for response "
1053                             + resp);
1054                     EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_RESP, status,
1055                             resultStatus, resp.errorMessage);
1056                     removeUser(newUser, "HAL call failed with "
1057                             + UserHalHelper.halCallbackStatusToString(status));
1058                     sendUserCreationResult(receiver, resultStatus, user, /* errorMsg= */ null);
1059                     return;
1060                 }
1061 
1062                 switch (resp.status) {
1063                     case CreateUserStatus.SUCCESS:
1064                         resultStatus = UserCreationResult.STATUS_SUCCESSFUL;
1065                         user = newUser;
1066                         break;
1067                     case CreateUserStatus.FAILURE:
1068                         // HAL failed to switch user
1069                         resultStatus = UserCreationResult.STATUS_HAL_FAILURE;
1070                         break;
1071                     default:
1072                         // Shouldn't happen because UserHalService validates the status
1073                         Log.wtf(TAG, "Received invalid user switch status from HAL: " + resp);
1074                 }
1075                 EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_RESP, status,
1076                         resultStatus, resp.errorMessage);
1077                 if (user == null) {
1078                     removeUser(newUser, "HAL returned "
1079                             + UserCreationResult.statusToString(resultStatus));
1080                 }
1081                 sendUserCreationResult(receiver, resultStatus, user, resp.errorMessage);
1082             });
1083         } catch (Exception e) {
1084             Log.w(TAG, "mHal.createUser(" + request + ") failed", e);
1085             removeUser(newUser, "mHal.createUser() failed");
1086             sendUserCreationResultFailure(receiver, UserCreationResult.STATUS_HAL_INTERNAL_FAILURE);
1087         }
1088     }
1089 
removeUser(@onNull UserInfo user, @NonNull String reason)1090     private void removeUser(@NonNull UserInfo user, @NonNull String reason) {
1091         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_USER_REMOVED, user.id, reason);
1092         try {
1093             if (!mUserManager.removeUser(user.id)) {
1094                 Log.w(TAG, "Failed to remove user " + user.toFullString());
1095             }
1096         } catch (Exception e) {
1097             Log.e(TAG, "Failed to remove user " + user.toFullString(), e);
1098         }
1099     }
1100 
1101     @Override
getUserIdentificationAssociation(int[] types)1102     public UserIdentificationAssociationResponse getUserIdentificationAssociation(int[] types) {
1103         if (!isUserHalUserAssociationSupported()) {
1104             return UserIdentificationAssociationResponse.forFailure(VEHICLE_HAL_NOT_SUPPORTED);
1105         }
1106 
1107         Preconditions.checkArgument(!ArrayUtils.isEmpty(types), "must have at least one type");
1108         checkManageUsersPermission("getUserIdentificationAssociation");
1109 
1110         int uid = getCallingUid();
1111         int userId = UserHandle.getUserId(uid);
1112         EventLog.writeEvent(EventLogTags.CAR_USER_MGR_GET_USER_AUTH_REQ, uid, userId);
1113 
1114         UserIdentificationGetRequest request = new UserIdentificationGetRequest();
1115         request.userInfo.userId = userId;
1116         request.userInfo.flags = getHalUserInfoFlags(userId);
1117 
1118         request.numberAssociationTypes = types.length;
1119         for (int i = 0; i < types.length; i++) {
1120             request.associationTypes.add(types[i]);
1121         }
1122 
1123         UserIdentificationResponse halResponse = mHal.getUserAssociation(request);
1124         if (halResponse == null) {
1125             Log.w(TAG, "getUserIdentificationAssociation(): HAL returned null for "
1126                     + Arrays.toString(types));
1127             return UserIdentificationAssociationResponse.forFailure();
1128         }
1129 
1130         int[] values = new int[halResponse.associations.size()];
1131         for (int i = 0; i < values.length; i++) {
1132             values[i] = halResponse.associations.get(i).value;
1133         }
1134         EventLog.writeEvent(EventLogTags.CAR_USER_MGR_GET_USER_AUTH_RESP, values.length);
1135 
1136         return UserIdentificationAssociationResponse.forSuccess(values, halResponse.errorMessage);
1137     }
1138 
1139     @Override
setUserIdentificationAssociation(int timeoutMs, int[] types, int[] values, AndroidFuture<UserIdentificationAssociationResponse> result)1140     public void setUserIdentificationAssociation(int timeoutMs, int[] types, int[] values,
1141             AndroidFuture<UserIdentificationAssociationResponse> result) {
1142         if (!isUserHalUserAssociationSupported()) {
1143             result.complete(
1144                     UserIdentificationAssociationResponse.forFailure(VEHICLE_HAL_NOT_SUPPORTED));
1145             return;
1146         }
1147 
1148         Preconditions.checkArgument(!ArrayUtils.isEmpty(types), "must have at least one type");
1149         Preconditions.checkArgument(!ArrayUtils.isEmpty(values), "must have at least one value");
1150         if (types.length != values.length) {
1151             throw new IllegalArgumentException("types (" + Arrays.toString(types) + ") and values ("
1152                     + Arrays.toString(values) + ") should have the same length");
1153         }
1154         checkManageUsersPermission("setUserIdentificationAssociation");
1155 
1156         int uid = getCallingUid();
1157         int userId = UserHandle.getUserId(uid);
1158         EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_REQ, uid, userId, types.length);
1159 
1160         UserIdentificationSetRequest request = new UserIdentificationSetRequest();
1161         request.userInfo.userId = userId;
1162         request.userInfo.flags = getHalUserInfoFlags(userId);
1163 
1164         request.numberAssociations = types.length;
1165         for (int i = 0; i < types.length; i++) {
1166             UserIdentificationSetAssociation association = new UserIdentificationSetAssociation();
1167             association.type = types[i];
1168             association.value = values[i];
1169             request.associations.add(association);
1170         }
1171 
1172         mHal.setUserAssociation(timeoutMs, request, (status, resp) -> {
1173             if (status != HalCallback.STATUS_OK) {
1174                 Log.w(TAG, "setUserIdentificationAssociation(): invalid callback status ("
1175                         + UserHalHelper.halCallbackStatusToString(status) + ") for response "
1176                         + resp);
1177                 if (resp == null || TextUtils.isEmpty(resp.errorMessage)) {
1178                     EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_RESP, 0);
1179                     result.complete(UserIdentificationAssociationResponse.forFailure());
1180                     return;
1181                 }
1182                 EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_RESP, 0,
1183                         resp.errorMessage);
1184                 result.complete(
1185                         UserIdentificationAssociationResponse.forFailure(resp.errorMessage));
1186                 return;
1187             }
1188             int respSize = resp.associations.size();
1189             EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SET_USER_AUTH_RESP, respSize,
1190                     resp.errorMessage);
1191 
1192             int[] responseTypes = new int[respSize];
1193             for (int i = 0; i < respSize; i++) {
1194                 responseTypes[i] = resp.associations.get(i).value;
1195             }
1196             UserIdentificationAssociationResponse response = UserIdentificationAssociationResponse
1197                     .forSuccess(responseTypes, resp.errorMessage);
1198             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1199                 Log.d(TAG, "setUserIdentificationAssociation(): resp= " + resp
1200                         + ", converted=" + response);
1201             }
1202             result.complete(response);
1203         });
1204     }
1205 
1206     /**
1207      * Gets the User HAL flags for the given user.
1208      *
1209      * @throws IllegalArgumentException if the user does not exist.
1210      */
getHalUserInfoFlags(@serIdInt int userId)1211     private int getHalUserInfoFlags(@UserIdInt int userId) {
1212         UserInfo user = mUserManager.getUserInfo(userId);
1213         Preconditions.checkArgument(user != null, "no user for id %d", userId);
1214         return UserHalHelper.convertFlags(user);
1215     }
1216 
sendResult(@onNull IResultReceiver receiver, int resultCode, @Nullable Bundle resultData)1217     private void sendResult(@NonNull IResultReceiver receiver, int resultCode,
1218             @Nullable Bundle resultData) {
1219         try {
1220             receiver.send(resultCode, resultData);
1221         } catch (RemoteException e) {
1222             // ignore
1223             Log.w(TAG_USER, "error while sending results", e);
1224         }
1225     }
1226 
sendUserSwitchResult(@onNull AndroidFuture<UserSwitchResult> receiver, @UserSwitchResult.Status int status)1227     private void sendUserSwitchResult(@NonNull AndroidFuture<UserSwitchResult> receiver,
1228             @UserSwitchResult.Status int status) {
1229         sendUserSwitchResult(receiver, status, /* errorMessage= */ null);
1230     }
1231 
sendUserSwitchResult(@onNull AndroidFuture<UserSwitchResult> receiver, @UserSwitchResult.Status int status, @Nullable String errorMessage)1232     private void sendUserSwitchResult(@NonNull AndroidFuture<UserSwitchResult> receiver,
1233             @UserSwitchResult.Status int status, @Nullable String errorMessage) {
1234         receiver.complete(new UserSwitchResult(status, errorMessage));
1235     }
1236 
sendUserCreationResultFailure(@onNull AndroidFuture<UserCreationResult> receiver, @UserCreationResult.Status int status)1237     private void sendUserCreationResultFailure(@NonNull AndroidFuture<UserCreationResult> receiver,
1238             @UserCreationResult.Status int status) {
1239         sendUserCreationResult(receiver, status, /* user= */ null, /* errorMessage= */ null);
1240     }
1241 
sendUserCreationResult(@onNull AndroidFuture<UserCreationResult> receiver, @UserCreationResult.Status int status, @NonNull UserInfo user, @Nullable String errorMessage)1242     private void sendUserCreationResult(@NonNull AndroidFuture<UserCreationResult> receiver,
1243             @UserCreationResult.Status int status, @NonNull UserInfo user,
1244             @Nullable String errorMessage) {
1245         if (TextUtils.isEmpty(errorMessage)) {
1246             errorMessage = null;
1247         }
1248         receiver.complete(new UserCreationResult(status, user, errorMessage));
1249     }
1250 
1251     /**
1252      * Calls activity manager for user switch.
1253      *
1254      * <p><b>NOTE</b> This method is meant to be called just by UserHalService.
1255      *
1256      * @param requestId for the user switch request
1257      * @param targetUserId of the target user
1258      *
1259      * @hide
1260      */
switchAndroidUserFromHal(int requestId, @UserIdInt int targetUserId)1261     public void switchAndroidUserFromHal(int requestId, @UserIdInt int targetUserId) {
1262         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_SWITCH_USER_FROM_HAL_REQ, requestId,
1263                 targetUserId);
1264         Log.i(TAG_USER, "User hal requested a user switch. Target user id " + targetUserId);
1265 
1266         try {
1267             boolean result = mAm.switchUser(targetUserId);
1268             if (result) {
1269                 updateUserSwitchInProcess(requestId, targetUserId);
1270             } else {
1271                 postSwitchHalResponse(requestId, targetUserId);
1272             }
1273         } catch (RemoteException e) {
1274             // ignore
1275             Log.w(TAG_USER, "error while switching user " + targetUserId, e);
1276         }
1277     }
1278 
updateUserSwitchInProcess(int requestId, @UserIdInt int targetUserId)1279     private void updateUserSwitchInProcess(int requestId, @UserIdInt int targetUserId) {
1280         synchronized (mLockUser) {
1281             if (mUserIdForUserSwitchInProcess != UserHandle.USER_NULL) {
1282                 // Some other user switch is in process.
1283                 if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1284                     Log.d(TAG_USER, "User switch for user: " + mUserIdForUserSwitchInProcess
1285                             + " is in process. Abandoning it as a new user switch is requested"
1286                             + " for the target user: " + targetUserId);
1287                 }
1288             }
1289             mUserIdForUserSwitchInProcess = targetUserId;
1290             mRequestIdForUserSwitchInProcess = requestId;
1291         }
1292     }
1293 
postSwitchHalResponse(int requestId, @UserIdInt int targetUserId)1294     private void postSwitchHalResponse(int requestId, @UserIdInt int targetUserId) {
1295         if (!isUserHalSupported()) return;
1296 
1297         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
1298         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_POST_SWITCH_USER_REQ, requestId,
1299                 targetUserId, usersInfo.currentUser.userId);
1300         SwitchUserRequest request = createUserSwitchRequest(targetUserId, usersInfo);
1301         request.requestId = requestId;
1302         mHal.postSwitchResponse(request);
1303     }
1304 
createUserSwitchRequest(@serIdInt int targetUserId, @NonNull UsersInfo usersInfo)1305     private SwitchUserRequest createUserSwitchRequest(@UserIdInt int targetUserId,
1306             @NonNull UsersInfo usersInfo) {
1307         UserInfo targetUser = mUserManager.getUserInfo(targetUserId);
1308         android.hardware.automotive.vehicle.V2_0.UserInfo halTargetUser =
1309                 new android.hardware.automotive.vehicle.V2_0.UserInfo();
1310         halTargetUser.userId = targetUser.id;
1311         halTargetUser.flags = UserHalHelper.convertFlags(targetUser);
1312         SwitchUserRequest request = new SwitchUserRequest();
1313         request.targetUser = halTargetUser;
1314         request.usersInfo = usersInfo;
1315         return request;
1316     }
1317 
1318     /**
1319      * Checks if the User HAL is supported.
1320      */
isUserHalSupported()1321     public boolean isUserHalSupported() {
1322         return mHal.isSupported();
1323     }
1324 
1325     /**
1326      * Checks if the User HAL user association is supported.
1327      */
1328     @Override
isUserHalUserAssociationSupported()1329     public boolean isUserHalUserAssociationSupported() {
1330         return mHal.isUserAssociationSupported();
1331     }
1332 
1333     /**
1334      * Sets a callback which is invoked before user switch.
1335      *
1336      * <p>
1337      * This method should only be called by the Car System UI. The purpose of this call is to notify
1338      * Car System UI to show the user switch UI before the user switch.
1339      */
1340     @Override
setUserSwitchUiCallback(@onNull IResultReceiver receiver)1341     public void setUserSwitchUiCallback(@NonNull IResultReceiver receiver) {
1342         checkManageUsersPermission("setUserSwitchUiCallback");
1343 
1344         // Confirm that caller is system UI.
1345         String systemUiPackageName = getSystemUiPackageName();
1346         if (systemUiPackageName == null) {
1347             throw new IllegalStateException("System UI package not found.");
1348         }
1349 
1350         try {
1351             int systemUiUid = mContext
1352                     .createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0).getPackageManager()
1353                     .getPackageUid(systemUiPackageName, PackageManager.MATCH_SYSTEM_ONLY);
1354             int callerUid = Binder.getCallingUid();
1355             if (systemUiUid != callerUid) {
1356                 throw new SecurityException("Invalid caller. Only" + systemUiPackageName
1357                         + " is allowed to make this call");
1358             }
1359         } catch (NameNotFoundException e) {
1360             throw new IllegalStateException("Package " + systemUiPackageName + " not found.");
1361         }
1362 
1363         mUserSwitchUiReceiver = receiver;
1364     }
1365 
1366     // TODO(157082995): This information can be taken from
1367     // PackageManageInternalImpl.getSystemUiServiceComponent
1368     @Nullable
getSystemUiPackageName()1369     private String getSystemUiPackageName() {
1370         try {
1371             ComponentName componentName = ComponentName.unflattenFromString(mContext.getResources()
1372                     .getString(com.android.internal.R.string.config_systemUIServiceComponent));
1373             return componentName.getPackageName();
1374         } catch (RuntimeException e) {
1375             Log.w(TAG_USER, "error while getting system UI package name.", e);
1376             return null;
1377         }
1378     }
1379 
updateDefaultUserRestriction()1380     private void updateDefaultUserRestriction() {
1381         // We want to set restrictions on system and guest users only once. These are persisted
1382         // onto disk, so it's sufficient to do it once + we minimize the number of disk writes.
1383         if (Settings.Global.getInt(mContext.getContentResolver(),
1384                 CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, /* default= */ 0) != 0) {
1385             return;
1386         }
1387         // Only apply the system user restrictions if the system user is headless.
1388         if (UserManager.isHeadlessSystemUserMode()) {
1389             setSystemUserRestrictions();
1390         }
1391         Settings.Global.putInt(mContext.getContentResolver(),
1392                 CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, 1);
1393     }
1394 
isPersistentUser(@serIdInt int userId)1395     private boolean isPersistentUser(@UserIdInt int userId) {
1396         return !mUserManager.getUserInfo(userId).isEphemeral();
1397     }
1398 
1399     /**
1400      * Adds a new {@link UserLifecycleListener} to listen to user activity events.
1401      */
addUserLifecycleListener(@onNull UserLifecycleListener listener)1402     public void addUserLifecycleListener(@NonNull UserLifecycleListener listener) {
1403         Objects.requireNonNull(listener, "listener cannot be null");
1404         mHandler.post(() -> mUserLifecycleListeners.add(listener));
1405     }
1406 
1407     /**
1408      * Removes previously added {@link UserLifecycleListener}.
1409      */
removeUserLifecycleListener(@onNull UserLifecycleListener listener)1410     public void removeUserLifecycleListener(@NonNull UserLifecycleListener listener) {
1411         Objects.requireNonNull(listener, "listener cannot be null");
1412         mHandler.post(() -> mUserLifecycleListeners.remove(listener));
1413     }
1414 
1415     /** Adds callback to listen to passenger activity events. */
addPassengerCallback(@onNull PassengerCallback callback)1416     public void addPassengerCallback(@NonNull PassengerCallback callback) {
1417         Objects.requireNonNull(callback, "callback cannot be null");
1418         mPassengerCallbacks.add(callback);
1419     }
1420 
1421     /** Removes previously added callback to listen passenger events. */
removePassengerCallback(@onNull PassengerCallback callback)1422     public void removePassengerCallback(@NonNull PassengerCallback callback) {
1423         Objects.requireNonNull(callback, "callback cannot be null");
1424         mPassengerCallbacks.remove(callback);
1425     }
1426 
1427     /** Sets the implementation of ZoneUserBindingHelper. */
setZoneUserBindingHelper(@onNull ZoneUserBindingHelper helper)1428     public void setZoneUserBindingHelper(@NonNull ZoneUserBindingHelper helper) {
1429         synchronized (mLockHelper) {
1430             mZoneUserBindingHelper = helper;
1431         }
1432     }
1433 
onUserUnlocked(@serIdInt int userId)1434     private void onUserUnlocked(@UserIdInt int userId) {
1435         ArrayList<Runnable> tasks = null;
1436         synchronized (mLockUser) {
1437             sendPostSwitchToHalLocked(userId);
1438             if (userId == UserHandle.USER_SYSTEM) {
1439                 if (!mUser0Unlocked) { // user 0, unlocked, do this only once
1440                     updateDefaultUserRestriction();
1441                     tasks = new ArrayList<>(mUser0UnlockTasks);
1442                     mUser0UnlockTasks.clear();
1443                     mUser0Unlocked = true;
1444                 }
1445             } else { // none user0
1446                 Integer user = userId;
1447                 if (isPersistentUser(userId)) {
1448                     // current foreground user should stay in top priority.
1449                     if (userId == ActivityManager.getCurrentUser()) {
1450                         mBackgroundUsersToRestart.remove(user);
1451                         mBackgroundUsersToRestart.add(0, user);
1452                     }
1453                     // -1 for user 0
1454                     if (mBackgroundUsersToRestart.size() > (mMaxRunningUsers - 1)) {
1455                         int userToDrop = mBackgroundUsersToRestart.get(
1456                                 mBackgroundUsersToRestart.size() - 1);
1457                         Log.i(TAG_USER, "New user unlocked:" + userId
1458                                 + ", dropping least recently user from restart list:" + userToDrop);
1459                         // Drop the least recently used user.
1460                         mBackgroundUsersToRestart.remove(mBackgroundUsersToRestart.size() - 1);
1461                     }
1462                 }
1463             }
1464         }
1465         if (tasks != null && tasks.size() > 0) {
1466             Log.d(TAG_USER, "User0 unlocked, run queued tasks:" + tasks.size());
1467             for (Runnable r : tasks) {
1468                 r.run();
1469             }
1470         }
1471     }
1472 
1473     /**
1474      * Starts all background users that were active in system.
1475      *
1476      * @return list of background users started successfully.
1477      */
1478     @NonNull
startAllBackgroundUsers()1479     public ArrayList<Integer> startAllBackgroundUsers() {
1480         ArrayList<Integer> users;
1481         synchronized (mLockUser) {
1482             users = new ArrayList<>(mBackgroundUsersToRestart);
1483             mBackgroundUsersRestartedHere.clear();
1484             mBackgroundUsersRestartedHere.addAll(mBackgroundUsersToRestart);
1485         }
1486         ArrayList<Integer> startedUsers = new ArrayList<>();
1487         for (Integer user : users) {
1488             if (user == ActivityManager.getCurrentUser()) {
1489                 continue;
1490             }
1491             try {
1492                 if (mAm.startUserInBackground(user)) {
1493                     if (mUserManager.isUserUnlockingOrUnlocked(user)) {
1494                         // already unlocked / unlocking. No need to unlock.
1495                         startedUsers.add(user);
1496                     } else if (mAm.unlockUser(user, null, null, null)) {
1497                         startedUsers.add(user);
1498                     } else { // started but cannot unlock
1499                         Log.w(TAG_USER, "Background user started but cannot be unlocked:" + user);
1500                         if (mUserManager.isUserRunning(user)) {
1501                             // add to started list so that it can be stopped later.
1502                             startedUsers.add(user);
1503                         }
1504                     }
1505                 }
1506             } catch (RemoteException e) {
1507                 // ignore
1508                 Log.w(TAG_USER, "error while starting user in background", e);
1509             }
1510         }
1511         // Keep only users that were re-started in mBackgroundUsersRestartedHere
1512         synchronized (mLockUser) {
1513             ArrayList<Integer> usersToRemove = new ArrayList<>();
1514             for (Integer user : mBackgroundUsersToRestart) {
1515                 if (!startedUsers.contains(user)) {
1516                     usersToRemove.add(user);
1517                 }
1518             }
1519             mBackgroundUsersRestartedHere.removeAll(usersToRemove);
1520         }
1521         return startedUsers;
1522     }
1523 
1524     /**
1525      * Stops all background users that were active in system.
1526      *
1527      * @return whether stopping succeeds.
1528      */
stopBackgroundUser(@serIdInt int userId)1529     public boolean stopBackgroundUser(@UserIdInt int userId) {
1530         if (userId == UserHandle.USER_SYSTEM) {
1531             return false;
1532         }
1533         if (userId == ActivityManager.getCurrentUser()) {
1534             Log.i(TAG_USER, "stopBackgroundUser, already a FG user:" + userId);
1535             return false;
1536         }
1537         try {
1538             int r = mAm.stopUserWithDelayedLocking(userId, true, null);
1539             if (r == ActivityManager.USER_OP_SUCCESS) {
1540                 synchronized (mLockUser) {
1541                     Integer user = userId;
1542                     mBackgroundUsersRestartedHere.remove(user);
1543                 }
1544             } else if (r == ActivityManager.USER_OP_IS_CURRENT) {
1545                 return false;
1546             } else {
1547                 Log.i(TAG_USER, "stopBackgroundUser failed, user:" + userId + " err:" + r);
1548                 return false;
1549             }
1550         } catch (RemoteException e) {
1551             // ignore
1552             Log.w(TAG_USER, "error while stopping user", e);
1553         }
1554         return true;
1555     }
1556 
1557     /**
1558      * Notifies all registered {@link UserLifecycleListener} with the event passed as argument.
1559      */
onUserLifecycleEvent(@serLifecycleEventType int eventType, long timestampMs, @UserIdInt int fromUserId, @UserIdInt int toUserId)1560     public void onUserLifecycleEvent(@UserLifecycleEventType int eventType, long timestampMs,
1561             @UserIdInt int fromUserId, @UserIdInt int toUserId) {
1562         int userId = toUserId;
1563 
1564         // Handle special cases first...
1565         if (eventType == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
1566             onUserSwitching(fromUserId, toUserId);
1567         } else if (eventType == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) {
1568             onUserUnlocked(userId);
1569         }
1570 
1571         // ...then notify listeners.
1572         UserLifecycleEvent event = new UserLifecycleEvent(eventType, fromUserId, userId);
1573 
1574         mHandler.post(() -> {
1575             handleNotifyServiceUserLifecycleListeners(event);
1576             handleNotifyAppUserLifecycleListeners(event);
1577         });
1578 
1579         if (timestampMs != 0) {
1580             // Finally, update metrics.
1581             mUserMetrics.onEvent(eventType, timestampMs, fromUserId, toUserId);
1582         }
1583     }
1584 
1585     /**
1586      * Sets the first user unlocking metrics.
1587      */
onFirstUserUnlocked(@serIdInt int userId, long timestampMs, long duration, int halResponseTime)1588     public void onFirstUserUnlocked(@UserIdInt int userId, long timestampMs, long duration,
1589             int halResponseTime) {
1590         mUserMetrics.logFirstUnlockedUser(userId, timestampMs, duration, halResponseTime);
1591     }
1592 
sendPostSwitchToHalLocked(@serIdInt int userId)1593     private void sendPostSwitchToHalLocked(@UserIdInt int userId) {
1594         if (mUserIdForUserSwitchInProcess == UserHandle.USER_NULL
1595                 || mUserIdForUserSwitchInProcess != userId
1596                 || mRequestIdForUserSwitchInProcess == 0) {
1597             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1598                 Log.d(TAG_USER, "No user switch request Id. No android post switch sent.");
1599             }
1600             return;
1601         }
1602         postSwitchHalResponse(mRequestIdForUserSwitchInProcess, mUserIdForUserSwitchInProcess);
1603         mUserIdForUserSwitchInProcess = UserHandle.USER_NULL;
1604         mRequestIdForUserSwitchInProcess = 0;
1605     }
1606 
handleNotifyAppUserLifecycleListeners(UserLifecycleEvent event)1607     private void handleNotifyAppUserLifecycleListeners(UserLifecycleEvent event) {
1608         int listenersSize = mAppLifecycleListeners.size();
1609         if (listenersSize == 0) {
1610             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1611                 Log.d(TAG_USER, "No app listener to be notified of " + event);
1612             }
1613             return;
1614         }
1615         // Must use a different TimingsTraceLog because it's another thread
1616         if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1617             Log.d(TAG_USER, "Notifying " + listenersSize + " app listeners of " + event);
1618         }
1619         int userId = event.getUserId();
1620         TimingsTraceLog t = new TimingsTraceLog(TAG_USER, Trace.TRACE_TAG_SYSTEM_SERVER);
1621         int eventType = event.getEventType();
1622         t.traceBegin("notify-app-listeners-user-" + userId + "-event-" + eventType);
1623         for (int i = 0; i < listenersSize; i++) {
1624             int uid = mAppLifecycleListeners.keyAt(i);
1625 
1626             IResultReceiver listener = mAppLifecycleListeners.valueAt(i);
1627             Bundle data = new Bundle();
1628             data.putInt(CarUserManager.BUNDLE_PARAM_ACTION, eventType);
1629 
1630             int fromUserId = event.getPreviousUserId();
1631             if (fromUserId != UserHandle.USER_NULL) {
1632                 data.putInt(CarUserManager.BUNDLE_PARAM_PREVIOUS_USER_ID, fromUserId);
1633             }
1634 
1635             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1636                 Log.d(TAG_USER, "Notifying listener for uid " + uid);
1637             }
1638             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_NOTIFY_APP_LIFECYCLE_LISTENER,
1639                     uid, eventType, fromUserId, userId);
1640             try {
1641                 t.traceBegin("notify-app-listener-uid-" + uid);
1642                 listener.send(userId, data);
1643             } catch (RemoteException e) {
1644                 Log.e(TAG_USER, "Error calling lifecycle listener", e);
1645             } finally {
1646                 t.traceEnd();
1647             }
1648         }
1649         t.traceEnd(); // notify-app-listeners-user-USERID-event-EVENT_TYPE
1650     }
1651 
handleNotifyServiceUserLifecycleListeners(UserLifecycleEvent event)1652     private void handleNotifyServiceUserLifecycleListeners(UserLifecycleEvent event) {
1653         TimingsTraceLog t = new TimingsTraceLog(TAG_USER, Trace.TRACE_TAG_SYSTEM_SERVER);
1654         if (mUserLifecycleListeners.isEmpty()) {
1655             Log.w(TAG_USER, "Not notifying internal UserLifecycleListeners");
1656             return;
1657         } else if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1658             Log.d(TAG_USER, "Notifying " + mUserLifecycleListeners.size() + " service listeners of "
1659                     + event);
1660         }
1661 
1662         int userId = event.getUserId();
1663         int eventType = event.getEventType();
1664         t.traceBegin("notify-listeners-user-" + userId + "-event-" + eventType);
1665         for (UserLifecycleListener listener : mUserLifecycleListeners) {
1666             String listenerName = FunctionalUtils.getLambdaName(listener);
1667             EventLog.writeEvent(EventLogTags.CAR_USER_SVC_NOTIFY_INTERNAL_LIFECYCLE_LISTENER,
1668                     listenerName, eventType, event.getPreviousUserId(), userId);
1669             try {
1670                 t.traceBegin("notify-listener-" + listenerName);
1671                 listener.onEvent(event);
1672             } catch (RuntimeException e) {
1673                 Log.e(TAG_USER,
1674                         "Exception raised when invoking onEvent for " + listenerName, e);
1675             } finally {
1676                 t.traceEnd();
1677             }
1678         }
1679         t.traceEnd(); // notify-listeners-user-USERID-event-EVENT_TYPE
1680     }
1681 
onUserSwitching(@serIdInt int fromUserId, @UserIdInt int toUserId)1682     private void onUserSwitching(@UserIdInt int fromUserId, @UserIdInt int toUserId) {
1683         Log.i(TAG_USER, "onUserSwitching() callback for user " + toUserId);
1684         TimingsTraceLog t = new TimingsTraceLog(TAG_USER, Trace.TRACE_TAG_SYSTEM_SERVER);
1685         t.traceBegin("onUserSwitching-" + toUserId);
1686 
1687         // Switch HAL users if user switch is not requested by CarUserService
1688         notifyHalLegacySwitch(fromUserId, toUserId);
1689 
1690         mCarUserManagerHelper.setLastActiveUser(toUserId);
1691 
1692         if (mLastPassengerId != UserHandle.USER_NULL) {
1693             stopPassengerInternal(mLastPassengerId, false);
1694         }
1695         if (mEnablePassengerSupport && isPassengerDisplayAvailable()) {
1696             setupPassengerUser();
1697             startFirstPassenger(toUserId);
1698         }
1699         t.traceEnd();
1700     }
1701 
notifyHalLegacySwitch(@serIdInt int fromUserId, @UserIdInt int toUserId)1702     private void notifyHalLegacySwitch(@UserIdInt int fromUserId, @UserIdInt int toUserId) {
1703         synchronized (mLockUser) {
1704             if (mUserIdForUserSwitchInProcess != UserHandle.USER_NULL) {
1705                 if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
1706                     Log.d(TAG, "notifyHalLegacySwitch(" + fromUserId + ", " + toUserId
1707                             + "): not needed, normal switch for " + mUserIdForUserSwitchInProcess);
1708                 }
1709                 return;
1710             }
1711         }
1712 
1713         if (!isUserHalSupported()) return;
1714 
1715         // switch HAL user
1716         UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager, fromUserId);
1717         SwitchUserRequest request = createUserSwitchRequest(toUserId, usersInfo);
1718         mHal.legacyUserSwitch(request);
1719     }
1720 
1721     /**
1722      * Runs the given runnable when user 0 is unlocked. If user 0 is already unlocked, it is
1723      * run inside this call.
1724      *
1725      * @param r Runnable to run.
1726      */
runOnUser0Unlock(@onNull Runnable r)1727     public void runOnUser0Unlock(@NonNull Runnable r) {
1728         Objects.requireNonNull(r, "runnable cannot be null");
1729         boolean runNow = false;
1730         synchronized (mLockUser) {
1731             if (mUser0Unlocked) {
1732                 runNow = true;
1733             } else {
1734                 mUser0UnlockTasks.add(r);
1735             }
1736         }
1737         if (runNow) {
1738             r.run();
1739         }
1740     }
1741 
1742     @VisibleForTesting
1743     @NonNull
getBackgroundUsersToRestart()1744     ArrayList<Integer> getBackgroundUsersToRestart() {
1745         ArrayList<Integer> backgroundUsersToRestart = null;
1746         synchronized (mLockUser) {
1747             backgroundUsersToRestart = new ArrayList<>(mBackgroundUsersToRestart);
1748         }
1749         return backgroundUsersToRestart;
1750     }
1751 
setSystemUserRestrictions()1752     private void setSystemUserRestrictions() {
1753         // Disable Location service for system user.
1754         LocationManager locationManager =
1755                 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
1756         locationManager.setLocationEnabledForUser(
1757                 /* enabled= */ false, UserHandle.of(UserHandle.USER_SYSTEM));
1758     }
1759 
1760     /**
1761      * Assigns a default icon to a user according to the user's id.
1762      *
1763      * @param userInfo User whose avatar is set to default icon.
1764      */
assignDefaultIcon(UserInfo userInfo)1765     private void assignDefaultIcon(UserInfo userInfo) {
1766         int idForIcon = userInfo.isGuest() ? UserHandle.USER_NULL : userInfo.id;
1767         Bitmap bitmap = UserIcons.convertToBitmap(
1768                 UserIcons.getDefaultUserIcon(mContext.getResources(), idForIcon, false));
1769         mUserManager.setUserIcon(userInfo.id, bitmap);
1770     }
1771 
1772     private interface UserFilter {
isEligibleUser(UserInfo user)1773         boolean isEligibleUser(UserInfo user);
1774     }
1775 
1776     /** Returns all users who are matched by the given filter. */
getUsers(UserFilter filter)1777     private List<UserInfo> getUsers(UserFilter filter) {
1778         List<UserInfo> users = mUserManager.getUsers(/* excludeDying= */ true);
1779 
1780         for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) {
1781             UserInfo user = iterator.next();
1782             if (!filter.isEligibleUser(user)) {
1783                 iterator.remove();
1784             }
1785         }
1786         return users;
1787     }
1788 
1789     /**
1790      * Enforces that apps which have the
1791      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
1792      * can make certain calls to the CarUserManager.
1793      *
1794      * @param message used as message if SecurityException is thrown.
1795      * @throws SecurityException if the caller is not system or root.
1796      */
checkManageUsersPermission(String message)1797     private static void checkManageUsersPermission(String message) {
1798         checkAtLeastOnePermission(message, android.Manifest.permission.MANAGE_USERS);
1799     }
1800 
checkManageOrCreateUsersPermission(String message)1801     private static void checkManageOrCreateUsersPermission(String message) {
1802         checkAtLeastOnePermission(message,
1803                 android.Manifest.permission.MANAGE_USERS,
1804                 android.Manifest.permission.CREATE_USERS);
1805     }
1806 
checkManageUsersOrDumpPermission(String message)1807     private static void checkManageUsersOrDumpPermission(String message) {
1808         checkAtLeastOnePermission(message,
1809                 android.Manifest.permission.MANAGE_USERS,
1810                 android.Manifest.permission.DUMP);
1811     }
1812 
checkInteractAcrossUsersPermission(String message)1813     private void checkInteractAcrossUsersPermission(String message) {
1814         checkAtLeastOnePermission(message, android.Manifest.permission.INTERACT_ACROSS_USERS,
1815                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
1816     }
1817 
checkAtLeastOnePermission(String message, String...permissions)1818     private static void checkAtLeastOnePermission(String message, String...permissions) {
1819         int callingUid = Binder.getCallingUid();
1820         if (!hasAtLeastOnePermissionGranted(callingUid, permissions)) {
1821             throw new SecurityException("You need one of " + Arrays.toString(permissions)
1822                     + " to: " + message);
1823         }
1824     }
1825 
hasAtLeastOnePermissionGranted(int uid, String... permissions)1826     private static boolean hasAtLeastOnePermissionGranted(int uid, String... permissions) {
1827         for (String permission : permissions) {
1828             if (ActivityManager.checkComponentPermission(permission, uid, /* owningUid = */-1,
1829                     /* exported = */ true)
1830                     == android.content.pm.PackageManager.PERMISSION_GRANTED) {
1831                 return true;
1832             }
1833         }
1834         return false;
1835     }
1836 
getNumberOfManagedProfiles(@serIdInt int userId)1837     private int getNumberOfManagedProfiles(@UserIdInt int userId) {
1838         List<UserInfo> users = mUserManager.getUsers(/* excludeDying= */true);
1839         // Count all users that are managed profiles of the given user.
1840         int managedProfilesCount = 0;
1841         for (UserInfo user : users) {
1842             if (user.isManagedProfile() && user.profileGroupId == userId) {
1843                 managedProfilesCount++;
1844             }
1845         }
1846         return managedProfilesCount;
1847     }
1848 
1849     /**
1850      * Starts the first passenger of the given driver and assigns the passenger to the front
1851      * passenger zone.
1852      *
1853      * @param driverId User id of the driver.
1854      * @return whether it succeeds.
1855      */
startFirstPassenger(@serIdInt int driverId)1856     private boolean startFirstPassenger(@UserIdInt int driverId) {
1857         int zoneId = getAvailablePassengerZone();
1858         if (zoneId == OccupantZoneInfo.INVALID_ZONE_ID) {
1859             Log.w(TAG_USER, "passenger occupant zone is not found");
1860             return false;
1861         }
1862         List<UserInfo> passengers = getPassengers(driverId);
1863         if (passengers.size() < 1) {
1864             Log.w(TAG_USER, "passenger is not found");
1865             return false;
1866         }
1867         // Only one passenger is supported. If there are two or more passengers, the first passenger
1868         // is chosen.
1869         int passengerId = passengers.get(0).id;
1870         if (!startPassenger(passengerId, zoneId)) {
1871             Log.w(TAG_USER, "cannot start passenger " + passengerId);
1872             return false;
1873         }
1874         return true;
1875     }
1876 
getAvailablePassengerZone()1877     private int getAvailablePassengerZone() {
1878         int[] occupantTypes = new int[] {CarOccupantZoneManager.OCCUPANT_TYPE_FRONT_PASSENGER,
1879                 CarOccupantZoneManager.OCCUPANT_TYPE_REAR_PASSENGER};
1880         for (int occupantType : occupantTypes) {
1881             int zoneId = getZoneId(occupantType);
1882             if (zoneId != OccupantZoneInfo.INVALID_ZONE_ID) {
1883                 return zoneId;
1884             }
1885         }
1886         return OccupantZoneInfo.INVALID_ZONE_ID;
1887     }
1888 
1889     /**
1890      * Creates a new passenger user when there is no passenger user.
1891      */
setupPassengerUser()1892     private void setupPassengerUser() {
1893         int currentUser = ActivityManager.getCurrentUser();
1894         int profileCount = getNumberOfManagedProfiles(currentUser);
1895         if (profileCount > 0) {
1896             Log.w(TAG_USER, "max profile of user" + currentUser
1897                     + " is exceeded: current profile count is " + profileCount);
1898             return;
1899         }
1900         // TODO(b/140311342): Use resource string for the default passenger name.
1901         UserInfo passenger = createPassenger("Passenger", currentUser);
1902         if (passenger == null) {
1903             // Couldn't create user, most likely because there are too many.
1904             Log.w(TAG_USER, "cannot create a passenger user");
1905             return;
1906         }
1907     }
1908 
1909     @NonNull
getOccupantZones(@ccupantTypeEnum int occupantType)1910     private List<OccupantZoneInfo> getOccupantZones(@OccupantTypeEnum int occupantType) {
1911         ZoneUserBindingHelper helper = null;
1912         synchronized (mLockHelper) {
1913             if (mZoneUserBindingHelper == null) {
1914                 Log.w(TAG_USER, "implementation is not delegated");
1915                 return new ArrayList<OccupantZoneInfo>();
1916             }
1917             helper = mZoneUserBindingHelper;
1918         }
1919         return helper.getOccupantZones(occupantType);
1920     }
1921 
assignUserToOccupantZone(@serIdInt int userId, int zoneId)1922     private boolean assignUserToOccupantZone(@UserIdInt int userId, int zoneId) {
1923         ZoneUserBindingHelper helper = null;
1924         synchronized (mLockHelper) {
1925             if (mZoneUserBindingHelper == null) {
1926                 Log.w(TAG_USER, "implementation is not delegated");
1927                 return false;
1928             }
1929             helper = mZoneUserBindingHelper;
1930         }
1931         return helper.assignUserToOccupantZone(userId, zoneId);
1932     }
1933 
unassignUserFromOccupantZone(@serIdInt int userId)1934     private boolean unassignUserFromOccupantZone(@UserIdInt int userId) {
1935         ZoneUserBindingHelper helper = null;
1936         synchronized (mLockHelper) {
1937             if (mZoneUserBindingHelper == null) {
1938                 Log.w(TAG_USER, "implementation is not delegated");
1939                 return false;
1940             }
1941             helper = mZoneUserBindingHelper;
1942         }
1943         return helper.unassignUserFromOccupantZone(userId);
1944     }
1945 
isPassengerDisplayAvailable()1946     private boolean isPassengerDisplayAvailable() {
1947         ZoneUserBindingHelper helper = null;
1948         synchronized (mLockHelper) {
1949             if (mZoneUserBindingHelper == null) {
1950                 Log.w(TAG_USER, "implementation is not delegated");
1951                 return false;
1952             }
1953             helper = mZoneUserBindingHelper;
1954         }
1955         return helper.isPassengerDisplayAvailable();
1956     }
1957 
1958     /**
1959      * Gets the zone id of the given occupant type. If there are two or more zones, the first found
1960      * zone is returned.
1961      *
1962      * @param occupantType The type of an occupant.
1963      * @return The zone id of the given occupant type. {@link OccupantZoneInfo.INVALID_ZONE_ID},
1964      *         if not found.
1965      */
getZoneId(@ccupantTypeEnum int occupantType)1966     private int getZoneId(@OccupantTypeEnum int occupantType) {
1967         List<OccupantZoneInfo> zoneInfos = getOccupantZones(occupantType);
1968         return (zoneInfos.size() > 0) ? zoneInfos.get(0).zoneId : OccupantZoneInfo.INVALID_ZONE_ID;
1969     }
1970 }
1971