Merge "Enable removed api dex for car-lib" into rvc-dev
diff --git a/FrameworkPackageStubs/AndroidManifest.xml b/FrameworkPackageStubs/AndroidManifest.xml
index 912944c..6c25bcd 100644
--- a/FrameworkPackageStubs/AndroidManifest.xml
+++ b/FrameworkPackageStubs/AndroidManifest.xml
@@ -95,6 +95,10 @@
                 <action android:name="android.settings.USER_DICTIONARY_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
+            <intent-filter android:priority="-1">
+                <action android:name="android.settings.PICTURE_IN_PICTURE_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
         </activity>
 
         <!-- CDD Core Application Intents Stubs -->
diff --git a/car-internal-lib/src/com/android/internal/car/EventLogTags.logtags b/car-internal-lib/src/com/android/internal/car/EventLogTags.logtags
index 0c634ae..46af12b 100644
--- a/car-internal-lib/src/com/android/internal/car/EventLogTags.logtags
+++ b/car-internal-lib/src/com/android/internal/car/EventLogTags.logtags
@@ -82,6 +82,10 @@
 150116 car_user_svc_create_user_resp (status|1),(result|1),(error_message|3)
 150117 car_user_svc_create_user_user_created (user_id|1),(safe_name|3),(user_type|3),(flags|1)
 150118 car_user_svc_create_user_user_removed (user_id|1),(reason|3)
+150119 car_user_svc_remove_user_req (user_id|1)
+150120 car_user_svc_remove_user_resp (user_id|1),(result|1)
+150121 car_user_svc_notify_app_lifecycle_listener (uid|1),(event_type|1),(from_user_id|1),(to_user_id|1)
+150122 car_user_svc_notify_internal_lifecycle_listener (listener_name|3),(event_type|1),(from_user_id|1),(to_user_id|1)
 
 150140 car_user_hal_initial_user_info_req (request_id|1),(request_type|1),(timeout|1)
 150141 car_user_hal_initial_user_info_resp (request_id|1),(status|1),(action|1),(user_id|1),(flags|1),(safe_name|3),(user_locales|3)
@@ -96,15 +100,19 @@
 150150 car_user_hal_oem_switch_user_req (request_id|1),(target_user_id|1)
 150151 car_user_hal_create_user_req (request_id|1),(safe_name|3),(flags|1),(timeout|1)
 150152 car_user_hal_create_user_resp (request_id|1),(status|1),(result|1),(error_message|3)
+150153 car_user_hal_remove_user_req (target_user_id|1),(current_user_id|1)
 
 150171 car_user_mgr_add_listener (uid|1)
 150172 car_user_mgr_remove_listener (uid|1)
 150173 car_user_mgr_disconnected (uid|1)
-150174 car_user_mgr_switch_user_request (uid|1),(user_id|1)
-150175 car_user_mgr_switch_user_response (uid|1),(status|1),(error_message|3)
+150174 car_user_mgr_switch_user_req (uid|1),(user_id|1)
+150175 car_user_mgr_switch_user_resp (uid|1),(status|1),(error_message|3)
 150176 car_user_mgr_get_user_auth_req (types|4)
 150177 car_user_mgr_get_user_auth_resp (values|4)
 150178 car_user_mgr_set_user_auth_req (types_and_values_pairs|4)
 150179 car_user_mgr_set_user_auth_resp (values|4)
 150180 car_user_mgr_create_user_req (uid|1),(safe_name|3),(user_type|3),(flags|1)
 150181 car_user_mgr_create_user_resp (uid|1),(status|1),(error_message|3)
+150182 car_user_mgr_remove_user_req (uid|1),(user_id|1)
+150183 car_user_mgr_remove_user_resp (uid|1),(status|1)
+150184 car_user_mgr_notify_lifecycle_listener (number_listeners|1),(event_type|1),(from_user_id|1),(to_user_id|1)
diff --git a/car-lib/Android.bp b/car-lib/Android.bp
index fbc68c7..39db28e 100644
--- a/car-lib/Android.bp
+++ b/car-lib/Android.bp
@@ -196,7 +196,7 @@
 droidstubs {
     name: "android.car-test-stubs-docs",
     defaults: ["android.car-docs-default"],
-    args: "--hide UnavailableSymbol --no-docs --stub-packages android.car* " +
+    args: "--hide HiddenSuperclass --hide UnavailableSymbol --no-docs --stub-packages android.car* " +
         "--show-annotation android.annotation.TestApi ",
     installable: false,
     check_api: {
@@ -219,7 +219,7 @@
         "android.car",
     ],
     api_filename: "api.txt",
-    args: "--hide UnavailableSymbol --no-docs --stub-packages android.car* ",
+    args: "--hide HiddenSuperclass --hide UnavailableSymbol --no-docs --stub-packages android.car* ",
     installable: false,
     product_variables: {
         pdk: {
diff --git a/car-lib/src/android/car/ICarUserService.aidl b/car-lib/src/android/car/ICarUserService.aidl
index df5e6ab..b3823b3 100644
--- a/car-lib/src/android/car/ICarUserService.aidl
+++ b/car-lib/src/android/car/ICarUserService.aidl
@@ -18,6 +18,7 @@
 
 import android.content.pm.UserInfo;
 import android.car.user.UserCreationResult;
+import android.car.user.UserRemovalResult;
 import android.car.user.UserIdentificationAssociationResponse;
 import android.car.user.UserSwitchResult;
 import com.android.internal.infra.AndroidFuture;
@@ -25,13 +26,14 @@
 
 /** @hide */
 interface ICarUserService {
-    UserInfo createDriver(@nullable String name, boolean admin);
+    AndroidFuture<UserCreationResult> createDriver(@nullable String name, boolean admin);
     UserInfo createPassenger(@nullable String name, int driverId);
     void switchDriver(int driverId, in AndroidFuture<UserSwitchResult> receiver);
     void switchUser(int tagerUserId, int timeoutMs, in AndroidFuture<UserSwitchResult> receiver);
     void setUserSwitchUiCallback(in IResultReceiver callback);
     void createUser(@nullable String name, String userType, int flags, int timeoutMs,
       in AndroidFuture<UserCreationResult> receiver);
+    UserRemovalResult removeUser(int userId);
     List<UserInfo> getAllDrivers();
     List<UserInfo> getPassengers(int driverId);
     boolean startPassenger(int passengerId, int zoneId);
diff --git a/car-lib/src/android/car/cluster/renderer/InstrumentClusterRenderingService.java b/car-lib/src/android/car/cluster/renderer/InstrumentClusterRenderingService.java
index 5272548..cdf0cca 100644
--- a/car-lib/src/android/car/cluster/renderer/InstrumentClusterRenderingService.java
+++ b/car-lib/src/android/car/cluster/renderer/InstrumentClusterRenderingService.java
@@ -412,13 +412,13 @@
             startActivityAsUser(intent, mActivityOptions.toBundle(), UserHandle.CURRENT);
             Log.i(TAG, String.format("Activity launched: %s (options: %s, displayId: %d)",
                     mActivityOptions, intent, mActivityOptions.getLaunchDisplayId()));
-        } catch (ActivityNotFoundException ex) {
+        } catch (ActivityNotFoundException e) {
             Log.w(TAG, "Unable to find activity for intent: " + intent);
             return false;
-        } catch (Exception ex) {
+        } catch (RuntimeException e) {
             // Catch all other possible exception to prevent service disruption by misbehaving
             // applications.
-            Log.e(TAG, "Error trying to launch intent: " + intent + ". Ignored", ex);
+            Log.e(TAG, "Error trying to launch intent: " + intent + ". Ignored", e);
             return false;
         }
         return true;
diff --git a/car-lib/src/android/car/hardware/hvac/CarHvacManager.java b/car-lib/src/android/car/hardware/hvac/CarHvacManager.java
index 54bda19..971f1fc 100644
--- a/car-lib/src/android/car/hardware/hvac/CarHvacManager.java
+++ b/car-lib/src/android/car/hardware/hvac/CarHvacManager.java
@@ -25,8 +25,6 @@
 import android.car.hardware.property.CarPropertyManager;
 import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
 import android.car.hardware.property.ICarProperty;
-import android.car.hardware.property.PropertyAccessDeniedSecurityException;
-import android.car.hardware.property.PropertyNotAvailableException;
 import android.os.IBinder;
 import android.util.ArraySet;
 import android.util.Log;
@@ -351,12 +349,9 @@
                     mCarPropertyMgr.unregisterCallback(mListenerToBase, c.getPropertyId());
 
                 }
-            } catch (PropertyAccessDeniedSecurityException
-                    | PropertyNotAvailableException
-                    | IllegalArgumentException e) {
+            } catch (RuntimeException e) {
                 Log.e(TAG, "getPropertyList exception ", e);
             }
-
             if (mCallbacks.isEmpty()) {
                 mCarPropertyMgr.unregisterCallback(mListenerToBase);
                 mListenerToBase = null;
diff --git a/car-lib/src/android/car/media/CarAudioManager.java b/car-lib/src/android/car/media/CarAudioManager.java
index 31eb173..9f57617 100644
--- a/car-lib/src/android/car/media/CarAudioManager.java
+++ b/car-lib/src/android/car/media/CarAudioManager.java
@@ -32,8 +32,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
-import android.view.Display;
-import android.view.DisplayAddress;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -538,43 +536,6 @@
     }
 
     /**
-     * Get the zone id for the display
-     *
-     * @param  display display to query
-     * @return zone id for display or
-     * CarAudioManager.PRIMARY_AUDIO_ZONE if no match is found.
-     * @hide
-     */
-    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
-    public int getZoneIdForDisplay(Display display) {
-        DisplayAddress address = display.getAddress();
-        if (address instanceof DisplayAddress.Physical) {
-            DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) address;
-            if (physicalAddress != null) {
-                return getZoneIdForDisplayPortId(physicalAddress.getPort());
-            }
-        }
-        return PRIMARY_AUDIO_ZONE;
-    }
-
-    /**
-     * Get the zone id for the display port id passed in
-     *
-     * @param  displayPortId display port id to query
-     * @return zone id for display port id or
-     * CarAudioManager.PRIMARY_AUDIO_ZONE if no match is found.
-     * @hide
-     */
-    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
-    public int getZoneIdForDisplayPortId(byte displayPortId) {
-        try {
-            return mService.getZoneIdForDisplayPortId(displayPortId);
-        } catch (RemoteException e) {
-            return handleRemoteExceptionFromCarService(e, 0);
-        }
-    }
-
-    /**
      * Gets the output device for a given {@link AudioAttributes} usage in zoneId.
      *
      * <p><b>Note:</b> To be used for routing to a specific device. Most applications should
diff --git a/car-lib/src/android/car/media/ICarAudio.aidl b/car-lib/src/android/car/media/ICarAudio.aidl
index 7491a19..a8997ce 100644
--- a/car-lib/src/android/car/media/ICarAudio.aidl
+++ b/car-lib/src/android/car/media/ICarAudio.aidl
@@ -48,8 +48,6 @@
     boolean setZoneIdForUid(int zoneId, int uid);
     boolean clearZoneIdForUid(int uid);
 
-    int getZoneIdForDisplayPortId(byte displayPortId);
-
     String getOutputDeviceAddressForUsage(int zoneId, int usage);
 
     List<AudioDeviceAttributes> getInputDevicesForZoneId(int zoneId);
diff --git a/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java b/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
index ac59bac..6f993e3 100644
--- a/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
+++ b/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
@@ -47,9 +47,17 @@
     private final SingleMessageHandler<IoStats> mMessageHandler;
     private final Set<IoStatsListener> mListeners = new HashSet<>();
 
+    /**
+     * Implementers will be notified on every new I/O activity calculated stats.
+     */
     public interface IoStatsListener {
+
+        /**
+         * Invoked when a new periodic snapshot delta of I/O activities is calculated.
+         */
         void onSnapshot(IoStats snapshot);
     }
