Moved Initial User setter logic from CarServiceHelperService to CarUserService
Bug: 158026653
Bug: 160819016
Test: atest CarServiceUnitTest:com.android.car.user.CarUserServiceTest
atest CarServicesTest:com.android.internal.car.CarHelperServiceTest
Change-Id: I3799f75f3d24bb8b3e9cab277a5dae5920ab6726
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index e4aeea8..8c2634c 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -40,6 +40,8 @@
import android.car.userlib.CarUserManagerHelper;
import android.car.userlib.CommonConstants.CarUserServiceConstants;
import android.car.userlib.HalCallback;
+import android.car.userlib.InitialUserSetter;
+import android.car.userlib.InitialUserSetter.InitialUserInfo;
import android.car.userlib.UserHalHelper;
import android.car.userlib.UserHelper;
import android.content.ComponentName;
@@ -52,6 +54,7 @@
import android.graphics.Bitmap;
import android.hardware.automotive.vehicle.V2_0.CreateUserRequest;
import android.hardware.automotive.vehicle.V2_0.CreateUserStatus;
+import android.hardware.automotive.vehicle.V2_0.InitialUserInfoRequestType;
import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponse;
import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction;
import android.hardware.automotive.vehicle.V2_0.RemoveUserRequest;
@@ -141,6 +144,7 @@
private final IActivityManager mAm;
private final UserManager mUserManager;
private final int mMaxRunningUsers;
+ private final InitialUserSetter mInitialUserSetter;
private final boolean mEnablePassengerSupport;
private final Object mLockUser = new Object();
@@ -234,13 +238,14 @@
@NonNull CarUserManagerHelper carUserManagerHelper, @NonNull UserManager userManager,
@NonNull IActivityManager am, int maxRunningUsers) {
this(context, hal, carUserManagerHelper, userManager, am, maxRunningUsers,
- new UserMetrics());
+ new UserMetrics(), /* initialUserSetter= */ null);
}
@VisibleForTesting
CarUserService(@NonNull Context context, @NonNull UserHalService hal,
@NonNull CarUserManagerHelper carUserManagerHelper, @NonNull UserManager userManager,
- @NonNull IActivityManager am, int maxRunningUsers, UserMetrics userMetrics) {
+ @NonNull IActivityManager am, int maxRunningUsers, @NonNull UserMetrics userMetrics,
+ @Nullable InitialUserSetter initialUserSetter) {
if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
Log.d(TAG_USER, "constructed");
}
@@ -253,6 +258,11 @@
mLastPassengerId = UserHandle.USER_NULL;
mEnablePassengerSupport = context.getResources().getBoolean(R.bool.enablePassengerSupport);
mUserMetrics = userMetrics;
+ if (initialUserSetter == null) {
+ mInitialUserSetter = new InitialUserSetter(context, (u) -> setInitialUser(u));
+ } else {
+ mInitialUserSetter = initialUserSetter;
+ }
}
@Override
@@ -695,17 +705,6 @@
}
}
- // TODO(b/150413515): temporary method called by ICarImpl.setInitialUser(int userId), as for
- // some reason passing the whole UserInfo through a raw binder transaction is not working.
- /**
- * Sets the initial foreground user after the device boots or resumes from suspension.
- */
- public void setInitialUser(@UserIdInt int userId) {
- UserInfo initialUser = userId == UserHandle.USER_NULL ? null
- : mUserManager.getUserInfo(userId);
- setInitialUser(initialUser);
- }
-
/**
* Sets the initial foreground user after the device boots or resumes from suspension.
*/
@@ -724,6 +723,90 @@
}
/**
+ * Call to start user at the android startup.
+ */
+ public void initBootUser() {
+ int requestType = getInitialUserInfoRequestType();
+ EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_REQ, requestType,
+ mHalTimeoutMs);
+ checkManageUsersPermission("startInitialUser");
+
+ if (!isUserHalSupported()) {
+ fallbackToDefaultInitialUserBehavior(/* userLocales= */ null);
+ return;
+ }
+
+ UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
+ mHal.getInitialUserInfo(requestType, mHalTimeoutMs, usersInfo, (status, resp) -> {
+ if (resp != null) {
+ EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_RESP,
+ status, resp.action, resp.userToSwitchOrCreate.userId,
+ resp.userToSwitchOrCreate.flags, resp.userNameToCreate, resp.userLocales);
+
+ String userLocales = resp.userLocales;
+ InitialUserInfo info;
+ switch (resp.action) {
+ case InitialUserInfoResponseAction.SWITCH:
+ int userId = resp.userToSwitchOrCreate.userId;
+ if (userId <= 0) {
+ Log.w(TAG, "invalid (or missing) user id sent by HAL: " + userId);
+ fallbackToDefaultInitialUserBehavior(userLocales);
+ break;
+ }
+ info = new InitialUserSetter.Builder(InitialUserSetter.TYPE_SWITCH)
+ .setUserLocales(userLocales)
+ .setSwitchUserId(userId)
+ .build();
+ mInitialUserSetter.set(info);
+ break;
+
+ case InitialUserInfoResponseAction.CREATE:
+ int halFlags = resp.userToSwitchOrCreate.flags;
+ String userName = resp.userNameToCreate;
+ info = new InitialUserSetter.Builder(InitialUserSetter.TYPE_CREATE)
+ .setUserLocales(userLocales)
+ .setNewUserName(userName)
+ .setNewUserFlags(halFlags)
+ .build();
+ mInitialUserSetter.set(info);
+ break;
+
+ case InitialUserInfoResponseAction.DEFAULT:
+ fallbackToDefaultInitialUserBehavior(userLocales);
+ break;
+ default:
+ Log.w(TAG_USER, "invalid response action on " + resp);
+ fallbackToDefaultInitialUserBehavior(/* user locale */ null);
+ break;
+
+ }
+ } else {
+ EventLog.writeEvent(EventLogTags.CAR_USER_SVC_INITIAL_USER_INFO_RESP, status);
+ fallbackToDefaultInitialUserBehavior(/* user locale */ null);
+ }
+ });
+ }
+
+ private void fallbackToDefaultInitialUserBehavior(String userLocales) {
+ InitialUserInfo info = new InitialUserSetter.Builder(
+ InitialUserSetter.TYPE_DEFAULT_BEHAVIOR)
+ .setUserLocales(userLocales)
+ .build();
+ mInitialUserSetter.set(info);
+ }
+
+ @VisibleForTesting
+ int getInitialUserInfoRequestType() {
+ if (!mCarUserManagerHelper.hasInitialUser()) {
+ return InitialUserInfoRequestType.FIRST_BOOT;
+ }
+ if (mContext.getPackageManager().isDeviceUpgrading()) {
+ return InitialUserInfoRequestType.FIRST_BOOT_AFTER_OTA;
+ }
+ return InitialUserInfoRequestType.COLD_BOOT;
+ }
+
+ /**
* Calls the User HAL to get the initial user info.
*
* @param requestType type as defined by {@code InitialUserInfoRequestType}.