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