+
     private static final class ListenerToService extends IIoStatsListener.Stub {
         private final WeakReference<CarStorageMonitoringManager> mManager;
 
@@ -109,7 +117,7 @@
      * It will return either PRE_EOL_INFO_UNKNOWN if the value can't be determined,
      * or one of PRE_EOL_INFO_{NORMAL|WARNING|URGENT} depending on the device state.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public int getPreEolIndicatorStatus() {
         try {
             return mService.getPreEolIndicatorStatus();
@@ -127,7 +135,7 @@
      *
      * If either or both indicators are not available, they will be reported as UNKNOWN.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public WearEstimate getWearEstimate() {
         try {
             return mService.getWearEstimate();
@@ -147,7 +155,7 @@
      *
      * If no indicators are available, an empty list will be returned.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public List<WearEstimateChange> getWearEstimateHistory() {
         try {
             return mService.getWearEstimateHistory();
@@ -166,7 +174,7 @@
      *
      * If the information is not available, an empty list will be returned.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public List<IoStatsEntry> getBootIoStats() {
         try {
             return mService.getBootIoStats();
@@ -196,7 +204,7 @@
      *
      * <p>If the information is not available, SHUTDOWN_COST_INFO_MISSING will be returned.</p>s
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public long getShutdownDiskWriteAmount() {
         try {
             return mService.getShutdownDiskWriteAmount();
@@ -213,7 +221,7 @@
      *
      * If the information is not available, an empty list will be returned.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public List<IoStatsEntry> getAggregateIoStats() {
         try {
             return mService.getAggregateIoStats();
@@ -233,7 +241,7 @@
      *
      * If the information is not available, an empty list will be returned.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public List<IoStats> getIoStatsDeltas() {
         try {
             return mService.getIoStatsDeltas();
@@ -250,7 +258,7 @@
      *
      * The timing of availability of the deltas is configurable by the OEM.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public void registerListener(IoStatsListener listener) {
         try {
             if (mListeners.isEmpty()) {
@@ -268,7 +276,7 @@
     /**
      * This method removes a registered listener of I/O stats deltas.
      */
-    @RequiresPermission(value=Car.PERMISSION_STORAGE_MONITORING)
+    @RequiresPermission(value = Car.PERMISSION_STORAGE_MONITORING)
     public void unregisterListener(IoStatsListener listener) {
         try {
             if (!mListeners.remove(listener)) {
diff --git a/car-lib/src/android/car/user/CarUserManager.java b/car-lib/src/android/car/user/CarUserManager.java
index 1525889..a4daa42 100644
--- a/car-lib/src/android/car/user/CarUserManager.java
+++ b/car-lib/src/android/car/user/CarUserManager.java
@@ -20,6 +20,8 @@
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static android.os.Process.myUid;
 
+import static com.android.internal.util.FunctionalUtils.getLambdaName;
+
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -57,6 +59,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
 
 /**
  * API to manage users related to car.
@@ -209,7 +212,7 @@
                 @Override
                 protected void onCompleted(UserSwitchResult result, Throwable err) {
                     if (result != null) {
-                        EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SWITCH_USER_RESPONSE, uid,
+                        EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SWITCH_USER_RESP, uid,
                                 result.getStatus(), result.getErrorMessage());
                     } else {
                         Log.w(TAG, "switchUser(" + targetUserId + ") failed: " + err);
@@ -217,7 +220,7 @@
                     super.onCompleted(result, err);
                 };
             };
-            EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SWITCH_USER_REQUEST, uid, targetUserId);
+            EventLog.writeEvent(EventLogTags.CAR_USER_MGR_SWITCH_USER_REQ, uid, targetUserId);
             mService.switchUser(targetUserId, HAL_TIMEOUT_MS, future);
             return future;
         } catch (RemoteException e) {
@@ -264,6 +267,28 @@
         }
     }
 
+     /**
+     * Removes a user.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    public UserRemovalResult removeUser(@UserIdInt int userId) {
+        int uid = myUid();
+        EventLog.writeEvent(EventLogTags.CAR_USER_MGR_REMOVE_USER_REQ, uid, userId);
+        int status = UserRemovalResult.STATUS_HAL_INTERNAL_FAILURE;
+        try {
+            UserRemovalResult result = mService.removeUser(userId);
+            status = result.getStatus();
+            return result;
+        } catch (RemoteException e) {
+            return handleRemoteExceptionFromCarService(e,
+                    new UserRemovalResult(UserRemovalResult.STATUS_HAL_INTERNAL_FAILURE));
+        } finally {
+            EventLog.writeEvent(EventLogTags.CAR_USER_MGR_REMOVE_USER_RESP, uid, status);
+        }
+    }
+
     /**
      * Adds a listener for {@link UserLifecycleEvent user lifecycle events}.
      *
@@ -298,6 +323,12 @@
 
             if (mListeners == null) {
                 mListeners = new ArrayMap<>(1); // Most likely app will have just one listener
+            } else if (DBG) {
+                Log.d(TAG, "addListener(" + getLambdaName(listener) + "): context " + getContext()
+                        + " already has " + mListeners.size() + " listeners: "
+                        + mListeners.keySet().stream()
+                                .map((l) -> getLambdaName(l))
+                                .collect(Collectors.toList()), new Exception());
             }
             if (DBG) Log.d(TAG, "Adding listener: " + listener);
             mListeners.put(listener, executor);
@@ -480,10 +511,15 @@
                 Log.w(TAG, "No listeners for event " + event);
                 return;
             }
-            for (int i = 0; i < listeners.size(); i++) {
+            int size = listeners.size();
+            EventLog.writeEvent(EventLogTags.CAR_USER_MGR_NOTIFY_LIFECYCLE_LISTENER,
+                    size, eventType, from, to);
+            for (int i = 0; i < size; i++) {
                 UserLifecycleListener listener = listeners.keyAt(i);
                 Executor executor = listeners.valueAt(i);
-                if (DBG) Log.d(TAG, "Calling listener " + listener + " for event " + event);
+                if (DBG) {
+                    Log.d(TAG, "Calling " + getLambdaName(listener) + " for event " + event);
+                }
                 executor.execute(() -> listener.onEvent(event));
             }
         }
diff --git a/car-lib/src/android/car/user/ExperimentalCarUserManager.java b/car-lib/src/android/car/user/ExperimentalCarUserManager.java
index 1396971..fa7eb72 100644
--- a/car-lib/src/android/car/user/ExperimentalCarUserManager.java
+++ b/car-lib/src/android/car/user/ExperimentalCarUserManager.java
@@ -72,19 +72,21 @@
      *
      * @param name The name of the driver to be created.
      * @param admin Whether the created driver will be an admin.
-     * @return user id of the created driver, or {@code INVALID_USER_ID} if the driver could
-     *         not be created.
+     * @return an {@link AndroidFuture} that can be used to track operation's completion and
+     *         retrieve its result (if any).
      *
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
-    @Nullable
-    public int createDriver(@NonNull String name, boolean admin) {
+    public AndroidFuture<UserCreationResult> createDriver(@NonNull String name, boolean admin) {
         try {
-            UserInfo ui = mService.createDriver(name, admin);
-            return ui != null ? ui.id : INVALID_USER_ID;
+            return mService.createDriver(name, admin);
         } catch (RemoteException e) {
-            return handleRemoteExceptionFromCarService(e, null);
+            AndroidFuture<UserCreationResult> future = new AndroidFuture<>();
+            future.complete(new UserCreationResult(UserCreationResult.STATUS_HAL_INTERNAL_FAILURE,
+                    null, null));
+            handleRemoteExceptionFromCarService(e);
+            return future;
         }
     }
 
diff --git a/car-lib/src/android/car/user/UserCreationResult.java b/car-lib/src/android/car/user/UserCreationResult.java
index a79abee..328908f 100644
--- a/car-lib/src/android/car/user/UserCreationResult.java
+++ b/car-lib/src/android/car/user/UserCreationResult.java
@@ -69,15 +69,21 @@
     public static final int STATUS_HAL_INTERNAL_FAILURE = CommonResults.STATUS_HAL_INTERNAL_FAILURE;
 
     /**
-     * Gets the user switch result status.
+     * {@link Status} called when given parameters or environment states are invalid for creating
+     * user - HAL or Android user creation is not requested.
+     */
+    public static final int STATUS_INVALID_REQUEST = CommonResults.STATUS_INVALID_REQUEST;
+
+    /**
+     * Gets the user creation result status.
      *
      * @return either {@link UserCreationResult#STATUS_SUCCESSFUL},
      *         {@link UserCreationResult#STATUS_ANDROID_FAILURE},
      *         {@link UserCreationResult#STATUS_HAL_FAILURE},
-     *         or
-     *         {@link UserCreationResult#STATUS_HAL_INTERNAL_FAILURE}
+     *         {@link UserCreationResult#STATUS_HAL_INTERNAL_FAILURE}, or
+     *         {@link UserCreationResult#STATUS_INVALID_REQUEST}.
      */
-    private final int mStatus;
+    private final @Status int mStatus;
 
     /**
      * Gets the created user.
@@ -98,6 +104,8 @@
         return mStatus == STATUS_SUCCESSFUL;
     }
 
+    // TODO(b/158195639): if you change any status constant, you need to manually assign its values
+
 
 
     // Code below generated by codegen v1.0.15.
@@ -118,7 +126,8 @@
         STATUS_SUCCESSFUL,
         STATUS_ANDROID_FAILURE,
         STATUS_HAL_FAILURE,
-        STATUS_HAL_INTERNAL_FAILURE
+        STATUS_HAL_INTERNAL_FAILURE,
+        STATUS_INVALID_REQUEST
     })
     @Retention(RetentionPolicy.SOURCE)
     @DataClass.Generated.Member
@@ -136,6 +145,8 @@
                     return "STATUS_HAL_FAILURE";
             case STATUS_HAL_INTERNAL_FAILURE:
                     return "STATUS_HAL_INTERNAL_FAILURE";
+            case STATUS_INVALID_REQUEST:
+                    return "STATUS_INVALID_REQUEST";
             default: return Integer.toHexString(value);
         }
     }
@@ -144,13 +155,13 @@
      * Creates a new UserCreationResult.
      *
      * @param status
-     *   Gets the user switch result status.
+     *   Gets the user creation result status.
      *
      *   @return either {@link UserCreationResult#STATUS_SUCCESSFUL},
      *           {@link UserCreationResult#STATUS_ANDROID_FAILURE},
      *           {@link UserCreationResult#STATUS_HAL_FAILURE},
-     *           or
-     *           {@link UserCreationResult#STATUS_HAL_INTERNAL_FAILURE}
+     *           {@link UserCreationResult#STATUS_HAL_INTERNAL_FAILURE}, or
+     *           {@link UserCreationResult#STATUS_INVALID_REQUEST}.
      * @param user
      *   Gets the created user.
      * @param errorMessage
@@ -159,10 +170,25 @@
      */
     @DataClass.Generated.Member
     public UserCreationResult(
-            int status,
+            @Status int status,
             @Nullable UserInfo user,
             @Nullable String errorMessage) {
         this.mStatus = status;
+
+        if (!(mStatus == STATUS_SUCCESSFUL)
+                && !(mStatus == STATUS_ANDROID_FAILURE)
+                && !(mStatus == STATUS_HAL_FAILURE)
+                && !(mStatus == STATUS_HAL_INTERNAL_FAILURE)
+                && !(mStatus == STATUS_INVALID_REQUEST)) {
+            throw new java.lang.IllegalArgumentException(
+                    "status was " + mStatus + " but must be one of: "
+                            + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+                            + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+                            + "STATUS_HAL_FAILURE(" + STATUS_HAL_FAILURE + "), "
+                            + "STATUS_HAL_INTERNAL_FAILURE(" + STATUS_HAL_INTERNAL_FAILURE + "), "
+                            + "STATUS_INVALID_REQUEST(" + STATUS_INVALID_REQUEST + ")");
+        }
+
         this.mUser = user;
         this.mErrorMessage = errorMessage;
 
@@ -170,16 +196,16 @@
     }
 
     /**
-     * Gets the user switch result status.
+     * Gets the user creation result status.
      *
      * @return either {@link UserCreationResult#STATUS_SUCCESSFUL},
      *         {@link UserCreationResult#STATUS_ANDROID_FAILURE},
      *         {@link UserCreationResult#STATUS_HAL_FAILURE},
-     *         or
-     *         {@link UserCreationResult#STATUS_HAL_INTERNAL_FAILURE}
+     *         {@link UserCreationResult#STATUS_HAL_INTERNAL_FAILURE}, or
+     *         {@link UserCreationResult#STATUS_INVALID_REQUEST}.
      */
     @DataClass.Generated.Member
-    public int getStatus() {
+    public @Status int getStatus() {
         return mStatus;
     }
 
@@ -206,7 +232,7 @@
         // String fieldNameToString() { ... }
 
         return "UserCreationResult { " +
-                "status = " + mStatus + ", " +
+                "status = " + statusToString(mStatus) + ", " +
                 "user = " + mUser + ", " +
                 "errorMessage = " + mErrorMessage +
         " }";
@@ -244,6 +270,21 @@
         String errorMessage = (flg & 0x4) == 0 ? null : in.readString();
 
         this.mStatus = status;
+
+        if (!(mStatus == STATUS_SUCCESSFUL)
+                && !(mStatus == STATUS_ANDROID_FAILURE)
+                && !(mStatus == STATUS_HAL_FAILURE)
+                && !(mStatus == STATUS_HAL_INTERNAL_FAILURE)
+                && !(mStatus == STATUS_INVALID_REQUEST)) {
+            throw new java.lang.IllegalArgumentException(
+                    "status was " + mStatus + " but must be one of: "
+                            + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+                            + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+                            + "STATUS_HAL_FAILURE(" + STATUS_HAL_FAILURE + "), "
+                            + "STATUS_HAL_INTERNAL_FAILURE(" + STATUS_HAL_INTERNAL_FAILURE + "), "
+                            + "STATUS_INVALID_REQUEST(" + STATUS_INVALID_REQUEST + ")");
+        }
+
         this.mUser = user;
         this.mErrorMessage = errorMessage;
 
@@ -265,10 +306,10 @@
     };
 
     @DataClass.Generated(
-            time = 1591121994170L,
+            time = 1591401523007L,
             codegenVersion = "1.0.15",
             sourceFile = "packages/services/Car/car-lib/src/android/car/user/UserCreationResult.java",
-            inputSignatures = "public static final  int STATUS_SUCCESSFUL\npublic static final  int STATUS_ANDROID_FAILURE\npublic static final  int STATUS_HAL_FAILURE\npublic static final  int STATUS_HAL_INTERNAL_FAILURE\nprivate final  int mStatus\nprivate final @android.annotation.Nullable android.content.pm.UserInfo mUser\nprivate final @android.annotation.Nullable java.lang.String mErrorMessage\npublic  boolean isSuccess()\nclass UserCreationResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+            inputSignatures = "public static final  int STATUS_SUCCESSFUL\npublic static final  int STATUS_ANDROID_FAILURE\npublic static final  int STATUS_HAL_FAILURE\npublic static final  int STATUS_HAL_INTERNAL_FAILURE\npublic static final  int STATUS_INVALID_REQUEST\nprivate final @android.car.user.UserCreationResult.Status int mStatus\nprivate final @android.annotation.Nullable android.content.pm.UserInfo mUser\nprivate final @android.annotation.Nullable java.lang.String mErrorMessage\npublic  boolean isSuccess()\nclass UserCreationResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/car-lib/src/android/car/user/UserRemovalResult.aidl b/car-lib/src/android/car/user/UserRemovalResult.aidl
new file mode 100644
index 0000000..00a0eba
--- /dev/null
+++ b/car-lib/src/android/car/user/UserRemovalResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.user;
+
+parcelable UserRemovalResult;
diff --git a/car-lib/src/android/car/user/UserRemovalResult.java b/car-lib/src/android/car/user/UserRemovalResult.java
new file mode 100644
index 0000000..dbfd8a6
--- /dev/null
+++ b/car-lib/src/android/car/user/UserRemovalResult.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.user;
+
+import android.annotation.IntDef;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * User remove result.
+ *
+ * @hide
+ */
+@DataClass(
+        genToString = true,
+        genHiddenConstructor = true,
+        genHiddenConstDefs = true)
+public final class UserRemovalResult implements Parcelable {
+
+    /**
+     * When user remove is successful.
+     *
+     * @hide
+     */
+    public static final int STATUS_SUCCESSFUL = CommonResults.STATUS_SUCCESSFUL;
+
+    /**
+     * When user remove fails for android. Hal user is not removed.
+     *
+     * @hide
+     */
+    public static final int STATUS_ANDROID_FAILURE = CommonResults.STATUS_ANDROID_FAILURE;
+
+    /**
+     * When remove user fails for unknown error.
+     *
+     * @hide
+     */
+    public static final int STATUS_HAL_INTERNAL_FAILURE = CommonResults.STATUS_HAL_INTERNAL_FAILURE;
+
+     /**
+     * When user to remove is same as current user.
+     *
+     * @hide
+     */
+    public static final int STATUS_TARGET_USER_IS_CURRENT_USER =
+            CommonResults.LAST_COMMON_STATUS + 1;
+
+    /**
+     * When user to remove doesn't exits.
+     *
+     * @hide
+     */
+    public static final int STATUS_USER_DOES_NOT_EXIST = CommonResults.LAST_COMMON_STATUS + 2;
+
+    /**
+     * When user to remove is last admin user.
+     *
+     * @hide
+     */
+    public static final int STATUS_TARGET_USER_IS_LAST_ADMIN_USER =
+            CommonResults.LAST_COMMON_STATUS + 3;
+
+    /**
+     * Gets the user switch result status.
+     *
+     * @return either {@link UserRemovalResult#STATUS_SUCCESSFUL},
+     *         {@link UserRemovalResult#STATUS_ANDROID_FAILURE},
+     *         {@link UserRemovalResult#STATUS_HAL_INTERNAL_FAILURE},
+     *         {@link UserRemovalResult#STATUS_TARGET_USER_IS_CURRENT_USER},
+     *         {@link UserRemovalResult#STATUS_USER_DOES_NOT_EXIST}, or
+     *         {@link UserRemovalResult#STATUS_TARGET_USER_IS_LAST_ADMIN_USER}.
+     */
+    private final @Status int mStatus;
+
+    public boolean isSuccess() {
+        return mStatus == STATUS_SUCCESSFUL;
+    }
+
+    // TODO(b/158195639): if you change any status constant, you need to manually assign its values
+    // (rather than using CommonResults) before running codegen to regenerate the class
+
+
+    // Code below generated by codegen v1.0.15.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/packages/services/Car/car-lib/src/android/car/user/UserRemovalResult.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /** @hide */
+    @IntDef(prefix = "STATUS_", value = {
+        STATUS_SUCCESSFUL,
+        STATUS_ANDROID_FAILURE,
+        STATUS_HAL_INTERNAL_FAILURE,
+        STATUS_TARGET_USER_IS_CURRENT_USER,
+        STATUS_USER_DOES_NOT_EXIST,
+        STATUS_TARGET_USER_IS_LAST_ADMIN_USER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface Status {}
+
+    /** @hide */
+    @DataClass.Generated.Member
+    public static String statusToString(@Status int value) {
+        switch (value) {
+            case STATUS_SUCCESSFUL:
+                    return "STATUS_SUCCESSFUL";
+            case STATUS_ANDROID_FAILURE:
+                    return "STATUS_ANDROID_FAILURE";
+            case STATUS_HAL_INTERNAL_FAILURE:
+                    return "STATUS_HAL_INTERNAL_FAILURE";
+            case STATUS_TARGET_USER_IS_CURRENT_USER:
+                    return "STATUS_TARGET_USER_IS_CURRENT_USER";
+            case STATUS_USER_DOES_NOT_EXIST:
+                    return "STATUS_USER_DOES_NOT_EXIST";
+            case STATUS_TARGET_USER_IS_LAST_ADMIN_USER:
+                    return "STATUS_TARGET_USER_IS_LAST_ADMIN_USER";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    /**
+     * Creates a new UserRemovalResult.
+     *
+     * @param status
+     *   Gets the user switch result status.
+     *
+     *   @return either {@link UserRemovalResult#STATUS_SUCCESSFUL},
+     *           {@link UserRemovalResult#STATUS_ANDROID_FAILURE},
+     *           {@link UserRemovalResult#STATUS_HAL_INTERNAL_FAILURE},
+     *           {@link UserRemovalResult#STATUS_TARGET_USER_IS_CURRENT_USER},
+     *           {@link UserRemovalResult#STATUS_USER_DOES_NOT_EXIST}, or
+     *           {@link UserRemovalResult#STATUS_TARGET_USER_IS_LAST_ADMIN_USER}.
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public UserRemovalResult(
+            int status) {
+        this.mStatus = status;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * Gets the user switch result status.
+     *
+     * @return either {@link UserRemovalResult#STATUS_SUCCESSFUL},
+     *         {@link UserRemovalResult#STATUS_ANDROID_FAILURE},
+     *         {@link UserRemovalResult#STATUS_HAL_INTERNAL_FAILURE},
+     *         {@link UserRemovalResult#STATUS_TARGET_USER_IS_CURRENT_USER},
+     *         {@link UserRemovalResult#STATUS_USER_DOES_NOT_EXIST}, or
+     *         {@link UserRemovalResult#STATUS_TARGET_USER_IS_LAST_ADMIN_USER}.
+     */
+    @DataClass.Generated.Member
+    public int getStatus() {
+        return mStatus;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "UserRemovalResult { " +
+                "status = " + mStatus +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@android.annotation.NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeInt(mStatus);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ UserRemovalResult(@android.annotation.NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        int status = in.readInt();
+
+        this.mStatus = status;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @android.annotation.NonNull Parcelable.Creator<UserRemovalResult> CREATOR
+            = new Parcelable.Creator<UserRemovalResult>() {
+        @Override
+        public UserRemovalResult[] newArray(int size) {
+            return new UserRemovalResult[size];
+        }
+
+        @Override
+        public UserRemovalResult createFromParcel(@android.annotation.NonNull android.os.Parcel in) {
+            return new UserRemovalResult(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1591259644931L,
+            codegenVersion = "1.0.15",
+            sourceFile = "packages/services/Car/car-lib/src/android/car/user/UserRemovalResult.java",
+            inputSignatures = "public static final  int STATUS_SUCCESSFUL\npublic static final  int STATUS_ANDROID_FAILURE\npublic static final  int STATUS_HAL_INTERNAL_FAILURE\npublic static final  int STATUS_TARGET_USER_IS_CURRENT_USER\npublic static final  int STATUS_USER_DOES_NOT_EXIST\npublic static final  int STATUS_TARGET_USER_IS_LAST_ADMIN_USER\nprivate final  int mStatus\npublic  boolean isSuccess()\nclass UserRemovalResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/car-lib/src/android/car/user/UserSwitchResult.java b/car-lib/src/android/car/user/UserSwitchResult.java
index 41da19b..55e2dbc 100644
--- a/car-lib/src/android/car/user/UserSwitchResult.java
+++ b/car-lib/src/android/car/user/UserSwitchResult.java
@@ -95,7 +95,7 @@
      *         {@link UserSwitchResult#STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST}, or
      *         {@link UserSwitchResult#STATUS_INVALID_REQUEST}.
      */
-    private final int mStatus;
+    private final @Status int mStatus;
 
     /**
      * Gets the error message, if any.
@@ -110,6 +110,8 @@
         return mStatus == STATUS_SUCCESSFUL || mStatus == STATUS_ALREADY_REQUESTED_USER;
     }
 
+    // TODO(b/158195639): if you change any status constant, you need to manually assign its values
+    // (rather than using CommonResults) before running codegen to regenerate the class
 
 
     // Code below generated by codegen v1.0.15.
diff --git a/car-usb-handler/res/values-ur/strings.xml b/car-usb-handler/res/values-ur/strings.xml
index 0fe5553..109dd4c 100644
--- a/car-usb-handler/res/values-ur/strings.xml
+++ b/car-usb-handler/res/values-ur/strings.xml
@@ -19,9 +19,7 @@
     <string name="app_name" msgid="6963366455471441257">"USB ہینڈلر"</string>
     <string name="usb_saved_devices" msgid="2829442070749964872">"محفوظ کردہ آلات"</string>
     <string name="usb_pref_delete_title" msgid="3885061814853467483">"USB آلہ کو ہینڈل کرنے والی اپپ کو ہٹائیں"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for usb_pref_delete_message (5849493572520646218) -->
-    <skip />
+    <string name="usb_pref_delete_message" msgid="5849493572520646218">"کیا آپ واقعی %1$s اپپ کی ڈیفالٹ ہینڈلنگ کو حذف کرنا چاہتے ہیں؟"</string>
     <string name="usb_pref_delete_yes" msgid="7803356145103146036">"ہاں"</string>
     <string name="usb_pref_delete_cancel" msgid="5999791462730255929">"منسوخ کریں"</string>
     <string name="usb_resolving_handlers" msgid="1943100136172948686">"تعاون یافتہ ہینڈلرز حاصل کر رہے ہیں"</string>
diff --git a/car-usb-handler/src/android/car/usb/handler/UsbDeviceHandlerResolver.java b/car-usb-handler/src/android/car/usb/handler/UsbDeviceHandlerResolver.java
index 8b2f425..a1be7dd 100644
--- a/car-usb-handler/src/android/car/usb/handler/UsbDeviceHandlerResolver.java
+++ b/car-usb-handler/src/android/car/usb/handler/UsbDeviceHandlerResolver.java
@@ -71,18 +71,16 @@
     private final PackageManager mPackageManager;
     private final UsbDeviceHandlerResolverCallback mDeviceCallback;
     private final Context mContext;
-    private final HandlerThread mHandlerThread;
-    private final UsbDeviceResolverHandler mHandler;
     private final AoapServiceManager mAoapServiceManager;
+    private HandlerThread mHandlerThread;
+    private UsbDeviceResolverHandler mHandler;
 
     public UsbDeviceHandlerResolver(UsbManager manager, Context context,
             UsbDeviceHandlerResolverCallback deviceListener) {
         mUsbManager = manager;
         mContext = context;
         mDeviceCallback = deviceListener;
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new UsbDeviceResolverHandler(mHandlerThread.getLooper());
+        createHandlerThread();
         mPackageManager = context.getPackageManager();
         mAoapServiceManager = new AoapServiceManager(mContext.getApplicationContext());
     }
@@ -104,9 +102,22 @@
     }
 
     /**
+     * Listener for failed {@code startAosp} command.
+     *
+     * <p>If {@code startAosp} fails, the device could be left in a inconsistent state, that's why
+     * we go back to USB enumeration, instead of just repeating the command.
+     */
+    public interface StartAoapFailureListener {
+
+        /** Called if startAoap fails. */
+        void onFailure();
+    }
+
+    /**
      * Dispatches device to component.
      */
-    public boolean dispatch(UsbDevice device, ComponentName component, boolean inAoap) {
+    public boolean dispatch(UsbDevice device, ComponentName component, boolean inAoap,
+            StartAoapFailureListener failureListener) {
         if (LOCAL_LOGD) {
             Log.d(TAG, "dispatch: " + device + " component: " + component + " inAoap: " + inAoap);
         }
@@ -128,10 +139,20 @@
                         packageMatches(activityInfo, intent.getAction(), device, true);
 
                 if (filter != null) {
+                    if (!mHandlerThread.isAlive()) {
+                        // Start a new thread. Used only when startAoap fails, and we need to
+                        // re-enumerate device in order to try again.
+                        createHandlerThread();
+                    }
                     mHandlerThread.getThreadHandler().post(() -> {
                         if (mAoapServiceManager.canSwitchDeviceToAoap(device,
                                 ComponentName.unflattenFromString(filter.mAoapService))) {
-                            requestAoapSwitch(device, filter);
+                            try {
+                                requestAoapSwitch(device, filter);
+                            } catch (IOException e) {
+                                Log.w(TAG, "Start AOAP command failed:" + e);
+                                failureListener.onFailure();
+                            }
                         } else {
                             Log.i(TAG, "Ignore AOAP switch for device " + device
                                     + " handled by " + filter.mAoapService);
@@ -151,6 +172,12 @@
         return true;
     }
 
+    private void createHandlerThread() {
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new UsbDeviceResolverHandler(mHandlerThread.getLooper());
+    }
+
     private static Intent createDeviceAttachedIntent(UsbDevice device) {
         Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
         intent.putExtra(UsbManager.EXTRA_DEVICE, device);
@@ -192,7 +219,7 @@
         return settings;
     }
 
-    private void requestAoapSwitch(UsbDevice device, UsbDeviceFilter filter) {
+    private void requestAoapSwitch(UsbDevice device, UsbDeviceFilter filter) throws IOException {
         UsbDeviceConnection connection = UsbUtil.openConnection(mUsbManager, device);
         if (connection == null) {
             Log.e(TAG, "Failed to connect to usb device.");
@@ -209,11 +236,9 @@
                     filter.mAoapVersion,
                     filter.mAoapUri,
                     hashedSerial);
-        } catch (IOException e) {
-            Log.w(TAG, "Failed to switch device into AOAP mode", e);
+        } finally {
+            connection.close();
         }
-
-        connection.close();
     }
 
     private String getHashed(String serial) {
diff --git a/car-usb-handler/src/android/car/usb/handler/UsbHostController.java b/car-usb-handler/src/android/car/usb/handler/UsbHostController.java
index 3fcb67b..0da71ac 100644
--- a/car-usb-handler/src/android/car/usb/handler/UsbHostController.java
+++ b/car-usb-handler/src/android/car/usb/handler/UsbHostController.java
@@ -30,6 +30,7 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -300,6 +301,12 @@
 
         private static final int DEVICE_REMOVE_TIMEOUT_MS = 500;
 
+        // Used to get the device that we are trying to connect to, if mActiveDevice is removed and
+        // startAoap fails afterwards. Used during USB enumeration when retrying to startAoap when
+        // there are multiple devices attached.
+        private int mLastDeviceId = 0;
+        private int mStartAoapRetries = 1;
+
         private UsbHostControllerHandler(Looper looper) {
             super(looper);
         }
@@ -308,6 +315,24 @@
             sendEmptyMessageDelayed(MSG_DEVICE_REMOVED, DEVICE_REMOVE_TIMEOUT_MS);
         }
 
+        private void onFailure() {
+            if (mStartAoapRetries == 0) {
+                Log.w(TAG, "Reached maximum retry count for startAoap. Giving up Aoa handshake.");
+                return;
+            }
+            mStartAoapRetries--;
+
+            Log.d(TAG, "Restarting USB enumeration.");
+            Iterator<UsbDevice> deviceIterator = mUsbManager.getDeviceList().values().iterator();
+            while (deviceIterator.hasNext()) {
+                UsbDevice device = deviceIterator.next();
+                if (mLastDeviceId == device.getDeviceId()) {
+                    processDevice(device);
+                    return;
+                }
+            }
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -318,8 +343,10 @@
                     UsbHostControllerHandlerDispatchData data =
                             (UsbHostControllerHandlerDispatchData) msg.obj;
                     UsbDevice device = data.getUsbDevice();
+                    mLastDeviceId = device.getDeviceId();
                     UsbDeviceSettings settings = data.getUsbDeviceSettings();
-                    if (!mUsbResolver.dispatch(device, settings.getHandler(), settings.getAoap())) {
+                    if (!mUsbResolver.dispatch(device, settings.getHandler(), settings.getAoap(),
+                            this::onFailure)) {
                         if (data.mRetries > 0) {
                             --data.mRetries;
                             Message nextMessage = Message.obtain(msg);
diff --git a/service/src/com/android/car/CarPowerManagementService.java b/service/src/com/android/car/CarPowerManagementService.java
index f9e15cc..aef68cd 100644
--- a/service/src/com/android/car/CarPowerManagementService.java
+++ b/service/src/com/android/car/CarPowerManagementService.java
@@ -44,6 +44,7 @@
 import android.os.PowerManager;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -59,6 +60,7 @@
 import com.android.car.user.CarUserService;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.IVoiceInteractionManagerService;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -137,6 +139,8 @@
     private final CarUserService mUserService;
     private final InitialUserSetter mInitialUserSetter;
 
+    private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
+
     // TODO:  Make this OEM configurable.
     private static final int SHUTDOWN_POLLING_INTERVAL_MS = 2000;
     private static final int SHUTDOWN_EXTEND_MAX_MS = 5000;
@@ -168,13 +172,16 @@
         this(context, context.getResources(), powerHal, systemInterface, UserManager.get(context),
                 carUserService, new InitialUserSetter(context,
                         (u) -> carUserService.setInitialUser(u),
-                        context.getString(R.string.default_guest_name)));
+                        context.getString(R.string.default_guest_name)),
+                IVoiceInteractionManagerService.Stub.asInterface(
+                        ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)));
     }
 
     @VisibleForTesting
     public CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal,
             SystemInterface systemInterface, UserManager userManager, CarUserService carUserService,
-            InitialUserSetter initialUserSetter) {
+            InitialUserSetter initialUserSetter,
+            IVoiceInteractionManagerService voiceInteractionService) {
         mContext = context;
         mHal = powerHal;
         mSystemInterface = systemInterface;
@@ -194,6 +201,7 @@
         }
         mUserService = carUserService;
         mInitialUserSetter = initialUserSetter;
+        mVoiceInteractionManagerService = voiceInteractionService;
     }
 
     @VisibleForTesting
@@ -408,6 +416,7 @@
 
         mSystemInterface.setDisplayState(true);
         sendPowerManagerEvent(CarPowerStateListener.ON);
+
         mHal.sendOn();
 
         try {
@@ -415,6 +424,8 @@
         } catch (Exception e) {
             Log.e(CarLog.TAG_POWER, "Could not switch user on resume", e);
         }
+
+        setVoiceInteractionDisabled(false);
     }
 
     @VisibleForTesting // Ideally it should not be exposed, but it speeds up the unit tests
@@ -552,6 +563,7 @@
     }
 
     private void handleShutdownPrepare(CpmsState newState) {
+        setVoiceInteractionDisabled(true);
         mSystemInterface.setDisplayState(false);
         // Shutdown on finish if the system doesn't support deep sleep or doesn't allow it.
         synchronized (mLock) {
@@ -619,6 +631,8 @@
                 throw new AssertionError("Should not return from PowerManager.reboot()");
             }
         }
+        setVoiceInteractionDisabled(true);
+
         if (mustShutDown) {
             // shutdown HU
             mSystemInterface.shutdown();
@@ -628,6 +642,14 @@
         mShutdownOnNextSuspend = false;
     }
 
+    private void setVoiceInteractionDisabled(boolean disabled) {
+        try {
+            mVoiceInteractionManagerService.setDisabled(disabled);
+        } catch (RemoteException e) {
+            Log.w(TAG, "setVoiceIntefactionDisabled(" + disabled + ") failed", e);
+        }
+    }
+
     @GuardedBy("mLock")
     private void releaseTimerLocked() {
         if (mTimer != null) {
diff --git a/service/src/com/android/car/CarShellCommand.java b/service/src/com/android/car/CarShellCommand.java
index ad7f31f..0a8c420 100644
--- a/service/src/com/android/car/CarShellCommand.java
+++ b/service/src/com/android/car/CarShellCommand.java
@@ -36,6 +36,7 @@
 import android.car.user.CarUserManager;
 import android.car.user.UserCreationResult;
 import android.car.user.UserIdentificationAssociationResponse;
+import android.car.user.UserRemovalResult;
 import android.car.user.UserSwitchResult;
 import android.car.userlib.HalCallback;
 import android.car.userlib.UserHalHelper;
@@ -46,6 +47,7 @@
 import android.hardware.automotive.vehicle.V2_0.CreateUserStatus;
 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponse;
 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction;
+import android.hardware.automotive.vehicle.V2_0.RemoveUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserMessageType;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserStatus;
@@ -125,6 +127,7 @@
     private static final String COMMAND_INJECT_ROTARY = "inject-rotary";
     private static final String COMMAND_GET_INITIAL_USER_INFO = "get-initial-user-info";
     private static final String COMMAND_SWITCH_USER = "switch-user";
+    private static final String COMMAND_REMOVE_USER = "remove-user";
     private static final String COMMAND_CREATE_USER = "create-user";
     private static final String COMMAND_GET_INITIAL_USER = "get-initial-user";
     private static final String COMMAND_SET_USER_ID_TO_OCCUPANT_ZONE =
@@ -155,6 +158,8 @@
                 android.Manifest.permission.MANAGE_USERS);
         USER_BUILD_COMMAND_TO_PERMISSION_MAP.put(COMMAND_SWITCH_USER,
                 android.Manifest.permission.MANAGE_USERS);
+        USER_BUILD_COMMAND_TO_PERMISSION_MAP.put(COMMAND_REMOVE_USER,
+                android.Manifest.permission.MANAGE_USERS);
         USER_BUILD_COMMAND_TO_PERMISSION_MAP.put(COMMAND_CREATE_USER,
                 android.Manifest.permission.MANAGE_USERS);
         USER_BUILD_COMMAND_TO_PERMISSION_MAP.put(COMMAND_GET_USER_AUTH_ASSOCIATION,
@@ -374,6 +379,10 @@
         pw.println("\t  The --hal-only option only calls HAL, without switching the user,");
         pw.println("\t  while the --timeout defines how long to wait for the HAL response.");
 
+        pw.printf("\t%s <USER_ID> [--hal-only]\n", COMMAND_REMOVE_USER);
+        pw.println("\t  Removes user with USER_ID using the HAL integration.");
+        pw.println("\t  The --hal-only option only calls HAL, without removing the user,");
+
         pw.printf("\t%s [--hal-only] [--timeout TIMEOUT_MS] [--type TYPE] [--flags FLAGS] [NAME]\n",
                 COMMAND_CREATE_USER);
         pw.println("\t  Creates a new user using the HAL integration.");
@@ -609,6 +618,9 @@
             case COMMAND_SWITCH_USER:
                 switchUser(args, writer);
                 break;
+            case COMMAND_REMOVE_USER:
+                removeUser(args, writer);
+                break;
             case COMMAND_CREATE_USER:
                 createUser(args, writer);
                 break;
@@ -1111,6 +1123,52 @@
         }
     }
 
+    private void removeUser(String[] args, PrintWriter writer) {
+        if (args.length < 2) {
+            writer.println("Insufficient number of args");
+            return;
+        }
+
+        int userId = Integer.parseInt(args[1]);
+        boolean halOnly = false;
+
+        for (int i = 2; i < args.length; i++) {
+            String arg = args[i];
+            switch (arg) {
+                case "--hal-only":
+                    halOnly = true;
+                    break;
+                default:
+                    writer.println("Invalid option at index " + i + ": " + arg);
+                    return;
+            }
+        }
+
+        Log.d(TAG, "handleRemoveUser(): User to remove=" + userId + ", halOnly=" + halOnly);
+
+        if (halOnly) {
+            UserHalService userHal = mHal.getUserHal();
+            UsersInfo usersInfo = generateUsersInfo();
+            UserInfo userInfo = new UserInfo();
+            userInfo.userId = userId;
+            userInfo.flags = getUserHalFlags(userId);
+
+            RemoveUserRequest request = new RemoveUserRequest();
+            request.removedUserInfo = userInfo;
+            request.usersInfo = usersInfo;
+
+            userHal.removeUser(request);
+            writer.printf("User removal sent for HAL only.\n");
+            return;
+        }
+
+        CarUserManager carUserManager = getCarUserManager(mContext);
+        UserRemovalResult result = carUserManager.removeUser(userId);
+        if (result == null) return;
+        writer.printf("UserRemovalResult: status = %s\n",
+                UserRemovalResult.statusToString(result.getStatus()));
+    }
+
     private static <T> T waitForFuture(@NonNull PrintWriter writer,
             @NonNull AndroidFuture<T> future, int timeoutMs) {
         T result = null;
diff --git a/service/src/com/android/car/audio/CarAudioService.java b/service/src/com/android/car/audio/CarAudioService.java
index b0dd41d..3efbd18 100644
--- a/service/src/com/android/car/audio/CarAudioService.java
+++ b/service/src/com/android/car/audio/CarAudioService.java
@@ -56,7 +56,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseIntArray;
-import android.view.DisplayAddress;
 import android.view.KeyEvent;
 
 import com.android.car.CarLocalServices;
@@ -1046,31 +1045,6 @@
         return true;
     }
 
-    /**
-     * Gets the zone id for the display port id.
-     * @param displayPortId display port id to match
-     * @return zone id for the display port id or
-     * CarAudioManager.PRIMARY_AUDIO_ZONE if none are found
-     */
-    @Override
-    public int getZoneIdForDisplayPortId(byte displayPortId) {
-        enforcePermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS);
-        requireDynamicRouting();
-        synchronized (mImplLock) {
-            for (int index = 0; index < mCarAudioZones.length; index++) {
-                CarAudioZone zone = mCarAudioZones[index];
-                List<DisplayAddress.Physical> displayAddresses = zone.getPhysicalDisplayAddresses();
-                if (displayAddresses.stream().anyMatch(displayAddress->
-                        displayAddress.getPort() == displayPortId)) {
-                    return index;
-                }
-            }
-
-            // Everything else defaults to primary audio zone
-            return CarAudioManager.PRIMARY_AUDIO_ZONE;
-        }
-    }
-
     @Override
     public void registerVolumeCallback(@NonNull IBinder binder) {
         synchronized (mImplLock) {
diff --git a/service/src/com/android/car/audio/CarAudioZone.java b/service/src/com/android/car/audio/CarAudioZone.java
index a87b4b1..f4a4a33 100644
--- a/service/src/com/android/car/audio/CarAudioZone.java
+++ b/service/src/com/android/car/audio/CarAudioZone.java
@@ -19,7 +19,6 @@
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
 import android.util.Log;
-import android.view.DisplayAddress;
 
 import com.android.car.CarLog;
 import com.android.internal.util.Preconditions;
@@ -45,14 +44,12 @@
     private final int mId;
     private final String mName;
     private final List<CarVolumeGroup> mVolumeGroups;
-    private final List<DisplayAddress.Physical> mPhysicalDisplayAddresses;
     private List<AudioDeviceAttributes> mInputAudioDevice;
 
     CarAudioZone(int id, String name) {
         mId = id;
         mName = name;
         mVolumeGroups = new ArrayList<>();
-        mPhysicalDisplayAddresses = new ArrayList<>();
         mInputAudioDevice = new ArrayList<>();
     }
 
@@ -96,23 +93,6 @@
     }
 
     /**
-     * Associates a new display physical port with this audio zone. This can be used to
-     * identify what zone an activity should produce sound in when launching on a particular display
-     * @param physicalDisplayAddress port to associate with this zone
-     */
-    void addPhysicalDisplayAddress(DisplayAddress.Physical physicalDisplayAddress) {
-        mPhysicalDisplayAddresses.add(physicalDisplayAddress);
-    }
-
-    /**
-     * Gets list of ports for displays associated with this audio zone
-     * @return list of Physical ports for displays associated with this audio zone
-     */
-    List<DisplayAddress.Physical> getPhysicalDisplayAddresses() {
-        return mPhysicalDisplayAddresses;
-    }
-
-    /**
      * @return Snapshot of available {@link CarVolumeGroup}s in array.
      */
     CarVolumeGroup[] getVolumeGroups() {
@@ -173,11 +153,6 @@
     void dump(String indent, PrintWriter writer) {
         String internalIndent = indent + "\t";
         writer.printf("%sCarAudioZone(%s:%d) isPrimary? %b\n", indent, mName, mId, isPrimaryZone());
-        for (DisplayAddress.Physical physical: mPhysicalDisplayAddresses) {
-            long port = (long) physical.getPort();
-            writer.printf("%sDisplayAddress.Physical(%d)\n", internalIndent, port);
-        }
-        writer.println();
 
         for (CarVolumeGroup group : mVolumeGroups) {
             group.dump(internalIndent, writer);
diff --git a/service/src/com/android/car/audio/CarAudioZonesHelper.java b/service/src/com/android/car/audio/CarAudioZonesHelper.java
index 3ff25e9..1a4e0ad 100644
--- a/service/src/com/android/car/audio/CarAudioZonesHelper.java
+++ b/service/src/com/android/car/audio/CarAudioZonesHelper.java
@@ -22,7 +22,6 @@
 import android.text.TextUtils;
 import android.util.SparseIntArray;
 import android.util.Xml;
-import android.view.DisplayAddress;
 
 import com.android.car.audio.CarAudioContext.AudioContext;
 import com.android.internal.util.Preconditions;
@@ -55,14 +54,11 @@
     private static final String TAG_VOLUME_GROUP = "group";
     private static final String TAG_AUDIO_DEVICE = "device";
     private static final String TAG_CONTEXT = "context";
-    private static final String TAG_DISPLAYS = "displays";
-    private static final String TAG_DISPLAY = "display";
     private static final String ATTR_VERSION = "version";
     private static final String ATTR_IS_PRIMARY = "isPrimary";
     private static final String ATTR_ZONE_NAME = "name";
     private static final String ATTR_DEVICE_ADDRESS = "address";
     private static final String ATTR_CONTEXT_NAME = "context";
-    private static final String ATTR_PHYSICAL_PORT = "port";
     private static final String ATTR_ZONE_ID = "audioZoneId";
     private static final String ATTR_OCCUPANT_ZONE_ID = "occupantZoneId";
     private static final String TAG_INPUT_DEVICES = "inputDevices";
@@ -132,7 +128,6 @@
     private final Map<String, CarAudioDeviceInfo> mAddressToCarAudioDeviceInfo;
     private final Map<String, AudioDeviceInfo> mAddressToInputAudioDeviceInfo;
     private final InputStream mInputStream;
-    private final Set<Long> mPortIds;
     private final SparseIntArray mZoneIdToOccupantZoneIdMapping;
     private final Set<Integer> mAudioZoneIds;
     private final Set<String> mInputAudioDevices;
@@ -158,7 +153,6 @@
         mAddressToInputAudioDeviceInfo =
                 CarAudioZonesHelper.generateAddressToInputAudioDeviceInfoMap(inputDeviceInfo);
         mNextSecondaryZoneId = CarAudioManager.PRIMARY_AUDIO_ZONE + 1;
-        mPortIds = new HashSet<>();
         mZoneIdToOccupantZoneIdMapping = new SparseIntArray();
         mAudioZoneIds = new HashSet<>();
         mInputAudioDevices = new HashSet<>();
@@ -258,8 +252,6 @@
             // Expect one <volumeGroups> in one audio zone
             if (TAG_VOLUME_GROUPS.equals(parser.getName())) {
                 parseVolumeGroups(parser, zone);
-            } else if (TAG_DISPLAYS.equals(parser.getName())) {
-                parseDisplays(parser, zone);
             } else if (TAG_INPUT_DEVICES.equals(parser.getName())) {
                 parseInputAudioDevices(parser, zone);
             } else {
@@ -364,37 +356,6 @@
         mInputAudioDevices.add(audioDeviceAddress);
     }
 
-    private void parseDisplays(XmlPullParser parser, CarAudioZone zone)
-            throws IOException, XmlPullParserException {
-        while (parser.next() != XmlPullParser.END_TAG) {
-            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
-            if (TAG_DISPLAY.equals(parser.getName())) {
-                zone.addPhysicalDisplayAddress(parsePhysicalDisplayAddress(parser));
-            }
-            skip(parser);
-        }
-    }
-
-    private DisplayAddress.Physical parsePhysicalDisplayAddress(XmlPullParser parser) {
-        String port = parser.getAttributeValue(NAMESPACE, ATTR_PHYSICAL_PORT);
-        long portId;
-        try {
-            portId = Long.parseLong(port);
-        } catch (NumberFormatException e) {
-            throw new IllegalArgumentException(String.format("Port %s is not a number", port), e);
-        }
-        validatePortIsUnique(portId);
-        return DisplayAddress.fromPhysicalDisplayId(portId);
-    }
-
-    private void validatePortIsUnique(Long portId) {
-        if (mPortIds.contains(portId)) {
-            throw new IllegalArgumentException(
-                    String.format("Port Id %d is already associated with a zone", portId));
-        }
-        mPortIds.add(portId);
-    }
-
     private void validateOccupantZoneIdIsUnique(int occupantZoneId) {
         if (mZoneIdToOccupantZoneIdMapping.indexOfValue(occupantZoneId) > -1) {
             throw new IllegalArgumentException(ATTR_OCCUPANT_ZONE_ID + " " + occupantZoneId
diff --git a/service/src/com/android/car/hal/UserHalService.java b/service/src/com/android/car/hal/UserHalService.java
index e76df37..645f563 100644
--- a/service/src/com/android/car/hal/UserHalService.java
+++ b/service/src/com/android/car/hal/UserHalService.java
@@ -17,6 +17,7 @@
 
 import static android.car.VehiclePropertyIds.CREATE_USER;
 import static android.car.VehiclePropertyIds.INITIAL_USER_INFO;
+import static android.car.VehiclePropertyIds.REMOVE_USER;
 import static android.car.VehiclePropertyIds.SWITCH_USER;
 import static android.car.VehiclePropertyIds.USER_IDENTIFICATION_ASSOCIATION;
 
@@ -34,6 +35,7 @@
 import android.hardware.automotive.vehicle.V2_0.CreateUserResponse;
 import android.hardware.automotive.vehicle.V2_0.CreateUserStatus;
 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponse;
+import android.hardware.automotive.vehicle.V2_0.RemoveUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserMessageType;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserResponse;
@@ -166,6 +168,9 @@
                     mHandler.sendMessage(obtainMessage(
                             UserHalService::handleOnCreateUserResponse, this, value));
                     break;
+                case REMOVE_USER:
+                    Log.w(TAG, "Received REMOVE_USER HAL event: " + value);
+                    break;
                 case USER_IDENTIFICATION_ASSOCIATION:
                     mHandler.sendMessage(obtainMessage(
                             UserHalService::handleOnUserIdentificationAssociation, this, value));
@@ -302,6 +307,34 @@
     }
 
     /**
+     * Calls HAL to remove user.
+     *
+     * @throws IllegalStateException if the HAL does not support user management (callers should
+     * call {@link #isSupported()} first to avoid this exception).
+     */
+    public void removeUser(@NonNull RemoveUserRequest request) {
+        Objects.requireNonNull(request, "request cannot be null");
+
+        if (DBG) Log.d(TAG, "removeUser(" + request.removedUserInfo.userId + ")");
+        EventLog.writeEvent(EventLogTags.CAR_USER_HAL_REMOVE_USER_REQ,
+                request.removedUserInfo.userId, request.usersInfo.currentUser.userId);
+
+        VehiclePropValue propRequest;
+        synchronized (mLock) {
+            checkSupportedLocked();
+            request.requestId = getNextRequestId();
+            propRequest = UserHalHelper.toVehiclePropValue(request);
+
+        }
+        try {
+            if (DBG) Log.d(TAG, "Calling hal.set(): " + propRequest);
+            mHal.set(propRequest);
+        } catch (ServiceSpecificException e) {
+            Log.w(TAG, "Failed to set REMOVE USER", e);
+        }
+    }
+
+    /**
      * Calls HAL to indicate an Android user was created.
      *
      * @param request info agout the created user.
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index 81d1b6c..8e08b28 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -35,6 +35,7 @@
 import android.car.user.CarUserManager.UserLifecycleListener;
 import android.car.user.UserCreationResult;
 import android.car.user.UserIdentificationAssociationResponse;
+import android.car.user.UserRemovalResult;
 import android.car.user.UserSwitchResult;
 import android.car.userlib.CarUserManagerHelper;
 import android.car.userlib.CommonConstants.CarUserServiceConstants;
@@ -53,6 +54,7 @@
 import android.hardware.automotive.vehicle.V2_0.CreateUserStatus;
 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponse;
 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction;
+import android.hardware.automotive.vehicle.V2_0.RemoveUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserStatus;
 import android.hardware.automotive.vehicle.V2_0.UserIdentificationGetRequest;
@@ -343,7 +345,7 @@
     private void handleDumpListeners(@NonNull PrintWriter writer, String indent) {
         CountDownLatch latch = new CountDownLatch(1);
         mHandler.post(() -> {
-            handleDumpUserLifecycleListeners(writer);
+            handleDumpServiceLifecycleListeners(writer);
             handleDumpAppLifecycleListeners(writer, indent);
             latch.countDown();
         });
@@ -359,57 +361,69 @@
         }
     }
 
-    private void handleDumpUserLifecycleListeners(@NonNull PrintWriter writer) {
+    private void handleDumpServiceLifecycleListeners(@NonNull PrintWriter writer) {
         if (mUserLifecycleListeners.isEmpty()) {
-            writer.println("No user lifecycle listeners");
+            writer.println("No lifecycle listeners for internal services");
             return;
         }
-        writer.printf("%d user lifecycle listeners\n", mUserLifecycleListeners.size());
+        int size = mUserLifecycleListeners.size();
+        writer.printf("%d lifecycle listener%s for services\n", size, size == 1 ? "" : "s");
+        String indent = "  ";
         for (UserLifecycleListener listener : mUserLifecycleListeners) {
-            writer.printf("Listener %s\n", listener);
+            writer.printf("%s%s\n", indent, FunctionalUtils.getLambdaName(listener));
         }
     }
 
     private void handleDumpAppLifecycleListeners(@NonNull PrintWriter writer, String indent) {
-        int numberListeners = mAppLifecycleListeners.size();
-        if (numberListeners == 0) {
-            writer.println("No lifecycle listeners");
+        int size = mAppLifecycleListeners.size();
+        if (size == 0) {
+            writer.println("No lifecycle listeners for apps");
             return;
         }
-        writer.printf("%d lifecycle listeners\n", numberListeners);
-        for (int i = 0; i < numberListeners; i++) {
+        writer.printf("%d lifecycle listener%s for apps \n", size, size == 1 ? "" : "s");
+        for (int i = 0; i < size; i++) {
             int uid = mAppLifecycleListeners.keyAt(i);
             IResultReceiver listener = mAppLifecycleListeners.valueAt(i);
-            writer.printf("%suid: %d Listener %s\n", indent, uid, listener);
+            writer.printf("%suid: %d\n", indent, uid);
         }
     }
 
     /**
-     * Creates a driver who is a regular user and is allowed to login to the driving occupant zone.
-     *
-     * @param name The name of the driver to be created.
-     * @param admin Whether the created driver will be an admin.
-     * @return {@link UserInfo} object of the created driver, or {@code null} if the driver could
-     *         not be created.
+     * @see ExperimentalCarUserManager.createDriver
      */
     @Override
-    @Nullable
-    public UserInfo createDriver(@NonNull String name, boolean admin) {
+    public AndroidFuture<UserCreationResult> createDriver(@NonNull String name, boolean admin) {
         checkManageUsersPermission("createDriver");
         Objects.requireNonNull(name, "name cannot be null");
+
+        AndroidFuture<UserCreationResult> future = new AndroidFuture<UserCreationResult>() {
+            @Override
+            protected void onCompleted(UserCreationResult result, Throwable err) {
+                if (result == null) {
+                    Log.w(TAG, "createDriver(" + name + "," + admin + ") failed: " + err);
+                } else {
+                    if (result.getStatus() == UserCreationResult.STATUS_SUCCESSFUL) {
+                        assignDefaultIcon(result.getUser());
+                    }
+                }
+                super.onCompleted(result, err);
+            };
+        };
+        int flags = 0;
         if (admin) {
-            return createNewAdminUser(name);
+            if (!(mUserManager.isAdminUser() || mUserManager.isSystemUser())) {
+                Log.e(TAG_USER, "Only admin users and system user can create other admins.");
+                sendUserCreationResultFailure(future, UserCreationResult.STATUS_INVALID_REQUEST);
+                return future;
+            }
+            flags = UserInfo.FLAG_ADMIN;
         }
-        return mCarUserManagerHelper.createNewNonAdminUser(name);
+        createUser(name, UserInfo.getDefaultUserType(flags), flags, mHalTimeoutMs, future);
+        return future;
     }
 
     /**
-     * Creates a passenger who is a profile of the given driver.
-     *
-     * @param name The name of the passenger to be created.
-     * @param driverId User id of the driver under whom a passenger is created.
-     * @return {@link UserInfo} object of the created passenger, or {@code null} if the passenger
-     *         could not be created.
+     * @see ExperimentalCarUserManager.createPassenger
      */
     @Override
     @Nullable
@@ -425,6 +439,7 @@
             Log.w(TAG_USER, "a guest driver cannot create a passenger");
             return null;
         }
+        // createPassenger doesn't use user HAL because user HAL doesn't support profile user yet.
         UserInfo user = mUserManager.createProfileForUser(name,
                 UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, driverId);
         if (user == null) {
@@ -439,7 +454,7 @@
     }
 
     /**
-     * @see CarUserManager.switchDriver
+     * @see ExperimentalCarUserManager.switchDriver
      */
     @Override
     public void switchDriver(@UserIdInt int driverId, AndroidFuture<UserSwitchResult> receiver) {
@@ -879,6 +894,62 @@
         });
     }
 
+    @Override
+    public UserRemovalResult removeUser(@UserIdInt int userId) {
+        checkManageUsersPermission("removeUser");
+        EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_REQ, userId);
+        // If the requested user is the current user, return error.
+        if (ActivityManager.getCurrentUser() == userId) {
+            return logAndGetResults(userId,
+                    UserRemovalResult.STATUS_TARGET_USER_IS_CURRENT_USER);
+        }
+
+        // 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);
+        }
+
+        android.hardware.automotive.vehicle.V2_0.UserInfo halUser =
+                new android.hardware.automotive.vehicle.V2_0.UserInfo();
+        halUser.userId = userInfo.id;
+        halUser.flags = UserHalHelper.convertFlags(userInfo);
+        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
+
+        // Do not delete last admin user.
+        if (UserHalHelper.isAdmin(halUser.flags)) {
+            int size = usersInfo.existingUsers.size();
+            int totalAdminUsers = 0;
+            for (int i = 0; i < size; i++) {
+                if (UserHalHelper.isAdmin(usersInfo.existingUsers.get(i).flags)) {
+                    totalAdminUsers++;
+                }
+            }
+            if (totalAdminUsers == 1) {
+                return logAndGetResults(userId,
+                        UserRemovalResult.STATUS_TARGET_USER_IS_LAST_ADMIN_USER);
+            }
+        }
+
+        // First remove user from android and then remove from HAL because HAL remove user is one
+        // way call.
+        if (!mUserManager.removeUser(userId)) {
+            return logAndGetResults(userId, UserRemovalResult.STATUS_ANDROID_FAILURE);
+        }
+
+        RemoveUserRequest request = new RemoveUserRequest();
+        request.removedUserInfo = halUser;
+        request.usersInfo = usersInfo;
+        mHal.removeUser(request);
+        return logAndGetResults(userId, UserRemovalResult.STATUS_SUCCESSFUL);
+    }
+
+    private UserRemovalResult logAndGetResults(@UserIdInt int userId,
+            @UserRemovalResult.Status int result) {
+        EventLog.writeEvent(EventLogTags.CAR_USER_SVC_REMOVE_USER_RESP, userId, result);
+        return new UserRemovalResult(result);
+    }
+
     private void sendUserSwitchUiCallback(@UserIdInt int targetUserId) {
         if (mUserSwitchUiReceiver == null) {
             Log.w(TAG_USER, "No User switch UI receiver.");
@@ -1492,23 +1563,27 @@
         }
         int userId = event.getUserId();
         TimingsTraceLog t = new TimingsTraceLog(TAG_USER, Trace.TRACE_TAG_SYSTEM_SERVER);
-        t.traceBegin("notify-app-listeners-user-" + userId + "-event-" + event.getEventType());
+        int eventType = event.getEventType();
+        t.traceBegin("notify-app-listeners-user-" + userId + "-event-" + eventType);
         for (int i = 0; i < listenersSize; i++) {
             int uid = mAppLifecycleListeners.keyAt(i);
+
             IResultReceiver listener = mAppLifecycleListeners.valueAt(i);
             Bundle data = new Bundle();
-            data.putInt(CarUserManager.BUNDLE_PARAM_ACTION, event.getEventType());
+            data.putInt(CarUserManager.BUNDLE_PARAM_ACTION, eventType);
 
-            int fromUid = event.getPreviousUserId();
-            if (fromUid != UserHandle.USER_NULL) {
-                data.putInt(CarUserManager.BUNDLE_PARAM_PREVIOUS_USER_ID, fromUid);
+            int fromUserId = event.getPreviousUserId();
+            if (fromUserId != UserHandle.USER_NULL) {
+                data.putInt(CarUserManager.BUNDLE_PARAM_PREVIOUS_USER_ID, fromUserId);
             }
 
             if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
                 Log.d(TAG_USER, "Notifying listener for uid " + uid);
             }
+            EventLog.writeEvent(EventLogTags.CAR_USER_SVC_NOTIFY_APP_LIFECYCLE_LISTENER,
+                    uid, eventType, fromUserId, userId);
             try {
-                t.traceBegin("notify-app-listener-" + uid);
+                t.traceBegin("notify-app-listener-uid-" + uid);
                 listener.send(userId, data);
             } catch (RemoteException e) {
                 Log.e(TAG_USER, "Error calling lifecycle listener", e);
@@ -1529,10 +1604,13 @@
                     + event);
         }
 
-        t.traceBegin("notify-listeners-user-" + event.getUserId() + "-event-"
-                + event.getEventType());
+        int userId = event.getUserId();
+        int eventType = event.getEventType();
+        t.traceBegin("notify-listeners-user-" + userId + "-event-" + eventType);
         for (UserLifecycleListener listener : mUserLifecycleListeners) {
             String listenerName = FunctionalUtils.getLambdaName(listener);
+            EventLog.writeEvent(EventLogTags.CAR_USER_SVC_NOTIFY_INTERNAL_LIFECYCLE_LISTENER,
+                    listenerName, eventType, event.getPreviousUserId(), userId);
             try {
                 t.traceBegin("notify-listener-" + listenerName);
                 listener.onEvent(event);
@@ -1568,11 +1646,17 @@
 
     private void notifyHalLegacySwitch(@UserIdInt int fromUserId, @UserIdInt int toUserId) {
         synchronized (mLockUser) {
-            if (mUserIdForUserSwitchInProcess != UserHandle.USER_NULL) return;
+            if (mUserIdForUserSwitchInProcess != UserHandle.USER_NULL) {
+                if (Log.isLoggable(TAG_USER, Log.DEBUG)) {
+                    Log.d(TAG, "notifyHalLegacySwitch(" + fromUserId + ", " + toUserId
+                            + "): not needed, normal switch for " + mUserIdForUserSwitchInProcess);
+                }
+                return;
+            }
         }
 
         // switch HAL user
-        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager);
+        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUserManager, fromUserId);
         SwitchUserRequest request = createUserSwitchRequest(toUserId, usersInfo);
         mHal.legacyUserSwitch(request);
     }
@@ -1617,42 +1701,15 @@
     }
 
     /**
-     * Creates a new user on the system, the created user would be granted admin role.
-     *
-     * @param name Name to be given to the newly created user.
-     * @return newly created admin user, {@code null} if it fails to create a user.
-     */
-    @Nullable
-    private UserInfo createNewAdminUser(String name) {
-        if (!(mUserManager.isAdminUser() || mUserManager.isSystemUser())) {
-            // Only admins or system user can create other privileged users.
-            Log.e(TAG_USER, "Only admin users and system user can create other admins.");
-            return null;
-        }
-
-        UserInfo user = mUserManager.createUser(name, UserInfo.FLAG_ADMIN);
-        if (user == null) {
-            // Couldn't create user, most likely because there are too many.
-            Log.w(TAG_USER, "can't create admin user.");
-            return null;
-        }
-        assignDefaultIcon(user);
-
-        return user;
-    }
-
-    /**
      * Assigns a default icon to a user according to the user's id.
      *
      * @param userInfo User whose avatar is set to default icon.
-     * @return Bitmap of the user icon.
      */
-    private Bitmap assignDefaultIcon(UserInfo userInfo) {
+    private void assignDefaultIcon(UserInfo userInfo) {
         int idForIcon = userInfo.isGuest() ? UserHandle.USER_NULL : userInfo.id;
         Bitmap bitmap = UserIcons.convertToBitmap(
                 UserIcons.getDefaultUserIcon(mContext.getResources(), idForIcon, false));
         mUserManager.setUserIcon(userInfo.id, bitmap);
-        return bitmap;
     }
 
     private interface UserFilter {
diff --git a/surround_view/service-impl/Android.bp b/surround_view/service-impl/Android.bp
index b89f7ed..80c77a3 100644
--- a/surround_view/service-impl/Android.bp
+++ b/surround_view/service-impl/Android.bp
@@ -14,6 +14,35 @@
 // limitations under the License.
 //
 
+cc_library {
+    name : "libobj_reader",
+    vendor : true,
+    srcs: [
+        "MtlReader.cpp",
+        "ObjReader.cpp",
+    ],
+    shared_libs : [
+        "libbase",
+    ]
+}
+
+cc_test{
+    name : "obj_reader_tests",
+    test_suites : ["device-tests"],
+    vendor : true,
+    srcs : ["ObjReaderTests.cpp"],
+    shared_libs : [
+        "libobj_reader",
+        "libcutils",
+        "libbase",
+        "libutils",
+    ],
+    required: [
+        "VolvoXC40_low.obj",
+        "VolvoXC40_low.mtl",
+    ],
+}
+
 cc_library{
     name : "libvhal_handler",
     vendor : true,
@@ -148,3 +177,15 @@
 name:
     "cam3.png", src : "test_data/3.png", sub_dir : "automotive/sv",
 }
+
+prebuilt_etc {
+    name: "cube.obj",
+    src: "test_data/cube.obj",
+    sub_dir: "automotive/sv",
+}
+
+prebuilt_etc {
+    name: "cube.mtl",
+    src: "test_data/cube.mtl",
+    sub_dir: "automotive/sv",
+}
diff --git a/surround_view/service-impl/MtlReader.cpp b/surround_view/service-impl/MtlReader.cpp
new file mode 100644
index 0000000..d86a15a
--- /dev/null
+++ b/surround_view/service-impl/MtlReader.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "MtlReader.h"
+
+#include <android-base/logging.h>
+#include <cstdio>
+
+#define LOG_TAG "MtlReader"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace sv {
+namespace V1_0 {
+namespace implementation {
+
+namespace {
+
+constexpr int kCharBufferSize = 128;
+
+void ReadFloat3(FILE* file, float* value) {
+    float temp[3];
+    int res = fscanf(file, "%f %f %f", &temp[0], &temp[1], &temp[2]);
+    3 == res ? std::memcpy(value, temp, 3 * sizeof(float)) : nullptr;
+}
+
+void ReadFloat(FILE* file, float* value) {
+    float temp;
+    int res = fscanf(file, "%f", &temp);
+    *value = res > 0 ? temp : -1;
+}
+
+void ReadInt(FILE* file, int* value) {
+    int temp;
+    int res = fscanf(file, "%d", &temp);
+    *value = res > 0 ? temp : -1;
+}
+
+void ReadString(FILE* file, std::string* value) {
+    char temp[kCharBufferSize];
+    fscanf(file, "%s", temp);
+    *value = temp;
+}
+}  // namespace
+
+bool ReadMtlFromFile(const std::string& mtlFilename,
+                     std::map<std::string, MtlConfigParams>* params) {
+    FILE* file = fopen(mtlFilename.c_str(), "r");
+    if (!file) {
+        LOG(ERROR) << "Failed to open mtl file: " << mtlFilename;
+        return false;
+    }
+
+    std::string currentConfig;
+    while (true) {
+        char lineHeader[kCharBufferSize];
+        // read the first word of the line
+        int res = fscanf(file, "%s", lineHeader);
+
+        if (res == EOF) {
+            break;  // EOF = End Of File. Quit the loop.
+        }
+
+        if (strcmp(lineHeader, "#") == 0) {
+            fgets(lineHeader, sizeof(lineHeader), file);
+            continue;
+        }
+        if (strcmp(lineHeader, "newmtl") == 0) {
+            res = fscanf(file, "%s", lineHeader);
+            if (params->find(lineHeader) != params->end()) {
+                fclose(file);
+                LOG(ERROR) << "Duplicated params of : " << lineHeader[0];
+                return false;
+            }
+            currentConfig = lineHeader;
+            continue;
+        }
+
+        if (strcmp(lineHeader, "Ns") == 0) {
+            ReadFloat(file, &((*params)[currentConfig].ns));
+            continue;
+        }
+        if (strcmp(lineHeader, "Ni") == 0) {
+            ReadFloat(file, &((*params)[currentConfig].ni));
+            continue;
+        }
+        if (strcmp(lineHeader, "d") == 0) {
+            ReadFloat(file, &((*params)[currentConfig].d));
+            continue;
+        }
+        if (strcmp(lineHeader, "Tr") == 0) {
+            ReadFloat(file, &((*params)[currentConfig].tr));
+            continue;
+        }
+        if (strcmp(lineHeader, "Tf") == 0) {
+            ReadFloat3(file, (*params)[currentConfig].tf);
+            continue;
+        }
+        if (strcmp(lineHeader, "illum") == 0) {
+            ReadInt(file, &((*params)[currentConfig].illum));
+            continue;
+        }
+        if (strcmp(lineHeader, "Ka") == 0) {
+            ReadFloat3(file, (*params)[currentConfig].ka);
+            continue;
+        }
+        if (strcmp(lineHeader, "Kd") == 0) {
+            ReadFloat3(file, (*params)[currentConfig].kd);
+            continue;
+        }
+        if (strcmp(lineHeader, "Ks") == 0) {
+            ReadFloat3(file, (*params)[currentConfig].ks);
+            continue;
+        }
+        if (strcmp(lineHeader, "Ke") == 0) {
+            ReadFloat3(file, (*params)[currentConfig].ke);
+            continue;
+        }
+        if (strcmp(lineHeader, "map_bump") == 0) {
+            ReadString(file, &((*params)[currentConfig].mapBump));
+            continue;
+        }
+        if (strcmp(lineHeader, "bump") == 0) {
+            ReadString(file, &((*params)[currentConfig].bump));
+            continue;
+        }
+        if (strcmp(lineHeader, "map_Ka") == 0) {
+            ReadString(file, &((*params)[currentConfig].mapKa));
+            continue;
+        }
+        if (strcmp(lineHeader, "map_Kd") == 0) {
+            ReadString(file, &((*params)[currentConfig].mapKd));
+            continue;
+        }
+        if (strcmp(lineHeader, "map_Ks") == 0) {
+            ReadString(file, &((*params)[currentConfig].mapKs));
+            continue;
+        } else {
+            LOG(WARNING) << "Unknown tag " << lineHeader << ". Skipped";
+            fgets(lineHeader, sizeof(lineHeader), file);
+            continue;
+        }
+    }
+
+    fclose(file);
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sv
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/surround_view/service-impl/MtlReader.h b/surround_view/service-impl/MtlReader.h
new file mode 100644
index 0000000..3e19876
--- /dev/null
+++ b/surround_view/service-impl/MtlReader.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SURROUND_VIEW_SERVICE_IMPL_MTLREADER_H_
+#define SURROUND_VIEW_SERVICE_IMPL_MTLREADER_H_
+
+#include <map>
+#include <string>
+
+#include "core_lib.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace sv {
+namespace V1_0 {
+namespace implementation {
+
+// Mtl defined params.
+struct MtlConfigParams {
+    // Ns exponent
+    // Specifies the specular exponent for the current material. This defines
+    // the focus of the specular highlight.
+    // Ns values normally range from 0 to 1000.
+    float ns = -1;
+
+    // optical_density
+    // Specifies the optical density for the surface. This is also known as
+    // index of refraction.
+    //  "optical_density" is the value for the optical density. The values can
+    // range from 0.001 to 10. A value of 1.0 means that light does not bend
+    // as it passes through an object. Increasing the optical_density
+    // increases the amount of bending. Glass has an index of refraction of
+    // about 1.5.  Values of less than 1.0 produce bizarre results and are not
+    // recommended.
+    float ni = -1;
+
+    // d defines the non-transparency of the material to be alpha.
+    // The default is 1.0 (not transparent at all).
+    // The quantities d and Tr are the opposites of each other.
+    float d = -1;
+
+    // The Tr statement specifies the transparency of the material to be alpha.
+    // The default is 0.0 (not transparent at all).
+    // The quantities d and Tr are the opposites of each other,
+    float tr = -1;
+
+    // The Tf statement specifies the transmission filter using RGB values.
+    // "r g b" are the values for the red, green, and blue components of the
+    // atmosphere.  The g and b arguments are optional. If only r is
+    // specified, then g, and b are assumed to be equal to r. The r g b values
+    // are normally in the range of 0.0 to 1.0. Values outside this range
+    // increase or decrease the relectivity accordingly.
+    float tf[3] = {-1, -1, -1};
+
+    // illum_#
+    // The "illum" statement specifies the illumination model to use in the
+    // material.  Illumination models are mathematical equations that represent
+    // various material lighting and shading effects.
+    //
+    // "illum_#"can be a number from 0 to 10. The illumination models are
+    // summarized below;
+    //
+    //  Illumination    Properties that are turned on in the
+    //  model           Property Editor
+    //
+    //  0 Color on and Ambient off
+    //  1 Color on and Ambient on
+    //  2 Highlight on
+    //  3 Reflection on and Ray trace on
+    //  4 Transparency: Glass on
+    //    Reflection: Ray trace on
+    //  5 Reflection: Fresnel on and Ray trace on
+    //  6 Transparency: Refraction on
+    //    Reflection: Fresnel off and Ray trace on
+    //  7 Transparency: Refraction on
+    //    Reflection: Fresnel on and Ray trace on
+    //  8 Reflection on and Ray trace off
+    //  9 Transparency: Glass on
+    //    Reflection: Ray trace off
+    // 10 Casts shadows onto invisible surfaces
+    int illum = -1;
+
+    // The Ka statement specifies the ambient reflectivity using RGB values.
+    // "r g b" are the values for the red, green, and blue components of the
+    // color.  The g and b arguments are optional. If only r is specified,
+    // then g, and b are assumed to be equal to r. The r g b values are
+    // normally in the range of 0.0 to 1.0. Values outside this range increase
+    // or decrease the relectivity accordingly.
+    float ka[3] = {-1, -1, -1};
+
+    // The Kd statement specifies the diffuse reflectivity using RGB values.
+    //  "r g b" are the values for the red, green, and blue components of the
+    // atmosphere.  The g and b arguments are optional.  If only r is
+    // specified, then g, and b are assumed to be equal to r. The r g b values
+    // are normally in the range of 0.0 to 1.0. Values outside this range
+    // increase or decrease the relectivity accordingly.
+    float kd[3] = {-1, -1, -1};
+
+    // The Ks statement specifies the specular reflectivity using RGB values.
+    //  "r g b" are the values for the red, green, and blue components of the
+    // atmosphere. The g and b arguments are optional. If only r is
+    // specified, then g, and b are assumed to be equal to r. The r g b values
+    // are normally in the range of 0.0 to 1.0. Values outside this range
+    // increase or decrease the relectivity accordingly.
+    float ks[3] = {-1, -1, -1};
+
+    // Emissive coeficient. It goes together with ambient, diffuse and specular
+    // and represents the amount of light emitted by the material.
+    float ke[3] = {-1, -1, -1};
+
+    // Specifies that a color texture file or color procedural texture file is
+    // linked to the specular reflectivity of the material. During rendering,
+    // the map_Ks value is multiplied by the Ks value.
+    std::string mapKs;
+
+    // Specifies that a color texture file or a color procedural texture file
+    // is applied to the ambient reflectivity of the material. During
+    // rendering, the "map_Ka" value is multiplied by the "Ka" value.
+    std::string mapKa;
+
+    // Specifies that a color texture file or color procedural texture file is
+    // linked to the diffuse reflectivity of the material. During rendering,
+    // the map_Kd value is multiplied by the Kd value.
+    std::string mapKd;
+
+    // Same as bump
+    std::string mapBump;
+
+    // Specifies that a bump texture file or a bump procedural texture file is
+    // linked to the material.
+    std::string bump;
+
+    MtlConfigParams& operator=(const MtlConfigParams& rhs) {
+        ns = rhs.ns;
+        ni = rhs.ni;
+        d = rhs.d;
+        tr = rhs.tr;
+        std::memcpy(tf, rhs.tf, 3 * sizeof(float));
+        illum = rhs.illum;
+        std::memcpy(ka, rhs.ka, 3 * sizeof(float));
+        std::memcpy(kd, rhs.kd, 3 * sizeof(float));
+        std::memcpy(ks, rhs.ks, 3 * sizeof(float));
+        std::memcpy(ke, rhs.ke, 3 * sizeof(float));
+        mapKs = rhs.mapKs;
+        mapKa = rhs.mapKa;
+        mapKd = rhs.mapKd;
+        mapBump = rhs.mapBump;
+        bump = rhs.bump;
+
+        return *this;
+    }
+};
+
+// Reads mtl file associated with obj file.
+// |filename| is the full path and name of the obj file.
+bool ReadMtlFromFile(const std::string& mtlFilename,
+                     std::map<std::string, MtlConfigParams>* params);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sv
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // SURROUND_VIEW_SERVICE_IMPL_MTLREADER_H_
diff --git a/surround_view/service-impl/ObjReader.cpp b/surround_view/service-impl/ObjReader.cpp
new file mode 100644
index 0000000..174ef5b
--- /dev/null
+++ b/surround_view/service-impl/ObjReader.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "ObjReader.h"
+
+#include <array>
+#include <cstdio>
+#include <filesystem>
+#include <vector>
+
+#include "MtlReader.h"
+#include "core_lib.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace sv {
+namespace V1_0 {
+namespace implementation {
+
+using android_auto::surround_view::CarMaterial;
+using android_auto::surround_view::CarVertex;
+
+namespace {
+
+constexpr int kNumberOfVerticesPerFace = 3;
+constexpr int kNumberOfAxes = 3;
+constexpr int kCharBufferSize = 128;
+
+const std::array<float, 16> kMat4Identity = {
+        /*row 0*/ 1, 0, 0, 0,
+        /*row 1*/ 0, 1, 0, 0,
+        /*row 2*/ 0, 0, 1, 0,
+        /*row 3*/ 0, 0, 0, 1};
+
+// Copies face vertices parsed from obj to car vertices.
+void CopyFaceToCarVertex(const std::vector<std::array<float, kNumberOfAxes>>& currentVertices,
+                         const std::vector<std::array<float, kNumberOfAxes>>& currentTextures,
+                         const std::vector<std::array<float, kNumberOfAxes>>& currentNormals,
+                         int vertexId, int textureId, int normalId, CarVertex* carVertex) {
+    std::memcpy(carVertex->pos.data(), currentVertices[vertexId - 1].data(),
+                currentVertices[vertexId - 1].size() * sizeof(float));
+
+    if (textureId != -1) {
+        std::memcpy(carVertex->tex_coord.data(), currentTextures[textureId - 1].data(),
+                    2 * sizeof(float));
+        // Set texture coodinates as invalid.
+        carVertex->tex_coord = {-1.0, -1.0};
+    }
+
+    std::memcpy(carVertex->normal.data(), currentNormals[normalId - 1].data(),
+                currentNormals[normalId - 1].size() * sizeof(float));
+}
+
+}  // namespace
+
+bool ReadObjFromFile(const std::string& objFilename, std::map<std::string, CarPart>* carPartsMap) {
+    return ReadObjFromFile(objFilename, ReadObjOptions(), carPartsMap);
+}
+
+bool ReadObjFromFile(const std::string& objFilename, const ReadObjOptions& option,
+                     std::map<std::string, CarPart>* carPartsMap) {
+    FILE* file = fopen(objFilename.c_str(), "r");
+    if (!file) {
+        LOG(ERROR) << "Failed to open obj file: " << objFilename;
+        return false;
+    }
+
+    for (int i = 0; i < kNumberOfAxes; ++i) {
+        if (option.coordinateMapping[i] >= kNumberOfAxes || option.coordinateMapping[i] < 0) {
+            fclose(file);
+            LOG(ERROR) << "coordinateMapping index must be less than 3 and greater or equal "
+                          "to 0.";
+            return false;
+        }
+    }
+
+    std::vector<std::array<float, kNumberOfAxes>> currentVertices;
+    std::vector<std::array<float, kNumberOfAxes>> currentNormals;
+    std::vector<std::array<float, kNumberOfAxes>> currentTextures;
+    std::map<std::string, MtlConfigParams> mtlConfigParamsMap;
+    std::string currentGroupName;
+    MtlConfigParams currentMtlConfig;
+
+    while (true) {
+        char lineHeader[kCharBufferSize];
+        // read the first word of the line
+        int res = fscanf(file, "%s", lineHeader);
+
+        if (res == EOF) {
+            break;  // EOF = End Of File. Quit the loop.
+        }
+        if (strcmp(lineHeader, "#") == 0) {
+            fgets(lineHeader, sizeof(lineHeader), file);
+            continue;
+        }
+
+        // TODO(b/156558814): add object type support.
+        // TODO(b/156559272): add document for supported format.
+        // Only single group per line is supported.
+        if (strcmp(lineHeader, "g") == 0) {
+            res = fscanf(file, "%s", lineHeader);
+            currentGroupName = lineHeader;
+            currentMtlConfig = MtlConfigParams();
+
+            if (carPartsMap->find(currentGroupName) != carPartsMap->end()) {
+                LOG(WARNING) << "Duplicate group name: " << currentGroupName
+                             << ". using car part name as: " << currentGroupName << "_dup";
+                currentGroupName.append("_dup");
+            }
+            carPartsMap->emplace(
+                    std::make_pair(currentGroupName,
+                                   CarPart((std::vector<CarVertex>()), CarMaterial(), kMat4Identity,
+                                           std::string(), std::vector<std::string>())));
+            continue;
+        }
+
+        // no "g" case, assign it as default.
+        if (currentGroupName.empty()) {
+            currentGroupName = "default";
+            currentMtlConfig = MtlConfigParams();
+            carPartsMap->emplace(
+                    std::make_pair(currentGroupName,
+                                   CarPart((std::vector<CarVertex>()), CarMaterial(), kMat4Identity,
+                                           std::string(), std::vector<std::string>())));
+        }
+
+        if (strcmp(lineHeader, "usemtl") == 0) {
+            res = fscanf(file, "%s", lineHeader);
+
+            // If material name not found.
+            if (mtlConfigParamsMap.find(lineHeader) == mtlConfigParamsMap.end()) {
+                carPartsMap->at(currentGroupName).material = CarMaterial();
+                LOG(ERROR) << "Material not found: $0" << lineHeader;
+                return false;
+            }
+
+            currentMtlConfig = mtlConfigParamsMap[lineHeader];
+
+            carPartsMap->at(currentGroupName).material.ka = {currentMtlConfig.ka[0],
+                                                             currentMtlConfig.ka[1],
+                                                             currentMtlConfig.ka[2]};
+
+            carPartsMap->at(currentGroupName).material.kd = {currentMtlConfig.kd[0],
+                                                             currentMtlConfig.kd[1],
+                                                             currentMtlConfig.kd[2]};
+
+            carPartsMap->at(currentGroupName).material.ks = {currentMtlConfig.ks[0],
+                                                             currentMtlConfig.ks[1],
+                                                             currentMtlConfig.ks[2]};
+
+            carPartsMap->at(currentGroupName).material.d = currentMtlConfig.d;
+
+            carPartsMap->at(currentGroupName).material.textures.clear();
+
+            continue;
+        }
+
+        if (strcmp(lineHeader, "mtllib") == 0) {
+            res = fscanf(file, "%s", lineHeader);
+            mtlConfigParamsMap.clear();
+            std::string mtlFilename;
+            if (option.mtlFilename.empty()) {
+                mtlFilename = objFilename.substr(0, objFilename.find_last_of("/"));
+                mtlFilename.append("/");
+                mtlFilename.append(lineHeader);
+            } else {
+                mtlFilename = option.mtlFilename;
+            }
+            if (!ReadMtlFromFile(mtlFilename, &mtlConfigParamsMap)) {
+                LOG(ERROR) << "Parse MTL file " << mtlFilename << " failed.";
+                return false;
+            }
+            continue;
+        }
+
+        if (strcmp(lineHeader, "v") == 0) {
+            std::array<float, kNumberOfAxes> pos;
+            fscanf(file, "%f %f %f\n", &pos[option.coordinateMapping[0]],
+                   &pos[option.coordinateMapping[1]], &pos[option.coordinateMapping[2]]);
+            for (int i = 0; i < kNumberOfAxes; ++i) {
+                pos[i] *= option.scales[i];
+                pos[i] += option.offsets[i];
+            }
+            currentVertices.push_back(pos);
+        } else if (strcmp(lineHeader, "vt") == 0) {
+            std::array<float, kNumberOfAxes> texture;
+            fscanf(file, "%f %f %f\n", &texture[0], &texture[1], &texture[2]);
+            currentTextures.push_back(texture);
+        } else if (strcmp(lineHeader, "vn") == 0) {
+            std::array<float, kNumberOfAxes> normal;
+            fscanf(file, "%f %f %f\n", &normal[option.coordinateMapping[0]],
+                   &normal[option.coordinateMapping[1]], &normal[option.coordinateMapping[2]]);
+            currentNormals.push_back(normal);
+        } else if (strcmp(lineHeader, "f") == 0) {
+            int vertexId[kNumberOfVerticesPerFace];
+            int textureId[kNumberOfVerticesPerFace] = {-1, -1, -1};
+            int normalId[kNumberOfVerticesPerFace];
+
+            // Face vertices supported formats:
+            // With texture:     pos/texture/normal
+            // Without texture:  pos//normal
+
+            // Scan first vertex position.
+            int matches = fscanf(file, "%d/", &vertexId[0]);
+
+            if (matches != 1) {
+                LOG(WARNING) << "Face index error. Skipped.";
+                fgets(lineHeader, sizeof(lineHeader), file);
+                continue;
+            }
+
+            // Try scanning first two face 2 vertices with texture format present.
+            bool isTexturePresent = true;
+            matches = fscanf(file, "%d/%d %d/%d/%d", &textureId[0], &normalId[0], &vertexId[1],
+                             &textureId[1], &normalId[1]);
+
+            // If 5 matches not found, try scanning first 2 face vertices without
+            // texture format.
+            if (matches != 5) {
+                matches = fscanf(file, "/%d %d//%d", &normalId[0], &vertexId[1], &normalId[1]);
+
+                // If 3 matches not found return with error.
+                if (matches != 3) {
+                    LOG(WARNING) << "Face format not supported. Skipped.";
+                    fgets(lineHeader, sizeof(lineHeader), file);
+                    continue;
+                }
+
+                isTexturePresent = false;
+            }
+
+            // Copy first two face vertices to car vertices.
+            std::array<CarVertex, kNumberOfVerticesPerFace> carVertices;
+            CopyFaceToCarVertex(currentVertices, currentTextures, currentNormals, vertexId[0],
+                                textureId[0], normalId[0], &carVertices[0]);
+            CopyFaceToCarVertex(currentVertices, currentTextures, currentNormals, vertexId[1],
+                                textureId[1], normalId[1], &carVertices[1]);
+
+            // Add a triangle that the first two vertices make with every subsequent
+            // face vertex 3 and onwards. Note this assumes the face is a convex
+            // polygon.
+            do {
+                if (isTexturePresent) {
+                    matches = fscanf(file, " %d/%d/%d", &vertexId[2], &textureId[2], &normalId[2]);
+                    // Warn if un-expected number of matches.
+                    if (matches != 3 && matches != 0) {
+                        LOG(WARNING) << "Face matches, expected 3, read: " << matches;
+                        break;
+                    }
+                } else {
+                    // Warn if un-expected number of matches.
+                    matches = fscanf(file, " %d//%d", &vertexId[2], &normalId[2]);
+                    if (matches != 2 && matches != 0) {
+                        LOG(WARNING) << "Face matches, expected 2, read: " << matches;
+                        break;
+                    }
+                }
+
+                if (matches == 0) {
+                    break;
+                }
+
+                CopyFaceToCarVertex(currentVertices, currentTextures, currentNormals, vertexId[2],
+                                    textureId[2], normalId[2], &carVertices[2]);
+
+                carPartsMap->at(currentGroupName).vertices.push_back(carVertices[0]);
+                carPartsMap->at(currentGroupName).vertices.push_back(carVertices[1]);
+                carPartsMap->at(currentGroupName).vertices.push_back(carVertices[2]);
+
+                carVertices[1] = carVertices[2];
+            } while (true);
+
+        } else {
+            // LOG(WARNING) << "Unknown tag " << lineHeader << ". Skipped";
+            fgets(lineHeader, sizeof(lineHeader), file);
+            continue;
+        }
+    }
+
+    fclose(file);
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sv
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/surround_view/service-impl/ObjReader.h b/surround_view/service-impl/ObjReader.h
new file mode 100644
index 0000000..c19be14
--- /dev/null
+++ b/surround_view/service-impl/ObjReader.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SURROUND_VIEW_SERVICE_IMPL_OBJREADER_H_
+#define SURROUND_VIEW_SERVICE_IMPL_OBJREADER_H_
+
+#include <map>
+#include <string>
+
+#include "core_lib.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace sv {
+namespace V1_0 {
+namespace implementation {
+
+using android_auto::surround_view::CarPart;
+
+// ReadObjOptions for processing obj's vertex coordinates.
+// Sequence of processing ReadObjOptions:
+// 1. coordinate_mapping
+// 2. scales
+// 3. offsets
+struct ReadObjOptions {
+    // Maps obj coordinates to the output overlay coordinate.
+    // 0 <-> x, 1 <-> y, 2 <-> z
+    // Default is {0, 1, 2}, without coordinate changes.
+    int coordinateMapping[3] = {0, 1, 2};
+
+    // scale of each coordinate (after offsets).
+    float scales[3] = {1.0f, 1.0f, 1.0f};
+
+    // offset of each coordinate (after mapping).
+    float offsets[3] = {0, 0, 0};
+
+    // Optional mtl filename. String name is obj file is used if this is empty.
+    std::string mtlFilename;
+};
+
+// Reads obj file to vector of OverlayVertex.
+// |obj_filename| is the full path and name of the obj file.
+// |car_parts_map| is a map containing all car parts.
+// Now it only supports two face formats:
+// 1. f x/x/x x/x/x x/x/x ...
+// 2. f x//x x//x x//x ...
+// b/
+bool ReadObjFromFile(const std::string& objFilename, std::map<std::string, CarPart>* carPartsMap);
+
+// Reads obj file to vector of OverlayVertex.
+// |obj_filename| is the full path and name of the obj file.
+// |option| provides optional changes on the coordinates.
+// |car_parts_map| is a map containing all car parts.
+bool ReadObjFromFile(const std::string& obFilename, const ReadObjOptions& option,
+                     std::map<std::string, CarPart>* carPartsMap);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sv
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // SURROUND_VIEW_SERVICE_IMPL_OBJREADER_H_
diff --git a/surround_view/service-impl/ObjReaderTests.cpp b/surround_view/service-impl/ObjReaderTests.cpp
new file mode 100644
index 0000000..9dae171
--- /dev/null
+++ b/surround_view/service-impl/ObjReaderTests.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ObjReaderTests"
+
+#include "ObjReader.h"
+
+#include "MtlReader.h"
+#include "core_lib.h"
+
+#include <gtest/gtest.h>
+#include <map>
+#include <string>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace sv {
+namespace V1_0 {
+namespace implementation {
+namespace {
+
+TEST(ObjParserTests, ReadCubeSuccess) {
+    std::map<std::string, CarPart> carPartsMap;
+    EXPECT_TRUE(ReadObjFromFile("/etc/automotive/sv/cube.obj", &carPartsMap));
+    EXPECT_NE(carPartsMap.size(), 0);
+}
+
+}  // namespace
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sv
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/surround_view/service-impl/lib/arm64/libcore_lib_shared.so b/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
index 2421d41..3988762 100755
--- a/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
+++ b/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
Binary files differ
diff --git a/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so b/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so
index 34d1f6a..e9f94db 100755
--- a/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so
+++ b/surround_view/service-impl/lib/x86-64/libcore_lib_shared.so
Binary files differ
diff --git a/surround_view/service-impl/lib/x86/libcore_lib_shared.so b/surround_view/service-impl/lib/x86/libcore_lib_shared.so
index c6ba2b6..b82d025 100755
--- a/surround_view/service-impl/lib/x86/libcore_lib_shared.so
+++ b/surround_view/service-impl/lib/x86/libcore_lib_shared.so
Binary files differ
diff --git a/surround_view/service-impl/test_data/cube.mtl b/surround_view/service-impl/test_data/cube.mtl
new file mode 100644
index 0000000..2f4e865
--- /dev/null
+++ b/surround_view/service-impl/test_data/cube.mtl
@@ -0,0 +1,5 @@
+newmtl flatwhite
+d 1.0000
+illum 1
+Ka 0.5000 0.5000 0.5000
+Kd 1.0000 1.0000 1.0000
diff --git a/surround_view/service-impl/test_data/cube.obj b/surround_view/service-impl/test_data/cube.obj
new file mode 100644
index 0000000..60ae1b2
--- /dev/null
+++ b/surround_view/service-impl/test_data/cube.obj
@@ -0,0 +1,32 @@
+mtllib cube.mtl
+g cube
+ 
+v 0.0 0.0 0.0
+v 0.0 0.0 1.0
+v 0.0 1.0 0.0
+v 0.0 1.0 1.0
+v 1.0 0.0 0.0
+v 1.0 0.0 1.0
+v 1.0 1.0 0.0
+v 1.0 1.0 1.0
+
+vn 0.0 0.0 1.0
+vn 0.0 0.0 -1.0
+vn 0.0 1.0 0.0
+vn 0.0 -1.0 0.0
+vn 1.0 0.0 0.0
+vn -1.0 0.0 0.0
+usemtl flatwhite 
+f 1//2 7//2 5//2
+f 1//2 3//2 7//2 
+f 1//6 4//6 3//6 
+f 1//6 2//6 4//6 
+f 3//3 8//3 7//3 
+f 3//3 4//3 8//3 
+f 5//5 7//5 8//5 
+f 5//5 8//5 6//5 
+f 1//4 5//4 6//4 
+f 1//4 6//4 2//4 
+f 2//1 6//1 8//1 
+f 2//1 8//1 4//1 
+
diff --git a/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml b/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml
index 8861afb..4c69e86 100644
--- a/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-b+sr+Latn/strings.xml
@@ -3190,7 +3190,7 @@
     <string name="other_sound_settings" msgid="5250376066099818676">"Drugi zvukovi"</string>
     <string name="dial_pad_tones_title" msgid="8877212139988655769">"Tonovi numeričke tastature"</string>
     <string name="screen_locking_sounds_title" msgid="4407110895465866809">"Zvukovi zaključavanja ekrana"</string>
-    <string name="charging_sounds_title" msgid="5070437987230894287">"Menjajući zvuci i vibracija"</string>
+    <string name="charging_sounds_title" msgid="5070437987230894287">"Zvukovi i vibracija punjenja"</string>
     <string name="docking_sounds_title" msgid="2573137471605541366">"Zvukovi montiranja"</string>
     <string name="touch_sounds_title" msgid="165237488496165652">"Zvukovi pri dodiru"</string>
     <string name="vibrate_on_touch_title" msgid="6360155469279157684">"Vibracija pri dodiru"</string>
diff --git a/tests/CarDeveloperOptions/res/values-be/strings.xml b/tests/CarDeveloperOptions/res/values-be/strings.xml
index ec27b37..8c34666 100644
--- a/tests/CarDeveloperOptions/res/values-be/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-be/strings.xml
@@ -3394,10 +3394,10 @@
     <string name="hide_silent_icons_title" msgid="1070905516921542662">"Хаваць значкі стану для апавяшчэнняў без гуку"</string>
     <string name="hide_silent_icons_summary" msgid="2624346914488256888">"Хаваць значкі для апавяшчэнняў без гуку на панэлі стану"</string>
     <string name="notification_badging_title" msgid="6311699476970264712">"Паказваць значкі апавяшчэнняў"</string>
-    <string name="notification_bubbles_title" msgid="9196562435741861317">"Дыялогі"</string>
+    <string name="notification_bubbles_title" msgid="9196562435741861317">"Усплывальныя апавяшчэнні"</string>
     <string name="notification_bubbles_summary" msgid="4624512775901949578">"Адусюль атрымлівайце хуткі доступ да змесціва праграмы з дапамогай зменлівых спалучэнняў клавіш"</string>
     <string name="bubbles_feature_education" msgid="8979109826818881018">"Некаторыя апавяшчэнні і іншае змесціва могуць паказвацца на экране ў выглядзе дыялогаў. Каб адкрыць дыялог, націсніце на яго. Каб закрыць дыялог, перацягніце яго ўніз экрана."</string>
-    <string name="bubbles_app_toggle_title" msgid="6401217027603326439">"Дыялогі"</string>
+    <string name="bubbles_app_toggle_title" msgid="6401217027603326439">"Усплывальныя апавяшчэнні"</string>
     <string name="bubbles_app_toggle_summary" msgid="7707611139796553855">"Дазваляе праграме \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" паказваць некаторыя апавяшчэнні ў выглядзе дыялогаў"</string>
     <string name="bubbles_feature_disabled_dialog_title" msgid="3375452386012079293">"Уключыце дыялогі"</string>
     <string name="bubbles_feature_disabled_dialog_text" msgid="326945485806386477">"Каб уключыць дыялогі для гэтай праграмы, уключыце дыялогі для прылады. Гэта паўплывае на іншыя праграмы, у якіх вы раней уключалі дыялогі."</string>
diff --git a/tests/CarDeveloperOptions/res/values-bn/strings.xml b/tests/CarDeveloperOptions/res/values-bn/strings.xml
index 78b74e4..c86b976 100644
--- a/tests/CarDeveloperOptions/res/values-bn/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-bn/strings.xml
@@ -3041,7 +3041,7 @@
     <string name="connected_devices_dashboard_no_driving_mode_summary" msgid="3524409078596318803">"ব্লুটুথ, এনএফসি"</string>
     <string name="connected_devices_dashboard_no_driving_mode_no_nfc_summary" msgid="7881286613528299400">"ব্লুটুথ"</string>
     <string name="app_and_notification_dashboard_title" msgid="8448096608058843730">"অ্যাপ ও বিজ্ঞপ্তি"</string>
-    <string name="app_and_notification_dashboard_summary" msgid="4165181440955038145">"অ্যাসিস্ট্যান্ট, সাম্প্রতিক অ্যাপ, ডিফল্ট অ্যাপ"</string>
+    <string name="app_and_notification_dashboard_summary" msgid="4165181440955038145">"Assistant, সাম্প্রতিক অ্যাপ, ডিফল্ট অ্যাপ"</string>
     <string name="notification_settings_work_profile" msgid="7190550347842400029">"কাজের প্রোফাইলে অ্যাপের জন্য বিজ্ঞপ্তি অ্যাক্সেস উপলভ্য নয়।"</string>
     <string name="account_dashboard_title" msgid="4734300939532555885">"অ্যাকাউন্ট"</string>
     <string name="account_dashboard_default_summary" msgid="6822549669771936206">"কোনও অ্যাকাউন্ট যোগ করা হয়নি"</string>
@@ -4325,7 +4325,7 @@
     <string name="battery_suggestion_summary" msgid="2669070349482656490"></string>
     <string name="gesture_prevent_ringing_screen_title" msgid="4173494225145223638">"রিং হওয়া বন্ধ করুন"</string>
     <string name="gesture_prevent_ringing_title" msgid="8827963588425673557">"রিং হওয়া বন্ধ করতে পাওয়ার ও ভলিউম বাড়ানোর বোতাম একসাথে প্রেস করুন"</string>
-    <string name="gesture_prevent_ringing_sound_title" msgid="8642330448721033641">"রিং হওয়া আটকানোর শর্টকাট"</string>
+    <string name="gesture_prevent_ringing_sound_title" msgid="8642330448721033641">"রিংয়ের আরওয়াজ আটকানোর শর্টকাট"</string>
     <string name="prevent_ringing_option_vibrate" msgid="6456505293904544108">"ভাইব্রেশন হতে দিন"</string>
     <string name="prevent_ringing_option_mute" msgid="53662688921253613">"মিউট করুন"</string>
     <string name="prevent_ringing_option_none" msgid="1450985763137666231">"যেমন আছে থাক"</string>
diff --git a/tests/CarDeveloperOptions/res/values-bs/strings.xml b/tests/CarDeveloperOptions/res/values-bs/strings.xml
index ba804e6..0bee24c 100644
--- a/tests/CarDeveloperOptions/res/values-bs/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-bs/strings.xml
@@ -3190,9 +3190,9 @@
     <string name="other_sound_settings" msgid="5250376066099818676">"Drugi zvukovi"</string>
     <string name="dial_pad_tones_title" msgid="8877212139988655769">"Tonovi tastature telefona"</string>
     <string name="screen_locking_sounds_title" msgid="4407110895465866809">"Zvukovi zaključavanja ekrana"</string>
-    <string name="charging_sounds_title" msgid="5070437987230894287">"Zvukovi/vibracija pri punjenju"</string>
+    <string name="charging_sounds_title" msgid="5070437987230894287">"Zvukovi/vibracija prilikom punjenja"</string>
     <string name="docking_sounds_title" msgid="2573137471605541366">"Zvukovi priključne stanice"</string>
-    <string name="touch_sounds_title" msgid="165237488496165652">"Zvukovi pri dodiru"</string>
+    <string name="touch_sounds_title" msgid="165237488496165652">"Zvukovi dodira"</string>
     <string name="vibrate_on_touch_title" msgid="6360155469279157684">"Vibracija pri dodiru"</string>
     <string name="vibrate_on_touch_summary" msgid="5504424764028676043">"Haptičke povratne informacije za dodir, tastaturu i drugo"</string>
     <string name="dock_audio_media_title" msgid="1859521680502040781">"Zvučnik priključne stanice reprodukuje zvuk"</string>
@@ -3470,8 +3470,8 @@
     <string name="notification_content_block_summary" msgid="2743896875255591743">"Nikad ne prikazuj obavještenja u nijansi ili na perifernim uređajima"</string>
     <string name="notification_badge_title" msgid="8989086619255666442">"Dozvoli tačku za obavještenja"</string>
     <string name="notification_channel_badge_title" msgid="8228215248332054612">"Prikaži tačku za obavještenja"</string>
-    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"Zamijeni način rada Ne ometaj"</string>
-    <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"Dozvolite da se obavještenja nastave pojavljivati kada je uključen način rada Ne ometaj"</string>
+    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"Zanemari način rada Ne ometaj"</string>
+    <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"Dozvoli da se obavještenja nastave pojavljivati kada je uključen način rada Ne ometaj"</string>
     <string name="app_notification_visibility_override_title" msgid="2349335170165637672">"Na zaključavanju ekrana"</string>
     <string name="app_notification_row_banned" msgid="2079325338122151677">"Blokirano"</string>
     <string name="app_notification_row_priority" msgid="432299064888787236">"Prioritetna"</string>
@@ -3553,7 +3553,7 @@
     <string name="zen_mode_media" msgid="3701280649874724055">"Reproduciraj zvukove medija"</string>
     <string name="zen_mode_media_list" msgid="509327580522287125">"mediji"</string>
     <string name="zen_mode_system" msgid="597437265986355038">"Dozvoli zvukove dodira"</string>
-    <string name="zen_mode_system_list" msgid="480192458506838077">"zvuci dodira"</string>
+    <string name="zen_mode_system_list" msgid="480192458506838077">"zvukovi dodira"</string>
     <string name="zen_mode_reminders" msgid="7560664194610054038">"Dozvoli podsjetnike"</string>
     <string name="zen_mode_reminders_list" msgid="7347061314032326677">"podsjetnici"</string>
     <string name="zen_mode_events" msgid="5784076928339534984">"Dozvoli događaje"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ca/strings.xml b/tests/CarDeveloperOptions/res/values-ca/strings.xml
index 60f9de3..29423a2 100644
--- a/tests/CarDeveloperOptions/res/values-ca/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ca/strings.xml
@@ -875,7 +875,7 @@
     <string name="wifi_cellular_data_fallback_title" msgid="5067241930716252665">"Canvia automàticament a dades mòbils"</string>
     <string name="wifi_cellular_data_fallback_summary" msgid="2721467405851519769">"Utilitza dades mòbils quan la Wi-Fi no tingui accés a Internet. És possible que s\'hi apliquin càrrecs per ús de dades."</string>
     <string name="wifi_add_network" msgid="4094957940791876640">"Afegeix una xarxa"</string>
-    <string name="wifi_configure_settings_preference_title" msgid="2678534679408777268">"Preferències de la Wi‑Fi"</string>
+    <string name="wifi_configure_settings_preference_title" msgid="2678534679408777268">"Preferències de Wi‑Fi"</string>
     <string name="wifi_configure_settings_preference_summary_wakeup_on" msgid="5714892572614655675">"La Wi‑Fi es torna a connectar automàticament"</string>
     <string name="wifi_configure_settings_preference_summary_wakeup_off" msgid="286904094152909651">"La Wi‑Fi no es torna a activar automàticament"</string>
     <string name="wifi_access_points" msgid="1647976498906871869">"Xarxes Wi-Fi"</string>
@@ -3548,7 +3548,7 @@
     <string name="zen_mode_screen_off" msgid="84211490206459038">"Quan la pantalla estigui apagada"</string>
     <string name="zen_mode_screen_off_summary" msgid="8592179073243001267">"Permet que les notificacions silenciades pel mode No molestis encenguin la pantalla i facin parpellejar el llum"</string>
     <string name="zen_mode_screen_off_summary_no_led" msgid="7255874108150630145">"Permet que les notificacions silenciades pel mode No molestis encenguin la pantalla"</string>
-    <string name="notification_app_settings_button" msgid="3651180424198580907">"Configuració de les notificacions"</string>
+    <string name="notification_app_settings_button" msgid="3651180424198580907">"Configuració de notificacions"</string>
     <string name="suggestion_button_text" msgid="5783566542423813847">"D\'acord"</string>
     <string name="device_feedback" msgid="4042352891448769818">"Envia suggeriments sobre el dispositiu"</string>
     <string name="restr_pin_enter_admin_pin" msgid="8577847751493521230">"Introdueix el PIN d\'administrador"</string>
diff --git a/tests/CarDeveloperOptions/res/values-es/strings.xml b/tests/CarDeveloperOptions/res/values-es/strings.xml
index eb24e4b..a7a06e2 100644
--- a/tests/CarDeveloperOptions/res/values-es/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-es/strings.xml
@@ -3140,7 +3140,7 @@
     <string name="alarm_volume_option_title" msgid="3184076022438477047">"Volumen de alarma"</string>
     <string name="ring_volume_option_title" msgid="2038924918468372264">"Volumen del tono"</string>
     <string name="notification_volume_option_title" msgid="1358512611511348260">"Volumen de notificaciones"</string>
-    <string name="ringtone_title" msgid="1409086028485922583">"Tono del teléfono"</string>
+    <string name="ringtone_title" msgid="1409086028485922583">"Tono de llamada del teléfono"</string>
     <string name="notification_ringtone_title" msgid="2932960620843976285">"Sonido de notificación predeterminado"</string>
     <string name="notification_unknown_sound_title" msgid="8043718667804838398">"Sonido proporcionado de app"</string>
     <string name="notification_sound_default" msgid="2664544380802426260">"Sonido de notificación predeterminado"</string>
@@ -3422,7 +3422,7 @@
     <string name="notification_content_block_summary" msgid="2743896875255591743">"No mostrar nunca notificaciones en el panel de notificaciones ni en dispositivos periféricos"</string>
     <string name="notification_badge_title" msgid="8989086619255666442">"Permitir burbuja de notificación"</string>
     <string name="notification_channel_badge_title" msgid="8228215248332054612">"Mostrar burbuja de notificación"</string>
-    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"Omitir No molestar"</string>
+    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"Ignorar modo No molestar"</string>
     <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"Permitir notificaciones cuando el modo No molestar esté activado"</string>
     <string name="app_notification_visibility_override_title" msgid="2349335170165637672">"En la pantalla de bloqueo"</string>
     <string name="app_notification_row_banned" msgid="2079325338122151677">"Bloqueada"</string>
diff --git a/tests/CarDeveloperOptions/res/values-fa/arrays.xml b/tests/CarDeveloperOptions/res/values-fa/arrays.xml
index 94410d3..2fcb737 100644
--- a/tests/CarDeveloperOptions/res/values-fa/arrays.xml
+++ b/tests/CarDeveloperOptions/res/values-fa/arrays.xml
@@ -111,7 +111,7 @@
     <item msgid="8247986727324120082">"۲ دقیقه"</item>
     <item msgid="2759776603549270587">"۵ دقیقه"</item>
     <item msgid="167772676068860015">"۱ ساعت"</item>
-    <item msgid="5985477119043628504">"بدون مهلت زمانی"</item>
+    <item msgid="5985477119043628504">"بدون درنگ"</item>
   </string-array>
   <string-array name="bluetooth_max_connected_audio_devices">
     <item msgid="3800257971619063588">"استفاده از پیش‌فرض سیستم: <xliff:g id="DEFAULT_BLUETOOTH_MAX_CONNECTED_AUDIO_DEVICES">%1$d</xliff:g>"</item>
@@ -415,7 +415,7 @@
     <item msgid="8754480102834556765">"آماده سازی..."</item>
     <item msgid="3351334355574270250">"در حال اتصال..."</item>
     <item msgid="8303882153995748352">"متصل"</item>
-    <item msgid="9135049670787351881">"وقفه زمانی"</item>
+    <item msgid="9135049670787351881">"درنگ"</item>
     <item msgid="2124868417182583926">"ناموفق"</item>
   </string-array>
   <string-array name="security_settings_premium_sms_values">
diff --git a/tests/CarDeveloperOptions/res/values-fa/strings.xml b/tests/CarDeveloperOptions/res/values-fa/strings.xml
index c715326..48e902e 100644
--- a/tests/CarDeveloperOptions/res/values-fa/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-fa/strings.xml
@@ -412,7 +412,7 @@
     <string name="face_intro_error_unknown" msgid="3241592604198351134">"چهره بیشتری نمی‌توان اضافه کرد"</string>
     <string name="security_settings_face_enroll_error_dialog_title" msgid="3933492758701563051">"ثبت انجام نشد"</string>
     <string name="security_settings_face_enroll_dialog_ok" msgid="1078348922734845090">"تأیید"</string>
-    <string name="security_settings_face_enroll_error_timeout_dialog_message" msgid="4917894418448325405">"مهلت زمانی ثبت چهره به پایان رسید. دوباره امتحان کنید."</string>
+    <string name="security_settings_face_enroll_error_timeout_dialog_message" msgid="4917894418448325405">"درنگ ثبت چهره به پایان رسید. دوباره امتحان کنید."</string>
     <string name="security_settings_face_enroll_error_generic_dialog_message" msgid="5160473187142616862">"ثبت چهره کار نکرد."</string>
     <string name="security_settings_face_enroll_finish_title" msgid="6800717857394410769">"همه چیز تنظیم شد. خوب به نظر می‌رسد."</string>
     <string name="security_settings_face_enroll_done" msgid="5409739233373490971">"تمام"</string>
@@ -488,7 +488,7 @@
     <string name="security_settings_fingerprint_enroll_touch_dialog_title" msgid="7410398793283818609">"اووه، آن حسگر نیست"</string>
     <string name="security_settings_fingerprint_enroll_touch_dialog_message" msgid="7192100314788868883">"با استفاده از انگشت اشاره، حسگر را در  پشت تلفن لمس کنید."</string>
     <string name="security_settings_fingerprint_enroll_error_dialog_title" msgid="1415709674142168770">"ثبت انجام نشد"</string>
-    <string name="security_settings_fingerprint_enroll_error_timeout_dialog_message" msgid="498951203761192366">"مهلت زمانی ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
+    <string name="security_settings_fingerprint_enroll_error_timeout_dialog_message" msgid="498951203761192366">"درنگ ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
     <string name="security_settings_fingerprint_enroll_error_generic_dialog_message" msgid="7896295829530444810">"ثبت اثر انگشت کار نمی‌کند. دوباره امتحان کنید یا از انگشت دیگری استفاده کنید."</string>
     <string name="fingerprint_enroll_button_add" msgid="6335782936874996629">"افزودن مورد دیگر"</string>
     <string name="fingerprint_enroll_button_next" msgid="6419214079104413695">"بعدی"</string>
@@ -3112,11 +3112,11 @@
     <string name="keywords_face_settings" msgid="4117345666006836599">"چهره"</string>
     <string name="keywords_fingerprint_settings" msgid="902902368701134163">"اثر انگشت، افزودن اثر انگشت"</string>
     <string name="keywords_display_auto_brightness" msgid="1810596220466483996">"تار کردن صفحه‌نمایش، صفحه لمسی، باتری، روشنایی هوشمند، روشنایی پویا"</string>
-    <string name="keywords_display_adaptive_sleep" msgid="1695357782432822811">"کم‌نور کردن صفحه، خواب، باتری، مهلت زمانی، توجه، نمایشگر، صفحه، بی‌فعالیتی"</string>
+    <string name="keywords_display_adaptive_sleep" msgid="1695357782432822811">"کم‌نور کردن صفحه، خواب، باتری، درنگ، توجه، نمایشگر، صفحه، بی‌فعالیتی"</string>
     <string name="keywords_auto_rotate" msgid="4320791369951647513">"چرخاندن، چرخش، چرخش، پرتره، منظره، جهت، عمودی، افقی"</string>
     <string name="keywords_system_update_settings" msgid="4419971277998986067">"ارتقا دادن، Android"</string>
     <string name="keywords_zen_mode_settings" msgid="4103819458182535493">"«مزاحم نشوید»، زمان‌بندی، اعلان‌ها، مسدود کردن، سکوت، لرزش، خواب، کار، کانونی کردن، صدا، صامت کردن، روز، روز هفته، آخر هفته، شب‌های طول هفته، رویداد"</string>
-    <string name="keywords_screen_timeout" msgid="4328381362313993666">"صفحه نمایش، زمان قفل شدن، مهلت زمانی، صفحه درحالت قفل"</string>
+    <string name="keywords_screen_timeout" msgid="4328381362313993666">"صفحه نمایش، زمان قفل شدن، درنگ، صفحه درحالت قفل"</string>
     <string name="keywords_storage_settings" msgid="6422454520424236476">"حافظه، حافظه پنهان، داده، حذف، پاک کردن، آزاد، فضا"</string>
     <string name="keywords_bluetooth_settings" msgid="1152229891590622822">"متصل، دستگاه، هدفون‌ها، هدست‌ها، بلندگو، بی‌سیم، مرتبط‌سازی، هدفون‌های توگوشی، موسیقی، رسانه"</string>
     <string name="keywords_wallpaper" msgid="7665778626293643625">"پس‌زمینه، صفحه نمایش، صفحه در حالت قفل، طرح زمینه"</string>
diff --git a/tests/CarDeveloperOptions/res/values-fi/strings.xml b/tests/CarDeveloperOptions/res/values-fi/strings.xml
index 61588ac..659ba8a 100644
--- a/tests/CarDeveloperOptions/res/values-fi/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-fi/strings.xml
@@ -246,7 +246,7 @@
     <string name="band_mode_set" msgid="4962130364076526789">"Aseta"</string>
     <string name="band_mode_failed" msgid="8350123391471974137">"Epäonnistui"</string>
     <string name="band_mode_succeeded" msgid="5516613616395402809">"Onnistui"</string>
-    <string name="sdcard_changes_instructions" msgid="4138217393448114001">"Muutokset tulevat voimaan, kun USB-kaapeli kytketään uudelleen."</string>
+    <string name="sdcard_changes_instructions" msgid="4138217393448114001">"Muutokset tulevat voimaan, kun USB-johto kytketään uudelleen."</string>
     <string name="sdcard_settings_screen_mass_storage_text" msgid="7486030250999007641">"Ota USB-massamuisti käyttöön"</string>
     <string name="sdcard_settings_total_bytes_label" msgid="6461741874400909157">"Tavuja yhteensä:"</string>
     <string name="sdcard_settings_not_present_status" product="nosdcard" msgid="5419085128792417589">"USB-tallennustila ei käytössä."</string>
@@ -849,7 +849,7 @@
     <string name="wifi_notify_open_networks" msgid="4782239203624619655">"Avaa verkkoilmoitus"</string>
     <string name="wifi_notify_open_networks_summary" msgid="1383681260705466715">"Ilmoita, kun käytettävissä on laadukkaita julkisia verkkoja."</string>
     <string name="wifi_wakeup" msgid="4963732992164721548">"Laita Wi-Fi päälle automaattisesti"</string>
-    <string name="wifi_wakeup_summary" msgid="1152699417411690">"Wi-Fi laitetaan automaattisesti päälle, kun lähistöllä on kotiverkkosi tai muita laadukkaita tallennettuja verkkoja."</string>
+    <string name="wifi_wakeup_summary" msgid="1152699417411690">"Wi-Fi laitetaan automaattisesti päälle, kun lähistöllä on kotiverkkosi tai muita laadukkaita tallennettuja verkkoja"</string>
     <string name="wifi_wakeup_summary_no_location" msgid="3007457288587966962">"Ei käytettävissä, koska sijainti on poistettu käytöstä. Ota "<annotation id="link">"sijainti"</annotation>" käyttöön."</string>
     <string name="wifi_wakeup_summary_scanning_disabled" msgid="6820040651529910914">"Ei käytettävissä, koska Wi‑Fi-haku on pois päältä."</string>
     <string name="wifi_wakeup_summary_scoring_disabled" msgid="7067018832237903151">"Valitse verkon arviointipalvelu, jotta voit käyttää tätä."</string>
diff --git a/tests/CarDeveloperOptions/res/values-gl/strings.xml b/tests/CarDeveloperOptions/res/values-gl/strings.xml
index d8f5367..51e5d0c 100644
--- a/tests/CarDeveloperOptions/res/values-gl/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-gl/strings.xml
@@ -4477,7 +4477,7 @@
     <string name="contextual_card_dismiss_confirm_message" msgid="2352465079667730312">"Queres eliminar esta suxestión?"</string>
     <string name="contextual_card_removed_message" msgid="4047307820743366876">"Quitouse a suxestión"</string>
     <string name="contextual_card_undo_dismissal_text" msgid="5009245286931852012">"Desfacer"</string>
-    <string name="low_storage_summary" msgid="4562224870189133400">"Queda pouco espazo. Utilizado: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Libre: <xliff:g id="FREE_SPACE">%2$s</xliff:g>"</string>
+    <string name="low_storage_summary" msgid="4562224870189133400">"Queda pouco espazo. En uso: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Libre: <xliff:g id="FREE_SPACE">%2$s</xliff:g>"</string>
     <string name="contextual_card_feedback_send" msgid="8698649023854350623">"Enviar comentarios"</string>
     <string name="contextual_card_feedback_confirm_message" msgid="3987973028353264878">"Queres indicarnos a túa opinión sobre esta suxestión?"</string>
     <string name="copyable_slice_toast" msgid="1357518174923789947">"<xliff:g id="COPY_CONTENT">%1$s</xliff:g>: copiouse no portapapeis."</string>
diff --git a/tests/CarDeveloperOptions/res/values-gu/strings.xml b/tests/CarDeveloperOptions/res/values-gu/strings.xml
index 398c56d..49de15b 100644
--- a/tests/CarDeveloperOptions/res/values-gu/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-gu/strings.xml
@@ -3041,7 +3041,7 @@
     <string name="connected_devices_dashboard_no_driving_mode_summary" msgid="3524409078596318803">"બ્લૂટૂથ, NFC"</string>
     <string name="connected_devices_dashboard_no_driving_mode_no_nfc_summary" msgid="7881286613528299400">"બ્લૂટૂથ"</string>
     <string name="app_and_notification_dashboard_title" msgid="8448096608058843730">"ઍપ્લિકેશનો અને નોટિફિકેશન"</string>
-    <string name="app_and_notification_dashboard_summary" msgid="4165181440955038145">"આસિસ્ટંટ, તાજેતરની ઍપ, ડિફૉલ્ટ ઍપ"</string>
+    <string name="app_and_notification_dashboard_summary" msgid="4165181440955038145">"Assistant, તાજેતરની ઍપ, ડિફૉલ્ટ ઍપ"</string>
     <string name="notification_settings_work_profile" msgid="7190550347842400029">"કાર્યાલયની પ્રોફાઇલમાં ઍપ માટે નોટિફિકેશન ઍક્સેસ ઉપલબ્ધ નથી."</string>
     <string name="account_dashboard_title" msgid="4734300939532555885">"એકાઉન્ટ"</string>
     <string name="account_dashboard_default_summary" msgid="6822549669771936206">"કોઈ એકાઉન્ટ ઉમેરવામાં આવ્યાં નથી"</string>
diff --git a/tests/CarDeveloperOptions/res/values-hy/strings.xml b/tests/CarDeveloperOptions/res/values-hy/strings.xml
index 0154721..5d6c540 100644
--- a/tests/CarDeveloperOptions/res/values-hy/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-hy/strings.xml
@@ -849,7 +849,7 @@
     <string name="wifi_notify_open_networks" msgid="4782239203624619655">"Ծանուցումներ բաց ցանցերի մասին"</string>
     <string name="wifi_notify_open_networks_summary" msgid="1383681260705466715">"Տեղեկացնել լավ ազդանշանով բաց ցանցերի հասանելիության մասին"</string>
     <string name="wifi_wakeup" msgid="4963732992164721548">"Ավտոմատ միացնել Wi‑Fi-ը"</string>
-    <string name="wifi_wakeup_summary" msgid="1152699417411690">"Wi‑Fi-ը կրկին կմիանա պահված լավ ազդանշանով պահված ցանցերի, օրինակ, ձեր տան ցանցի մոտակայքում"</string>
+    <string name="wifi_wakeup_summary" msgid="1152699417411690">"Wi‑Fi-ը կրկին կմիանա լավ ազդանշանով պահված ցանցերի, օրինակ, ձեր տան ցանցի մոտակայքում"</string>
     <string name="wifi_wakeup_summary_no_location" msgid="3007457288587966962">"Անհասանելի է, քանի որ տեղորոշումն անջատված է։ Միացրեք "<annotation id="link">"տեղորոշումը"</annotation>"։"</string>
     <string name="wifi_wakeup_summary_scanning_disabled" msgid="6820040651529910914">"Անհասանելի է, քանի որ Wi‑Fi ցանցերի որոնումն անջատված է"</string>
     <string name="wifi_wakeup_summary_scoring_disabled" msgid="7067018832237903151">"Օգտագործելու համար ընտրեք ցանցի վարկանիշի մատակարարը"</string>
diff --git a/tests/CarDeveloperOptions/res/values-in/strings.xml b/tests/CarDeveloperOptions/res/values-in/strings.xml
index 6ada981..307e232 100644
--- a/tests/CarDeveloperOptions/res/values-in/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-in/strings.xml
@@ -2862,7 +2862,7 @@
     <string name="user_summary_managed_profile_not_set_up" msgid="3032986082684011281">"Tidak disiapkan - Profil kerja"</string>
     <string name="user_admin" msgid="805802526361071709">"Admin"</string>
     <string name="user_you" msgid="8212549708652717106">"Anda (<xliff:g id="NAME">%s</xliff:g>)"</string>
-    <string name="user_nickname" msgid="1088216221559125529">"Nama julukan"</string>
+    <string name="user_nickname" msgid="1088216221559125529">"Nama panggilan"</string>
     <string name="user_add_user_type_title" msgid="8672326434351387845">"Tambahkan"</string>
     <string name="user_add_max_count" msgid="4524573950126500416">"Anda dapat menambahkan maksimal <xliff:g id="USER_COUNT">%1$d</xliff:g> pengguna"</string>
     <string name="user_add_user_item_summary" msgid="6114355152711455716">"Pengguna memiliki aplikasi dan konten mereka sendiri"</string>
@@ -3035,7 +3035,7 @@
     <string name="network_dashboard_summary_mobile" msgid="5560545061217580626">"seluler"</string>
     <string name="network_dashboard_summary_data_usage" msgid="4695629715072542102">"penggunaan kuota"</string>
     <string name="network_dashboard_summary_hotspot" msgid="3928610802321995214">"hotspot"</string>
-    <string name="connected_devices_dashboard_title" msgid="7795222675849060444">"Perangkat tersambung"</string>
+    <string name="connected_devices_dashboard_title" msgid="7795222675849060444">"Perangkat terhubung"</string>
     <string name="connected_devices_dashboard_summary" msgid="1072664369515033179">"Bluetooth, mode mengemudi, NFC"</string>
     <string name="connected_devices_dashboard_no_nfc_summary" msgid="2610085597733526722">"Bluetooth, mode mengemudi"</string>
     <string name="connected_devices_dashboard_no_driving_mode_summary" msgid="3524409078596318803">"Bluetooth, NFC"</string>
diff --git a/tests/CarDeveloperOptions/res/values-it/strings.xml b/tests/CarDeveloperOptions/res/values-it/strings.xml
index 5c72158..02abed3 100644
--- a/tests/CarDeveloperOptions/res/values-it/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-it/strings.xml
@@ -4325,7 +4325,7 @@
     <string name="battery_suggestion_summary" msgid="2669070349482656490"></string>
     <string name="gesture_prevent_ringing_screen_title" msgid="4173494225145223638">"Disattiva suoneria"</string>
     <string name="gesture_prevent_ringing_title" msgid="8827963588425673557">"Premi contemporaneamente i tasti di accensione e Volume su per"</string>
-    <string name="gesture_prevent_ringing_sound_title" msgid="8642330448721033641">"Scorciatoia per impedire al telefono di suonare"</string>
+    <string name="gesture_prevent_ringing_sound_title" msgid="8642330448721033641">"Scorciatoia per disattivare la suoneria"</string>
     <string name="prevent_ringing_option_vibrate" msgid="6456505293904544108">"Vibrazione"</string>
     <string name="prevent_ringing_option_mute" msgid="53662688921253613">"Disattiva audio"</string>
     <string name="prevent_ringing_option_none" msgid="1450985763137666231">"Non fare niente"</string>
diff --git a/tests/CarDeveloperOptions/res/values-km/strings.xml b/tests/CarDeveloperOptions/res/values-km/strings.xml
index 29c5ca4..c8b2bdb 100644
--- a/tests/CarDeveloperOptions/res/values-km/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-km/strings.xml
@@ -3136,7 +3136,7 @@
     <string name="sound_settings_example_summary" msgid="2091822107298841827">"កម្រិតសំឡេងរោទ៍ត្រឹម 80%"</string>
     <string name="media_volume_option_title" msgid="3553411883305505682">"កម្រិត​សំឡេង​មេឌៀ"</string>
     <string name="remote_media_volume_option_title" msgid="6355710054191873836">"កម្រិតសំឡេងនៃការបញ្ជូន"</string>
-    <string name="call_volume_option_title" msgid="5028003296631037334">"កម្រិត​សំឡេង​ហៅ"</string>
+    <string name="call_volume_option_title" msgid="5028003296631037334">"កម្រិត​សំឡេង​ហៅទូរសព្ទ"</string>
     <string name="alarm_volume_option_title" msgid="3184076022438477047">"កម្រិត​សំឡេងម៉ោង​រោទ៍"</string>
     <string name="ring_volume_option_title" msgid="2038924918468372264">"កម្រិត​សំឡេង​រោទ៍"</string>
     <string name="notification_volume_option_title" msgid="1358512611511348260">"កម្រិត​សំឡេង​ការ​ជូន​ដំណឹង"</string>
@@ -3153,7 +3153,7 @@
     <string name="docking_sounds_title" msgid="2573137471605541366">"សំឡេង​​ភ្ជាប់"</string>
     <string name="touch_sounds_title" msgid="165237488496165652">"សំឡេង​ប៉ះ"</string>
     <string name="vibrate_on_touch_title" msgid="6360155469279157684">"ការ​ញ័រ​ពេល​ប៉ះ"</string>
-    <string name="vibrate_on_touch_summary" msgid="5504424764028676043">"មតិស្ថាបនា​តាម​ការប៉ះ​សម្រាប់​ការចុច ក្ដារចុច និងច្រើនទៀត"</string>
+    <string name="vibrate_on_touch_summary" msgid="5504424764028676043">"ប្រតិកម្មញ័រពេលចុច ក្ដារចុច និងច្រើនទៀត"</string>
     <string name="dock_audio_media_title" msgid="1859521680502040781">"ភ្ជាប់ការ​ចាក់​តាមអូប៉ាល័រ"</string>
     <string name="dock_audio_media_disabled" msgid="4300752306178486302">"អូឌីយ៉ូ​​ទាំងអស់"</string>
     <string name="dock_audio_media_enabled" msgid="2873275045878628153">"តែ​អូឌីយ៉ូ​​មេឌៀ​ប៉ុណ្ណោះ"</string>
@@ -4310,7 +4310,7 @@
     <string name="change_wifi_state_title" msgid="5140754955787584174">"ការ​គ្រប់គ្រង Wi-Fi"</string>
     <string name="change_wifi_state_app_detail_switch" msgid="6489090744937816260">"អនុញ្ញាត​ឱ្យ​កម្មវិធី​គ្រប់គ្រង Wi-Fi"</string>
     <string name="change_wifi_state_app_detail_summary" msgid="614854822469259860">"អនុញ្ញាត​ឱ្យ​កម្មវិធី​នេះ​បើក ឬបិទ Wi-Fi ស្កេន និងភ្ជាប់បណ្តាញ Wi-Fi បញ្ចូល ឬលុប​បណ្តាញ ឬចាប់ផ្តើមតែហតស្ប៉តមូលដ្ឋាន​ប៉ុណ្ណោះ"</string>
-    <string name="media_output_title" msgid="8710632337456601848">"ចាក់​មេឌៀទៅកាន់"</string>
+    <string name="media_output_title" msgid="8710632337456601848">"ចាក់​មេឌៀនៅលើ"</string>
     <string name="media_output_default_summary" msgid="3159237976830415584">"ឧបករណ៍នេះ"</string>
     <string name="media_output_summary" product="default" msgid="6294261435613551178">"ទូរសព្ទ"</string>
     <string name="media_output_summary" product="tablet" msgid="6672024060360538526">"ថេប្លេត"</string>
diff --git a/tests/CarDeveloperOptions/res/values-kn/arrays.xml b/tests/CarDeveloperOptions/res/values-kn/arrays.xml
index 63d5f6a..2b09f58 100644
--- a/tests/CarDeveloperOptions/res/values-kn/arrays.xml
+++ b/tests/CarDeveloperOptions/res/values-kn/arrays.xml
@@ -223,7 +223,7 @@
     <item msgid="2585253854462134715">"ಒರಟು ಸ್ಥಳ"</item>
     <item msgid="1830619568689922920">"ಉತ್ಕೃಷ್ಟ ಸ್ಥಳ"</item>
     <item msgid="3317274469481923141">"GPS"</item>
-    <item msgid="8931785990160383356">"ಕಂಪನ"</item>
+    <item msgid="8931785990160383356">"ವೈಬ್ರೇಟ್‌"</item>
     <item msgid="8632513128515114092">"ಓದುವ ಸಂಪರ್ಕಗಳು"</item>
     <item msgid="3741042113569620272">"ಸಂಪರ್ಕಗಳನ್ನು ಮಾರ್ಪಡಿಸಿ"</item>
     <item msgid="4204420969709009931">"ಕರೆಯ ಲಾಗ್‌ ಓದಿ"</item>
diff --git a/tests/CarDeveloperOptions/res/values-kn/strings.xml b/tests/CarDeveloperOptions/res/values-kn/strings.xml
index 5d1e489..ad359d0 100644
--- a/tests/CarDeveloperOptions/res/values-kn/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-kn/strings.xml
@@ -3124,7 +3124,7 @@
     <string name="keywords_default_payment_app" msgid="845369409578423996">"ಪಾವತಿ, ಡಿಫಾಲ್ಟ್"</string>
     <string name="keywords_ambient_display" msgid="8835182491798487184">"ಒಳಬರುವ ಅಧಿಸೂಚನೆ"</string>
     <string name="keywords_hotspot_tethering" msgid="1723591462602613867">"usb ಟೆಥರ್, ಬ್ಲೂಟೂತ್ ಟೆಥರ್, ವೈಫೈ ಹಾಟ್‌ಸ್ಪಾಟ್"</string>
-    <string name="keywords_touch_vibration" msgid="2081175517528255224">"ಹ್ಯಾಪ್ಟಿಕ್ಸ್, ಕಂಪನ, ಪರದೆ, ಸಂವೇದನೆ"</string>
+    <string name="keywords_touch_vibration" msgid="2081175517528255224">"ಹ್ಯಾಪ್ಟಿಕ್ಸ್, ವೈಬ್ರೇಟ್‌, ಪರದೆ, ಸಂವೇದನೆ"</string>
     <string name="keywords_ring_vibration" msgid="4210509151866460210">"ಹ್ಯಾಪ್ಟಿಕ್ಸ್, ವೈಬ್ರೇಟ್‌, ಫೋನ್, ಕರೆ, ಸೂಕ್ಷ್ಮತೆ, ರಿಂಗ್"</string>
     <string name="keywords_notification_vibration" msgid="1077515502086745166">"ಹ್ಯಾಪ್ಟಿಕ್ಸ್, ವೈಬ್ರೇಟ್‌, ಸೂಕ್ಷ್ಮತೆ"</string>
     <string name="keywords_battery_saver_sticky" msgid="8733804259716284872">"ಬ್ಯಾಟರಿ ಸೇವರ್, ಸ್ಟಿಕಿ, ತಡೆ ಹಿಡಿ, ಪವರ್ ಸೇವರ್, ಬ್ಯಾಟರಿ"</string>
@@ -3149,7 +3149,7 @@
     <string name="other_sound_settings" msgid="5250376066099818676">"ಇತರ ಧ್ವನಿಗಳು"</string>
     <string name="dial_pad_tones_title" msgid="8877212139988655769">"ಡಯಲ್‌ ಪ್ಯಾಡ್‌ ಟೋನ್‌ಗಳು"</string>
     <string name="screen_locking_sounds_title" msgid="4407110895465866809">"ಸ್ಕ್ರೀನ್ ಲಾಕಿಂಗ್ ಧ್ವನಿಗಳು"</string>
-    <string name="charging_sounds_title" msgid="5070437987230894287">"ಚಾರ್ಜಿಂಗ್ ಧ್ವನಿಗಳು ಮತ್ತು ಕಂಪನ"</string>
+    <string name="charging_sounds_title" msgid="5070437987230894287">"ಚಾರ್ಜಿಂಗ್ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಟ್‌"</string>
     <string name="docking_sounds_title" msgid="2573137471605541366">"ಡಾಕಿಂಗ್ ಧ್ವನಿಗಳು"</string>
     <string name="touch_sounds_title" msgid="165237488496165652">"ಸ್ಪರ್ಶ ಧ್ವನಿಗಳು"</string>
     <string name="vibrate_on_touch_title" msgid="6360155469279157684">"ಸ್ಪರ್ಶಿಸಿದಾಗ ವೈಬ್ರೇಷನ್‌"</string>
@@ -4037,7 +4037,7 @@
     <string name="notification_log_details_ashmem" msgid="4272241723105041393">"ಆಶ್ಮೆಮ್"</string>
     <string name="notification_log_details_alerted" msgid="1891749888625061319">"ಅಧಿಸೂಚನೆಯ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡಲಾಗಿದೆ"</string>
     <string name="notification_log_details_sound" msgid="4028782443557466322">"ಶಬ್ದ"</string>
-    <string name="notification_log_details_vibrate" msgid="8372400602058888072">"ಕಂಪನ"</string>
+    <string name="notification_log_details_vibrate" msgid="8372400602058888072">"ವೈಬ್ರೇಟ್‌"</string>
     <string name="notification_log_details_vibrate_pattern" msgid="7015554755444260922">"ಪ್ಯಾಟರ್ನ್"</string>
     <string name="notification_log_details_default" msgid="455451833359888182">"ಡಿಫಾಲ್ಟ್"</string>
     <string name="notification_log_details_none" msgid="4294690532744821638">"ಯಾವುದೂ ಇಲ್ಲ"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ky/strings.xml b/tests/CarDeveloperOptions/res/values-ky/strings.xml
index c436ab2..be41ac2 100644
--- a/tests/CarDeveloperOptions/res/values-ky/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ky/strings.xml
@@ -3035,7 +3035,7 @@
     <string name="network_dashboard_summary_mobile" msgid="5560545061217580626">"мобилдик"</string>
     <string name="network_dashboard_summary_data_usage" msgid="4695629715072542102">"дайын-даректердин өткөрүлүшү"</string>
     <string name="network_dashboard_summary_hotspot" msgid="3928610802321995214">"байланыш түйүнү"</string>
-    <string name="connected_devices_dashboard_title" msgid="7795222675849060444">"Туташкан түзмөктөр"</string>
+    <string name="connected_devices_dashboard_title" msgid="7795222675849060444">"Байланышкан түзмөктөр"</string>
     <string name="connected_devices_dashboard_summary" msgid="1072664369515033179">"Bluetooth, айдоо режими, NFC"</string>
     <string name="connected_devices_dashboard_no_nfc_summary" msgid="2610085597733526722">"Bluetooth, айдоо режими"</string>
     <string name="connected_devices_dashboard_no_driving_mode_summary" msgid="3524409078596318803">"Bluetooth, NFC"</string>
diff --git a/tests/CarDeveloperOptions/res/values-lo/strings.xml b/tests/CarDeveloperOptions/res/values-lo/strings.xml
index 4d48d74..f43a442 100644
--- a/tests/CarDeveloperOptions/res/values-lo/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-lo/strings.xml
@@ -3403,7 +3403,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ໝວດໝູ່</item>
       <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ໝວດໝູ່</item>
     </plurals>
-    <string name="no_channels" msgid="8884254729302501652">"This app has not posted any notifications"</string>
+    <string name="no_channels" msgid="8884254729302501652">"ແອັບນີ້ຍັງບໍ່ໄດ້ໂພສການແຈ້ງເຕືອນໃດເທື່ອ"</string>
     <string name="app_settings_link" msgid="8465287765715790984">"ການຕັ້ງຄ່າເພີ່ມເຕີມໃນແອັບ"</string>
     <string name="app_notification_listing_summary_zero" msgid="4047782719487686699">"ເປີດສຳລັບທຸກແອັບ"</string>
     <plurals name="app_notification_listing_summary_others" formatted="false" msgid="1161774065480666519">
diff --git a/tests/CarDeveloperOptions/res/values-mk/strings.xml b/tests/CarDeveloperOptions/res/values-mk/strings.xml
index 56d2a0c..94c0d71 100644
--- a/tests/CarDeveloperOptions/res/values-mk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-mk/strings.xml
@@ -1608,7 +1608,7 @@
     <string name="master_clear_not_available" msgid="4676613348163652454">"Фабричкото ресетирање не е достапно за овој корисник"</string>
     <string name="master_clear_progress_title" msgid="378953167274114857">"Се брише"</string>
     <string name="master_clear_progress_text" msgid="5418958116008976218">"Почекајте..."</string>
-    <string name="call_settings_title" msgid="5033906789261282752">"Поставки на повик"</string>
+    <string name="call_settings_title" msgid="5033906789261282752">"Поставки за повици"</string>
     <string name="call_settings_summary" msgid="2119161087671450035">"Постави говорна пошта, проследување на повик, повик на чекање, ID на повикувач"</string>
     <string name="tether_settings_title_usb" msgid="4265582654602420357">"Интернет преку USB"</string>
     <string name="tether_settings_title_wifi" msgid="2060965130234484613">"Преносл. точка на пристап"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ml/strings.xml b/tests/CarDeveloperOptions/res/values-ml/strings.xml
index a529cee..2f0c29a 100644
--- a/tests/CarDeveloperOptions/res/values-ml/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ml/strings.xml
@@ -3105,7 +3105,7 @@
     <string name="keywords_android_version" msgid="4842749998088987740">"android സുരക്ഷാ പാച്ച് നില, ബേസ്‌ബാൻഡ് പതിപ്പ്, കെർണൽ പതിപ്പ്"</string>
     <string name="keywords_dark_ui_mode" msgid="1027966176887770318">"തീം, പ്രകാശം, ഇരുണ്ട മോഡ്"</string>
     <string name="keywords_financial_apps_sms_access" msgid="3236014691838121857">"സാമ്പത്തിക ആപ്പ്, SMS, അനുമതി"</string>
-    <string name="keywords_systemui_theme" msgid="9150908170417305866">"ഇരുണ്ട തീം"</string>
+    <string name="keywords_systemui_theme" msgid="9150908170417305866">"ഡാർക്ക് തീം"</string>
     <string name="keywords_device_feedback" msgid="6948977907405738490">"ബഗ്"</string>
     <string name="keywords_ambient_display_screen" msgid="5873935693887583428">"പാതിമയക്ക ഡിസ്‌പ്ലേ, ലോക്ക് സ്‌ക്രീൻ ഡിസ്‌പ്ലേ"</string>
     <string name="keywords_lock_screen_notif" msgid="4914337222856805463">"ലോക്ക് സ്‌ക്രീൻ അറിയിപ്പ്, അറിയിപ്പുകൾ"</string>
@@ -4310,8 +4310,8 @@
     <string name="change_wifi_state_title" msgid="5140754955787584174">"വൈഫൈ നിയന്ത്രണം"</string>
     <string name="change_wifi_state_app_detail_switch" msgid="6489090744937816260">"വൈഫൈയെ നിയന്ത്രിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
     <string name="change_wifi_state_app_detail_summary" msgid="614854822469259860">"വൈഫൈ ഓണോ ഓഫോ ആക്കാനോ വൈഫൈ നെറ്റ്‌വർക്കുകൾ സ്കാൻ ചെയ്യാനോ അവയിലേക്ക് കണക്‌റ്റ് ചെയ്യാനോ നെറ്റ്‌വർക്കുകൾ ചേർക്കാനോ നീക്കം ചെയ്യാനോ ഉപകരണം ഉള്ളിടത്ത് മാത്രം പ്രവർത്തിക്കുന്ന ഒരു ഹോട്ട്‌സ്പോട്ട് ആരംഭിക്കാനോ ഈ ആപ്പിനെ അനുവദിക്കുക"</string>
-    <string name="media_output_title" msgid="8710632337456601848">"ഇതിലേക്ക് മീഡിയ പ്ലേ ചെയ്യുക"</string>
-    <string name="media_output_default_summary" msgid="3159237976830415584">"ഈ ഉപകരണം"</string>
+    <string name="media_output_title" msgid="8710632337456601848">"മീഡിയ പ്ലേ ചെയ്യുക:"</string>
+    <string name="media_output_default_summary" msgid="3159237976830415584">"ഈ ഉപകരണത്തിൽ"</string>
     <string name="media_output_summary" product="default" msgid="6294261435613551178">"ഫോൺ"</string>
     <string name="media_output_summary" product="tablet" msgid="6672024060360538526">"ടാബ്‌ലെറ്റ്"</string>
     <string name="media_output_summary" product="device" msgid="5132223072593052660">"ഉപകരണം"</string>
diff --git a/tests/CarDeveloperOptions/res/values-my/strings.xml b/tests/CarDeveloperOptions/res/values-my/strings.xml
index 4ad5b8e..3716e91 100644
--- a/tests/CarDeveloperOptions/res/values-my/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-my/strings.xml
@@ -3332,7 +3332,7 @@
     <string name="lock_screen_notifications_interstitial_title_profile" msgid="4043621508889929254">"ပရိုဖိုင်သတိပေးချက်များ"</string>
     <string name="notifications_title" msgid="8334011924253810654">"အကြောင်းကြားချက်များ"</string>
     <string name="app_notifications_title" msgid="1141791221581312325">"အက်ပ် အကြောင်းကြားချက်များ"</string>
-    <string name="notification_channel_title" msgid="6637705960909690229">"အသိပေးချက် အမျိုးအစား"</string>
+    <string name="notification_channel_title" msgid="6637705960909690229">"အကြောင်းကြားချက် အမျိုးအစား"</string>
     <string name="notification_group_title" msgid="6105337987437608590">"အကြောင်းကြားချက် အုပ်စုအမျိုးအစား"</string>
     <string name="notification_importance_title" msgid="4131979083408000545">"အပြုအမူ"</string>
     <string name="notification_importance_unspecified" msgid="2515778981253707724">"အသံကို ခွင့်ပြုရန်"</string>
diff --git a/tests/CarDeveloperOptions/res/values-or/strings.xml b/tests/CarDeveloperOptions/res/values-or/strings.xml
index bbc3273..17e330b 100644
--- a/tests/CarDeveloperOptions/res/values-or/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-or/strings.xml
@@ -1608,7 +1608,7 @@
     <string name="master_clear_not_available" msgid="4676613348163652454">"ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଫ୍ୟାକ୍ଟୋରୀ ରିସେଟ୍‌ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="master_clear_progress_title" msgid="378953167274114857">"ଲିଭାଉଛି"</string>
     <string name="master_clear_progress_text" msgid="5418958116008976218">"ଦୟାକରି ଅପେକ୍ଷା କରନ୍ତୁ..."</string>
-    <string name="call_settings_title" msgid="5033906789261282752">"କଲ୍‌ ସେଟିଙ୍ଗ"</string>
+    <string name="call_settings_title" msgid="5033906789261282752">"କଲ୍‌ ସେଟିଂସ୍"</string>
     <string name="call_settings_summary" msgid="2119161087671450035">"ଭଏସ୍‌ମେଲ୍‌, କଲ୍‌ ଫର୍‌ୱାର୍ଡିଙ୍ଗ, କଲ୍‌ ୱେଟିଙ୍ଗ, କଲର୍‌ ID ସେଟ୍‌ କରନ୍ତୁ"</string>
     <string name="tether_settings_title_usb" msgid="4265582654602420357">"USB ଟିଥରିଂ"</string>
     <string name="tether_settings_title_wifi" msgid="2060965130234484613">"ପୋର୍ଟବଲ୍‌ ହଟସ୍ପଟ୍‌"</string>
@@ -3147,13 +3147,13 @@
     <string name="alarm_ringtone_title" msgid="6411326147408635902">"ଡିଫଲ୍ଟ ଆଲାର୍ମ ସାଉଣ୍ଡ"</string>
     <string name="vibrate_when_ringing_title" msgid="2757996559847126952">"କଲ୍‍ ପାଇଁ ଭାଇବ୍ରେଟ୍‍ କରନ୍ତୁ"</string>
     <string name="other_sound_settings" msgid="5250376066099818676">"ଅନ୍ୟାନ୍ୟ ଶବ୍ଦ"</string>
-    <string name="dial_pad_tones_title" msgid="8877212139988655769">"ଡାୟଲ୍‌ ପ୍ୟାଡ୍‌ ଟୋନ୍‍"</string>
+    <string name="dial_pad_tones_title" msgid="8877212139988655769">"ଡାଏଲ୍‌ ପ୍ୟାଡ୍‌ ଟୋନ୍‍"</string>
     <string name="screen_locking_sounds_title" msgid="4407110895465866809">"ସ୍କ୍ରୀନ୍‌ ଲକ୍‌ କରିବା ସାଉଣ୍ଡ"</string>
     <string name="charging_sounds_title" msgid="5070437987230894287">"ସାଉଣ୍ଡ ଓ ଭାଇବ୍ରେସନ୍ ଚାର୍ଜ ହେଉଛି"</string>
     <string name="docking_sounds_title" msgid="2573137471605541366">"ଡକ୍‌ କରିବା ଧ୍ୱନୀ"</string>
     <string name="touch_sounds_title" msgid="165237488496165652">"ସ୍ପର୍ଶ ଶବ୍ଦ"</string>
-    <string name="vibrate_on_touch_title" msgid="6360155469279157684">"ସ୍ପର୍ଶଜନିତ ଭାଇବ୍ରେଶନ୍"</string>
-    <string name="vibrate_on_touch_summary" msgid="5504424764028676043">"ଟ୍ୟାପ୍‌, କୀ-ବୋର୍ଡ ଓ ଆହୁରି ଅଧିକ ପାଇଁ ସ୍ପର୍ଶ ମାଧ୍ୟମରେ ମତାମତ"</string>
+    <string name="vibrate_on_touch_title" msgid="6360155469279157684">"ସ୍ପର୍ଶ ଭାଇବ୍ରେସନ୍"</string>
+    <string name="vibrate_on_touch_summary" msgid="5504424764028676043">"ଟ୍ୟାପ୍‌, କୀ-ବୋର୍ଡ ଓ ଆହୁରି ଅଧିକ ପାଇଁ ହେପଟିକ୍ ମତାମତ"</string>
     <string name="dock_audio_media_title" msgid="1859521680502040781">"ଡକ୍‌ ସ୍ପିକର୍‌ ବାଜିବ"</string>
     <string name="dock_audio_media_disabled" msgid="4300752306178486302">"ସମସ୍ତ ଅଡିଓ"</string>
     <string name="dock_audio_media_enabled" msgid="2873275045878628153">"କେବଳ ମିଡିଆ ଅଡିଓ"</string>
@@ -3293,7 +3293,7 @@
     <string name="ringtones_install_custom_sound_title" msgid="210551218424553671">"କଷ୍ଟମ୍‌ ସାଉଣ୍ଡ ଯୋଡ଼ିବେ?"</string>
     <string name="ringtones_install_custom_sound_content" msgid="6683649115132255452">"<xliff:g id="FOLDER_NAME">%s</xliff:g> ଫୋଲ୍ଡର୍‌କୁ ଏହି ଫାଇଲ୍‌ କପୀ କରାଯିବ"</string>
     <string name="ringtones_category_preference_title" msgid="4491932700769815470">"ରିଙ୍ଗଟୋନ୍‌"</string>
-    <string name="other_sound_category_preference_title" msgid="2045757472469840859">"ଅନ୍ୟାନ୍ୟ ସାଉଣ୍ଡ ଓ ଭାଇବ୍ରେଶନ୍"</string>
+    <string name="other_sound_category_preference_title" msgid="2045757472469840859">"ଅନ୍ୟ ସାଉଣ୍ଡ ଓ ଭାଇବ୍ରେସନ୍"</string>
     <string name="configure_notification_settings" msgid="291914315140851270">"ବିଜ୍ଞପ୍ତି"</string>
     <string name="recent_notifications" msgid="8125865995065032049">"କିଛି ସମୟ ପୂର୍ବରୁ ବିଜ୍ଞପ୍ତି ପଠାଇଥିବା ଆପ୍"</string>
     <string name="recent_notifications_see_all_title" msgid="4089007770442871469">"ବିଗତ 7 ଦିନରୁ ସବୁଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
@@ -3423,7 +3423,7 @@
     <string name="notification_badge_title" msgid="8989086619255666442">"ବିଜ୍ଞପ୍ତି ଡଟ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="notification_channel_badge_title" msgid="8228215248332054612">"ବିଜ୍ଞପ୍ତି ଡଟ୍‌ ଦେଖାନ୍ତୁ"</string>
     <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"ବିରକ୍ତ କରନାହିଁ ଓଭରରାଇଡ"</string>
-    <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"’ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ’ ଅନ୍ ଥିବାବେଳେ ଏହି ବିଜ୍ଞପ୍ତିର ବାଧା ଦେବା ପ୍ରକ୍ରିୟାକୁ ଜାରି ରଖନ୍ତୁ"</string>
+    <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"\'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\' ଚାଲୁଥିବା ବେଳେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ବାଧା ଦେବା ପ୍ରକ୍ରିୟାକୁ ଜାରି ରଖନ୍ତୁ"</string>
     <string name="app_notification_visibility_override_title" msgid="2349335170165637672">"ଲକ୍ ସ୍କ୍ରୀନ୍ ଉପରେ"</string>
     <string name="app_notification_row_banned" msgid="2079325338122151677">"ଅବରୋଧିତ"</string>
     <string name="app_notification_row_priority" msgid="432299064888787236">"ପ୍ରାଥମିକତା"</string>
@@ -4310,7 +4310,7 @@
     <string name="change_wifi_state_title" msgid="5140754955787584174">"ୱାଇ-ଫାଇର ନିୟନ୍ତ୍ରଣ"</string>
     <string name="change_wifi_state_app_detail_switch" msgid="6489090744937816260">"ୱାଇ-ଫାଇକୁ ନିୟନ୍ତ୍ରଣ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="change_wifi_state_app_detail_summary" msgid="614854822469259860">"ୱାଇ-ଫାଇକୁ ଚାଲୁ କରିବା କିମ୍ବା ବନ୍ଦ କରିବା, ୱାଇ-ଫାଇ ନେଟୱର୍କକୁ ଖୋଜିବା ଓ କନେକ୍ଟ କରିବା, ନେଟୱର୍କକୁ ଯୋଡ଼ିବା କିମ୍ବା କାଢ଼ିଦେବା କିମ୍ବା କେବଳ ସୀମିତ କ୍ଷେତ୍ରରେ କାମ କରୁଥିବା ହଟସ୍ପଟ୍‌କୁ ଚାଲୁ କରିବା ପାଇଁ ଏହି ଆପ୍‌କୁ ଅନୁମତି ଦେବା"</string>
-    <string name="media_output_title" msgid="8710632337456601848">"ମିଡିଆ ଚଲାନ୍ତୁ"</string>
+    <string name="media_output_title" msgid="8710632337456601848">"ଏଥିରେ ମିଡିଆ ଚଲାନ୍ତୁ"</string>
     <string name="media_output_default_summary" msgid="3159237976830415584">"ଏହି ଡିଭାଇସ୍‍"</string>
     <string name="media_output_summary" product="default" msgid="6294261435613551178">"ଫୋନ୍"</string>
     <string name="media_output_summary" product="tablet" msgid="6672024060360538526">"ଟାବଲେଟ୍‌"</string>
@@ -4330,7 +4330,7 @@
     <string name="prevent_ringing_option_mute" msgid="53662688921253613">"ମ୍ୟୁଟ୍ କରନ୍ତୁ"</string>
     <string name="prevent_ringing_option_none" msgid="1450985763137666231">"କିଛି କରନ୍ତୁ ନାହିଁ"</string>
     <string name="prevent_ringing_option_vibrate_summary" msgid="7961818570574683926">"ଚାଲୁ (ଭାଇବ୍ରେଟ୍)"</string>
-    <string name="prevent_ringing_option_mute_summary" msgid="3509459199090688328">"(ମ୍ୟୁଟ୍) ଅନ୍ ଅଛି"</string>
+    <string name="prevent_ringing_option_mute_summary" msgid="3509459199090688328">"ଚାଲୁ (ମ୍ୟୁଟ୍)"</string>
     <string name="prevent_ringing_option_none_summary" msgid="5152618221093037451">"ଅଫ୍"</string>
     <string name="pref_title_network_details" msgid="3971074015034595956">"ନେଟୱାର୍କ୍‌ ବିବରଣୀ"</string>
     <string name="about_phone_device_name_warning" msgid="9088572775969880106">"ଆପଣଙ୍କ ଡିଭାଇସ୍‌ରେ ଥିବା ଆପ୍‌ଗୁଡ଼ିକୁ ଆପଣଙ୍କର ଡିଭାଇସ୍‍ ନାମ ଦେଖାଯାଉଛି। ବ୍ଲୁଟୂଥ୍‍ ଡିଭାଇସ୍‍ ସହ ଯୋଡ଼ି ହେବାବେଳେ କିମ୍ୱା ଏକ ୱାଇ-ଫାଇ ହଟସ୍ପଟ୍ ସେଟ୍ କରିବା ସମୟରେ, ଏହା ଅନ୍ୟ ଲୋକମାନଙ୍କୁ ମଧ୍ୟ ଦେଖାଦେଇପାରେ।"</string>
diff --git a/tests/CarDeveloperOptions/res/values-pt/strings.xml b/tests/CarDeveloperOptions/res/values-pt/strings.xml
index 41b6c14..1f678e4 100644
--- a/tests/CarDeveloperOptions/res/values-pt/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-pt/strings.xml
@@ -3031,7 +3031,7 @@
       <item quantity="one">Mostrar %d item oculto</item>
       <item quantity="other">Mostrar %d itens ocultos</item>
     </plurals>
-    <string name="network_dashboard_title" msgid="8288134139584687806">"Rede e internet"</string>
+    <string name="network_dashboard_title" msgid="8288134139584687806">"Rede e Internet"</string>
     <string name="network_dashboard_summary_mobile" msgid="5560545061217580626">"rede móvel"</string>
     <string name="network_dashboard_summary_data_usage" msgid="4695629715072542102">"uso de dados"</string>
     <string name="network_dashboard_summary_hotspot" msgid="3928610802321995214">"ponto de acesso"</string>
@@ -3423,7 +3423,7 @@
     <string name="notification_badge_title" msgid="8989086619255666442">"Permitir ponto de notificação"</string>
     <string name="notification_channel_badge_title" msgid="8228215248332054612">"Mostrar ponto de notificação"</string>
     <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"Ignorar o Não perturbe"</string>
-    <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"Permitir que essas notificações sejam mostradas mesmo quando o Não perturbe estiver ativado"</string>
+    <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"Permitir que as notificações sejam mostradas mesmo quando o Não perturbe estiver ativado"</string>
     <string name="app_notification_visibility_override_title" msgid="2349335170165637672">"Na tela de bloqueio"</string>
     <string name="app_notification_row_banned" msgid="2079325338122151677">"Bloqueadas"</string>
     <string name="app_notification_row_priority" msgid="432299064888787236">"Prioridade"</string>
diff --git a/tests/CarDeveloperOptions/res/values-sk/strings.xml b/tests/CarDeveloperOptions/res/values-sk/strings.xml
index fbac769..0d97f16 100644
--- a/tests/CarDeveloperOptions/res/values-sk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sk/strings.xml
@@ -766,7 +766,7 @@
     <string name="bluetooth_pairing_request" msgid="7221745525632573125">"Spárovať so zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>?"</string>
     <string name="bluetooth_pairing_key_msg" msgid="1139230917419961975">"Párovací kód Bluetooth"</string>
     <string name="bluetooth_enter_passkey_msg" msgid="6205151011298670207">"Zadajte párovací kód a potom stlačte tlačidlo Return alebo Enter"</string>
-    <string name="bluetooth_enable_alphanumeric_pin" msgid="9138308197078115672">"Kód PIN obsahuje písmená alebo symboly"</string>
+    <string name="bluetooth_enable_alphanumeric_pin" msgid="9138308197078115672">"PIN obsahuje písmená či symboly"</string>
     <string name="bluetooth_pin_values_hint" msgid="8044671726261326240">"Obvykle 0000 alebo 1234"</string>
     <string name="bluetooth_pin_values_hint_16_digits" msgid="2665983525706661525">"Musí obsahovať 16 číslic"</string>
     <string name="bluetooth_enter_pin_other_device" msgid="1727015949040507621">"Tento kód PIN bude možno treba zadať aj na druhom zariadení."</string>
diff --git a/tests/CarDeveloperOptions/res/values-sq/strings.xml b/tests/CarDeveloperOptions/res/values-sq/strings.xml
index 37c7aa3..ac2c3bc 100644
--- a/tests/CarDeveloperOptions/res/values-sq/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sq/strings.xml
@@ -3555,7 +3555,7 @@
     <string name="switch_on_text" msgid="7100491749799298324">"Aktivizuar"</string>
     <string name="switch_off_text" msgid="3539551289454353555">"Joaktiv"</string>
     <string name="screen_pinning_title" msgid="578020318289781102">"Gozhdimi i ekranit"</string>
-    <string name="screen_pinning_description" msgid="3814537379086412278">"Kur ky funksion është i aktivizuar, mund të përdorësh gozhdimin e ekranit për të mbajtur pamjen aktuale të ekranit deri sa ta anulosh gozhdimin.\n\nPër të përdorur gozhdimin e ekranit:\n\n1. Sigurohu që gozhdimi i ekranit është i aktivizuar\n\n2. Hap \"Përmbledhja\"\n\n3. Trokit tek ikona e aplikacionit në krye të ekranit dhe më pas trokit te \"Gozhdo\""</string>
+    <string name="screen_pinning_description" msgid="3814537379086412278">"Kur ky cilësim është i aktivizuar, mund të përdorësh gozhdimin e ekranit për të mbajtur pamjen aktuale të ekranit deri sa ta anulosh gozhdimin.\n\nPër të përdorur gozhdimin e ekranit:\n\n1. Sigurohu që gozhdimi i ekranit është i aktivizuar\n\n2. Hap \"Përmbledhja\"\n\n3. Trokit tek ikona e aplikacionit në krye të ekranit dhe më pas trokit te \"Gozhdo\""</string>
     <string name="screen_pinning_unlock_pattern" msgid="1060334707088339444">"Kërko motivin e shkyçjes para anulimit të mbërthimit"</string>
     <string name="screen_pinning_unlock_pin" msgid="1441705536015645023">"Zhgozhdimi kërkon PIN-in"</string>
     <string name="screen_pinning_unlock_password" msgid="1017776884000170841">"Kërko fjalëkalim para heqjes nga gozhdimi"</string>
diff --git a/tests/CarDeveloperOptions/res/values-sr/strings.xml b/tests/CarDeveloperOptions/res/values-sr/strings.xml
index fbee5c3..edf510e 100644
--- a/tests/CarDeveloperOptions/res/values-sr/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sr/strings.xml
@@ -3190,7 +3190,7 @@
     <string name="other_sound_settings" msgid="5250376066099818676">"Други звукови"</string>
     <string name="dial_pad_tones_title" msgid="8877212139988655769">"Тонови нумеричке тастатуре"</string>
     <string name="screen_locking_sounds_title" msgid="4407110895465866809">"Звукови закључавања екрана"</string>
-    <string name="charging_sounds_title" msgid="5070437987230894287">"Мењајући звуци и вибрација"</string>
+    <string name="charging_sounds_title" msgid="5070437987230894287">"Звукови и вибрација пуњења"</string>
     <string name="docking_sounds_title" msgid="2573137471605541366">"Звукови монтирања"</string>
     <string name="touch_sounds_title" msgid="165237488496165652">"Звукови при додиру"</string>
     <string name="vibrate_on_touch_title" msgid="6360155469279157684">"Вибрација при додиру"</string>
diff --git a/tests/CarDeveloperOptions/res/values-sv/strings.xml b/tests/CarDeveloperOptions/res/values-sv/strings.xml
index 5b2dcd1..68c7e34 100644
--- a/tests/CarDeveloperOptions/res/values-sv/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sv/strings.xml
@@ -3149,7 +3149,7 @@
     <string name="other_sound_settings" msgid="5250376066099818676">"Andra ljud"</string>
     <string name="dial_pad_tones_title" msgid="8877212139988655769">"Knappsatsljud"</string>
     <string name="screen_locking_sounds_title" msgid="4407110895465866809">"Ljud vid skärmlåsning"</string>
-    <string name="charging_sounds_title" msgid="5070437987230894287">"Laddningsljud- och vibration"</string>
+    <string name="charging_sounds_title" msgid="5070437987230894287">"Laddningsljud och -vibration"</string>
     <string name="docking_sounds_title" msgid="2573137471605541366">"Ljud via dockningsstationen"</string>
     <string name="touch_sounds_title" msgid="165237488496165652">"Ljud vid tryck"</string>
     <string name="vibrate_on_touch_title" msgid="6360155469279157684">"Vibration vid tryck"</string>
diff --git a/tests/CarDeveloperOptions/res/values-sw/strings.xml b/tests/CarDeveloperOptions/res/values-sw/strings.xml
index a07110a..b665336 100644
--- a/tests/CarDeveloperOptions/res/values-sw/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sw/strings.xml
@@ -2094,7 +2094,7 @@
     <string name="accessibility_vibration_settings_title" msgid="1902649657883159406">"Mtetemo"</string>
     <string name="accessibility_notification_vibration_title" msgid="1005799039440510298">"Mtetemo wa arifa"</string>
     <string name="accessibility_ring_vibration_title" msgid="7943341443551359985">"Mtetemo wa mlio"</string>
-    <string name="accessibility_touch_vibration_title" msgid="285890135612038092">"Mtetemo wa mguso"</string>
+    <string name="accessibility_touch_vibration_title" msgid="285890135612038092">"Mtetemo inapoguswa"</string>
     <string name="accessibility_service_master_switch_title" msgid="2734791644475782924">"Tumia huduma"</string>
     <string name="accessibility_daltonizer_master_switch_title" msgid="4855011639012300777">"Tumia usahihishaji wa rangi"</string>
     <string name="accessibility_caption_master_switch_title" msgid="6373335123229234053">"Tumia manukuu"</string>
@@ -3152,7 +3152,7 @@
     <string name="charging_sounds_title" msgid="5070437987230894287">"Sauti za kuchaji na mtetemo"</string>
     <string name="docking_sounds_title" msgid="2573137471605541366">"Kuambatisha sauti"</string>
     <string name="touch_sounds_title" msgid="165237488496165652">"Sauti inapoguswa"</string>
-    <string name="vibrate_on_touch_title" msgid="6360155469279157684">"Mtetemo wa mguso"</string>
+    <string name="vibrate_on_touch_title" msgid="6360155469279157684">"Mtetemo inapoguswa"</string>
     <string name="vibrate_on_touch_summary" msgid="5504424764028676043">"Majibu unayoweza kuhisi kwa kugusa, kibodi na mengineyo"</string>
     <string name="dock_audio_media_title" msgid="1859521680502040781">"Cheza kutumia spika ya kituo"</string>
     <string name="dock_audio_media_disabled" msgid="4300752306178486302">"Sauti zote"</string>
@@ -3341,11 +3341,11 @@
     <string name="notification_importance_low" msgid="7609797151662295364">"Onyesha chinichini"</string>
     <string name="notification_importance_default" msgid="4091563759103917166">"Toa sauti"</string>
     <string name="notification_importance_high" msgid="7973764540402436656">"Toa sauti na ibukizi kwenye skrini"</string>
-    <string name="notification_importance_high_silent" msgid="3177662759865661155">"Ichomoze kwenye skrini"</string>
+    <string name="notification_importance_high_silent" msgid="3177662759865661155">"Zionekane kwenye skrini"</string>
     <string name="notification_importance_min_title" msgid="705872537330744154">"Punguza"</string>
     <string name="notification_importance_low_title" msgid="2956199021781786232">"Wastani"</string>
     <string name="notification_importance_default_title" msgid="7985549807203332482">"Juu"</string>
-    <string name="notification_importance_high_title" msgid="7258373094258585858">"Ichomoze kwenye skrini"</string>
+    <string name="notification_importance_high_title" msgid="7258373094258585858">"Zionekane kwenye skrini"</string>
     <string name="notification_block_title" msgid="2570364198866886906">"Zuia"</string>
     <string name="notification_silence_title" msgid="6959637402003838093">"Ionyeshe bila kutoa sauti"</string>
     <string name="notification_alert_title" msgid="750683027055192648">"Arifa"</string>
diff --git a/tests/CarDeveloperOptions/res/values-te/strings.xml b/tests/CarDeveloperOptions/res/values-te/strings.xml
index b646142..6e54dda 100644
--- a/tests/CarDeveloperOptions/res/values-te/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-te/strings.xml
@@ -2323,9 +2323,9 @@
     <string name="smart_battery_manager_title" msgid="5744035036663849515">"బ్యాటరీ మేనేజర్"</string>
     <string name="smart_battery_title" msgid="4919670408532804351">"యాప్‌లను ఆటోమేటిక్‌గా నిర్వహించండి"</string>
     <string name="smart_battery_summary" msgid="640027046471198174">"మీరు తరచుగా ఉపయోగించని యాప్‌ల కోసం బ్యాటరీని పరిమితం చేయండి"</string>
-    <string name="smart_battery_footer" product="default" msgid="3971715848890205632">"యాప్‌లు బ్యాటరీ శక్తిని హరిస్తున్నయని బ్యాటరీ మేనేజర్ గుర్తించినప్పుడు, ఈ యాప్‌లను పరిమితం చేసే ఎంపిక మీకు ఉంటుంది. పరిమితం చేయబడిన యాప్‌లు సరిగ్గా పనిచేయకపోవచ్చు మరియు నోటిఫికేషన్‌లు రావడానికి ఆలస్యం కావచ్చు."</string>
-    <string name="smart_battery_footer" product="tablet" msgid="3971715848890205632">"యాప్‌లు బ్యాటరీ శక్తిని హరిస్తున్నయని బ్యాటరీ మేనేజర్ గుర్తించినప్పుడు, ఈ యాప్‌లను పరిమితం చేసే ఎంపిక మీకు ఉంటుంది. పరిమితం చేయబడిన యాప్‌లు సరిగ్గా పనిచేయకపోవచ్చు మరియు నోటిఫికేషన్‌లు రావడానికి ఆలస్యం కావచ్చు."</string>
-    <string name="smart_battery_footer" product="device" msgid="3971715848890205632">"యాప్‌లు బ్యాటరీ శక్తిని హరిస్తున్నయని బ్యాటరీ మేనేజర్ గుర్తించినప్పుడు, ఈ యాప్‌లను పరిమితం చేసే ఎంపిక మీకు ఉంటుంది. పరిమితం చేయబడిన యాప్‌లు సరిగ్గా పనిచేయకపోవచ్చు మరియు నోటిఫికేషన్‌లు రావడానికి ఆలస్యం కావచ్చు."</string>
+    <string name="smart_battery_footer" product="default" msgid="3971715848890205632">"ఏవైనా యాప్‌లు బ్యాటరీని అధికంగా వాడుతున్నాయని బ్యాటరీ మేనేజర్ గుర్తించినప్పుడు, ఆ యాప్‌లను పరిమితం చేసే ఎంపిక మీకు ఉంటుంది. పరిమితం చేయబడిన యాప్‌లు సరిగ్గా పనిచేయకపోవచ్చు, వాటి నోటిఫికేషన్‌లు రావడానికి ఆలస్యం కావచ్చు."</string>
+    <string name="smart_battery_footer" product="tablet" msgid="3971715848890205632">"ఏవైనా యాప్‌లు బ్యాటరీని అధికంగా వాడుతున్నాయని బ్యాటరీ మేనేజర్ గుర్తించినప్పుడు, ఆ యాప్‌లను పరిమితం చేసే ఎంపిక మీకు ఉంటుంది. పరిమితం చేయబడిన యాప్‌లు సరిగ్గా పనిచేయకపోవచ్చు, వాటి నోటిఫికేషన్‌లు రావడానికి ఆలస్యం కావచ్చు."</string>
+    <string name="smart_battery_footer" product="device" msgid="3971715848890205632">"ఏవైనా యాప్‌లు బ్యాటరీని అధికంగా వాడుతున్నాయని బ్యాటరీ మేనేజర్ గుర్తించినప్పుడు, ఆ యాప్‌లను పరిమితం చేసే ఎంపిక మీకు ఉంటుంది. పరిమితం చేయబడిన యాప్‌లు సరిగ్గా పనిచేయకపోవచ్చు, వాటి నోటిఫికేషన్‌లు రావడానికి ఆలస్యం కావచ్చు."</string>
     <string name="restricted_app_title" msgid="4957644700640127606">"నియంత్రించబడిన యాప్‌లు"</string>
     <plurals name="restricted_app_summary" formatted="false" msgid="7609538735465186040">
       <item quantity="other">%1$d యాప్‌ల కోసం బ్యాటరీ వినియోగాన్ని పరిమితం చేయడం</item>
@@ -3041,7 +3041,7 @@
     <string name="connected_devices_dashboard_no_driving_mode_summary" msgid="3524409078596318803">"బ్లూటూత్, NFC"</string>
     <string name="connected_devices_dashboard_no_driving_mode_no_nfc_summary" msgid="7881286613528299400">"బ్లూటూత్"</string>
     <string name="app_and_notification_dashboard_title" msgid="8448096608058843730">"యాప్‌లు &amp; నోటిఫికేషన్‌లు"</string>
-    <string name="app_and_notification_dashboard_summary" msgid="4165181440955038145">"అసిస్టెంట్, ఇటీవలి యాప్‌లు, డిఫాల్ట్ యాప్‌లు"</string>
+    <string name="app_and_notification_dashboard_summary" msgid="4165181440955038145">"Assistant, ఇటీవలి యాప్‌లు, డిఫాల్ట్ యాప్‌లు"</string>
     <string name="notification_settings_work_profile" msgid="7190550347842400029">"కార్యాలయ ప్రొఫైల్‌లో ఉన్న యాప్‌లకు సంబంధించి నోటిఫికేషన్ యాక్సెస్ అందుబాటులో లేదు."</string>
     <string name="account_dashboard_title" msgid="4734300939532555885">"ఖాతాలు"</string>
     <string name="account_dashboard_default_summary" msgid="6822549669771936206">"ఖాతాలు జోడించబడలేదు"</string>
@@ -4473,7 +4473,7 @@
     <string name="hwui_force_dark_title" msgid="3744825212652331461">"ఫోర్స్‌-డార్క్‌ను అధిగ‌మించ‌డం"</string>
     <string name="hwui_force_dark_summary" msgid="2051891908674765817">"ఫోర్స్‌-డార్క్ ఫీచ‌ర్‌ను అధిగ‌మించ‌డం ఎల్ల‌ప్పుడూ ఆన్‌లో ఉండాలి"</string>
     <string name="privacy_dashboard_title" msgid="8764930992456607513">"గోప్యత"</string>
-    <string name="privacy_dashboard_summary" msgid="7916431309860824945">"అనుమతులు, ఖాతా కార్యకలాపం, వ్యక్తిగత డేటా"</string>
+    <string name="privacy_dashboard_summary" msgid="7916431309860824945">"అనుమతులు, ఖాతా యాక్టివిటీ, వ్యక్తిగత డేటా"</string>
     <string name="contextual_card_dismiss_remove" msgid="1750420285615827309">"తీసివేయి"</string>
     <string name="contextual_card_dismiss_keep" msgid="3204450672928193661">"Keep"</string>
     <string name="contextual_card_dismiss_confirm_message" msgid="2352465079667730312">"ఈ సూచనని తీసేయాలా?"</string>
diff --git a/tests/CarDeveloperOptions/res/values-uk/strings.xml b/tests/CarDeveloperOptions/res/values-uk/strings.xml
index 2816cc8..b39d1a4 100644
--- a/tests/CarDeveloperOptions/res/values-uk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-uk/strings.xml
@@ -1246,7 +1246,7 @@
     <string name="adaptive_sleep_summary_off" msgid="2891586225954973431">"Вимкнено"</string>
     <string name="adaptive_sleep_description" msgid="812673735459170009">"Не дає екрану вимикатись, якщо ви на нього дивитесь."</string>
     <string name="adaptive_sleep_privacy" msgid="5706802215479902623">"Розпізнавання уваги за допомогою передньої камери визначає, чи дивиться користувач на екран. Ця функція працює лише на пристрої, не зберігає зображень і не надсилає їх у Google."</string>
-    <string name="night_display_title" msgid="1305002424893349814">"Нічний режим"</string>
+    <string name="night_display_title" msgid="1305002424893349814">"Нічний екран"</string>
     <string name="night_display_text" msgid="5330502493684652527">"У нічному режимі екран набуває бурштинового відтінку. Це знімає напруження очей при тьмяному освітленні та допомагає легше заснути."</string>
     <string name="night_display_auto_mode_title" msgid="8493573087102481588">"Розклад"</string>
     <string name="night_display_auto_mode_never" msgid="2897444637217807088">"Ніколи"</string>
@@ -4464,7 +4464,7 @@
     <string name="change_wifi_state_title" msgid="5140754955787584174">"Керування Wi-Fi"</string>
     <string name="change_wifi_state_app_detail_switch" msgid="6489090744937816260">"Дозволити додатку керувати Wi-Fi"</string>
     <string name="change_wifi_state_app_detail_summary" msgid="614854822469259860">"Дозволити цьому додатку вмикати чи вимикати Wi-Fi, шукати мережі Wi-Fi та підключатися до них, додавати або видаляти мережі чи запускати лише локальну точку доступу"</string>
-    <string name="media_output_title" msgid="8710632337456601848">"Відтворювати медіа-вміст у додатку"</string>
+    <string name="media_output_title" msgid="8710632337456601848">"Відтворення медіаконтенту"</string>
     <string name="media_output_default_summary" msgid="3159237976830415584">"Цей пристрій"</string>
     <string name="media_output_summary" product="default" msgid="6294261435613551178">"Телефон"</string>
     <string name="media_output_summary" product="tablet" msgid="6672024060360538526">"Планшет"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ur/strings.xml b/tests/CarDeveloperOptions/res/values-ur/strings.xml
index 787d550..4a881ea 100644
--- a/tests/CarDeveloperOptions/res/values-ur/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ur/strings.xml
@@ -1128,7 +1128,7 @@
     <string name="notification_sound_title" msgid="6812164482799723931">"ڈیفالٹ اطلاع کی آواز"</string>
     <string name="incoming_call_volume_title" msgid="4736570528754310450">"رنگ ٹون"</string>
     <string name="notification_volume_title" msgid="6022562909288085275">"اطلاع"</string>
-    <string name="checkbox_notification_same_as_incoming_call" msgid="7312942422655861175">"اطلاعات کیلئے آنے والی کال کا والیوم استعمال کریں"</string>
+    <string name="checkbox_notification_same_as_incoming_call" msgid="7312942422655861175">"اطلاعات کیلئے اِن کمنگ کال کا والیوم استعمال کریں"</string>
     <string name="home_work_profile_not_supported" msgid="6137073723297076818">"کام کے پروفائلز کا تعاون نہیں کرتا ہے"</string>
     <string name="notification_sound_dialog_title" msgid="6653341809710423276">"ڈیفالٹ اطلاع کی آواز"</string>
     <string name="media_volume_title" msgid="1030438549497800914">"میڈیا"</string>
@@ -3401,7 +3401,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> زمرے</item>
       <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> زمرہ</item>
     </plurals>
-    <string name="no_channels" msgid="8884254729302501652">"اس ایپ نے کوئی اطلاعات شائع نہیں کیا ہے"</string>
+    <string name="no_channels" msgid="8884254729302501652">"اس ایپ نے کوئی اطلاعات شائع نہیں کی ہیں"</string>
     <string name="app_settings_link" msgid="8465287765715790984">"ایپ میں اضافی ترتیبات"</string>
     <string name="app_notification_listing_summary_zero" msgid="4047782719487686699">"سبھی ایپس کے لیے آن ہے"</string>
     <plurals name="app_notification_listing_summary_others" formatted="false" msgid="1161774065480666519">
diff --git a/tests/CarDeveloperOptions/res/values-uz/strings.xml b/tests/CarDeveloperOptions/res/values-uz/strings.xml
index 401fb18..f2fb286 100644
--- a/tests/CarDeveloperOptions/res/values-uz/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-uz/strings.xml
@@ -732,7 +732,7 @@
     <string name="bluetooth_pairing_request" msgid="7221745525632573125">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga ulansinmi?"</string>
     <string name="bluetooth_pairing_key_msg" msgid="1139230917419961975">"Bluetooth orqali ulanish kodi"</string>
     <string name="bluetooth_enter_passkey_msg" msgid="6205151011298670207">"Ulanish kodini kiriting va keyin “Return” yoki “Enter” tugmasini bosing"</string>
-    <string name="bluetooth_enable_alphanumeric_pin" msgid="9138308197078115672">"PIN-kod harflar va belgilardan iborat bo‘ladi"</string>
+    <string name="bluetooth_enable_alphanumeric_pin" msgid="9138308197078115672">"Harflar yoki maxsus belgilardan iborat PIN kod"</string>
     <string name="bluetooth_pin_values_hint" msgid="8044671726261326240">"Odatda 0000 yoki 1234"</string>
     <string name="bluetooth_pin_values_hint_16_digits" msgid="2665983525706661525">"16 ta raqam bo‘lishi lozim"</string>
     <string name="bluetooth_enter_pin_other_device" msgid="1727015949040507621">"Ushbu PIN kodni boshqa qurilmada ham terish lozim bo‘lishi mumkin."</string>
@@ -2754,7 +2754,7 @@
     <string name="data_usage_metered_no" msgid="1961524615778610008">"Bepul"</string>
     <string name="data_usage_disclaimer" msgid="4683321532922590425">"Aloqa operatorining hisob-kitobi qurilmanikidan farq qilishi mumkin."</string>
     <string name="cryptkeeper_emergency_call" msgid="4625420047524693116">"Favqulodda chaqiruv"</string>
-    <string name="cryptkeeper_return_to_call" msgid="4433942821196822815">"Chaqiruvga qaytish"</string>
+    <string name="cryptkeeper_return_to_call" msgid="4433942821196822815">"Suhbatga qaytish"</string>
     <string name="vpn_name" msgid="3538818658670774080">"Tarmoq nomi"</string>
     <string name="vpn_type" msgid="6389116710008658550">"Turi"</string>
     <string name="vpn_server" msgid="5216559017318406820">"Server manzili"</string>
diff --git a/tests/CarDeveloperOptions/res/values-vi/strings.xml b/tests/CarDeveloperOptions/res/values-vi/strings.xml
index ab20398..1efea2d 100644
--- a/tests/CarDeveloperOptions/res/values-vi/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-vi/strings.xml
@@ -34,7 +34,7 @@
     <string name="radio_info_data_connection_enable" msgid="2554249462719717119">"Bật kết nối dữ liệu"</string>
     <string name="radio_info_data_connection_disable" msgid="2430609627397999371">"Tắt kết nối dữ liệu"</string>
     <string name="volte_provisioned_switch_string" msgid="6326756678226686704">"Đã cấp phép VoLTE"</string>
-    <string name="vt_provisioned_switch_string" msgid="7458479879009293613">"Đã cấp phép gọi điện video"</string>
+    <string name="vt_provisioned_switch_string" msgid="7458479879009293613">"Đã cấp phép gọi video"</string>
     <string name="wfc_provisioned_switch_string" msgid="5446697646596639516">"Đã cấp phép gọi điện qua Wi-Fi"</string>
     <string name="eab_provisioned_switch_string" msgid="3921103790584572430">"Đã cấp phép hiện diện/EAB"</string>
     <string name="cbrs_data_switch_string" msgid="9120919504831536183">"Dữ liệu Cbrs"</string>
@@ -53,7 +53,7 @@
     <string name="radio_info_ims_reg_status_not_registered" msgid="1286050699734226077">"Chưa được đăng ký"</string>
     <string name="radio_info_ims_feature_status_available" msgid="2040629393134756058">"Khả dụng"</string>
     <string name="radio_info_ims_feature_status_unavailable" msgid="3348223769202693596">"Không khả dụng"</string>
-    <string name="radio_info_ims_reg_status" msgid="4771711884059371514">"Đăng ký IMS: <xliff:g id="STATUS">%1$s</xliff:g>\nThoại trên nền LTE: <xliff:g id="AVAILABILITY_0">%2$s</xliff:g>\nThoại qua Wi-Fi: <xliff:g id="AVAILABILITY_1">%3$s</xliff:g>\nGọi điện video: <xliff:g id="AVAILABILITY_2">%4$s</xliff:g>\nGiao diện UT: <xliff:g id="AVAILABILITY_3">%5$s</xliff:g>"</string>
+    <string name="radio_info_ims_reg_status" msgid="4771711884059371514">"Đăng ký IMS: <xliff:g id="STATUS">%1$s</xliff:g>\nThoại trên nền LTE: <xliff:g id="AVAILABILITY_0">%2$s</xliff:g>\nThoại qua Wi-Fi: <xliff:g id="AVAILABILITY_1">%3$s</xliff:g>\nGọi video: <xliff:g id="AVAILABILITY_2">%4$s</xliff:g>\nGiao diện UT: <xliff:g id="AVAILABILITY_3">%5$s</xliff:g>"</string>
     <string name="radioInfo_service_in" msgid="1297020186765943857">"Đang sử dụng"</string>
     <string name="radioInfo_service_out" msgid="8460363463722476510">"Không có dịch vụ"</string>
     <string name="radioInfo_service_emergency" msgid="7674989004735662599">"Chỉ cuộc gọi khẩn cấp"</string>
@@ -3403,8 +3403,8 @@
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> loại</item>
       <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> loại</item>
     </plurals>
-    <string name="no_channels" msgid="8884254729302501652">"Ứng dụng chưa đăng bất kỳ thông báo nào"</string>
-    <string name="app_settings_link" msgid="8465287765715790984">"Cài đặt bổ sung trong ứng dụng"</string>
+    <string name="no_channels" msgid="8884254729302501652">"Ứng dụng này chưa đăng bất kỳ thông báo nào"</string>
+    <string name="app_settings_link" msgid="8465287765715790984">"Tùy chọn cài đặt bổ sung trong ứng dụng"</string>
     <string name="app_notification_listing_summary_zero" msgid="4047782719487686699">"Đang bật cho tất cả ứng dụng"</string>
     <plurals name="app_notification_listing_summary_others" formatted="false" msgid="1161774065480666519">
       <item quantity="other">Tắt cho <xliff:g id="COUNT_1">%d</xliff:g> ứng dụng</item>
@@ -3422,7 +3422,7 @@
     <string name="notification_content_block_summary" msgid="2743896875255591743">"Không bao giờ hiển thị thông báo trong ngăn thông báo hoặc trên thiết bị ngoại vi"</string>
     <string name="notification_badge_title" msgid="8989086619255666442">"Cho phép dấu chấm thông báo"</string>
     <string name="notification_channel_badge_title" msgid="8228215248332054612">"Hiển thị dấu chấm thông báo"</string>
-    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"Ghi đè Không làm phiền"</string>
+    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"Vô hiệu hóa chế độ Không làm phiền"</string>
     <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"Cho phép những thông báo này tiếp tục làm gián đoạn khi chế độ Không làm phiền đang bật"</string>
     <string name="app_notification_visibility_override_title" msgid="2349335170165637672">"Trên màn hình khóa"</string>
     <string name="app_notification_row_banned" msgid="2079325338122151677">"Bị chặn"</string>
@@ -3511,8 +3511,8 @@
     <string name="zen_mode_bypassing_apps" msgid="3080739479028713449">"Cho phép ứng dụng ghi đè"</string>
     <string name="zen_mode_bypassing_apps_title" msgid="2115024664615538847">"Ứng dụng ngoại lệ"</string>
     <plurals name="zen_mode_bypassing_apps_subtext" formatted="false" msgid="8723144434730871572">
-      <item quantity="other">Thông báo từ <xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng có thể ghi đè chế độ Không làm phiền</item>
-      <item quantity="one">Thông báo từ 1 ứng dụng có thể ghi đè chế độ Không làm phiền</item>
+      <item quantity="other">Thông báo từ <xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng có thể vô hiệu hóa chế độ Không làm phiền</item>
+      <item quantity="one">Thông báo từ 1 ứng dụng có thể vô hiệu hóa chế độ Không làm phiền</item>
     </plurals>
     <string name="zen_mode_events_list" msgid="8578102701815684873">"sự kiện"</string>
     <string name="zen_mode_all_callers" msgid="4455039040077343838">"bất kỳ ai"</string>
diff --git a/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml b/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml
index 51500a7..5e42e3c 100644
--- a/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml
@@ -3423,7 +3423,7 @@
     <string name="notification_content_block_summary" msgid="2743896875255591743">"永不在通知欄或周邊裝置上顯示通知"</string>
     <string name="notification_badge_title" msgid="8989086619255666442">"允許通知圓點"</string>
     <string name="notification_channel_badge_title" msgid="8228215248332054612">"顯示通知圓點"</string>
-    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"蓋過「請勿騷擾」設定"</string>
+    <string name="app_notification_override_dnd_title" msgid="1757042206738172601">"忽略「請勿騷擾」設定"</string>
     <string name="app_notification_override_dnd_summary" msgid="3152957611171210980">"「請勿騷擾」模式開啟時繼續接收這些通知"</string>
     <string name="app_notification_visibility_override_title" msgid="2349335170165637672">"在上鎖畫面上"</string>
     <string name="app_notification_row_banned" msgid="2079325338122151677">"已封鎖"</string>
@@ -3512,8 +3512,8 @@
     <string name="zen_mode_bypassing_apps" msgid="3080739479028713449">"允許應用程式取代「請勿騷擾」"</string>
     <string name="zen_mode_bypassing_apps_title" msgid="2115024664615538847">"應用程式例外情況"</string>
     <plurals name="zen_mode_bypassing_apps_subtext" formatted="false" msgid="8723144434730871572">
-      <item quantity="other"><xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式的通知可蓋過「請勿騷擾」設定</item>
-      <item quantity="one">1 個應用程式的通知可蓋過「請勿騷擾」設定</item>
+      <item quantity="other"><xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式的通知可忽略「請勿騷擾」設定</item>
+      <item quantity="one">1 個應用程式的通知可忽略「請勿騷擾」設定</item>
     </plurals>
     <string name="zen_mode_events_list" msgid="8578102701815684873">"活動"</string>
     <string name="zen_mode_all_callers" msgid="4455039040077343838">"任何人"</string>
diff --git a/tests/CarSecurityPermissionTest/src/com/android/car/media/CarAudioManagerPermissionTest.java b/tests/CarSecurityPermissionTest/src/com/android/car/media/CarAudioManagerPermissionTest.java
index cf98255..1e4391b 100644
--- a/tests/CarSecurityPermissionTest/src/com/android/car/media/CarAudioManagerPermissionTest.java
+++ b/tests/CarSecurityPermissionTest/src/com/android/car/media/CarAudioManagerPermissionTest.java
@@ -25,16 +25,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.junit.Assume.assumeNotNull;
 import static org.testng.Assert.expectThrows;
 
 import android.car.Car;
 import android.car.media.CarAudioManager;
 import android.content.Context;
-import android.hardware.display.DisplayManager;
 import android.os.Handler;
-import android.view.Display;
-import android.view.DisplayAddress;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
@@ -43,9 +39,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Arrays;
 import java.util.Objects;
-import java.util.Optional;
 
 /**
  * This class contains security permission tests for the {@link CarAudioManager}'s system APIs.
@@ -220,22 +214,6 @@
     }
 
     @Test
-    public void getZoneIdForDisplayPermission() {
-        Display display = getPhysicalDisplay();
-        assumeNotNull(display);
-        Exception e = expectThrows(SecurityException.class,
-                () -> mCarAudioManager.getZoneIdForDisplay(display));
-        assertThat(e.getMessage()).contains(PERMISSION_CAR_CONTROL_AUDIO_SETTINGS);
-    }
-
-    @Test
-    public void getZoneIdForDisplayPortIdPermission() {
-        Exception e = expectThrows(SecurityException.class,
-                () -> mCarAudioManager.getZoneIdForDisplayPortId(Byte.MAX_VALUE));
-        assertThat(e.getMessage()).contains(PERMISSION_CAR_CONTROL_AUDIO_SETTINGS);
-    }
-
-    @Test
     public void getOutputDeviceForUsagePermission() {
         Exception e = expectThrows(SecurityException.class,
                 () -> mCarAudioManager.getOutputDeviceForUsage(PRIMARY_AUDIO_ZONE, USAGE_MEDIA));
@@ -255,12 +233,4 @@
                 () -> mCarAudioManager.onCarDisconnected());
         assertThat(e.getMessage()).contains(PERMISSION_CAR_CONTROL_AUDIO_VOLUME);
     }
-
-    private Display getPhysicalDisplay() {
-        DisplayManager displayManager = (DisplayManager) mContext.getSystemService(
-                Context.DISPLAY_SERVICE);
-        Optional<Display> physical = Arrays.stream(displayManager.getDisplays()).filter(
-                display -> (display.getAddress() instanceof DisplayAddress.Physical)).findFirst();
-        return physical.orElse(null);
-    }
 }
diff --git a/tests/CarSecurityPermissionTest/src/com/android/car/user/CarUserManagerPermissionTest.java b/tests/CarSecurityPermissionTest/src/com/android/car/user/CarUserManagerPermissionTest.java
index b0edd13..3a5ea1b 100644
--- a/tests/CarSecurityPermissionTest/src/com/android/car/user/CarUserManagerPermissionTest.java
+++ b/tests/CarSecurityPermissionTest/src/com/android/car/user/CarUserManagerPermissionTest.java
@@ -82,6 +82,12 @@
     }
 
     @Test
+    public void testRemoveUserPermission() throws Exception {
+        Exception e = expectThrows(SecurityException.class, () -> mCarUserManager.removeUser(100));
+        assertThat(e.getMessage()).contains(MANAGE_USERS);
+    }
+
+    @Test
     public void testAddListenerPermission() {
         UserLifecycleListener listener = (e) -> { };
 
diff --git a/tests/carservice_test/res/raw/car_audio_configuration.xml b/tests/carservice_test/res/raw/car_audio_configuration.xml
index b4bb08a..e1d75df 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration.xml
@@ -21,10 +21,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_V1.xml b/tests/carservice_test/res/raw/car_audio_configuration_V1.xml
index 4aaaa6c..26b1c08 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_V1.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_V1.xml
@@ -33,10 +33,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_V1_with_non_legacy_contexts.xml b/tests/carservice_test/res/raw/car_audio_configuration_V1_with_non_legacy_contexts.xml
index 03e9a0f..5c39ceb 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_V1_with_non_legacy_contexts.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_V1_with_non_legacy_contexts.xml
@@ -33,10 +33,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_duplicate_audio_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_duplicate_audio_zone_id.xml
index 4b5abc5..8561968 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_duplicate_audio_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_duplicate_audio_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="1" occupantZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_duplicate_occupant_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_duplicate_occupant_zone_id.xml
index 1d15b36..8c1d0e8 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_duplicate_occupant_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_duplicate_occupant_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2" occupantZoneId="1">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_duplicate_ports.xml b/tests/carservice_test/res/raw/car_audio_configuration_duplicate_ports.xml
index 288e8fb..dba13a2 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_duplicate_ports.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_duplicate_ports.xml
@@ -17,10 +17,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="1"/>
-            </displays>
         </zone>
     </zones>
 </carAudioConfiguration>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_empty_occupant_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_empty_occupant_zone_id.xml
index 182e606..972da37 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_empty_occupant_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_empty_occupant_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_negative_audio_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_negative_audio_zone_id.xml
index acdb784..060934b 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_negative_audio_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_negative_audio_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_negative_occupant_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_negative_occupant_zone_id.xml
index b7d7a62..cffad51 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_negative_occupant_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_negative_occupant_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_audio_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_audio_zone_id.xml
index 09168a6..8e1c41b 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_audio_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_audio_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_occupant_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_occupant_zone_id.xml
index af57c24..f00b169 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_occupant_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_occupant_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_port.xml b/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_port.xml
index f6995bc..9adef24 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_port.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_non_numerical_port.xml
@@ -21,9 +21,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="one"/>
-            </displays>
         </zone>
     </zones>
 </carAudioConfiguration>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_non_primary_zone_with_primary_audio_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_non_primary_zone_with_primary_audio_zone_id.xml
index f822469..4364a1d 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_non_primary_zone_with_primary_audio_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_non_primary_zone_with_primary_audio_zone_id.xml
@@ -33,10 +33,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="0">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_output_address_does_not_exist.xml b/tests/carservice_test/res/raw/car_audio_configuration_output_address_does_not_exist.xml
index 83c054c..a359d36 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_output_address_does_not_exist.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_output_address_does_not_exist.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/res/raw/car_audio_configuration_primary_zone_with_non_zero_audio_zone_id.xml b/tests/carservice_test/res/raw/car_audio_configuration_primary_zone_with_non_zero_audio_zone_id.xml
index 6f845e7..2d25716 100644
--- a/tests/carservice_test/res/raw/car_audio_configuration_primary_zone_with_non_zero_audio_zone_id.xml
+++ b/tests/carservice_test/res/raw/car_audio_configuration_primary_zone_with_non_zero_audio_zone_id.xml
@@ -37,10 +37,6 @@
                     </device>
                 </group>
             </volumeGroups>
-            <displays>
-                <display port="1"/>
-                <display port="2"/>
-            </displays>
         </zone>
         <zone name="rear seat zone" audioZoneId="2">
             <volumeGroups>
diff --git a/tests/carservice_test/src/com/android/car/audio/CarAudioZonesHelperTest.java b/tests/carservice_test/src/com/android/car/audio/CarAudioZonesHelperTest.java
index a37c0e4..fce0a78 100644
--- a/tests/carservice_test/src/com/android/car/audio/CarAudioZonesHelperTest.java
+++ b/tests/carservice_test/src/com/android/car/audio/CarAudioZonesHelperTest.java
@@ -28,7 +28,6 @@
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
 import android.util.SparseIntArray;
-import android.view.DisplayAddress;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -293,56 +292,6 @@
     }
 
     @Test
-    public void loadAudioZones_parsesPhysicalDisplayAddresses() throws Exception {
-        CarAudioZonesHelper cazh = new CarAudioZonesHelper(mCarAudioSettings, mInputStream,
-                mCarAudioOutputDeviceInfos, mInputAudioDeviceInfos);
-
-        CarAudioZone[] zones = cazh.loadAudioZones();
-
-        CarAudioZone primaryZone = zones[0];
-        List<DisplayAddress.Physical> primaryPhysicals = primaryZone.getPhysicalDisplayAddresses();
-        assertThat(primaryPhysicals).hasSize(2);
-        assertThat(primaryPhysicals.get(0).getPort()).isEqualTo(1);
-        assertThat(primaryPhysicals.get(1).getPort()).isEqualTo(2);
-    }
-
-    @Test
-    public void loadAudioZones_defaultsDisplayAddressesToEmptyList() throws Exception {
-        CarAudioZonesHelper cazh = new CarAudioZonesHelper(mCarAudioSettings, mInputStream,
-                mCarAudioOutputDeviceInfos, mInputAudioDeviceInfos);
-
-        CarAudioZone[] zones = cazh.loadAudioZones();
-
-        CarAudioZone rseZone = zones[1];
-        List<DisplayAddress.Physical> rsePhysicals = rseZone.getPhysicalDisplayAddresses();
-        assertThat(rsePhysicals).isEmpty();
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void loadAudioZones_throwsOnDuplicatePorts() throws Exception {
-        try (InputStream duplicatePortStream = mContext.getResources().openRawResource(
-                R.raw.car_audio_configuration_duplicate_ports)) {
-            CarAudioZonesHelper cazh =
-                    new CarAudioZonesHelper(mCarAudioSettings, duplicatePortStream,
-                            mCarAudioOutputDeviceInfos, mInputAudioDeviceInfos);
-
-            cazh.loadAudioZones();
-        }
-    }
-
-    @Test
-    public void loadAudioZones_throwsOnNonNumericalPort() {
-        InputStream duplicatePortStream = mContext.getResources().openRawResource(
-                R.raw.car_audio_configuration_non_numerical_port);
-        CarAudioZonesHelper cazh = new CarAudioZonesHelper(mCarAudioSettings, duplicatePortStream,
-                mCarAudioOutputDeviceInfos, mInputAudioDeviceInfos);
-
-        IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
-                cazh::loadAudioZones);
-        assertThat(exception).hasMessageThat().contains("Port one is not a number");
-    }
-
-    @Test
     public void loadAudioZones_passesOnMissingAudioZoneIdForPrimary() throws Exception {
         try (InputStream missingAudioZoneIdStream = mContext.getResources().openRawResource(
                 R.raw.car_audio_configuration_no_audio_zone_id_for_primary_zone)) {
diff --git a/tests/carservice_unit_test/src/android/car/userlib/UserHalHelperTest.java b/tests/carservice_unit_test/src/android/car/userlib/UserHalHelperTest.java
index 4d64225..29a1946 100644
--- a/tests/carservice_unit_test/src/android/car/userlib/UserHalHelperTest.java
+++ b/tests/carservice_unit_test/src/android/car/userlib/UserHalHelperTest.java
@@ -17,6 +17,7 @@
 package android.car.userlib;
 
 import static android.car.userlib.UserHalHelper.CREATE_USER_PROPERTY;
+import static android.car.userlib.UserHalHelper.REMOVE_USER_PROPERTY;
 import static android.car.userlib.UserHalHelper.SWITCH_USER_PROPERTY;
 import static android.car.userlib.UserHalHelper.USER_IDENTIFICATION_ASSOCIATION_PROPERTY;
 import static android.hardware.automotive.vehicle.V2_0.UserIdentificationAssociationSetValue.ASSOCIATE_CURRENT_USER;
@@ -50,6 +51,7 @@
 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;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserMessageType;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
 import android.hardware.automotive.vehicle.V2_0.UserFlags;
@@ -864,6 +866,62 @@
     }
 
     @Test
+    public void testRemoveUserRequestToVehiclePropValue_null() {
+        assertThrows(NullPointerException.class,
+                () -> UserHalHelper.toVehiclePropValue((RemoveUserRequest) null));
+    }
+
+    @Test
+    public void testRemoveUserRequestToVehiclePropValue_emptyRequest() {
+        RemoveUserRequest request = new RemoveUserRequest();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> UserHalHelper.toVehiclePropValue(request));
+    }
+
+    @Test
+    public void testRemoveUserRequestToVehiclePropValue_missingRequestId() {
+        RemoveUserRequest request = new RemoveUserRequest();
+        request.removedUserInfo.userId = 11;
+        request.usersInfo.existingUsers.add(request.removedUserInfo);
+
+        assertThrows(IllegalArgumentException.class,
+                () -> UserHalHelper.toVehiclePropValue(request));
+    }
+
+    @Test
+    public void testRemoveUserRequestToVehiclePropValue_ok() {
+        RemoveUserRequest request = new RemoveUserRequest();
+        request.requestId = 42;
+
+        android.hardware.automotive.vehicle.V2_0.UserInfo user10 =
+                new android.hardware.automotive.vehicle.V2_0.UserInfo();
+        user10.userId = 10;
+        user10.flags = UserFlags.ADMIN;
+
+        // existing users
+        request.usersInfo.numberUsers = 1;
+        request.usersInfo.existingUsers.add(user10);
+
+        // current user
+        request.usersInfo.currentUser = user10;
+        // user to remove
+        request.removedUserInfo = user10;
+
+        VehiclePropValue propValue = UserHalHelper.toVehiclePropValue(request);
+
+        assertWithMessage("wrong prop on %s", propValue).that(propValue.prop)
+                .isEqualTo(REMOVE_USER_PROPERTY);
+        assertWithMessage("wrong int32values on %s", propValue).that(propValue.value.int32Values)
+                .containsExactly(42, // request id
+                        10, UserFlags.ADMIN, // user to remove
+                        10, UserFlags.ADMIN, // current user
+                        1, // number of users
+                        10, UserFlags.ADMIN  // existing user 1
+                        ).inOrder();
+    }
+
+    @Test
     public void testCreateUserRequestToVehiclePropValue_null() {
         assertThrows(NullPointerException.class,
                 () -> UserHalHelper.toVehiclePropValue((CreateUserRequest) null));
@@ -1066,12 +1124,12 @@
 
     @Test
     public void testNewUsersInfo_nullUm() {
-        assertThrows(IllegalArgumentException.class, () -> UserHalHelper.newUsersInfo(null));
+        assertThrows(IllegalArgumentException.class, () -> UserHalHelper.newUsersInfo(null, 100));
     }
 
     @Test
     public void testNewUsersInfo_nullUsers() {
-        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUm);
+        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUm, 100);
 
         assertEmptyUsersInfo(usersInfo);
     }
@@ -1081,12 +1139,58 @@
         List<UserInfo> users = new ArrayList<>();
         AndroidMockitoHelper.mockUmGetUsers(mUm, users);
 
-        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUm);
+        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUm, 100);
 
         assertEmptyUsersInfo(usersInfo);
     }
 
     @Test
+    public void testNewUsersInfo_ok() {
+        UserInfo user100 = new UserInfoBuilder(100).setFlags(UserInfo.FLAG_ADMIN).build();
+        UserInfo user200 = new UserInfoBuilder(200).build();
+
+        AndroidMockitoHelper.mockUmGetUsers(mUm, user100, user200);
+        AndroidMockitoHelper.mockAmGetCurrentUser(300); // just to make sure it's not used
+
+        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUm, 100);
+
+        assertThat(usersInfo).isNotNull();
+        assertThat(usersInfo.currentUser.userId).isEqualTo(100);
+        assertThat(usersInfo.currentUser.flags).isEqualTo(UserFlags.ADMIN);
+
+        assertThat(usersInfo.numberUsers).isEqualTo(2);
+        assertThat(usersInfo.existingUsers).hasSize(2);
+
+        assertThat(usersInfo.existingUsers.get(0).userId).isEqualTo(100);
+        assertThat(usersInfo.existingUsers.get(0).flags).isEqualTo(UserFlags.ADMIN);
+        assertThat(usersInfo.existingUsers.get(1).userId).isEqualTo(200);
+        assertThat(usersInfo.existingUsers.get(1).flags).isEqualTo(UserFlags.NONE);
+    }
+
+    @Test
+    public void testNewUsersInfo_currentUser_ok() {
+        UserInfo user100 = new UserInfoBuilder(100).setFlags(UserInfo.FLAG_ADMIN).build();
+        UserInfo user200 = new UserInfoBuilder(200).build();
+
+        AndroidMockitoHelper.mockUmGetUsers(mUm, user100, user200);
+        AndroidMockitoHelper.mockAmGetCurrentUser(100);
+
+        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUm);
+
+        assertThat(usersInfo).isNotNull();
+        assertThat(usersInfo.currentUser.userId).isEqualTo(100);
+        assertThat(usersInfo.currentUser.flags).isEqualTo(UserFlags.ADMIN);
+
+        assertThat(usersInfo.numberUsers).isEqualTo(2);
+        assertThat(usersInfo.existingUsers).hasSize(2);
+
+        assertThat(usersInfo.existingUsers.get(0).userId).isEqualTo(100);
+        assertThat(usersInfo.existingUsers.get(0).flags).isEqualTo(UserFlags.ADMIN);
+        assertThat(usersInfo.existingUsers.get(1).userId).isEqualTo(200);
+        assertThat(usersInfo.existingUsers.get(1).flags).isEqualTo(UserFlags.NONE);
+    }
+
+    @Test
     public void testNewUsersInfo_noCurrentUser() {
         UserInfo user100 = new UserInfoBuilder(100).setFlags(UserInfo.FLAG_ADMIN).build();
         UserInfo user200 = new UserInfoBuilder(200).build();
@@ -1110,29 +1214,6 @@
     }
 
     @Test
-    public void testNewUsersInfo_ok() {
-        UserInfo user100 = new UserInfoBuilder(100).setFlags(UserInfo.FLAG_ADMIN).build();
-        UserInfo user200 = new UserInfoBuilder(200).build();
-
-        AndroidMockitoHelper.mockUmGetUsers(mUm, user100, user200);
-        AndroidMockitoHelper.mockAmGetCurrentUser(100);
-
-        UsersInfo usersInfo = UserHalHelper.newUsersInfo(mUm);
-
-        assertThat(usersInfo).isNotNull();
-        assertThat(usersInfo.currentUser.userId).isEqualTo(100);
-        assertThat(usersInfo.currentUser.flags).isEqualTo(UserFlags.ADMIN);
-
-        assertThat(usersInfo.numberUsers).isEqualTo(2);
-        assertThat(usersInfo.existingUsers).hasSize(2);
-
-        assertThat(usersInfo.existingUsers.get(0).userId).isEqualTo(100);
-        assertThat(usersInfo.existingUsers.get(0).flags).isEqualTo(UserFlags.ADMIN);
-        assertThat(usersInfo.existingUsers.get(1).userId).isEqualTo(200);
-        assertThat(usersInfo.existingUsers.get(1).flags).isEqualTo(UserFlags.NONE);
-    }
-
-    @Test
     public void testCheckValidUsersInfo_null() {
         assertThrows(IllegalArgumentException.class, () -> UserHalHelper.checkValid(null));
     }
diff --git a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
index f146dcb..3cbfffc 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
@@ -62,6 +62,7 @@
 import com.android.car.systeminterface.WakeLockInterface;
 import com.android.car.test.utils.TemporaryDirectory;
 import com.android.car.user.CarUserService;
+import com.android.internal.app.IVoiceInteractionManagerService;
 
 import org.junit.After;
 import org.junit.Before;
@@ -107,6 +108,9 @@
     private CarUserService mUserService;
     @Mock
     private InitialUserSetter mInitialUserSetter;
+    @Mock
+    private IVoiceInteractionManagerService mVoiceInteractionManagerService;
+
 
     @Override
     protected void onSessionBuilder(CustomMockitoSessionBuilder session) {
@@ -150,7 +154,8 @@
                 + ", maxGarageModeRunningDurationInSecs="
                 + mResources.getInteger(R.integer.maxGarageModeRunningDurationInSecs));
         mService = new CarPowerManagementService(mContext, mResources, mPowerHal,
-                mSystemInterface, mUserManager, mUserService, mInitialUserSetter);
+                mSystemInterface, mUserManager, mUserService, mInitialUserSetter,
+                mVoiceInteractionManagerService);
         mService.init();
         mService.setShutdownTimersForTest(0, 0);
         mPowerHal.setSignalListener(mPowerSignalListener);
@@ -501,6 +506,7 @@
                 VehicleApPowerStateShutdownParam.CAN_SLEEP));
         assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isFalse();
         assertStateReceivedForShutdownOrSleepWithPostpone(PowerHalService.SET_DEEP_SLEEP_ENTRY);
+        assertVoiceInteractionDisabled();
         mPowerSignalListener.waitForSleepEntry(WAIT_TIMEOUT_MS);
 
         // Send the finished signal
@@ -530,6 +536,7 @@
         mSystemStateInterface.waitForSleepEntryAndWakeup(WAIT_TIMEOUT_MS);
         // Since we just woke up from shutdown, wake up time will be 0
         assertStateReceived(PowerHalService.SET_DEEP_SLEEP_EXIT, 0);
+        assertVoiceInteractionEnabled();
         assertThat(mDisplayInterface.getDisplayState()).isFalse();
     }
 
@@ -573,6 +580,14 @@
         assertStateReceivedForShutdownOrSleepWithPostpone(lastState, expectedSecondParameter);
     }
 
+    private void assertVoiceInteractionEnabled() throws Exception {
+        verify(mVoiceInteractionManagerService).setDisabled(false);
+    }
+
+    private void assertVoiceInteractionDisabled() throws Exception {
+        verify(mVoiceInteractionManagerService).setDisabled(true);
+    }
+
     private static void waitForSemaphore(Semaphore semaphore, long timeoutMs)
             throws InterruptedException {
         if (!semaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
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 25917c3..e6a81b6 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
@@ -18,6 +18,7 @@
 import static android.car.VehiclePropertyIds.CREATE_USER;
 import static android.car.VehiclePropertyIds.CURRENT_GEAR;
 import static android.car.VehiclePropertyIds.INITIAL_USER_INFO;
+import static android.car.VehiclePropertyIds.REMOVE_USER;
 import static android.car.VehiclePropertyIds.SWITCH_USER;
 import static android.car.VehiclePropertyIds.USER_IDENTIFICATION_ASSOCIATION;
 import static android.car.test.mocks.CarArgumentMatchers.isProperty;
@@ -53,6 +54,7 @@
 import android.hardware.automotive.vehicle.V2_0.CreateUserStatus;
 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponse;
 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction;
+import android.hardware.automotive.vehicle.V2_0.RemoveUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserMessageType;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserResponse;
@@ -684,6 +686,55 @@
     }
 
     @Test
+    public void testRemoveUser_nullRequest() {
+        RemoveUserRequest request = null;
+
+        assertThrows(NullPointerException.class,
+                () -> mUserHalService.removeUser(request));
+    }
+
+    @Test
+    public void testRemoveUser_noRequestId() {
+        RemoveUserRequest request = new RemoveUserRequest();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mUserHalService.removeUser(request));
+    }
+
+    @Test
+    public void testRemoveUser_noRemovedUserInfo() {
+        RemoveUserRequest request = new RemoveUserRequest();
+        request.requestId = 1;
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mUserHalService.removeUser(request));
+    }
+
+    @Test
+    public void testRemoveUser_noUsersInfo() {
+        RemoveUserRequest request = new RemoveUserRequest();
+        request.requestId = 1;
+        request.removedUserInfo = mUser10;
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mUserHalService.removeUser(request));
+    }
+
+    @Test
+    public void testRemoveUser_HalCalledWithCorrectProp() {
+        RemoveUserRequest request = new RemoveUserRequest();
+        request.removedUserInfo = mUser10;
+        request.usersInfo = mUsersInfo;
+        ArgumentCaptor<VehiclePropValue> propCaptor =
+                ArgumentCaptor.forClass(VehiclePropValue.class);
+
+        mUserHalService.removeUser(request);
+
+        verify(mVehicleHal).set(propCaptor.capture());
+        assertHalSetRemoveUserRequest(propCaptor.getValue(), mUser10);
+    }
+
+    @Test
     public void testLegacyUserSwitch_noUsersInfo() {
         SwitchUserRequest request = new SwitchUserRequest();
         request.messageType = SwitchUserMessageType.ANDROID_SWITCH;
@@ -1366,6 +1417,17 @@
         assertUsersInfo(req, mUsersInfo, 4);
     }
 
+    private void assertHalSetRemoveUserRequest(VehiclePropValue req, UserInfo userInfo) {
+        assertThat(req.prop).isEqualTo(REMOVE_USER);
+        assertWithMessage("wrong request Id on %s", req).that(req.value.int32Values.get(0))
+                .isAtLeast(1);
+        assertWithMessage("user.id mismatch on %s", req).that(req.value.int32Values.get(1))
+                .isEqualTo(userInfo.userId);
+        assertWithMessage("user.flags mismatch on %s", req).that(req.value.int32Values.get(2))
+                .isEqualTo(userInfo.flags);
+        assertUsersInfo(req, mUsersInfo, 3);
+    }
+
     private void assertHalSetCreateUserRequest(VehiclePropValue prop, CreateUserRequest request) {
         assertThat(prop.prop).isEqualTo(CREATE_USER);
         assertWithMessage("wrong request Id on %s", prop).that(prop.value.int32Values.get(0))
diff --git a/tests/carservice_unit_test/src/com/android/car/hardware/power/CarPowerManagerUnitTest.java b/tests/carservice_unit_test/src/com/android/car/hardware/power/CarPowerManagerUnitTest.java
index 6100dbc..ae86874 100644
--- a/tests/carservice_unit_test/src/com/android/car/hardware/power/CarPowerManagerUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/hardware/power/CarPowerManagerUnitTest.java
@@ -41,6 +41,7 @@
 import com.android.car.systeminterface.DisplayInterface;
 import com.android.car.systeminterface.SystemInterface;
 import com.android.car.systeminterface.SystemStateInterface;
+import com.android.internal.app.IVoiceInteractionManagerService;
 
 import org.junit.After;
 import org.junit.Before;
@@ -73,6 +74,8 @@
     private Resources mResources;
     @Mock
     private Car mCar;
+    @Mock
+    private IVoiceInteractionManagerService mVoiceInteractionManagerService;
 
     @Before
     public void setUp() throws Exception {
@@ -204,7 +207,7 @@
                 + ", maxGarageModeRunningDurationInSecs="
                 + mResources.getInteger(R.integer.maxGarageModeRunningDurationInSecs));
         mService = new CarPowerManagementService(mContext, mResources, mPowerHal,
-                mSystemInterface, null, null, null);
+                mSystemInterface, null, null, null, mVoiceInteractionManagerService);
         mService.init();
         mService.setShutdownTimersForTest(0, 0);
         assertStateReceived(MockedPowerHalService.SET_WAIT_FOR_VHAL, 0);
diff --git a/tests/carservice_unit_test/src/com/android/car/user/CarUserManagerUnitTest.java b/tests/carservice_unit_test/src/com/android/car/user/CarUserManagerUnitTest.java
index 540e1d1..1003957 100644
--- a/tests/carservice_unit_test/src/com/android/car/user/CarUserManagerUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/user/CarUserManagerUnitTest.java
@@ -45,6 +45,7 @@
 import android.car.user.CarUserManager.UserSwitchUiCallback;
 import android.car.user.UserCreationResult;
 import android.car.user.UserIdentificationAssociationResponse;
+import android.car.user.UserRemovalResult;
 import android.car.user.UserSwitchResult;
 import android.content.pm.UserInfo;
 import android.content.pm.UserInfo.UserInfoFlag;
@@ -188,6 +189,28 @@
     }
 
     @Test
+    public void testRemoveUser_success() throws Exception {
+        int userId = 11;
+        int status = UserRemovalResult.STATUS_SUCCESSFUL;
+        when(mService.removeUser(userId)).thenReturn(new UserRemovalResult(status));
+
+        UserRemovalResult result = mMgr.removeUser(11);
+
+        assertThat(result.getStatus()).isEqualTo(UserRemovalResult.STATUS_SUCCESSFUL);
+    }
+
+    @Test
+    public void testRemoveUser_remoteException() throws Exception {
+        int userId = 11;
+        doThrow(new RemoteException("D'OH!")).when(mService).removeUser(eq(userId));
+        mockHandleRemoteExceptionFromCarServiceWithDefaultValue(mCar);
+
+        UserRemovalResult result = mMgr.removeUser(11);
+
+        assertThat(result.getStatus()).isEqualTo(UserRemovalResult.STATUS_HAL_INTERNAL_FAILURE);
+    }
+
+    @Test
     public void testSetSwitchUserUICallback_success() throws Exception {
         UserSwitchUiCallback callback = (u)-> { };
 
diff --git a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
index dc26946..79d3282 100644
--- a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
@@ -21,6 +21,7 @@
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetUserInfo;
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetUsers;
 import static android.car.test.util.UserTestingHelper.UserInfoBuilder;
+import static android.content.pm.UserInfo.FLAG_ADMIN;
 import static android.content.pm.UserInfo.FLAG_EPHEMERAL;
 import static android.content.pm.UserInfo.FLAG_GUEST;
 
@@ -65,6 +66,7 @@
 import android.car.user.CarUserManager.UserLifecycleListener;
 import android.car.user.UserCreationResult;
 import android.car.user.UserIdentificationAssociationResponse;
+import android.car.user.UserRemovalResult;
 import android.car.user.UserSwitchResult;
 import android.car.userlib.CarUserManagerHelper;
 import android.car.userlib.HalCallback;
@@ -82,6 +84,7 @@
 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;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserResponse;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserStatus;
@@ -462,33 +465,37 @@
     }
 
     @Test
-    public void testCreateAdminDriver_IfCurrentUserIsAdminUser() {
-        doReturn(true).when(mMockedUserManager).isSystemUser();
-        String userName = "testUser";
-        UserInfo userInfo = new UserInfo();
-        doReturn(userInfo).when(mMockedUserManager).createUser(userName, UserInfo.FLAG_ADMIN);
-        assertEquals(userInfo, mCarUserService.createDriver(userName, true));
+    public void testCreateAdminDriver_IfCurrentUserIsAdminUser() throws Exception {
+        when(mMockedUserManager.isSystemUser()).thenReturn(true);
+        mockUmCreateUser(mMockedUserManager, "testUser", UserManager.USER_TYPE_FULL_SECONDARY,
+                UserInfo.FLAG_ADMIN, 10);
+        mockHalCreateUser(HalCallback.STATUS_OK, CreateUserStatus.SUCCESS);
+
+        AndroidFuture<UserCreationResult> future = mCarUserService.createDriver("testUser", true);
+
+        assertThat(getResult(future).getUser().name).isEqualTo("testUser");
+        assertThat(getResult(future).getUser().id).isEqualTo(10);
     }
 
     @Test
-    public void testCreateAdminDriver_IfCurrentUserIsNotSystemUser() {
-        doReturn(false).when(mMockedUserManager).isSystemUser();
-        assertEquals(null, mCarUserService.createDriver("testUser", true));
+    public void testCreateAdminDriver_IfCurrentUserIsNotSystemUser() throws Exception {
+        when(mMockedUserManager.isSystemUser()).thenReturn(false);
+        AndroidFuture<UserCreationResult> future = mCarUserService.createDriver("testUser", true);
+        assertThat(getResult(future).getStatus())
+                .isEqualTo(UserCreationResult.STATUS_INVALID_REQUEST);
     }
 
     @Test
-    public void testCreateNonAdminDriver() {
-        String userName = "testUser";
-        UserInfo userInfo = new UserInfo();
-        doReturn(userInfo).when(mMockedCarUserManagerHelper).createNewNonAdminUser(userName);
-        assertEquals(userInfo, mCarUserService.createDriver(userName, false));
-    }
+    public void testCreateNonAdminDriver() throws Exception {
+        mockUmCreateUser(mMockedUserManager, "testUser", UserManager.USER_TYPE_FULL_SECONDARY,
+                NO_USER_INFO_FLAGS, 10);
+        mockHalCreateUser(HalCallback.STATUS_OK, CreateUserStatus.SUCCESS);
 
-    @Test
-    public void testCreateNonAdminDriver_IfMaximumUserAlreadyCreated() {
-        String userName = "testUser";
-        doReturn(null).when(mMockedUserManager).createUser(userName, NO_USER_INFO_FLAGS);
-        assertEquals(null, mCarUserService.createDriver(userName, false));
+        AndroidFuture<UserCreationResult> future = mCarUserService.createDriver("testUser", false);
+
+        UserInfo userInfo = getResult(future).getUser();
+        assertThat(userInfo.name).isEqualTo("testUser");
+        assertThat(userInfo.id).isEqualTo(10);
     }
 
     @Test
@@ -658,6 +665,73 @@
     }
 
     @Test
+    public void testRemoveUser_currentUserCannotBeRemoved() throws Exception {
+        mockCurrentUser(mAdminUser);
+
+        UserRemovalResult result = mCarUserService.removeUser(mAdminUser.id);
+
+        assertThat(result.getStatus())
+                .isEqualTo(UserRemovalResult.STATUS_TARGET_USER_IS_CURRENT_USER);
+    }
+
+    @Test
+    public void testRemoveUser_userNotExist() throws Exception {
+        UserRemovalResult result = mCarUserService.removeUser(15);
+
+        assertThat(result.getStatus())
+                .isEqualTo(UserRemovalResult.STATUS_USER_DOES_NOT_EXIST);
+    }
+
+    @Test
+    public void testRemoveUser_lastAdminUser() throws Exception {
+        mockCurrentUser(mRegularUser);
+        mockExistingUsers();
+
+        UserRemovalResult result = mCarUserService.removeUser(mAdminUser.id);
+
+        assertThat(result.getStatus())
+                .isEqualTo(UserRemovalResult.STATUS_TARGET_USER_IS_LAST_ADMIN_USER);
+    }
+
+    @Test
+    public void testRemoveUser_notLastAdminUser_success() throws Exception {
+        // Give admin rights to regular user.
+        UserInfo currentUser = mRegularUser;
+        currentUser.flags = currentUser.flags | FLAG_ADMIN;
+        mockExistingUsersAndCurrentUser(currentUser);
+        int removeUserId = mAdminUser.id;
+        when(mMockedUserManager.removeUser(removeUserId)).thenReturn(true);
+
+        UserRemovalResult result = mCarUserService.removeUser(removeUserId);
+
+        assertThat(result.getStatus()).isEqualTo(UserRemovalResult.STATUS_SUCCESSFUL);
+        assertHalRemove(currentUser.id, removeUserId);
+    }
+
+    @Test
+    public void testRemoveUser_success() throws Exception {
+        mockExistingUsersAndCurrentUser(mAdminUser);
+        int removeUserId = mRegularUser.id;
+        when(mMockedUserManager.removeUser(removeUserId)).thenReturn(true);
+
+        UserRemovalResult result = mCarUserService.removeUser(removeUserId);
+
+        assertThat(result.getStatus()).isEqualTo(UserRemovalResult.STATUS_SUCCESSFUL);
+        assertHalRemove(mAdminUser.id, removeUserId);
+    }
+
+    @Test
+    public void testRemoveUser_androidFailure() throws Exception {
+        mockExistingUsersAndCurrentUser(mAdminUser);
+        int targetUserId = mRegularUser.id;
+        when(mMockedUserManager.removeUser(targetUserId)).thenReturn(false);
+
+        UserRemovalResult result = mCarUserService.removeUser(targetUserId);
+
+        assertThat(result.getStatus()).isEqualTo(UserRemovalResult.STATUS_ANDROID_FAILURE);
+    }
+
+    @Test
     public void testSwitchUser_nullReceiver() throws Exception {
         mockExistingUsersAndCurrentUser(mAdminUser);
 
@@ -964,8 +1038,8 @@
     }
 
     @Test
-    public void testHalUserSwitchOnAndroidSwitch_successfulNoExitingUserSwitch() throws Exception {
-        mockExistingUsersAndCurrentUser(mAdminUser);
+    public void testLegacyUserSwitch_ok() throws Exception {
+        mockExistingUsers();
 
         sendUserSwitchingEvent(mAdminUser.id, mRegularUser.id);
 
@@ -973,7 +1047,8 @@
     }
 
     @Test
-    public void testHalUserSwitchOnAndroidSwitch_failureExitingUserSwitch() throws Exception {
+    public void testLegacyUserSwitch_notCalledAfterNormalSwitch() throws Exception {
+        // Arrange - emulate normal switch
         mockExistingUsersAndCurrentUser(mAdminUser);
         int requestId = 42;
         mSwitchUserResponse.status = SwitchUserStatus.SUCCESS;
@@ -982,8 +1057,10 @@
         mockAmSwitchUser(mGuestUser, true);
         mCarUserService.switchUser(mGuestUser.id, mAsyncCallTimeoutMs, mUserSwitchFuture);
 
+        // Act - trigger legacy switch
         sendUserSwitchingEvent(mAdminUser.id, mGuestUser.id);
 
+        // Assert
         verify(mUserHal, never()).legacyUserSwitch(any());
     }
 
@@ -1877,6 +1954,14 @@
         verify(mUserHal, never()).createUser(any(), eq(mAsyncCallTimeoutMs), any());
     }
 
+    private void assertHalRemove(int currentId, int removeUserId) {
+        ArgumentCaptor<RemoveUserRequest> request =
+                ArgumentCaptor.forClass(RemoveUserRequest.class);
+        verify(mUserHal).removeUser(request.capture());
+        assertThat(request.getValue().removedUserInfo.userId).isEqualTo(removeUserId);
+        assertThat(request.getValue().usersInfo.currentUser.userId).isEqualTo(currentId);
+    }
+
     @NonNull
     private static SwitchUserRequest isSwitchUserRequest(int requestId,
             @UserIdInt int currentUserId, @UserIdInt int targetUserId) {
diff --git a/tests/carservice_unit_test/src/com/android/car/user/ExperimentalCarUserManagerUnitTest.java b/tests/carservice_unit_test/src/com/android/car/user/ExperimentalCarUserManagerUnitTest.java
index 8b4dc55..2869d5d 100644
--- a/tests/carservice_unit_test/src/com/android/car/user/ExperimentalCarUserManagerUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/user/ExperimentalCarUserManagerUnitTest.java
@@ -20,6 +20,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.notNull;
 import static org.mockito.Mockito.doAnswer;
@@ -33,6 +34,7 @@
 import android.car.test.util.UserTestingHelper;
 import android.car.user.CarUserManager;
 import android.car.user.ExperimentalCarUserManager;
+import android.car.user.UserCreationResult;
 import android.car.user.UserSwitchResult;
 import android.content.pm.UserInfo;
 import android.os.RemoteException;
@@ -66,23 +68,41 @@
 
     @Test
     public void testCreateDriver_Success_Admin() throws Exception {
-        expectCreateDriverSucceed(10);
-        int userId = mManager.createDriver("test driver", true);
-        assertThat(userId).isEqualTo(10);
+        String name = "test driver";
+        int userId = 10;
+        expectCreateDriverSucceed(name, userId);
+
+        AndroidFuture<UserCreationResult> future = mManager.createDriver(name, true);
+
+        UserCreationResult result = getResult(future);
+        assertThat(result.getErrorMessage()).isNull();
+        assertThat(result.getStatus()).isEqualTo(UserCreationResult.STATUS_SUCCESSFUL);
+        assertThat(result.getUser().id).isEqualTo(userId);
     }
 
     @Test
     public void testCreateDriver_Success_NonAdmin() throws Exception {
-        expectCreateDriverSucceed(10);
-        int userId = mManager.createDriver("test driver", false);
-        assertThat(userId).isEqualTo(10);
+        String name = "test driver";
+        int userId = 10;
+        expectCreateDriverSucceed(name, userId);
+
+        AndroidFuture<UserCreationResult> future = mManager.createDriver(name, false);
+
+        UserCreationResult result = getResult(future);
+        assertThat(result.getErrorMessage()).isNull();
+        assertThat(result.getStatus()).isEqualTo(UserCreationResult.STATUS_SUCCESSFUL);
+        assertThat(result.getUser().id).isEqualTo(userId);
     }
 
     @Test
     public void testCreateDriver_Error() throws Exception {
         expectCreateDriverFail();
-        int userId = mManager.createDriver("test driver", false);
-        assertThat(userId).isEqualTo(UserHandle.USER_NULL);
+
+        AndroidFuture<UserCreationResult> future = mManager.createDriver("test driver", false);
+
+        assertThat(future).isNotNull();
+        UserCreationResult result = getResult(future);
+        assertThat(result.getStatus()).isEqualTo(UserSwitchResult.STATUS_HAL_INTERNAL_FAILURE);
     }
 
     @Test
@@ -165,13 +185,16 @@
         assertThat(success).isFalse();
     }
 
-    private void expectCreateDriverSucceed(@UserIdInt int userId) throws Exception {
-        UserInfo userInfo = UserTestingHelper.newUser(userId);
-        when(mService.createDriver(eq("test driver"), anyBoolean())).thenReturn(userInfo);
+    private void expectCreateDriverSucceed(String name, @UserIdInt int userId) throws Exception {
+        AndroidFuture<UserCreationResult> future = new AndroidFuture<>();
+        future.complete(new UserCreationResult(UserCreationResult.STATUS_SUCCESSFUL,
+                UserTestingHelper.newUser(userId), null));
+        when(mService.createDriver(eq(name), anyBoolean())).thenReturn(future);
     }
 
     private void expectCreateDriverFail() throws Exception {
-        when(mService.createDriver(eq("test driver"), anyBoolean())).thenReturn(null);
+        doThrow(new RemoteException("D'OH!")).when(mService)
+            .createDriver(anyString(), anyBoolean());
     }
 
     private void expectCreatePassengerSucceed() throws Exception {
diff --git a/user/car-user-lib/src/android/car/userlib/UserHalHelper.java b/user/car-user-lib/src/android/car/userlib/UserHalHelper.java
index cb03788..67a83c3 100644
--- a/user/car-user-lib/src/android/car/userlib/UserHalHelper.java
+++ b/user/car-user-lib/src/android/car/userlib/UserHalHelper.java
@@ -27,6 +27,7 @@
 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;
 import android.hardware.automotive.vehicle.V2_0.SwitchUserRequest;
 import android.hardware.automotive.vehicle.V2_0.UserFlags;
 import android.hardware.automotive.vehicle.V2_0.UserIdentificationAssociation;
@@ -63,8 +64,10 @@
     public static final int INITIAL_USER_INFO_PROPERTY = 299896583;
     public static final int SWITCH_USER_PROPERTY = 299896584;
     public static final int CREATE_USER_PROPERTY = 299896585;
+    public static final int REMOVE_USER_PROPERTY = 299896586;
     public static final int USER_IDENTIFICATION_ASSOCIATION_PROPERTY = 299896587;
 
+
     private static final String STRING_SEPARATOR = "\\|\\|";
 
     /**
@@ -539,10 +542,40 @@
     }
 
     /**
-     * Creates a {@link UsersInfo} instance populated with the current users.
+     * Creates a generic {@link VehiclePropValue} (that can be sent to HAL) from a
+     * {@link RemoveUserRequest}.
+     *
+     * @throws IllegalArgumentException if the request doesn't have the proper format.
+     */
+    @NonNull
+    public static VehiclePropValue toVehiclePropValue(@NonNull RemoveUserRequest request) {
+        checkArgument(request.requestId > 0, "invalid requestId on %s", request);
+        android.hardware.automotive.vehicle.V2_0.UserInfo removedUserInfo = request.removedUserInfo;
+        Objects.requireNonNull(removedUserInfo);
+        UsersInfo usersInfo = request.usersInfo;
+        checkValid(usersInfo);
+
+        VehiclePropValue propValue = createPropRequest(REMOVE_USER_PROPERTY, request.requestId);
+        addUserInfo(propValue, removedUserInfo);
+        addUsersInfo(propValue, usersInfo);
+        return propValue;
+    }
+
+    /**
+     * Creates a {@link UsersInfo} instance populated with the current users, using
+     * {@link ActivityManager#getCurrentUser()} as the current user.
      */
     @NonNull
     public static UsersInfo newUsersInfo(@NonNull UserManager um) {
+        return newUsersInfo(um, ActivityManager.getCurrentUser());
+    }
+
+    /**
+     * Creates a {@link UsersInfo} instance populated with the current users, using
+     * {@code userId} as the current user.
+     */
+    @NonNull
+    public static UsersInfo newUsersInfo(@NonNull UserManager um, @UserIdInt int userId) {
         Preconditions.checkArgument(um != null, "UserManager cannot be null");
 
         List<UserInfo> users = um.getUsers(/*excludeDying= */ true);
@@ -553,7 +586,7 @@
         }
 
         UsersInfo usersInfo = new UsersInfo();
-        usersInfo.currentUser.userId = ActivityManager.getCurrentUser();
+        usersInfo.currentUser.userId = userId;
         UserInfo currentUser = null;
         usersInfo.numberUsers = users.size();