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