Make removeUser call asynchronous for CarUserService
Bug: 179823276
Bug: 181295928
Test: atest CarServiceUnitTest:com.android.car.user.CarUserServiceTest
atest CarServiceUnitTest:com.android.car.user.CarUserManagerUnitTest
atest CarServiceUnitTest:com.android.car.admin.CarDevicePolicyServiceTest
atest CarServiceUnitTest:android.car.admin.CarDevicePolicyManagerUnitTest
atest CarSecurityPermissionTest:com.android.car.user.CarUserManagerPermissionTest
Change-Id: Iea51003c5efdc0502efa3f17afdca58dc93ee1b0
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index 36f97f7..8fc0da5 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -1103,8 +1103,8 @@
}
@Override
- public UserRemovalResult removeUser(@UserIdInt int userId) {
- return removeUser(userId, /* hasCallerRestrictions= */ false);
+ public void removeUser(@UserIdInt int userId, AndroidFuture<UserRemovalResult> receiver) {
+ removeUser(userId, /* hasCallerRestrictions= */ false, receiver);
}
/**
@@ -1114,20 +1114,14 @@
* @param userId user to be removed
* @param hasCallerRestrictions when {@code true}, if the caller user is not an admin, it can
* only remove itself.
- *
- * @return result of the operation.
+ * @param receiver to post results
*/
- public UserRemovalResult removeUser(@UserIdInt int userId, boolean hasCallerRestrictions) {
+ public void removeUser(@UserIdInt int userId, boolean hasCallerRestrictions,
+ AndroidFuture<UserRemovalResult> receiver) {
checkManageOrCreateUsersPermission("removeUser");
EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_REQ, userId,
hasCallerRestrictions ? 1 : 0);
- // If requested user is the only admin user, return error.
- UserInfo userInfo = mUserManager.getUserInfo(userId);
- if (userInfo == null) {
- return logAndGetResults(userId, UserRemovalResult.STATUS_USER_DOES_NOT_EXIST);
- }
-
if (hasCallerRestrictions) {
// Restrictions: non-admin user can only remove itself, admins have no restrictions
int callingUserId = Binder.getCallingUserHandle().getIdentifier();
@@ -1137,7 +1131,16 @@
+ " can only remove itself");
}
}
+ mHandler.post(()-> removeUserInternal(userId, hasCallerRestrictions, receiver));
+ }
+ private void removeUserInternal(@UserIdInt int userId, boolean hasCallerRestrictions,
+ AndroidFuture<UserRemovalResult> receiver) {
+ UserInfo userInfo = mUserManager.getUserInfo(userId);
+ if (userInfo == null) {
+ sendUserRemovalResult(userId, UserRemovalResult.STATUS_USER_DOES_NOT_EXIST, receiver);
+ return;
+ }
android.hardware.automotive.vehicle.V2_0.UserInfo halUser =
new android.hardware.automotive.vehicle.V2_0.UserInfo();
halUser.userId = userInfo.id;
@@ -1168,7 +1171,8 @@
boolean evenWhenDisallowed = hasCallerRestrictions;
int result = mUserManager.removeUserOrSetEphemeral(userId, evenWhenDisallowed);
if (result == UserManager.REMOVE_RESULT_ERROR) {
- return logAndGetResults(userId, UserRemovalResult.STATUS_ANDROID_FAILURE);
+ sendUserRemovalResult(userId, UserRemovalResult.STATUS_ANDROID_FAILURE, receiver);
+ return;
}
if (isLastAdmin) {
@@ -1179,15 +1183,15 @@
switch (result) {
case UserManager.REMOVE_RESULT_REMOVED:
case UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED:
- return logAndGetResults(userId,
+ sendUserRemovalResult(userId,
isLastAdmin ? UserRemovalResult.STATUS_SUCCESSFUL_LAST_ADMIN_REMOVED
- : UserRemovalResult.STATUS_SUCCESSFUL);
+ : UserRemovalResult.STATUS_SUCCESSFUL, receiver);
case UserManager.REMOVE_RESULT_SET_EPHEMERAL:
- return logAndGetResults(userId,
+ sendUserRemovalResult(userId,
isLastAdmin ? UserRemovalResult.STATUS_SUCCESSFUL_LAST_ADMIN_SET_EPHEMERAL
- : UserRemovalResult.STATUS_SUCCESSFUL_SET_EPHEMERAL);
+ : UserRemovalResult.STATUS_SUCCESSFUL_SET_EPHEMERAL, receiver);
default:
- throw new IllegalStateException("Unknown user removal result code " + result);
+ sendUserRemovalResult(userId, UserRemovalResult.STATUS_ANDROID_FAILURE, receiver);
}
}
@@ -1237,10 +1241,10 @@
mHal.removeUser(request);
}
- private UserRemovalResult logAndGetResults(@UserIdInt int userId,
- @UserRemovalResult.Status int result) {
+ private void sendUserRemovalResult(@UserIdInt int userId, @UserRemovalResult.Status int result,
+ AndroidFuture<UserRemovalResult> receiver) {
EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_RESP, userId, result);
- return new UserRemovalResult(result);
+ receiver.complete(new UserRemovalResult(result));
}
private void sendUserSwitchUiCallback(@UserIdInt int targetUserId) {