Added isSupported() method on UserHalService.
This method should be called to make sure the Vehicle Hal supports user
management.
Test: atest CarServiceUnitTest:com.android.car.hal.UserHalServiceTest
Bug: 146207078
Change-Id: I89ab9bb0159ae1a64dafa109cdda5c26ac44c551
diff --git a/service/src/com/android/car/hal/UserHalService.java b/service/src/com/android/car/hal/UserHalService.java
index ab44046..4ce7c16 100644
--- a/service/src/com/android/car/hal/UserHalService.java
+++ b/service/src/com/android/car/hal/UserHalService.java
@@ -37,7 +37,6 @@
import android.util.SparseArray;
import com.android.car.CarLog;
-import com.android.car.hal.UserHalService.HalCallback.HalCallbackStatus;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -54,6 +53,8 @@
*/
public final class UserHalService extends HalServiceBase {
+ private static final String UNSUPPORTED_MSG = "Vehicle HAL does not support user management";
+
private static final String TAG = CarLog.TAG_USER;
// TODO(b/146207078): STOPSHIP - change to false before R is launched
@@ -64,7 +65,8 @@
private final VehicleHal mHal;
@GuardedBy("mLock")
- private final SparseArray<VehiclePropConfig> mProperties = new SparseArray<>(1);
+ @Nullable
+ private SparseArray<VehiclePropConfig> mProperties;
// NOTE: handler is currently only used to check if HAL times out replying to requests, by
// posting messages whose id is the request id. If it needs to be used for more messages, we'll
@@ -131,19 +133,28 @@
@Nullable
public Collection<VehiclePropConfig> takeSupportedProperties(
Collection<VehiclePropConfig> allProperties) {
- ArrayList<VehiclePropConfig> supported = new ArrayList<>();
- synchronized (mLock) {
- for (VehiclePropConfig config : allProperties) {
- switch (config.prop) {
- case INITIAL_USER_INFO:
- supported.add(config);
- mProperties.put(config.prop, config);
- break;
- }
-
+ boolean supported = false;
+ // TODO(b/146207078): increase capacity once it supports more
+ SparseArray<VehiclePropConfig> properties = new SparseArray<>(1);
+ ArrayList<VehiclePropConfig> taken = new ArrayList<>();
+ for (VehiclePropConfig config : allProperties) {
+ switch (config.prop) {
+ case INITIAL_USER_INFO:
+ supported = true;
+ taken.add(config);
+ properties.put(config.prop, config);
+ break;
}
+
}
- return supported.isEmpty() ? null : supported;
+ if (!supported) {
+ Log.w(TAG, UNSUPPORTED_MSG);
+ return null;
+ }
+ synchronized (mLock) {
+ mProperties = properties;
+ }
+ return taken;
}
/**
@@ -179,6 +190,19 @@
}
/**
+ * Checks if the Vehicle HAL supports user management.
+ */
+ public boolean isSupported() {
+ synchronized (mLock) {
+ return mProperties != null;
+ }
+ }
+
+ private void checkSupportedLocked() {
+ Preconditions.checkState(isSupported(), UNSUPPORTED_MSG);
+ }
+
+ /**
* Calls HAL to asynchronously get info about the initial user.
*
* @param requestType type of request (as defined by
@@ -186,6 +210,9 @@
* @param timeoutMs how long to wait (in ms) for the property change event.
* @param usersInfo current state of Android users.
* @param callback callback to handle the response.
+ *
+ * @throws IllegalStateException if the HAL does not support user management (callers should
+ * call {@link #isSupported()} first to avoid this exception).
*/
public void getInitialUserInfo(int requestType, int timeoutMs, @NonNull UsersInfo usersInfo,
@NonNull HalCallback<InitialUserInfoResponse> callback) {
@@ -199,6 +226,7 @@
propRequest.prop = INITIAL_USER_INFO;
int requestId;
synchronized (mLock) {
+ checkSupportedLocked();
requestId = mNextRequestId++;
// TODO(b/146207078): use helper method to convert request to prop value
propRequest.value.int32Values.add(requestId);
@@ -307,6 +335,16 @@
public void dump(PrintWriter writer) {
writer.printf("*User HAL*\n");
synchronized (mLock) {
+ if (!isSupported()) {
+ writer.println(UNSUPPORTED_MSG);
+ return;
+ }
+ int numberProperties = mProperties.size();
+ String indent = " ";
+ writer.printf("%d supported properties\n", numberProperties);
+ for (int i = 0; i < numberProperties; i++) {
+ writer.printf("%s%s\n", indent, mProperties.valueAt(i));
+ }
writer.printf("next request id: %d\n", mNextRequestId);
if (mPendingCallbacks.size() == 0) {
writer.println("no pending callbacks");
diff --git a/tests/carservice_unit_test/src/com/android/car/hal/UserHalServiceTest.java b/tests/carservice_unit_test/src/com/android/car/hal/UserHalServiceTest.java
index a18a73d..9e3c4e3 100644
--- a/tests/carservice_unit_test/src/com/android/car/hal/UserHalServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/hal/UserHalServiceTest.java
@@ -99,6 +99,8 @@
@Before
public void setFixtures() {
mUserHalService = new UserHalService(mVehicleHal);
+ mUserHalService
+ .takeSupportedProperties(Arrays.asList(newSubscribableConfig(INITIAL_USER_INFO)));
mUser0.userId = 0;
mUser0.flags = 100;
@@ -114,24 +116,32 @@
@Test
public void testTakeSupportedProperties_unsupportedOnly() {
+ // Cannot use mUserHalService because it's already set with supported properties
+ UserHalService myHalService = new UserHalService(mVehicleHal);
+
List<VehiclePropConfig> input = Arrays.asList(newConfig(CURRENT_GEAR));
- Collection<VehiclePropConfig> output = mUserHalService.takeSupportedProperties(input);
+ Collection<VehiclePropConfig> output = myHalService.takeSupportedProperties(input);
+ assertThat(myHalService.isSupported()).isFalse();
assertThat(output).isNull();
}
@Test
public void testTakeSupportedPropertiesAndInit() {
+ // Cannot use mUserHalService because it's already set with supported properties
+ UserHalService myHalService = new UserHalService(mVehicleHal);
+
VehiclePropConfig unsupportedConfig = newConfig(CURRENT_GEAR);
VehiclePropConfig userInfoConfig = newSubscribableConfig(INITIAL_USER_INFO);
List<VehiclePropConfig> input = Arrays.asList(unsupportedConfig, userInfoConfig);
- Collection<VehiclePropConfig> output = mUserHalService.takeSupportedProperties(input);
+ Collection<VehiclePropConfig> output = myHalService.takeSupportedProperties(input);
+ assertThat(mUserHalService.isSupported()).isTrue();
assertThat(output).containsExactly(userInfoConfig);
// Ideally there should be 2 test methods (one for takeSupportedProperties() and one for
// init()), but on "real life" VehicleHal calls these 2 methods in sequence, and the latter
// depends on the properties set by the former, so it's ok to test both here...
- mUserHalService.init();
- verify(mVehicleHal).subscribeProperty(mUserHalService, INITIAL_USER_INFO);
+ myHalService.init();
+ verify(mVehicleHal).subscribeProperty(myHalService, INITIAL_USER_INFO);
}
@Test