Merge "Extend UxR to all displays with a physical port"
diff --git a/FrameworkPackageStubs/res/values-en-rCA/strings.xml b/FrameworkPackageStubs/res/values-en-rCA/strings.xml
index 92b3376..97c9277 100644
--- a/FrameworkPackageStubs/res/values-en-rCA/strings.xml
+++ b/FrameworkPackageStubs/res/values-en-rCA/strings.xml
@@ -3,6 +3,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="6179574017413146651">"Activity Stub"</string>
     <string name="message_not_supported" msgid="133939962837892495">"No application can handle this action"</string>
-    <string name="pip_not_supported" msgid="8681268258599412706">"Picture in Picture is not supported on this device"</string>
+    <string name="pip_not_supported" msgid="8681268258599412706">"Picture-in-picture is not supported on this device"</string>
     <string name="stub_name" msgid="3987164490218189006">"None"</string>
 </resources>
diff --git a/car-admin-ui-lib/src/main/res/values-en-rCA/strings.xml b/car-admin-ui-lib/src/main/res/values-en-rCA/strings.xml
index a8ba7f8..4b4db08 100644
--- a/car-admin-ui-lib/src/main/res/values-en-rCA/strings.xml
+++ b/car-admin-ui-lib/src/main/res/values-en-rCA/strings.xml
@@ -16,6 +16,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_admin_ui_managed_device_message_generic" msgid="2432263900803667538">"This vehicle is managed by an organization"</string>
+    <string name="car_admin_ui_managed_device_message_generic" msgid="2432263900803667538">"This vehicle is managed by an organisation"</string>
     <string name="car_admin_ui_managed_device_message_by_org" msgid="6717022763136116277">"This vehicle is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
 </resources>
diff --git a/car-lib-module/api/current.txt b/car-lib-module/api/current.txt
index 35ed850..d58b829 100644
--- a/car-lib-module/api/current.txt
+++ b/car-lib-module/api/current.txt
@@ -316,6 +316,7 @@
     field @RequiresPermission(android.car.Car.PERMISSION_POWERTRAIN) public static final int CURRENT_GEAR = 289408001; // 0x11400401
     field @RequiresPermission("android.car.permission.CAR_POWER") public static final int DISPLAY_BRIGHTNESS = 289409539; // 0x11400a03
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_DISPLAY_UNITS)) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(allOf={android.car.Car.PERMISSION_CONTROL_DISPLAY_UNITS, "android.car.permission.CAR_VENDOR_EXTENSION"})) public static final int DISTANCE_DISPLAY_UNITS = 289408512; // 0x11400600
+    field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_CHILD_LOCK_ENABLED = 371198723; // 0x16200b03
     field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_LOCK = 371198722; // 0x16200b02
     field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_MOVE = 373295873; // 0x16400b01
     field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_POS = 373295872; // 0x16400b00
@@ -443,7 +444,8 @@
     field @RequiresPermission("android.car.permission.CONTROL_CAR_SEATS") public static final int SEAT_OCCUPANCY = 356518832; // 0x15400bb0
     field @RequiresPermission("android.car.permission.CONTROL_CAR_SEATS") public static final int SEAT_TILT_MOVE = 356518800; // 0x15400b90
     field @RequiresPermission("android.car.permission.CONTROL_CAR_SEATS") public static final int SEAT_TILT_POS = 356518799; // 0x15400b8f
-    field @RequiresPermission("android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED") public static final int STORAGE_ENCRYPTION_BINDING_SEED = 292554247; // 0x11700607
+    field @RequiresPermission("android.car.permission.CONTROL_STEERING_WHEEL") public static final int STEERING_WHEEL_DEPTH_MOVE = 289410017; // 0x11400be1
+    field @RequiresPermission("android.car.permission.CONTROL_STEERING_WHEEL") public static final int STEERING_WHEEL_DEPTH_POS = 289410016; // 0x11400be0
     field @RequiresPermission("android.car.permission.CAR_TIRES") public static final int TIRE_PRESSURE = 392168201; // 0x17600309
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_DISPLAY_UNITS)) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(allOf={android.car.Car.PERMISSION_CONTROL_DISPLAY_UNITS, "android.car.permission.CAR_VENDOR_EXTENSION"})) public static final int TIRE_PRESSURE_DISPLAY_UNITS = 289408514; // 0x11400602
     field @RequiresPermission("android.car.permission.CAR_DYNAMICS_STATE") public static final int TRACTION_CONTROL_ACTIVE = 287310859; // 0x1120040b
diff --git a/car-lib-module/api/system-current.txt b/car-lib-module/api/system-current.txt
index 6082e2a..c9aefd1 100644
--- a/car-lib-module/api/system-current.txt
+++ b/car-lib-module/api/system-current.txt
@@ -68,6 +68,7 @@
     field public static final String PERMISSION_CONTROL_EXTERIOR_LIGHTS = "android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS";
     field public static final String PERMISSION_CONTROL_REMOTE_ACCESS = "android.car.permission.CONTROL_REMOTE_ACCESS";
     field public static final String PERMISSION_CONTROL_SHUTDOWN_PROCESS = "android.car.permission.CONTROL_SHUTDOWN_PROCESS";
+    field public static final String PERMISSION_CONTROL_STEERING_WHEEL = "android.car.permission.CONTROL_STEERING_WHEEL";
     field public static final String PERMISSION_EXTERIOR_LIGHTS = "android.car.permission.CAR_EXTERIOR_LIGHTS";
     field public static final String PERMISSION_MANAGE_OCCUPANT_ZONE = "android.car.permission.MANAGE_OCCUPANT_ZONE";
     field public static final String PERMISSION_MANAGE_THREAD_PRIORITY = "android.car.permission.MANAGE_THREAD_PRIORITY";
@@ -78,7 +79,6 @@
     field public static final String PERMISSION_READ_CAR_VENDOR_PERMISSION_INFO = "android.car.permission.READ_CAR_VENDOR_PERMISSION_INFO";
     field public static final String PERMISSION_RECEIVE_CAR_AUDIO_DUCKING_EVENTS = "android.car.permission.RECEIVE_CAR_AUDIO_DUCKING_EVENTS";
     field public static final String PERMISSION_REQUEST_CAR_EVS_ACTIVITY = "android.car.permission.REQUEST_CAR_EVS_ACTIVITY";
-    field public static final String PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED = "android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED";
     field public static final String PERMISSION_STORAGE_MONITORING = "android.car.permission.STORAGE_MONITORING";
     field public static final String PERMISSION_TEMPLATE_RENDERER = "android.car.permission.TEMPLATE_RENDERER";
     field public static final String PERMISSION_TIRES = "android.car.permission.CAR_TIRES";
@@ -1247,8 +1247,8 @@
   }
 
   public interface OemCarAudioFocusService extends android.car.oem.OemCarServiceComponent {
-    method public void audioFocusChanged(@NonNull java.util.List<android.media.AudioFocusInfo>, @NonNull java.util.List<android.media.AudioFocusInfo>, int);
     method @NonNull public android.car.oem.OemCarAudioFocusResult evaluateAudioFocusRequest(@NonNull android.car.oem.OemCarAudioFocusEvaluationRequest);
+    method public void notifyAudioFocusChange(@NonNull java.util.List<android.media.AudioFocusInfo>, @NonNull java.util.List<android.media.AudioFocusInfo>, int);
   }
 
   public abstract class OemCarService extends android.app.Service {
@@ -1256,9 +1256,8 @@
     method @CallSuper public void dump(@Nullable java.io.FileDescriptor, @Nullable java.io.PrintWriter, @Nullable String[]);
     method @Nullable public android.car.oem.OemCarAudioFocusService getOemAudioFocusService();
     method @NonNull public abstract android.car.CarVersion getSupportedCarVersion();
-    method public abstract boolean isOemServiceReady();
     method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
-    method @CallSuper public void onCarServiceReady();
+    method public abstract void onCarServiceReady();
     method public final int onStartCommand(@Nullable android.content.Intent, int, int);
   }
 
diff --git a/car-lib/api/current.txt b/car-lib/api/current.txt
index 97a17f9..b85d2d3 100644
--- a/car-lib/api/current.txt
+++ b/car-lib/api/current.txt
@@ -316,6 +316,7 @@
     field @RequiresPermission(android.car.Car.PERMISSION_POWERTRAIN) public static final int CURRENT_GEAR = 289408001; // 0x11400401
     field @RequiresPermission("android.car.permission.CAR_POWER") public static final int DISPLAY_BRIGHTNESS = 289409539; // 0x11400a03
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_DISPLAY_UNITS)) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(allOf={android.car.Car.PERMISSION_CONTROL_DISPLAY_UNITS, "android.car.permission.CAR_VENDOR_EXTENSION"})) public static final int DISTANCE_DISPLAY_UNITS = 289408512; // 0x11400600
+    field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_CHILD_LOCK_ENABLED = 371198723; // 0x16200b03
     field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_LOCK = 371198722; // 0x16200b02
     field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_MOVE = 373295873; // 0x16400b01
     field @RequiresPermission("android.car.permission.CONTROL_CAR_DOORS") public static final int DOOR_POS = 373295872; // 0x16400b00
@@ -443,7 +444,8 @@
     field @RequiresPermission("android.car.permission.CONTROL_CAR_SEATS") public static final int SEAT_OCCUPANCY = 356518832; // 0x15400bb0
     field @RequiresPermission("android.car.permission.CONTROL_CAR_SEATS") public static final int SEAT_TILT_MOVE = 356518800; // 0x15400b90
     field @RequiresPermission("android.car.permission.CONTROL_CAR_SEATS") public static final int SEAT_TILT_POS = 356518799; // 0x15400b8f
-    field @RequiresPermission("android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED") public static final int STORAGE_ENCRYPTION_BINDING_SEED = 292554247; // 0x11700607
+    field @RequiresPermission("android.car.permission.CONTROL_STEERING_WHEEL") public static final int STEERING_WHEEL_DEPTH_MOVE = 289410017; // 0x11400be1
+    field @RequiresPermission("android.car.permission.CONTROL_STEERING_WHEEL") public static final int STEERING_WHEEL_DEPTH_POS = 289410016; // 0x11400be0
     field @RequiresPermission("android.car.permission.CAR_TIRES") public static final int TIRE_PRESSURE = 392168201; // 0x17600309
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_DISPLAY_UNITS)) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(allOf={android.car.Car.PERMISSION_CONTROL_DISPLAY_UNITS, "android.car.permission.CAR_VENDOR_EXTENSION"})) public static final int TIRE_PRESSURE_DISPLAY_UNITS = 289408514; // 0x11400602
     field @RequiresPermission("android.car.permission.CAR_DYNAMICS_STATE") public static final int TRACTION_CONTROL_ACTIVE = 287310859; // 0x1120040b
diff --git a/car-lib/api/system-current.txt b/car-lib/api/system-current.txt
index 6082e2a..c9aefd1 100644
--- a/car-lib/api/system-current.txt
+++ b/car-lib/api/system-current.txt
@@ -68,6 +68,7 @@
     field public static final String PERMISSION_CONTROL_EXTERIOR_LIGHTS = "android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS";
     field public static final String PERMISSION_CONTROL_REMOTE_ACCESS = "android.car.permission.CONTROL_REMOTE_ACCESS";
     field public static final String PERMISSION_CONTROL_SHUTDOWN_PROCESS = "android.car.permission.CONTROL_SHUTDOWN_PROCESS";
+    field public static final String PERMISSION_CONTROL_STEERING_WHEEL = "android.car.permission.CONTROL_STEERING_WHEEL";
     field public static final String PERMISSION_EXTERIOR_LIGHTS = "android.car.permission.CAR_EXTERIOR_LIGHTS";
     field public static final String PERMISSION_MANAGE_OCCUPANT_ZONE = "android.car.permission.MANAGE_OCCUPANT_ZONE";
     field public static final String PERMISSION_MANAGE_THREAD_PRIORITY = "android.car.permission.MANAGE_THREAD_PRIORITY";
@@ -78,7 +79,6 @@
     field public static final String PERMISSION_READ_CAR_VENDOR_PERMISSION_INFO = "android.car.permission.READ_CAR_VENDOR_PERMISSION_INFO";
     field public static final String PERMISSION_RECEIVE_CAR_AUDIO_DUCKING_EVENTS = "android.car.permission.RECEIVE_CAR_AUDIO_DUCKING_EVENTS";
     field public static final String PERMISSION_REQUEST_CAR_EVS_ACTIVITY = "android.car.permission.REQUEST_CAR_EVS_ACTIVITY";
-    field public static final String PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED = "android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED";
     field public static final String PERMISSION_STORAGE_MONITORING = "android.car.permission.STORAGE_MONITORING";
     field public static final String PERMISSION_TEMPLATE_RENDERER = "android.car.permission.TEMPLATE_RENDERER";
     field public static final String PERMISSION_TIRES = "android.car.permission.CAR_TIRES";
@@ -1247,8 +1247,8 @@
   }
 
   public interface OemCarAudioFocusService extends android.car.oem.OemCarServiceComponent {
-    method public void audioFocusChanged(@NonNull java.util.List<android.media.AudioFocusInfo>, @NonNull java.util.List<android.media.AudioFocusInfo>, int);
     method @NonNull public android.car.oem.OemCarAudioFocusResult evaluateAudioFocusRequest(@NonNull android.car.oem.OemCarAudioFocusEvaluationRequest);
+    method public void notifyAudioFocusChange(@NonNull java.util.List<android.media.AudioFocusInfo>, @NonNull java.util.List<android.media.AudioFocusInfo>, int);
   }
 
   public abstract class OemCarService extends android.app.Service {
@@ -1256,9 +1256,8 @@
     method @CallSuper public void dump(@Nullable java.io.FileDescriptor, @Nullable java.io.PrintWriter, @Nullable String[]);
     method @Nullable public android.car.oem.OemCarAudioFocusService getOemAudioFocusService();
     method @NonNull public abstract android.car.CarVersion getSupportedCarVersion();
-    method public abstract boolean isOemServiceReady();
     method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
-    method @CallSuper public void onCarServiceReady();
+    method public abstract void onCarServiceReady();
     method public final int onStartCommand(@Nullable android.content.Intent, int, int);
   }
 
diff --git a/car-lib/api/test-current.txt b/car-lib/api/test-current.txt
index 7fa8931..5e269b1 100644
--- a/car-lib/api/test-current.txt
+++ b/car-lib/api/test-current.txt
@@ -68,6 +68,7 @@
     field public static final String PERMISSION_CONTROL_EXTERIOR_LIGHTS = "android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS";
     field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.UPSIDE_DOWN_CAKE_0) public static final String PERMISSION_CONTROL_REMOTE_ACCESS = "android.car.permission.CONTROL_REMOTE_ACCESS";
     field public static final String PERMISSION_CONTROL_SHUTDOWN_PROCESS = "android.car.permission.CONTROL_SHUTDOWN_PROCESS";
+    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public static final String PERMISSION_CONTROL_STEERING_WHEEL = "android.car.permission.CONTROL_STEERING_WHEEL";
     field public static final String PERMISSION_EXTERIOR_LIGHTS = "android.car.permission.CAR_EXTERIOR_LIGHTS";
     field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.UPSIDE_DOWN_CAKE_0) public static final String PERMISSION_MANAGE_OCCUPANT_ZONE = "android.car.permission.MANAGE_OCCUPANT_ZONE";
     field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_1) public static final String PERMISSION_MANAGE_THREAD_PRIORITY = "android.car.permission.MANAGE_THREAD_PRIORITY";
@@ -78,7 +79,6 @@
     field public static final String PERMISSION_READ_CAR_VENDOR_PERMISSION_INFO = "android.car.permission.READ_CAR_VENDOR_PERMISSION_INFO";
     field public static final String PERMISSION_RECEIVE_CAR_AUDIO_DUCKING_EVENTS = "android.car.permission.RECEIVE_CAR_AUDIO_DUCKING_EVENTS";
     field public static final String PERMISSION_REQUEST_CAR_EVS_ACTIVITY = "android.car.permission.REQUEST_CAR_EVS_ACTIVITY";
-    field public static final String PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED = "android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED";
     field public static final String PERMISSION_STORAGE_MONITORING = "android.car.permission.STORAGE_MONITORING";
     field public static final String PERMISSION_TEMPLATE_RENDERER = "android.car.permission.TEMPLATE_RENDERER";
     field public static final String PERMISSION_TIRES = "android.car.permission.CAR_TIRES";
@@ -1251,92 +1251,91 @@
 
 package android.car.oem {
 
-  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final class AudioFocusEntry implements android.os.Parcelable {
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int describeContents();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioContextId();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.media.AudioFocusInfo getAudioFocusInfo();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioFocusResult();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioVolumeGroupId();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.os.Parcelable.Creator<android.car.oem.AudioFocusEntry> CREATOR;
+  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final class AudioFocusEntry implements android.os.Parcelable {
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int describeContents();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioContextId();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.media.AudioFocusInfo getAudioFocusInfo();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioFocusResult();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioVolumeGroupId();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.os.Parcelable.Creator<android.car.oem.AudioFocusEntry> CREATOR;
   }
 
-  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public static final class AudioFocusEntry.Builder {
+  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public static final class AudioFocusEntry.Builder {
     ctor public AudioFocusEntry.Builder(@NonNull android.media.AudioFocusInfo, int, int, int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry build();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioContextId(int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioFocusInfo(@NonNull android.media.AudioFocusInfo);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioFocusResult(int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioVolumeGroupId(int);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry build();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioContextId(int);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioFocusInfo(@NonNull android.media.AudioFocusInfo);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioFocusResult(int);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.AudioFocusEntry.Builder setAudioVolumeGroupId(int);
   }
 
-  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final class OemCarAudioFocusEvaluationRequest implements android.os.Parcelable {
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int describeContents();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @Nullable public android.car.oem.AudioFocusEntry getAudioFocusRequest();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioZoneId();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getFocusHolders();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getFocusLosers();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.media.CarVolumeGroupInfo> getMutedVolumeGroups();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.os.Parcelable.Creator<android.car.oem.OemCarAudioFocusEvaluationRequest> CREATOR;
+  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final class OemCarAudioFocusEvaluationRequest implements android.os.Parcelable {
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int describeContents();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @Nullable public android.car.oem.AudioFocusEntry getAudioFocusRequest();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioZoneId();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getFocusHolders();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getFocusLosers();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.media.CarVolumeGroupInfo> getMutedVolumeGroups();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.os.Parcelable.Creator<android.car.oem.OemCarAudioFocusEvaluationRequest> CREATOR;
   }
 
-  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public static final class OemCarAudioFocusEvaluationRequest.Builder {
+  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public static final class OemCarAudioFocusEvaluationRequest.Builder {
     ctor public OemCarAudioFocusEvaluationRequest.Builder(@NonNull java.util.List<android.car.media.CarVolumeGroupInfo>, @NonNull java.util.List<android.car.oem.AudioFocusEntry>, @NonNull java.util.List<android.car.oem.AudioFocusEntry>, int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder addFocusHolders(@NonNull android.car.oem.AudioFocusEntry);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder addFocusLosers(@NonNull android.car.oem.AudioFocusEntry);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder addMutedVolumeGroups(@NonNull android.car.media.CarVolumeGroupInfo);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest build();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setAudioFocusRequest(@NonNull android.car.oem.AudioFocusEntry);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setAudioZoneId(int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setFocusHolders(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setFocusLosers(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setMutedVolumeGroups(@NonNull java.util.List<android.car.media.CarVolumeGroupInfo>);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder addFocusHolders(@NonNull android.car.oem.AudioFocusEntry);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder addFocusLosers(@NonNull android.car.oem.AudioFocusEntry);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder addMutedVolumeGroups(@NonNull android.car.media.CarVolumeGroupInfo);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest build();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setAudioFocusRequest(@NonNull android.car.oem.AudioFocusEntry);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setAudioZoneId(int);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setFocusHolders(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setFocusLosers(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusEvaluationRequest.Builder setMutedVolumeGroups(@NonNull java.util.List<android.car.media.CarVolumeGroupInfo>);
   }
 
-  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final class OemCarAudioFocusResult implements android.os.Parcelable {
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int describeContents();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @Nullable public android.car.oem.AudioFocusEntry getAudioFocusEntry();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioFocusResult();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getNewlyBlockedAudioFocusEntries();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getNewlyLossAudioFocusEntries();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.os.Parcelable.Creator<android.car.oem.OemCarAudioFocusResult> CREATOR;
-    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.car.oem.OemCarAudioFocusResult EMPTY_OEM_CAR_AUDIO_FOCUS_RESULTS;
+  @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final class OemCarAudioFocusResult implements android.os.Parcelable {
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int describeContents();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @Nullable public android.car.oem.AudioFocusEntry getAudioFocusEntry();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public int getAudioFocusResult();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getNewlyBlockedAudioFocusEntries();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public java.util.List<android.car.oem.AudioFocusEntry> getNewlyLossAudioFocusEntries();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.os.Parcelable.Creator<android.car.oem.OemCarAudioFocusResult> CREATOR;
+    field @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public static final android.car.oem.OemCarAudioFocusResult EMPTY_OEM_CAR_AUDIO_FOCUS_RESULTS;
   }
 
   public static final class OemCarAudioFocusResult.Builder {
     ctor public OemCarAudioFocusResult.Builder(@NonNull java.util.List<android.car.oem.AudioFocusEntry>, @NonNull java.util.List<android.car.oem.AudioFocusEntry>, int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder addNewlyBlockedAudioFocusEntry(@NonNull android.car.oem.AudioFocusEntry);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder addNewlyLossAudioFocusEntry(@NonNull android.car.oem.AudioFocusEntry);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult build();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setAudioFocusEntry(@NonNull android.car.oem.AudioFocusEntry);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setAudioFocusResult(int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setNewlyBlockedAudioFocusEntries(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_1, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setNewlyLossAudioFocusEntries(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder addNewlyBlockedAudioFocusEntry(@NonNull android.car.oem.AudioFocusEntry);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder addNewlyLossAudioFocusEntry(@NonNull android.car.oem.AudioFocusEntry);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult build();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setAudioFocusEntry(@NonNull android.car.oem.AudioFocusEntry);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setAudioFocusResult(int);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setNewlyBlockedAudioFocusEntries(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult.Builder setNewlyLossAudioFocusEntries(@NonNull java.util.List<android.car.oem.AudioFocusEntry>);
   }
 
   public interface OemCarAudioFocusService extends android.car.oem.OemCarServiceComponent {
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void audioFocusChanged(@NonNull java.util.List<android.media.AudioFocusInfo>, @NonNull java.util.List<android.media.AudioFocusInfo>, int);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult evaluateAudioFocusRequest(@NonNull android.car.oem.OemCarAudioFocusEvaluationRequest);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public android.car.oem.OemCarAudioFocusResult evaluateAudioFocusRequest(@NonNull android.car.oem.OemCarAudioFocusEvaluationRequest);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void notifyAudioFocusChange(@NonNull java.util.List<android.media.AudioFocusInfo>, @NonNull java.util.List<android.media.AudioFocusInfo>, int);
   }
 
   public abstract class OemCarService extends android.app.Service {
     ctor public OemCarService();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @CallSuper public void dump(@Nullable java.io.FileDescriptor, @Nullable java.io.PrintWriter, @Nullable String[]);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @Nullable public android.car.oem.OemCarAudioFocusService getOemAudioFocusService();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public abstract android.car.CarVersion getSupportedCarVersion();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public abstract boolean isOemServiceReady();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @CallSuper public void onCarServiceReady();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final int onStartCommand(@Nullable android.content.Intent, int, int);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @CallSuper public void dump(@Nullable java.io.FileDescriptor, @Nullable java.io.PrintWriter, @Nullable String[]);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @Nullable public android.car.oem.OemCarAudioFocusService getOemAudioFocusService();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public abstract android.car.CarVersion getSupportedCarVersion();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public abstract void onCarServiceReady();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public final int onStartCommand(@Nullable android.content.Intent, int, int);
   }
 
   public interface OemCarServiceComponent {
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void dump(@Nullable java.io.PrintWriter, @Nullable String[]);
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void init();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void onCarServiceReady();
-    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void release();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void dump(@Nullable java.io.PrintWriter, @Nullable String[]);
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void init();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void onCarServiceReady();
+    method @android.car.annotation.ApiRequirements(minCarVersion=android.car.annotation.ApiRequirements.CarVersion.TIRAMISU_2, minPlatformVersion=android.car.annotation.ApiRequirements.PlatformVersion.TIRAMISU_0) public void release();
   }
 
 }
diff --git a/car-lib/src/android/car/Car.java b/car-lib/src/android/car/Car.java
index f366d00..cccebe0 100644
--- a/car-lib/src/android/car/Car.java
+++ b/car-lib/src/android/car/Car.java
@@ -744,16 +744,6 @@
     public static final String PERMISSION_CAR_EPOCH_TIME = "android.car.permission.CAR_EPOCH_TIME";
 
     /**
-     * Permission necessary to access car's property
-     * {@link VehiclePropertyIds#STORAGE_ENCRYPTION_BINDING_SEED}.
-     * @hide
-     */
-    @SystemApi
-    @AddedInOrBefore(majorVersion = 33)
-    public static final String PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED =
-            "android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED";
-
-    /**
      * Permission necessary to access car's steering angle information.
      */
     @AddedInOrBefore(majorVersion = 33)
@@ -1180,7 +1170,15 @@
             minPlatformVersion = ApiRequirements.PlatformVersion.UPSIDE_DOWN_CAKE_0)
     public static final String PERMISSION_CONTROL_REMOTE_ACCESS =
             "android.car.permission.CONTROL_REMOTE_ACCESS";
-
+    /**
+     * Permission necessary to control car's steering wheel.
+     * @hide
+     */
+    @SystemApi
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+            minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
+    public static final String PERMISSION_CONTROL_STEERING_WHEEL =
+            "android.car.permission.CONTROL_STEERING_WHEEL";
     /**
      * Intent for connecting to the template renderer. Services that handle this intent must also
      * hold {@link #PERMISSION_TEMPLATE_RENDERER}. Applications would not bind to this service
diff --git a/car-lib/src/android/car/VehiclePropertyIds.java b/car-lib/src/android/car/VehiclePropertyIds.java
index c274b02..f8a3482 100644
--- a/car-lib/src/android/car/VehiclePropertyIds.java
+++ b/car-lib/src/android/car/VehiclePropertyIds.java
@@ -1344,6 +1344,30 @@
     @AddedInOrBefore(majorVersion = 33)
     public static final int DOOR_LOCK = 371198722;
     /**
+     * Door child lock feature enabled
+     *
+     * <p>Returns true if the door child lock feature is enabled and false if it is disabled.
+     * If enabled, the door is unable to be opened from the inside.
+     *
+     * <p>Property Config:
+     * <ul>
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ_WRITE}
+     *  <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_DOOR}
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE}
+     *  <li>{@code Boolean} property type
+     * </ul>
+     *
+     * <p>Required Permission:
+     * <ul>
+     *  <li>Privileged|Signature permission {@link Car#PERMISSION_CONTROL_CAR_DOORS} to read
+     *  and write property.
+     * </ul>
+     */
+    @RequiresPermission(Car.PERMISSION_CONTROL_CAR_DOORS)
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
+    public static final int DOOR_CHILD_LOCK_ENABLED = 371198723;
+    /**
      * Mirror Z Position
      * The property is protected by the signature permission:
      * android.car.permission.CONTROL_CAR_MIRRORS.
@@ -1652,6 +1676,61 @@
     @AddedInOrBefore(majorVersion = 33)
     public static final int WINDOW_LOCK = 320867268;
     /**
+     * Steering wheel depth position
+     *
+     * <p>Returns how close the steering wheel is to the driver. This value is not in any
+     * particular unit but in a specified range of steps. The max value indicates the wheel
+     * position closest to the driver. See {@link CarPropertyConfig#getMaxValue(int)} and
+     * {@link CarPropertyConfig#getMinValue(int)} for the range of possible positions.
+     *
+     * <p>Property Config:
+     * <ul>
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ_WRITE}
+     *  <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL}
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE}
+     *  <li>{@code Integer} property type
+     * </ul>
+     *
+     * <p>Required Permission:
+     * <ul>
+     *  <li>Privileged|Signature permission {@link Car#PERMISSION_CONTROL_STEERING_WHEEL} to read
+     *  and write property.
+     * </ul>
+     */
+    @RequiresPermission(Car.PERMISSION_CONTROL_STEERING_WHEEL)
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
+    public static final int STEERING_WHEEL_DEPTH_POS = 289410016;
+    /**
+     * Steering wheel depth movement
+     *
+     * <p>Returns the speed and direction, either towards or away from the driver, that the
+     * steering wheel is moving in. This value is not in any particular unit but in a specified
+     * range of steps. Positive values mean moving towards the driver and negative values mean
+     * moving away from the driver. Larger integers, either positive or negative, indicate a
+     * faster speed. Once the steering wheel reaches the positional limit, the value resets to 0.
+     * See {@link CarPropertyConfig#getMaxValue(int)} and {@link CarPropertyConfig#getMinValue(int)}
+     * for the range of possible values.
+     *
+     * <p>Property Config:
+     * <ul>
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ_WRITE}
+     *  <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL}
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE}
+     *  <li>{@code Integer} property type
+     * </ul>
+     *
+     * <p>Required Permission:
+     * <ul>
+     *  <li>Privileged|Signature permission {@link Car#PERMISSION_CONTROL_STEERING_WHEEL} to read
+     *  and write property.
+     * </ul>
+     */
+    @RequiresPermission(Car.PERMISSION_CONTROL_STEERING_WHEEL)
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
+    public static final int STEERING_WHEEL_DEPTH_MOVE = 289410017;
+    /**
      * Vehicle Maps Service (VMS) message
      * The property is protected by the signature permissions:
      * android.car.permission.VMS_PUBLISHER and android.car.permission.VMS_SUBSCRIBER.
@@ -2011,18 +2090,6 @@
     public static final int EPOCH_TIME = 290457094;
 
     /**
-     * External encryption binding seed.
-     *
-     * <p>This value is mixed with the local storage encryption seed. This property holds 16 bytes,
-     * and is expected to be persisted on an ECU separate from the IVI. The property is initially
-     * set by AAOS, who generates it using a CSRNG. AAOS will then read the property on subsequent
-     * boots.
-     */
-    @RequiresPermission(Car.PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED)
-    @AddedInOrBefore(majorVersion = 33)
-    public static final int STORAGE_ENCRYPTION_BINDING_SEED = 292554247;
-
-    /**
      * Electronic Toll Collection card type.
      *
      * <p>This property indicates the type of ETC(Electronic Toll Collection) card in the vehicle.
diff --git a/car-lib/src/android/car/drivingstate/CarUxRestrictionsConfiguration.java b/car-lib/src/android/car/drivingstate/CarUxRestrictionsConfiguration.java
index 827c35a..424bf30 100644
--- a/car-lib/src/android/car/drivingstate/CarUxRestrictionsConfiguration.java
+++ b/car-lib/src/android/car/drivingstate/CarUxRestrictionsConfiguration.java
@@ -592,7 +592,7 @@
 
         CarUxRestrictionsConfiguration other = (CarUxRestrictionsConfiguration) obj;
 
-        return mPhysicalPort == other.mPhysicalPort
+        return Objects.equals(mPhysicalPort, other.mPhysicalPort)
                 && hasSameParameters(other)
                 && mRestrictionModes.equals(other.mRestrictionModes);
     }
diff --git a/car-lib/src/android/car/oem/AudioFocusEntry.java b/car-lib/src/android/car/oem/AudioFocusEntry.java
index d61edd1..931518d 100644
--- a/car-lib/src/android/car/oem/AudioFocusEntry.java
+++ b/car-lib/src/android/car/oem/AudioFocusEntry.java
@@ -28,7 +28,7 @@
  * @hide
  */
 @SystemApi
-@ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+@ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
         minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
 public final class AudioFocusEntry implements Parcelable {
 
@@ -52,7 +52,7 @@
     /**
      * Returns the audio focus info
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @NonNull AudioFocusInfo getAudioFocusInfo() {
         return mAudioFocusInfo;
@@ -61,7 +61,7 @@
     /**
      * Returns the caudio context as evaluated from the audio attributes
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int getAudioContextId() {
         return mAudioContextId;
@@ -70,7 +70,7 @@
     /**
      * Returns the volume group as evaluated from the audio attributes
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int getAudioVolumeGroupId() {
         return mAudioVolumeGroupId;
@@ -81,14 +81,14 @@
      * {@link AudioManager.AUDIOFOCUS_LOSS}, {@link AudioManager.AUDIOFOCUS_LOSS_TRANSIENT},
      * {@link AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}
      **/
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int getAudioFocusResult() {
         return mAudioFocusResult;
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public String toString() {
         return new StringBuilder().append("AudioFocusEntry { audioFocusInfo = ")
@@ -110,7 +110,7 @@
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
         dest.writeTypedObject(mAudioFocusInfo, flags);
@@ -120,7 +120,7 @@
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int describeContents() {
         return 0;
@@ -140,7 +140,7 @@
         mAudioFocusResult = focusResult;
     }
 
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     @NonNull
     public static final Parcelable.Creator<AudioFocusEntry> CREATOR =
@@ -160,7 +160,7 @@
      * A builder for {@link AudioFocusEntry}
      */
     @SuppressWarnings("WeakerAccess")
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public static final class Builder {
 
@@ -184,7 +184,7 @@
         }
 
         /** see {@link AudioFocusEntry#getAudioFocusInfo()} */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder setAudioFocusInfo(@NonNull AudioFocusInfo value) {
             checkNotUsed();
@@ -194,7 +194,7 @@
         }
 
         /** see {@link AudioFocusEntry#getAudioContextId()} */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder setAudioContextId(int value) {
             checkNotUsed();
@@ -204,7 +204,7 @@
         }
 
         /** see {@link AudioFocusEntry#getAudioVolumeGroupId()} */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder setAudioVolumeGroupId(int value) {
             checkNotUsed();
@@ -214,7 +214,7 @@
         }
 
         /** see {@link AudioFocusEntry#getAudioFocusResult()} */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder setAudioFocusResult(int value) {
             checkNotUsed();
@@ -224,7 +224,7 @@
         }
 
         /** Builds the instance. This builder should not be touched after calling this! */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull AudioFocusEntry build() {
             checkNotUsed();
diff --git a/car-lib/src/android/car/oem/IOemCarAudioFocusService.aidl b/car-lib/src/android/car/oem/IOemCarAudioFocusService.aidl
index e5be1cc..914db8a 100644
--- a/car-lib/src/android/car/oem/IOemCarAudioFocusService.aidl
+++ b/car-lib/src/android/car/oem/IOemCarAudioFocusService.aidl
@@ -22,7 +22,7 @@
 
 /** @hide */
 interface IOemCarAudioFocusService {
-    void audioFocusChanged(in List<AudioFocusInfo> currentFocusHolders,
+    oneway void notifyAudioFocusChange(in List<AudioFocusInfo> currentFocusHolders,
            in List<AudioFocusInfo> currentFocusLosers, int zoneId);
 
     OemCarAudioFocusResult evaluateAudioFocusRequest(in
diff --git a/car-lib/src/android/car/oem/IOemCarService.aidl b/car-lib/src/android/car/oem/IOemCarService.aidl
index f722a4a..ffc7125 100644
--- a/car-lib/src/android/car/oem/IOemCarService.aidl
+++ b/car-lib/src/android/car/oem/IOemCarService.aidl
@@ -37,16 +37,16 @@
     void onCarServiceReady(in IOemCarServiceCallback callback);
 
     /*
-     * This is to check if OEM service is ready. This callback should have returned within limited
-     * time else CarService and OemService would be crashed.
+     * Gets the supported CarVersion for the OEM service. It is possible that CarModule is updated
+     * but OEM service is not updated. CarService needs to be aware of that.
      */
-    boolean isOemServiceReady();
+    CarVersion getSupportedCarVersion();
 
     /*
      * Gets the supported CarVersion for the OEM service. It is possible that CarModule is updated
      * but OEM service is not updated. CarService needs to be aware of that.
      */
-    CarVersion getSupportedCarVersion();
+    String getAllStackTraces();
 
     // Component services
     IOemCarAudioFocusService getOemAudioFocusService();
diff --git a/car-lib/src/android/car/oem/OemCarAudioFocusEvaluationRequest.java b/car-lib/src/android/car/oem/OemCarAudioFocusEvaluationRequest.java
index 08ee6de..841504f 100644
--- a/car-lib/src/android/car/oem/OemCarAudioFocusEvaluationRequest.java
+++ b/car-lib/src/android/car/oem/OemCarAudioFocusEvaluationRequest.java
@@ -38,7 +38,7 @@
  * @hide
  */
 @SystemApi
-@ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+@ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
         minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
 public final class OemCarAudioFocusEvaluationRequest implements Parcelable {
 
@@ -65,7 +65,7 @@
         mAudioZoneId = in.readInt();
     }
 
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     @NonNull
     public static final Creator<OemCarAudioFocusEvaluationRequest> CREATOR =
@@ -84,7 +84,7 @@
 
     @Override
     @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE)
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int describeContents() {
         return 0;
@@ -92,7 +92,7 @@
 
     @Override
     @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE)
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         byte flg = 0;
@@ -112,7 +112,7 @@
     /**
      * Returns the audio zone id for the request
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int getAudioZoneId() {
         return mAudioZoneId;
@@ -123,7 +123,7 @@
      * in cases where the audio focus info is null
      * the request is to re-evaluate current focus holder and losers.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @Nullable AudioFocusEntry getAudioFocusRequest() {
         return mAudioFocusRequest;
@@ -132,7 +132,7 @@
     /**
      * Returns the currently muted volume groups
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @NonNull List<CarVolumeGroupInfo> getMutedVolumeGroups() {
         return mMutedVolumeGroups;
@@ -141,7 +141,7 @@
     /**
      * Returns the current focus holder
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @NonNull List<AudioFocusEntry> getFocusHolders() {
         return mFocusHolders;
@@ -150,7 +150,7 @@
     /**
      * Returns the current focus losers (.i.e focus request that have transiently lost focus)
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @NonNull List<AudioFocusEntry> getFocusLosers() {
         return mFocusLosers;
@@ -172,7 +172,7 @@
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public String toString() {
         return new StringBuilder().append("OemCarAudioFocusEvaluationRequest {audioZoneId = ")
@@ -187,7 +187,7 @@
      * A builder for {@link OemCarAudioFocusEvaluationRequest}
      */
     @SuppressWarnings("WeakerAccess")
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public static final class Builder {
 
@@ -226,7 +226,7 @@
         /**
          * set the audio zone id
          */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder setAudioZoneId(int value) {
             checkNotUsed();
@@ -238,7 +238,7 @@
         /**
          * Sets the current focus info to evaluate
          */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder setAudioFocusRequest(@NonNull AudioFocusEntry audioFocusRequest) {
@@ -253,7 +253,7 @@
         /**
          * Sets the currently muted group volumes
          */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder setMutedVolumeGroups(
@@ -267,7 +267,7 @@
         }
 
         /** @see #setMutedVolumeGroups */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder addMutedVolumeGroups(@NonNull CarVolumeGroupInfo mutedVolumeGroup) {
             Preconditions.checkArgument(mutedVolumeGroup != null,
@@ -280,7 +280,7 @@
         /**
          * Sets the focus holders
          */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder setFocusHolders(@NonNull List<AudioFocusEntry> focusHolders) {
             Preconditions.checkArgument(focusHolders != null,
@@ -292,7 +292,7 @@
         }
 
         /** @see #setFocusHolders */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder addFocusHolders(@NonNull AudioFocusEntry focusHolder) {
             Preconditions.checkArgument(focusHolder != null,
@@ -305,7 +305,7 @@
         /**
          * Sets the focus losers
          */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder setFocusLosers(@NonNull List<AudioFocusEntry> focusLosers) {
             Preconditions.checkArgument(focusLosers != null,
@@ -317,7 +317,7 @@
         }
 
         /** @see #setFocusLosers */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         public @NonNull Builder addFocusLosers(@NonNull AudioFocusEntry focusLoser) {
             Preconditions.checkArgument(focusLoser != null,
@@ -328,7 +328,7 @@
         }
 
         /** Builds the instance. This builder should not be touched after calling this! */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public OemCarAudioFocusEvaluationRequest build() {
diff --git a/car-lib/src/android/car/oem/OemCarAudioFocusResult.java b/car-lib/src/android/car/oem/OemCarAudioFocusResult.java
index f5049a8..0d26032 100644
--- a/car-lib/src/android/car/oem/OemCarAudioFocusResult.java
+++ b/car-lib/src/android/car/oem/OemCarAudioFocusResult.java
@@ -36,7 +36,7 @@
  * @hide
  */
 @SystemApi
-@ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+@ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
         minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
 public final class OemCarAudioFocusResult implements Parcelable {
     private final @Nullable AudioFocusEntry mAudioFocusEntry;
@@ -66,7 +66,7 @@
      * re-evaluated once any of the current focus holders abandons focus. For failed request,
      * the car audio focus stack will not change and the current request will not gain focus.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @Nullable AudioFocusEntry getAudioFocusEntry() {
         return mAudioFocusEntry;
@@ -80,7 +80,7 @@
      * For transient losses, the new entry will be added as a blocker but will only receive
      * transient focus loss.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @NonNull List<AudioFocusEntry> getNewlyLossAudioFocusEntries() {
         return mNewlyLossAudioFocusEntries;
@@ -94,7 +94,7 @@
      * For transient losses, the new entry will be added as a blocker but will only receive
      * transient focus loss.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public @NonNull List<AudioFocusEntry> getNewlyBlockedAudioFocusEntries() {
         return mNewlyBlockedAudioFocusEntries;
@@ -105,14 +105,14 @@
      * {@link AudioManager.AUDIOFOCUS_LOSS}, {@link AudioManager.AUDIOFOCUS_LOSS_TRANSIENT},
      * {@link AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int getAudioFocusResult() {
         return mAudioFocusResult;
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public String toString() {
         return new StringBuilder().append("OemCarAudioFocusResult { audioFocusEntry = ")
@@ -125,7 +125,7 @@
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         byte flg = 0;
@@ -140,7 +140,7 @@
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public int describeContents() {
         return 0;
@@ -164,7 +164,7 @@
         this.mAudioFocusResult = audioFocusResult;
     }
 
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     @NonNull
     public static final OemCarAudioFocusResult EMPTY_OEM_CAR_AUDIO_FOCUS_RESULTS =
@@ -173,7 +173,7 @@
                     /* newlyBlockedAudioFocusEntries= */ new ArrayList<>(/* initialCapacity= */ 0),
                     AUDIOFOCUS_REQUEST_FAILED);
 
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     @NonNull
     public static final Parcelable.Creator<OemCarAudioFocusResult> CREATOR =
@@ -221,7 +221,7 @@
         }
 
         /** @see OemCarAudioFocusResult#getAudioFocusEntry */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder setAudioFocusEntry(@NonNull AudioFocusEntry focusEntry) {
@@ -234,7 +234,7 @@
         }
 
         /** @see OemCarAudioFocusResult#getNewlyLossAudioFocusEntries */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder setNewlyLossAudioFocusEntries(
@@ -248,7 +248,7 @@
         }
 
         /** @see #setNewlyLossAudioFocusEntries */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder addNewlyLossAudioFocusEntry(@NonNull AudioFocusEntry lossEntry) {
@@ -262,7 +262,7 @@
         }
 
         /** @see OemCarAudioFocusResult#getNewlyBlockedAudioFocusEntries */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder setNewlyBlockedAudioFocusEntries(
@@ -276,7 +276,7 @@
         }
 
         /** @see #setNewlyBlockedAudioFocusEntries */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder addNewlyBlockedAudioFocusEntry(
@@ -291,7 +291,7 @@
         }
 
         /** @see OemCarAudioFocusResult#getAudioFocusResult */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public Builder setAudioFocusResult(int audioFocusResult) {
@@ -301,7 +301,7 @@
         }
 
         /** Builds the instance. This builder should not be touched after calling this! */
-        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_1,
+        @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
                 minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
         @NonNull
         public OemCarAudioFocusResult build() {
diff --git a/car-lib/src/android/car/oem/OemCarAudioFocusService.java b/car-lib/src/android/car/oem/OemCarAudioFocusService.java
index cd05fa4..4537ba1 100644
--- a/car-lib/src/android/car/oem/OemCarAudioFocusService.java
+++ b/car-lib/src/android/car/oem/OemCarAudioFocusService.java
@@ -35,11 +35,11 @@
 @SystemApi
 public interface OemCarAudioFocusService extends OemCarServiceComponent {
     /**
-     * Updates audio focus change. It is one way call for OEM Service.
+     * Notifies of audio focus changes in car focus stack. It is one way call for OEM Service.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
-    void audioFocusChanged(@NonNull List<AudioFocusInfo> currentFocusHolders,
+    void notifyAudioFocusChange(@NonNull List<AudioFocusInfo> currentFocusHolders,
             @NonNull List<AudioFocusInfo> currentFocusLosers, int zoneId);
 
     /**
@@ -63,7 +63,7 @@
      * Everytime there is focus change the blocked entries will be re-evaluated to determine
      * which can regain, lose, or continue with block focus.
      **/
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     @NonNull
     OemCarAudioFocusResult evaluateAudioFocusRequest(
diff --git a/car-lib/src/android/car/oem/OemCarAudioFocusServiceImpl.java b/car-lib/src/android/car/oem/OemCarAudioFocusServiceImpl.java
index 117ab39..10395a2 100644
--- a/car-lib/src/android/car/oem/OemCarAudioFocusServiceImpl.java
+++ b/car-lib/src/android/car/oem/OemCarAudioFocusServiceImpl.java
@@ -40,16 +40,16 @@
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
-    public void audioFocusChanged(@NonNull List<AudioFocusInfo> currentFocusHolders,
+    public void notifyAudioFocusChange(@NonNull List<AudioFocusInfo> currentFocusHolders,
             @NonNull List<AudioFocusInfo> currentFocusLosers, int zoneId) {
-        mOemCarAudioFocusService.audioFocusChanged(currentFocusHolders, currentFocusLosers,
+        mOemCarAudioFocusService.notifyAudioFocusChange(currentFocusHolders, currentFocusLosers,
                 zoneId);
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     @NonNull
     public OemCarAudioFocusResult evaluateAudioFocusRequest(
diff --git a/car-lib/src/android/car/oem/OemCarService.java b/car-lib/src/android/car/oem/OemCarService.java
index 9d154e5..90c4057 100644
--- a/car-lib/src/android/car/oem/OemCarService.java
+++ b/car-lib/src/android/car/oem/OemCarService.java
@@ -36,8 +36,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Map;
 
-// TODO(b/241294844): Expose Slogf as system API and use it here.
 /**
  * This code will be running as part of the OEM Service. This provides basic implementation for OEM
  * Service. OEMs should extend this class and override relevant methods.
@@ -72,30 +72,45 @@
         }
 
         @Override
-        public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-            assertPermission();
-            OemCarService.this.dump(fd, writer, args);
-        }
-
-        @Override
         public void onCarServiceReady(IOemCarServiceCallback callback) throws RemoteException {
             assertPermission();
             OemCarService.this.onCarServiceReady();
+            synchronized (mLock) {
+                for (int i = 0; i < mOemCarServiceComponents.size(); i++) {
+                    if (DBG) {
+                        Slogf.d(TAG, "Calling onCarServiceReady for %s\n",
+                                mOemCarServiceComponents.keyAt(i).getSimpleName());
+                    }
+                    mOemCarServiceComponents.valueAt(i).onCarServiceReady();
+                }
+            }
             callback.sendOemCarServiceReady();
         }
 
         @Override
-        public boolean isOemServiceReady() {
-            assertPermission();
-            return OemCarService.this.isOemServiceReady();
-        }
-
-        @Override
         public CarVersion getSupportedCarVersion() {
             assertPermission();
             return OemCarService.this.getSupportedCarVersion();
         }
 
+        @Override
+        public String getAllStackTraces() {
+            assertPermission();
+            Map<Thread, StackTraceElement[]> tracesMap = Thread.getAllStackTraces();
+            StringBuilder sb = new StringBuilder();
+            sb.append("OemService stack trace:\n");
+            int i = 0;
+            for (Map.Entry<Thread, StackTraceElement[]> entry : tracesMap.entrySet()) {
+                sb.append("Thread: ").append(i++).append('\n');
+                StackTraceElement[] stack = entry.getValue();
+                for (int j = 0; j < stack.length; j++) {
+                    sb.append(stack[j].toString()).append('\n');
+                }
+            }
+
+            return sb.toString();
+        }
+
         private void assertPermission() {
             if (checkCallingPermission(
                     PERMISSION_BIND_OEM_CAR_SERVICE) != PackageManager.PERMISSION_GRANTED) {
@@ -107,12 +122,15 @@
         }
     };
 
+
     /**
      * {@inheritDoc}
+     *
      * <p>
-     * OEM should override this method and do the initialization. OEM should also call super as this
-     * method would call {@link OemCarServiceComponent#init()} for each component implemented by
-     * OEM.
+     * OEM should override this method and do the initialization. OEM should also call super after
+     * initialization as this method would call {@link OemCarServiceComponent#init()} for each
+     * component implemented by OEM.
+     *
      * <p>
      * Car Service will not be available at the time of this initialization. If the OEM needs
      * anything from CarService, they should wait for the CarServiceReady() call. It is expected
@@ -120,13 +138,12 @@
      */
     @Override
     @CallSuper
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public void onCreate() {
         if (DBG) {
             Slogf.d(TAG, "OnCreate");
         }
-        super.onCreate();
 
         // Create all components
         OemCarAudioFocusService oemCarAudioFocusService = getOemAudioFocusService();
@@ -138,27 +155,32 @@
 
             // Initialize them
             for (int i = 0; i < mOemCarServiceComponents.size(); i++) {
+                if (DBG) {
+                    Slogf.d(TAG, "Initializing %s\n",
+                            mOemCarServiceComponents.keyAt(i).getSimpleName());
+                }
                 mOemCarServiceComponents.valueAt(i).init();
             }
         }
+        super.onCreate();
     }
 
     /**
      * {@inheritDoc}
+     *
      * <p>
      * OEM should override this method and do all the resources deallocation. OEM should also call
-     * super as this method would call {@link OemCarServiceComponent#release()} for each component
-     * implemented by OEM.
+     * super after resource deallocation as this method would call
+     * {@link OemCarServiceComponent#release()} for each component implemented by OEM.
      */
     @Override
     @CallSuper
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public void onDestroy() {
         if (DBG) {
             Slogf.d(TAG, "OnDestroy");
         }
-        super.onDestroy();
 
         // Destroy all components and release the resources
         synchronized (mLock) {
@@ -166,10 +188,12 @@
                 mOemCarServiceComponents.valueAt(i).release();
             }
         }
+
+        super.onDestroy();
     }
 
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public final int onStartCommand(@Nullable Intent intent, int flags, int startId) {
         if (DBG) {
@@ -180,7 +204,7 @@
 
     @NonNull
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public final IBinder onBind(@Nullable Intent intent) {
         if (DBG) {
@@ -196,7 +220,7 @@
      */
     @Nullable
     @SuppressWarnings("[OnNameExpected]")
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public OemCarAudioFocusService getOemAudioFocusService() {
         if (DBG) {
@@ -205,16 +229,9 @@
         return null;
     }
 
-    /**
-     * Dumps OEM Car Service.
-     * <p>
-     * OEM should override this method to dump. OEM should also call super as this method would call
-     * {@link OemCarServiceComponent#dump(FileDescriptor, PrintWriter, String[])} for each component
-     * implemented by OEM.
-     */
     @CallSuper
     @Override
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public void dump(@Nullable FileDescriptor fd, @Nullable PrintWriter writer,
             @Nullable String[] args) {
@@ -227,41 +244,21 @@
     }
 
     /**
-     * Checks if OEM service is ready. OEM service must be ready within certain time.
-     */
-    @SuppressWarnings("[OnNameExpected]")
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
-            minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
-    public abstract boolean isOemServiceReady();
-
-    /**
      * Checks the supported CarVersion by the OEM service.
      */
     @SuppressWarnings("[OnNameExpected]")
     @NonNull
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     public abstract CarVersion getSupportedCarVersion();
 
     /**
      * Informs OEM service that CarService is now ready for communication.
+     *
      * <p>
-     * OEM should override this method and do the necessary initialization depending on CarService.
-     * OEM should also call super as this method would call
-     * {@link OemCarServiceComponent#onCarServiceReady()} for each component implemented by OEM.
+     * OEM should override this method if there is any initialization depending on CarService.
      */
-    @CallSuper
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
-    public void onCarServiceReady() {
-        if (DBG) {
-            Slogf.d(TAG, "onCarServiceReady");
-        }
-
-        synchronized (mLock) {
-            for (int i = 0; i < mOemCarServiceComponents.size(); i++) {
-                mOemCarServiceComponents.valueAt(i).onCarServiceReady();
-            }
-        }
-    }
+    public abstract void onCarServiceReady();
 }
diff --git a/car-lib/src/android/car/oem/OemCarServiceComponent.java b/car-lib/src/android/car/oem/OemCarServiceComponent.java
index 0fe6361..e0e5960 100644
--- a/car-lib/src/android/car/oem/OemCarServiceComponent.java
+++ b/car-lib/src/android/car/oem/OemCarServiceComponent.java
@@ -38,7 +38,7 @@
      * <p>This is called for each service component during {@link OemCarService#onCreate()}
      * call of OemCarService.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     void init();
 
@@ -48,7 +48,7 @@
      * <p>This is called for each service component during {@link OemCarService#onDestroy()}
      * call of OemCarService.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     void release();
 
@@ -58,7 +58,7 @@
      * <p>Each service component should implement a dump command to dump. It is called from
      * {@link OemCarService#dump(java.io.FileDescriptor, PrintWriter, String[])} call.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     void dump(@Nullable PrintWriter writer, @Nullable String[] args);
 
@@ -68,7 +68,7 @@
      * <p> Each service component should do the necessary initialization depending on CarService. It
      * is called from {@link OemCarService#onCarServiceReady()} call.
      */
-    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.UPSIDE_DOWN_CAKE_0,
+    @ApiRequirements(minCarVersion = ApiRequirements.CarVersion.TIRAMISU_2,
             minPlatformVersion = ApiRequirements.PlatformVersion.TIRAMISU_0)
     void onCarServiceReady();
 }
diff --git a/car-lib/src/android/car/telemetry/telemetry.proto b/car-lib/src/android/car/telemetry/telemetry.proto
index de1dac1..e384e83 100644
--- a/car-lib/src/android/car/telemetry/telemetry.proto
+++ b/car-lib/src/android/car/telemetry/telemetry.proto
@@ -84,6 +84,7 @@
     // Collects all the app start events with the initial used RSS/CACHE/SWAP memory.
     APP_START_MEMORY_STATE_CAPTURED = 1;
     // Collects memory state of processes in 5-minute buckets (1 memory measurement per bucket).
+    // Consider using PROCESS_MEMORY_SNAPSHOT instead for smaller data size.
     PROCESS_MEMORY_STATE = 2;
     // Collects activity foreground/background transition events.
     ACTIVITY_FOREGROUND_STATE_CHANGED = 3;
@@ -95,6 +96,10 @@
     ANR_OCCURRED = 6;
     // Collects "wtf"-level log events.
     WTF_OCCURRED = 7;
+    // Collects memory snapshot of processes in 5-minute buckets (1 memory measurement per bucket).
+    // It differs from PROCESS_MEMORY_STATE in that the snapshot can be used for leaked memory
+    // detection by tracking anon RSS + swap usage.
+    PROCESS_MEMORY_SNAPSHOT = 8;
   }
 
   // Required.
diff --git a/car-lib/src/android/car/test/ICarTest.aidl b/car-lib/src/android/car/test/ICarTest.aidl
index 590a6e6..9874cc2 100644
--- a/car-lib/src/android/car/test/ICarTest.aidl
+++ b/car-lib/src/android/car/test/ICarTest.aidl
@@ -33,6 +33,11 @@
     void startCarService(IBinder token) = 2;
 
     /**
+     * Returns OEM service name.
+     */
+    String getOemServiceName() = 3;
+
+    /**
      * Dumps VHAL's information or debug VHAL.
      *
      * {@code waitTimeoutMs} specifies the longest time CarTestService will wait to receive all
@@ -41,15 +46,10 @@
      * how long CarTestService would wait before it determines that VHAL is dead or stuck and
      * returns error.
      */
-    String dumpVhal(in List<String> options, long waitTimeoutMs) = 3;
+    String dumpVhal(in List<String> options, long waitTimeoutMs) = 4;
 
     /**
      * Returns whether AIDL VHAL is used for VHAL backend.
      */
-    boolean hasAidlVhal() = 4;
-
-    /**
-     * Returns OEM service name.
-     */
-    String getOemServiceName() = 5;
+    boolean hasAidlVhal() = 5;
 }
diff --git a/car-lib/src/com/android/car/internal/ICarServiceHelper.aidl b/car-lib/src/com/android/car/internal/ICarServiceHelper.aidl
index 3c9c5b1..dec3135 100644
--- a/car-lib/src/com/android/car/internal/ICarServiceHelper.aidl
+++ b/car-lib/src/com/android/car/internal/ICarServiceHelper.aidl
@@ -84,4 +84,7 @@
      * Check {@link android.app.AcitivityManager#startUserInBackgroundOnSecondaryDisplay(int, int)}
      */
     boolean startUserInBackgroundOnSecondaryDisplay(int userId, int displayId) = 11;
+
+    /** Check {@link android.os.Process#setProcessProfile(int, int, String)}. */
+    void setProcessProfile(int pid, int uid, in String profile) = 12;
 }
diff --git a/car-test-lib/src/android/car/test/mocks/AndroidMockitoHelper.java b/car-test-lib/src/android/car/test/mocks/AndroidMockitoHelper.java
index 44cd92a..5b62a6b 100644
--- a/car-test-lib/src/android/car/test/mocks/AndroidMockitoHelper.java
+++ b/car-test-lib/src/android/car/test/mocks/AndroidMockitoHelper.java
@@ -59,11 +59,14 @@
 import org.mockito.ArgumentMatcher;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 
 /**
  * Provides common Mockito calls for core Android classes.
@@ -371,6 +374,18 @@
     }
 
     /**
+     * Mocks a call to {@code UserManager#getVisibleUsers()} that
+     * returns {@link UserHandle UserHandles} with the given {@code userIds}.
+     */
+    public static void mockUmGetVisibleUsers(UserManager um, @UserIdInt int...userIds) {
+        Set<UserHandle> users = Arrays.stream(userIds).mapToObj(u -> UserHandle.of(u))
+                .collect(Collectors.toSet());
+        Log.v(TAG, "mockUmGetVisibleUsers(" + Arrays.toString(userIds) + ": returning "
+                + users);
+        when(um.getVisibleUsers()).thenReturn(users);
+    }
+
+    /**
      * Mocks a call to {@link ServiceManager#getService(name)}.
      *
      * <p><b>Note: </b>it must be made inside a
diff --git a/car-usb-handler/res/values-en-rCA/strings.xml b/car-usb-handler/res/values-en-rCA/strings.xml
index ebe84f8..de72fc2 100644
--- a/car-usb-handler/res/values-en-rCA/strings.xml
+++ b/car-usb-handler/res/values-en-rCA/strings.xml
@@ -19,12 +19,12 @@
     <string name="app_name" msgid="6963366455471441257">"USB Handler"</string>
     <string name="usb_saved_devices" msgid="2829442070749964872">"Saved devices"</string>
     <string name="usb_pref_delete_title" msgid="3885061814853467483">"Remove handling app for USB device"</string>
-    <string name="usb_pref_delete_message" msgid="5849493572520646218">"Are you sure you wan to delete dafault handling app for %1$s?"</string>
+    <string name="usb_pref_delete_message" msgid="5849493572520646218">"Are you sure that you want to delete default handling app for %1$s?"</string>
     <string name="usb_pref_delete_yes" msgid="7803356145103146036">"Yes"</string>
     <string name="usb_pref_delete_cancel" msgid="5999791462730255929">"Cancel"</string>
     <string name="usb_resolving_handlers" msgid="1943100136172948686">"Getting supported handlers"</string>
     <string name="usb_unknown_device" msgid="4211439272338937095">"Unknown USB device"</string>
-    <string name="usb_boot_service_notification" msgid="8519949189071048797">"Analyzing USB devices"</string>
+    <string name="usb_boot_service_notification" msgid="8519949189071048797">"Analysing USB devices"</string>
   <string-array name="config_AoapIncompatibleDeviceIds">
     <item msgid="4267974637522344258">"18d1:9302"</item>
   </string-array>
diff --git a/car_product/build/car.mk b/car_product/build/car.mk
index b967670..7f15aba 100644
--- a/car_product/build/car.mk
+++ b/car_product/build/car.mk
@@ -158,6 +158,7 @@
     RotaryPlayground \
     android.car.builtin \
     car-frameworks-service \
+    libcarservicehelperjni \
     com.android.car.procfsinspector \
     com.android.permission \
 
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/res/layout/car_ui_portrait_launcher.xml b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/res/layout/car_ui_portrait_launcher.xml
index 2ed691e..d3c31a0 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/res/layout/car_ui_portrait_launcher.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/res/layout/car_ui_portrait_launcher.xml
@@ -41,7 +41,6 @@
         <RelativeLayout
             android:id="@+id/grip_bar"
             android:layout_width="match_parent"
-            android:visibility="invisible"
             android:layout_height="@dimen/grip_bar_height"
             android:background="@drawable/title_bar_background">
             <View
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java
index 1aa23df..03d9442 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java
@@ -18,12 +18,12 @@
 
 import static android.view.InsetsState.ITYPE_BOTTOM_GENERIC_OVERLAY;
 import static android.view.InsetsState.ITYPE_TOP_GENERIC_OVERLAY;
-import static android.view.View.GONE;
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
 
+import static com.android.car.caruiportrait.common.service.CarUiPortraitService.MSG_FG_TASK_VIEW_READY;
 import static com.android.car.caruiportrait.common.service.CarUiPortraitService.MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE;
 import static com.android.car.caruiportrait.common.service.CarUiPortraitService.MSG_IMMERSIVE_MODE_REQUESTED;
 import static com.android.car.caruiportrait.common.service.CarUiPortraitService.MSG_REGISTER_CLIENT;
@@ -173,15 +173,15 @@
     private ComponentName mBackgroundActivityComponent;
     private ArraySet<ComponentName> mIgnoreOpeningRootTaskViewComponentsSet;
     private Set<HomeCardModule> mHomeCardModules;
-    private boolean mIsLowerPanelInitialized;
+    private boolean mIsRootPanelInitialized;
     private int mNavBarHeight;
     private int mControlBarHeightMinusCornerRadius;
     private int mCornerRadius;
-
     /** Messenger for communicating with {@link CarUiPortraitService}. */
     private Messenger mService = null;
     /** Flag indicating whether or not {@link CarUiPortraitService} is bounded. */
     private boolean mIsBound;
+    private boolean mLastFrontActivityIsFullScreenActivity;
 
     /**
      * All messages from {@link CarUiPortraitService} are received in this handler.
@@ -215,7 +215,6 @@
             mService = null;
         }
     };
-
     // This listener lets us know when actives are added and removed from any of the display regions
     // we care about, so we can trigger the opening and closing of the app containers as needed.
     private final TaskStackListener mTaskStackListener = new TaskStackListener() {
@@ -223,6 +222,8 @@
         public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
                 throws RemoteException {
             CarUiPortraitHomeScreen.this.updateRootTaskViewVisibility(taskInfo);
+            mLastFrontActivityIsFullScreenActivity = mFullScreenActivities.contains(
+                    taskInfo.baseActivity);
         }
 
         /**
@@ -253,6 +254,7 @@
                 return;
             }
 
+            logIfDebuggable("Update UI state on app restart attempt, task = " + task);
             // Toggle between STATE_OPEN and STATE_CLOSE when any task is in foreground and a new
             // Intent is sent to start the same task. In this case it's needed to toggle the root
             // task view when notification or AppGrid is in foreground and onClick on nav bar
@@ -320,7 +322,6 @@
                 R.bool.config_setInsetsOnUpperTaskView);
         mGripBar = findViewById(R.id.grip_bar);
         mGripBarView = findViewById(R.id.grip_bar_view);
-        mGripBar.setVisibility(GONE);
 
         mChevronUpDrawable = getDrawable(R.drawable.ic_chevron_up);
         mChevronDownDrawable = getDrawable(R.drawable.ic_chevron_down);
@@ -333,15 +334,15 @@
             mImmersiveButtonView.setOnClickListener(v -> {
                 if (mIsRootTaskViewFullScreen) {
                     // notify systemUI to show bars
-                    notifySystemUI(MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE, boolToInt(false));
                     mIsRootTaskViewFullScreen = false;
                     updateUIState(STATE_OPEN, true);
                     mControlBarView.setVisibility(VISIBLE);
+                    notifySystemUI(MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE, boolToInt(false));
                 } else {
                     // notify systemUI to hide bars
-                    notifySystemUI(MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE, boolToInt(true));
                     mControlBarView.setVisibility(INVISIBLE);
                     mIsRootTaskViewFullScreen = true;
+                    notifySystemUI(MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE, boolToInt(true));
                 }
                 mImmersiveButtonView.setImageDrawable(
                         mIsRootTaskViewFullScreen ? mChevronDownDrawable
@@ -384,23 +385,24 @@
         if (mTaskViewManager == null) {
             mTaskViewManager = new TaskViewManager(this, getMainThreadHandler());
         }
-        ViewGroup upperAppArea = findViewById(R.id.upper_app_area);
-        if (upperAppArea != null) {
-            setUpUpperTaskView(upperAppArea);
-        }
 
         ViewGroup lowerAppArea = findViewById(R.id.lower_app_area);
         if (lowerAppArea != null) {
             setUpRootTaskView(lowerAppArea);
         }
 
+        ViewGroup upperAppArea = findViewById(R.id.upper_app_area);
+        if (upperAppArea != null) {
+            setUpBackgroundTaskView(upperAppArea);
+        }
+
         ViewGroup fullscreenContainer = findViewById(R.id.fullscreen_container);
         if (fullscreenContainer != null) {
             setUpFullScreenTaskView(fullscreenContainer);
         }
 
         requireViewById(android.R.id.content).post(() -> {
-            resetRootTaskViewToDefaultHeight();
+            mIsRootPanelInitialized = true;
             updateUIState(STATE_CLOSE, /* animate = */ false);
         });
 
@@ -537,7 +539,7 @@
         if (!shouldTaskShowOnRootTaskView(taskInfo)) {
             return;
         }
-        logIfDebuggable("sowing task in task view: ");
+        logIfDebuggable("showing task in task view: ");
         // check if the foreground DA is visible to the user. If not, make it visible.
         if (mRootAppAreaState == STATE_CLOSE) {
             updateUIState(STATE_OPEN, /* animate = */ true);
@@ -548,6 +550,7 @@
     private boolean shouldTaskShowOnRootTaskView(TaskInfo taskInfo) {
         if (taskInfo.baseIntent == null || taskInfo.baseIntent.getComponent() == null
                 || mIsAnimating) {
+            logIfDebuggable("Should not show on root task view since task is null");
             return false;
         }
 
@@ -556,15 +559,19 @@
         // fullscreen activities will open in a separate task view which will show on top most
         // z-layer, that should not change the state of the root task view.
         if (mFullScreenActivities.contains(taskInfo.baseActivity)) {
+            logIfDebuggable("Should not show on root task view since task is full screen activity");
             return false;
         }
 
-        if (mDrawerActivities.contains(taskInfo.baseActivity)) {
+        if (mDrawerActivities.contains(taskInfo.baseActivity)
+                && mLastFrontActivityIsFullScreenActivity) {
+            logIfDebuggable("Don't open drawer activity after full screen task hide");
             return false;
         }
 
         boolean isBackgroundApp = mBackgroundActivityComponent.equals(componentName);
         if (isBackgroundApp) {
+            logIfDebuggable("Should not show on root task view since task is background activity");
             // we don't want to change the state of the root task view when background
             // task are launched or brought to front.
             return false;
@@ -586,15 +593,18 @@
                 taskInfo.baseIntent.getComponent());
     }
 
-    private void updateUIState(int newLowerAppAreaState, boolean animate) {
-        logIfDebuggable("updating UI state to: " + newLowerAppAreaState);
-        if (!mIsLowerPanelInitialized) {
+    private void updateUIState(int newRootAppAreaState, boolean animate) {
+        logIfDebuggable(
+                "updating UI state to: " + newRootAppAreaState + ", with animate = " + animate);
+
+        if (!mIsRootPanelInitialized) {
+            logIfDebuggable("Root panel hasn't inited");
             return;
         }
-        int lowerAppAreaTop = 0;
+        int rootAppAreaTopMargin = 0;
         Runnable onAnimationEnd = null;
-        if (newLowerAppAreaState == STATE_OPEN) {
-            lowerAppAreaTop = mBackgroundAppAreaHeightWhenCollapsed - mGripBarHeight;
+        if (newRootAppAreaState == STATE_OPEN) {
+            rootAppAreaTopMargin = mBackgroundAppAreaHeightWhenCollapsed - mGripBarHeight;
 
             // Animate the lower app area first and then change the upper app area size to avoid
             // black patch on screen.
@@ -606,8 +616,8 @@
                 mIsAnimating = false;
                 mGripBar.setVisibility(VISIBLE);
             };
-        } else if (newLowerAppAreaState == STATE_CLOSE) {
-            lowerAppAreaTop = mContainer.getMeasuredHeight();
+        } else if (newRootAppAreaState == STATE_CLOSE) {
+            rootAppAreaTopMargin = mContainer.getMeasuredHeight();
 
             // Change the upper app area's size to full-screen first and then animate the lower app
             // area to avoid black patch on screen.
@@ -621,7 +631,7 @@
             };
         } else {
             // newLowerAppAreaState == STATE_FULL
-            lowerAppAreaTop = 0;
+            rootAppAreaTopMargin = 0;
 
             // Animate the lower app area first and then change the upper app area size to avoid
             // black patch on screen.
@@ -631,32 +641,36 @@
                 mIsAnimating = false;
             };
         }
-
+        logIfDebuggable("Root App Area top margin = " + rootAppAreaTopMargin);
         if (animate) {
             mIsAnimating = true;
             Animation animation = null;
-            if (newLowerAppAreaState == STATE_FULL) {
-                animation = createImmersiveAnimationForLowerAppArea(lowerAppAreaTop /* newTop */,
+            if (newRootAppAreaState == STATE_FULL) {
+                animation = createImmersiveAnimationForLowerAppArea(
+                        rootAppAreaTopMargin /* newTop */,
                         onAnimationEnd);
-            } else if (mRootAppAreaState == STATE_FULL && newLowerAppAreaState == STATE_OPEN) {
-                animation = createImmersiveAnimationForLowerAppArea(lowerAppAreaTop /* newTop */,
+            } else if (mRootAppAreaState == STATE_FULL && newRootAppAreaState == STATE_OPEN) {
+                animation = createImmersiveAnimationForLowerAppArea(
+                        rootAppAreaTopMargin /* newTop */,
                         onAnimationEnd);
             } else {
-                animation = createAnimationForLowerAppArea(lowerAppAreaTop /* newTop */,
+                animation = createAnimationForLowerAppArea(rootAppAreaTopMargin /* newTop */,
                         onAnimationEnd);
             }
 
             mRootAppAreaContainer.startAnimation(animation);
         } else {
-            if (newLowerAppAreaState == STATE_OPEN) {
+            if (newRootAppAreaState == STATE_OPEN) {
                 // Update the height only for the open state because for the closed state, it
                 // is anyhow not visible.
                 // Triggering height change when it is off-screen sometimes gives problems.
-                if (!mIsRootTaskViewFullScreen) {
-                    resetRootTaskViewToDefaultHeight();
-                } else {
+                if (mIsRootTaskViewFullScreen) {
                     makeRootTaskViewFullscreen();
+                } else {
+                    resetRootTaskViewToDefaultHeight(rootAppAreaTopMargin);
                 }
+            } else if (newRootAppAreaState == STATE_CLOSE) {
+                resetRootTaskViewToDefaultHeight(rootAppAreaTopMargin);
             }
 
             onAnimationEnd.run();
@@ -675,16 +689,17 @@
         mControlBarView.setVisibility(INVISIBLE);
     }
 
-    private void resetRootTaskViewToDefaultHeight() {
-        int lowerAppAreaTop = mBackgroundAppAreaHeightWhenCollapsed - mGripBarHeight;
+    private void resetRootTaskViewToDefaultHeight(int rootAppAreaTopMargin) {
+        logIfDebuggable(
+                "resetRootTaskViewToDefaultHeight with top margin = " + rootAppAreaTopMargin);
 
-        FrameLayout.LayoutParams lowerAppAreaParams =
+        FrameLayout.LayoutParams rootAppAreaParams =
                 (FrameLayout.LayoutParams) mRootAppAreaContainer.getLayoutParams();
-        lowerAppAreaParams.height = mContainer.getMeasuredHeight()
+        rootAppAreaParams.height = mContainer.getMeasuredHeight()
                 - mBackgroundAppAreaHeightWhenCollapsed + mGripBarHeight;
-        lowerAppAreaParams.topMargin = lowerAppAreaTop;
+        rootAppAreaParams.topMargin = rootAppAreaTopMargin;
 
-        mRootAppAreaContainer.setLayoutParams(lowerAppAreaParams);
+        mRootAppAreaContainer.setLayoutParams(rootAppAreaParams);
 
         // Set bottom padding to be height of controller bar, so they won't overlap
         int rootAppAreaContainerBottomPadding =
@@ -693,19 +708,19 @@
         mRootAppAreaContainer.setPadding(0, 0, 0, rootAppAreaContainerBottomPadding);
 
         mControlBarView.setVisibility(VISIBLE);
-        mIsLowerPanelInitialized = true;
     }
 
     private Animation createAnimationForLowerAppArea(int newTop, Runnable onAnimationEnd) {
-        FrameLayout.LayoutParams lowerAppAreaParams =
+        logIfDebuggable("createAnimationForLowerAppArea, new top = " + newTop);
+        FrameLayout.LayoutParams rootAppAreaParams =
                 (FrameLayout.LayoutParams) mRootAppAreaContainer.getLayoutParams();
         Animation animation = new Animation() {
             @Override
             protected void applyTransformation(float interpolatedTime, Transformation t) {
-                lowerAppAreaParams.topMargin =
-                        lowerAppAreaParams.topMargin - (int) ((lowerAppAreaParams.topMargin
-                                - newTop) * interpolatedTime);
-                mRootAppAreaContainer.setLayoutParams(lowerAppAreaParams);
+                setTopMarginForView(
+                        rootAppAreaParams.topMargin - (int) ((rootAppAreaParams.topMargin
+                                - newTop) * interpolatedTime), mRootAppAreaContainer,
+                        rootAppAreaParams);
             }
         };
         animation.setAnimationListener(new Animation.AnimationListener() {
@@ -729,15 +744,15 @@
     }
 
     private Animation createImmersiveAnimationForLowerAppArea(int newTop, Runnable onAnimationEnd) {
-        FrameLayout.LayoutParams lowerAppAreaParams =
+        FrameLayout.LayoutParams rootAppAreaParams =
                 (FrameLayout.LayoutParams) mRootAppAreaContainer.getLayoutParams();
         Animation animation = new Animation() {
             @Override
             protected void applyTransformation(float interpolatedTime, Transformation t) {
-                lowerAppAreaParams.topMargin =
-                        lowerAppAreaParams.topMargin - (int) ((lowerAppAreaParams.topMargin
-                                - newTop) * interpolatedTime);
-                mRootAppAreaContainer.setLayoutParams(lowerAppAreaParams);
+                setTopMarginForView(
+                        rootAppAreaParams.topMargin - (int) ((rootAppAreaParams.topMargin
+                                - newTop) * interpolatedTime), mRootAppAreaContainer,
+                        rootAppAreaParams);
             }
         };
         animation.setAnimationListener(new Animation.AnimationListener() {
@@ -760,7 +775,14 @@
         return animation;
     }
 
-    private void updateBottomOverlap(int newLowerAppAreaState) {
+    private void setTopMarginForView(int newTop, View view, FrameLayout.LayoutParams lp) {
+        lp.topMargin = newTop;
+        view.setLayoutParams(lp);
+    }
+
+    private void updateBottomOverlap(int newRootAppAreaState) {
+        logIfDebuggable(
+                "updateBottomOverlap with new root app area state = " + newRootAppAreaState);
         if (mBackgroundTaskView == null) {
             return;
         }
@@ -774,7 +796,7 @@
         Region obscuredRegion = new Region(gripBarBounds.left, gripBarBounds.top,
                 gripBarBounds.right, gripBarBounds.bottom);
         Rect controlBarBounds = new Rect();
-        if (newLowerAppAreaState != STATE_FULL) {
+        if (newRootAppAreaState != STATE_FULL) {
             mControlBarView.getBoundsOnScreen(controlBarBounds);
             obscuredRegion.union(controlBarBounds);
         }
@@ -782,14 +804,14 @@
         // Use setObscuredTouchRect on all the taskviews that overlap with the grip bar.
         mBackgroundTaskView.setObscuredTouchRegion(obscuredRegion);
         mFullScreenTaskView.setObscuredTouchRegion(obscuredRegion);
-        if (newLowerAppAreaState == STATE_OPEN) {
+        if (newRootAppAreaState == STATE_OPEN) {
             // Set control bar bounds as obscured region on RootTaskview when AppGrid launcher is
             // open.
             mRootTaskView.setObscuredTouchRect(controlBarBounds);
             applyBottomInsetsToUpperTaskView(
                     mRootAppAreaContainer.getHeight() - mControlBarHeightMinusCornerRadius,
                     upperAppAreaBounds);
-        } else if (newLowerAppAreaState == STATE_FULL) {
+        } else if (newRootAppAreaState == STATE_FULL) {
             mRootTaskView.setObscuredTouchRect(null);
             applyBottomInsetsToUpperTaskView(mNavBarHeight, upperAppAreaBounds);
         } else {
@@ -827,7 +849,7 @@
         }
     }
 
-    private void setUpUpperTaskView(ViewGroup parent) {
+    private void setUpBackgroundTaskView(ViewGroup parent) {
         mTaskViewManager.createControlledCarTaskView(getMainExecutor(),
                 CarLauncherUtils.getMapsIntent(getApplicationContext()),
                 true,
@@ -856,6 +878,8 @@
 
                     @Override
                     public void onTaskViewReady() {
+                        logIfDebuggable("Foreground Task View is ready");
+                        notifySystemUI(MSG_FG_TASK_VIEW_READY, boolToInt(true));
                     }
                 });
     }
@@ -885,6 +909,7 @@
     }
 
     private void onImmersiveModeRequested(boolean requested) {
+        logIfDebuggable("onImmersiveModeRequested = " + requested);
         if (mGripBarView != null) {
             mGripBarView.setVisibility(requested ? View.GONE : View.VISIBLE);
         }
@@ -892,7 +917,7 @@
             mImmersiveButtonView.setVisibility(requested ? View.VISIBLE : View.GONE);
         }
         if (!requested) {
-            resetRootTaskViewToDefaultHeight();
+            updateUIState(mRootAppAreaState, false);
         }
     }
 
@@ -911,7 +936,7 @@
                     if (isSuwInProgress) {
                         makeRootTaskViewFullscreen();
                     } else {
-                        resetRootTaskViewToDefaultHeight();
+                        updateUIState(STATE_CLOSE, false);
                     }
                     break;
                 default:
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/proguard.flags b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/proguard.flags
index c252272..f442803 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/proguard.flags
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/proguard.flags
@@ -9,4 +9,6 @@
     *;
 }
 
+-keep class com.android.systemui.car.qc.CarUiPortraitProfileSwitcher { *; }
+
 -include ../../../../../../../packages/apps/Car/SystemUI/proguard.flags
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/qc_dialog_button_background.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/qc_dialog_button_background.xml
index 23cae4d..f6651ca 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/qc_dialog_button_background.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/qc_dialog_button_background.xml
@@ -19,7 +19,7 @@
         android:color="@*android:color/car_card_ripple_background">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/car_quick_controls_footer_button_color" />
+            <solid android:color="@color/car_primary" />
             <corners android:radius="@dimen/car_quick_controls_footer_button_radius"/>
         </shape>
     </item>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
index ae5567c..acfbd55 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
@@ -48,7 +48,7 @@
             android:gravity="center"
             android:layoutDirection="ltr">
 
-            <com.android.systemui.car.systembar.CarSystemBarButton
+            <com.android.systemui.car.systembar.CarUiPortraitSystemBarButton
                 android:id="@+id/grid_nav"
                 style="@style/SystemBarButton"
                 systemui:componentNames="com.android.car.portraitlauncher/com.android.car.carlauncher.AppGridActivity"
@@ -65,7 +65,7 @@
                 systemui:highlightWhenSelected="true"
                 systemui:useDefaultAppIconForRole="true"/>
 
-            <com.android.systemui.car.systembar.CarSystemBarButton
+            <com.android.systemui.car.systembar.CarUiPortraitSystemBarButton
                 android:id="@+id/standalone_notifications"
                 style="@style/SystemBarButton"
                 systemui:componentNames="com.android.car.notification/.CarNotificationCenterActivity"
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/qc_profile_switcher.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/qc_profile_switcher.xml
new file mode 100644
index 0000000..c03b51d
--- /dev/null
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/qc_profile_switcher.xml
@@ -0,0 +1,57 @@
+<!--
+  ~ Copyright (C) 2022 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.
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/status_icon_panel_bg_color">
+    <com.android.car.ui.FocusParkingView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+    <com.android.car.ui.FocusArea
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:orientation="vertical">
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                app:layout_constraintHeight_default="wrap"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@+id/qc_profile_footer_button">
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:localQCProvider="com.android.systemui.car.qc.CarUiPortraitProfileSwitcher"/>
+            </ScrollView>
+            <com.android.systemui.car.qc.QCFooterButton
+                android:id="@+id/qc_profile_footer_button"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                style="@style/QCFooterButtonStyle"
+                android:text="@string/qc_footer_profiles_accounts_settings"
+                app:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$ProfileDetailsActivity;launchFlags=0x08080000;end"/>
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </com.android.car.ui.FocusArea>
+</FrameLayout>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-af/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-af/strings.xml
index bb63fb4..8f280f0 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-af/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-af/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Gemakkontroles"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"NVT"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-b+sr+Latn/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-b+sr+Latn/strings.xml
index 33973f0..a37ec36 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-b+sr+Latn/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-b+sr+Latn/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Kontrole režima Prijatno"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Ne važi"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-bs/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-bs/strings.xml
index 2ca9a78..a5c691f 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-bs/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-bs/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Ugodne kontrole"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Neprimj."</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-cs/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-cs/strings.xml
index 33979d9..0ed3fd0 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-cs/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-cs/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Ovládání režimu Komfort"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"–"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-el/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-el/strings.xml
index 25bdafd..d4f2884 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-el/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-el/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Στοιχεία ελέγχου Άνεσης"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Δ/Ι"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rAU/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rAU/strings.xml
index 0647745..486c7c7 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rAU/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rAU/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Comfort controls"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rCA/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rCA/strings.xml
index 0647745..486c7c7 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rCA/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rCA/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Comfort controls"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rGB/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rGB/strings.xml
index 0647745..486c7c7 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rGB/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rGB/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Comfort controls"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rIN/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rIN/strings.xml
index 0647745..486c7c7 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rIN/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rIN/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Comfort controls"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rXC/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rXC/strings.xml
index 369dbb5..9fd467e 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rXC/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-en-rXC/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎Comfort controls‎‏‎‎‏‎"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎N/A‎‏‎‎‏‎"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-es-rUS/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-es-rUS/strings.xml
index 270d99a..c2c650c 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-es-rUS/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-es-rUS/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Controles de comodidad"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-eu/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-eu/strings.xml
index 1c45a88..7303fc9 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-eu/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-eu/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Erosotasun modua kontrolatzeko aukerak"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"E.a."</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-fa/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-fa/strings.xml
index 9f7ed67..11f7478 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-fa/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-fa/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"کنترل‌های آسایش"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"موجود نیست"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hr/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hr/strings.xml
index 38b7e4a..7f0efed 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hr/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hr/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Kontrole za ugodnost"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Neprimj."</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hu/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hu/strings.xml
index d94612f..3a4edc2 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hu/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hu/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Kényelmes hőmérséklet beállítása"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hy/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hy/strings.xml
index 6abb5cb..0875518 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hy/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-hy/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"«Կոմֆորտ» ռեժիմի կարգավորումներ"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Կիրառելի չէ"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-in/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-in/strings.xml
index 85f610e..19d0281 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-in/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-in/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Kontrol kenyamanan"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"T/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-iw/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-iw/strings.xml
index 43d0d9d..bf3c76d 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-iw/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-iw/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"אמצעי בקרת נוחות"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"לא זמין"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-km/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-km/strings.xml
index ea4481e..e1cc922 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-km/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-km/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"ការគ្រប់គ្រង​ផាសុកភាព"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"គ្មាន"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-kn/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-kn/strings.xml
index fab274c..7e6762a 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-kn/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-kn/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"ಆರಾಮದಾಯಕ ನಿಯಂತ್ರಕಗಳು"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"ಅನ್ವಯ ಇಲ್ಲ"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-lo/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-lo/strings.xml
index fea7a54..bf1eed5 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-lo/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-lo/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"ການຄວບຄຸມຄວາມສະດວກສະບາຍ"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mk/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mk/strings.xml
index b142777..b89a0b5 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mk/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mk/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Контроли за удобност"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Недостапно"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mn/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mn/strings.xml
index 8725d0b..36284e5 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mn/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mn/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Тав тухтай температурын хяналт"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mr/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mr/strings.xml
index f0102ad..2e73029 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mr/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-mr/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"कंफर्ट नियंत्रणे"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ms/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ms/strings.xml
index 3b69f98..e8a170b 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ms/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ms/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Kawalan keselesaan"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"T/B"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-or/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-or/strings.xml
index d9dc434..9f82e40 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-or/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-or/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"ଆରାମଦାୟକ ତାପମାତ୍ରା ପାଇଁ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pl/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pl/strings.xml
index 6c053f1..89d55bd 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pl/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pl/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Opcje komfortu jazdy"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Nd."</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pt-rPT/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pt-rPT/strings.xml
index ab94690..0e5bbce 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pt-rPT/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-pt-rPT/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Controlos de Conforto"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ro/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ro/strings.xml
index ea86dbf..bff8dda 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ro/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-ro/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Comenzi pentru Confort"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Nu e cazul"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sk/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sk/strings.xml
index fc95693..d580e41 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sk/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sk/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Ovládanie pohodlia"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"-"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sr/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sr/strings.xml
index 9e1bf9a..41975fb 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sr/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-sr/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Контроле режима Пријатно"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"Не важи"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-te/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-te/strings.xml
index 65f08ad..ccd49ee 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-te/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-te/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"సౌకర్య సంబంధిత కంట్రోల్స్"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-th/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-th/strings.xml
index 9b2b653..0f3383c 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-th/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-th/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"การควบคุมความสบาย"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"ไม่มี"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-tl/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-tl/strings.xml
index b95595d..35b8757 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-tl/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values-tl/strings.xml
@@ -18,6 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="hvac_panel_header" msgid="1299061170810305529">"Mga kontrol sa Comfort"</string>
-    <!-- no translation found for default_sensor_string (3994996854548513870) -->
-    <skip />
+    <string name="default_sensor_string" msgid="3994996854548513870">"N/A"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
index 0fee201..aa04aa8 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
@@ -29,6 +29,7 @@
 
     <color name="status_icon_not_highlighted_color">#202124</color>
     <color name="status_icon_selected_button_color">#6BF0FF</color>
+    <color name="status_icon_panel_bg_color">@color/car_surface_2</color>
     <color name="privacy_chip_indicator_color">@color/car_surface_3</color>
 
     <color name="status_bar_background_color">#00000000</color>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/strings.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/strings.xml
index 102826d..871a34d 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/strings.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/strings.xml
@@ -29,4 +29,10 @@
     </string>
     <!-- Format for temperature in the temperature control view (No decimal) in celsius -->
     <string name="statusbar_temperature_format_celsius" translatable="false">%.0f\u00B0 C</string>
+
+    <!-- Message shown when task view is not ready which asks user to wait until system has finished loading [CHAR LIMIT=75]-->
+    <string name="task_view_not_ready_message">Please wait for system to load</string>
+
+    <!-- Subtitle for current profile in profile switch panel [CHAR LIMIT=20]-->
+    <string name="current_profile_subtitle">Current profile</string>
 </resources>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
index 44bc4e3..ede8c98 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
@@ -40,7 +40,7 @@
         <item name="android:layout_marginVertical">@dimen/car_quick_controls_footer_button_vertical_margin</item>
         <item name="android:layout_marginHorizontal">@dimen/car_quick_controls_footer_button_horizontal_margin</item>
         <item name="android:background">@drawable/qc_dialog_button_background</item>
-        <item name="android:textColor">@color/car_quick_controls_footer_button_text_color</item>
+        <item name="android:textColor">@color/car_on_primary</item>
         <item name="android:gravity">center</item>
     </style>
 
@@ -51,7 +51,7 @@
     </style>
 
     <style name="TextAppearance.QC" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textColor">@color/car_ui_text_color_primary</item>
+        <item name="android:textColor">@color/car_on_surface</item>
     </style>
 
     <style name="TextAppearance.QC.Title">
@@ -59,7 +59,7 @@
     </style>
 
     <style name="TextAppearance.QC.Subtitle">
-        <item name="android:textColor">@color/car_ui_text_color_secondary</item>
+        <item name="android:textColor">@color/car_primary</item>
         <item name="android:textSize">@dimen/car_ui_body3_size</item>
     </style>
 </resources>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/CarUiPortraitSystemUIBinder.java b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/CarUiPortraitSystemUIBinder.java
index c4c1d5f..b687631 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/CarUiPortraitSystemUIBinder.java
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/CarUiPortraitSystemUIBinder.java
@@ -18,6 +18,7 @@
 
 import com.android.systemui.car.displayarea.CarDisplayAreaModule;
 import com.android.systemui.car.displayarea.DisplayAreaComponent;
+import com.android.systemui.car.qc.CarUiPortraitQuickControlsModule;
 import com.android.systemui.car.statusicon.ui.ReadOnlyStatusIconModule;
 import com.android.systemui.car.systembar.CarUiPortraitSystemBarModule;
 import com.android.systemui.car.window.ExtendedOverlayWindowModule;
@@ -29,7 +30,8 @@
 
 /** Binder for AAECarSystemUI specific {@link CoreStartable} modules and components. */
 @Module(includes = {ExtendedOverlayWindowModule.class, CarDisplayAreaModule.class,
-        CarUiPortraitSystemBarModule.class, ReadOnlyStatusIconModule.class})
+        CarUiPortraitSystemBarModule.class, ReadOnlyStatusIconModule.class,
+        CarUiPortraitQuickControlsModule.class})
 abstract class CarUiPortraitSystemUIBinder extends CarSystemUIBinder {
 
     /** Inject into ClusterDisplayController. */
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/qc/CarUiPortraitProfileSwitcher.java b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/qc/CarUiPortraitProfileSwitcher.java
new file mode 100644
index 0000000..887a24a
--- /dev/null
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/qc/CarUiPortraitProfileSwitcher.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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 com.android.systemui.car.qc;
+
+import static com.android.car.ui.utils.CarUiUtils.drawableToBitmap;
+
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+
+import com.android.car.qc.QCItem;
+import com.android.car.qc.QCRow;
+import com.android.systemui.R;
+import com.android.systemui.settings.UserTracker;
+
+import javax.inject.Inject;
+
+/**
+ * Local provider for the profile switcher panel with secondary text for current profile.
+ */
+public class CarUiPortraitProfileSwitcher extends ProfileSwitcher {
+
+    @Inject
+    public CarUiPortraitProfileSwitcher(Context context, UserTracker userTracker) {
+        super(context, userTracker);
+
+    }
+
+    @Override
+    protected QCRow createUserProfileRow(UserInfo userInfo) {
+        if (userInfo.id == mUserTracker.getUserId()) {
+            return createUserProfileRowForCurrentProfile(userInfo);
+        }
+        return super.createUserProfileRow(userInfo);
+    }
+
+    private QCRow createUserProfileRowForCurrentProfile(UserInfo userInfo) {
+        QCItem.ActionHandler actionHandler = (item, context, intent) -> {
+            if (mPendingUserAdd) {
+                return;
+            }
+            switchUser(userInfo.id);
+        };
+        return createUserProfileRowForCurrentProfile(userInfo.name,
+                mUserIconProvider.getDrawableWithBadge(mContext, userInfo), actionHandler);
+    }
+
+    private QCRow createUserProfileRowForCurrentProfile(String title, Drawable iconDrawable,
+            QCItem.ActionHandler actionHandler) {
+        Icon icon = Icon.createWithBitmap(drawableToBitmap(iconDrawable));
+        String subtitle = mContext.getString(R.string.current_profile_subtitle);
+        QCRow row = new QCRow.Builder()
+                .setIcon(icon)
+                .setIconTintable(false)
+                .setTitle(title)
+                .setSubtitle(subtitle)
+                .build();
+        row.setActionHandler(actionHandler);
+        return row;
+    }
+}
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/qc/CarUiPortraitQuickControlsModule.java b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/qc/CarUiPortraitQuickControlsModule.java
new file mode 100644
index 0000000..2b4f9a2
--- /dev/null
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/qc/CarUiPortraitQuickControlsModule.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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 com.android.systemui.car.qc;
+
+import com.android.car.qc.provider.BaseLocalQCProvider;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
+
+/**
+ * Dagger injection module for {@link SystemUIQCViewController}
+ */
+@Module
+public abstract class CarUiPortraitQuickControlsModule {
+    /** Injects CarUiPortraitProfileSwitcher. */
+    @Binds
+    @IntoMap
+    @ClassKey(CarUiPortraitProfileSwitcher.class)
+    public abstract BaseLocalQCProvider bindCarUiPortraitProfileSwitcher(
+            CarUiPortraitProfileSwitcher carUiPortraitProfileSwitcher);
+}
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/systembar/CarUiPortraitSystemBarButton.java b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/systembar/CarUiPortraitSystemBarButton.java
new file mode 100644
index 0000000..1440ff6
--- /dev/null
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/car/systembar/CarUiPortraitSystemBarButton.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 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 com.android.systemui.car.systembar;
+
+import static com.android.car.caruiportrait.common.service.CarUiPortraitService.INTENT_EXTRA_FG_TASK_VIEW_READY;
+import static com.android.car.caruiportrait.common.service.CarUiPortraitService.REQUEST_FROM_LAUNCHER;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+
+import com.android.systemui.R;
+
+/**
+ * CarUiPortraitSystemBarButton is an extension of {@link CarSystemBarButton} that disables itself
+ * until it receives a signal from launcher that tasks views are ready.
+ */
+public class CarUiPortraitSystemBarButton extends CarSystemBarButton {
+
+    private static final String TAG = "CarUiPortraitSystemBarButton";
+    private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+
+    private boolean mTaskViewReady = false;
+
+    public CarUiPortraitSystemBarButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        // disable button by default
+        super.setDisabled(/* disabled= */ true, getDisabledRunnable(context));
+
+        BroadcastReceiver taskViewReadyReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (intent.hasExtra(INTENT_EXTRA_FG_TASK_VIEW_READY)) {
+                    boolean taskViewReady = intent.getBooleanExtra(
+                            INTENT_EXTRA_FG_TASK_VIEW_READY, /* defaultValue= */ false);
+                    mTaskViewReady = taskViewReady;
+                    if (mTaskViewReady) {
+                        logIfDebuggable("Foreground task view ready");
+                    }
+                    setDisabled(!taskViewReady, getDisabledRunnable(context));
+                }
+            }
+        };
+        context.registerReceiverForAllUsers(taskViewReadyReceiver,
+                new IntentFilter(REQUEST_FROM_LAUNCHER), null, null);
+    }
+
+    @Override
+    public void setDisabled(boolean disabled, @Nullable Runnable runnable) {
+        // do not externally control disable state until taskview is ready
+        if (!mTaskViewReady) {
+            return;
+        }
+
+        super.setDisabled(disabled, runnable);
+    }
+
+    private Runnable getDisabledRunnable(Context context) {
+        return () -> Toast.makeText(context, R.string.task_view_not_ready_message,
+                Toast.LENGTH_LONG).show();
+    }
+
+    private static void logIfDebuggable(String message) {
+        if (DEBUG) {
+            Log.d(TAG, message);
+        }
+    }
+}
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/wm/CarUiPortraitDisplaySystemBarsController.java b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/wm/CarUiPortraitDisplaySystemBarsController.java
index dec65a6..b23df7c 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/wm/CarUiPortraitDisplaySystemBarsController.java
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/src/com/android/systemui/wm/CarUiPortraitDisplaySystemBarsController.java
@@ -210,8 +210,8 @@
             }
             mAppRequestedVisibleTypes = mRequestedVisibleTypes;
 
-            showInsets(barVisibilities[0], /* fromIme= */ false);
-            hideInsets(barVisibilities[1], /* fromIme= */ false);
+            showInsets(barVisibilities[0], /* fromIme= */ false, /* statsToken= */ null);
+            hideInsets(barVisibilities[1], /* fromIme= */ false, /* statsToken= */ null);
 
             boolean immersiveState = mImmersiveOverride || mImmersiveForSUW || (
                     (barVisibilities[1] & (WindowInsets.Type.statusBars()
diff --git a/car_product/car_ui_portrait/rro/CarEvsCameraPreviewAppRRO/res/values-en-rCA/strings.xml b/car_product/car_ui_portrait/rro/CarEvsCameraPreviewAppRRO/res/values-en-rCA/strings.xml
index ee8979c..2f87e87 100644
--- a/car_product/car_ui_portrait/rro/CarEvsCameraPreviewAppRRO/res/values-en-rCA/strings.xml
+++ b/car_product/car_ui_portrait/rro/CarEvsCameraPreviewAppRRO/res/values-en-rCA/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="2859195686616302703">"Rearview Camera"</string>
+    <string name="app_name" msgid="2859195686616302703">"Rearview camera"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/rro/CarUIPortraitCommon/res/values/dimens.xml b/car_product/car_ui_portrait/rro/CarUIPortraitCommon/res/values/dimens.xml
index 9f915b2..c589910 100644
--- a/car_product/car_ui_portrait/rro/CarUIPortraitCommon/res/values/dimens.xml
+++ b/car_product/car_ui_portrait/rro/CarUIPortraitCommon/res/values/dimens.xml
@@ -15,10 +15,15 @@
   ~ limitations under the License.
   -->
 <resources>
+    <dimen name="car_portrait_ui_selectable_item_radius">24dp</dimen>
     <dimen name="car_portrait_ui_button_radius">44dp</dimen>
     <dimen name="car_portrait_ui_window_rounded_corner_radius">44dp</dimen>
 
     <dimen name="car_portrait_ui_toast_margin">24dp</dimen>
     <dimen name="car_portrait_ui_toast_icon_size">48dp</dimen>
     <dimen name="car_portrait_ui_toast_bottom_margin">32dp</dimen>
+
+    <dimen name="car_portrait_ui_tab_width">320dp</dimen>
+    <dimen name="car_portrait_ui_tab_height">96dp</dimen>
+    <dimen name="car_portrait_ui_tab_margin_horizontal">16dp</dimen>
 </resources>
diff --git a/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java b/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java
index 1e60c49..5e6255a 100644
--- a/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java
+++ b/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java
@@ -59,6 +59,10 @@
     public static final String INTENT_EXTRA_SUW_IN_PROGRESS =
             "INTENT_EXTRA_SUW_IN_PROGRESS";
 
+    // key name for the intent's extra that tells if task views are ready
+    public static final String INTENT_EXTRA_FG_TASK_VIEW_READY =
+            "INTENT_EXTRA_TASK_VIEW_READY";
+
     // Keeps track of all current registered clients.
     private final ArrayList<Messenger> mClients = new ArrayList<Messenger>();
 
@@ -98,6 +102,11 @@
      */
     public static final int MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE = 6;
 
+    /**
+     * Command to service to notify when task views are ready.
+     */
+    public static final int MSG_FG_TASK_VIEW_READY = 7;
+
     private boolean mIsSystemInImmersiveMode;
     private boolean mIsSuwInProgress;
 
@@ -127,6 +136,12 @@
                             intToBoolean(val));
                     CarUiPortraitService.this.sendBroadcast(hideSysBarIntent);
                     break;
+                case MSG_FG_TASK_VIEW_READY:
+                    Intent taskViewReadyIntent = new Intent(REQUEST_FROM_LAUNCHER);
+                    taskViewReadyIntent.putExtra(INTENT_EXTRA_FG_TASK_VIEW_READY,
+                            intToBoolean(msg.arg1));
+                    CarUiPortraitService.this.sendBroadcast(taskViewReadyIntent);
+                    break;
                 default:
                     super.handleMessage(msg);
             }
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/Android.bp b/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/Android.bp
index 8b0fafd..be714eb 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/Android.bp
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/Android.bp
@@ -24,5 +24,6 @@
     ],
     static_libs: [
         "car-portrait-ui-common",
+        "car-apps-common",
     ],
 }
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values-night/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/res/values/styles.xml
similarity index 63%
rename from car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values-night/colors.xml
rename to car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/res/values/styles.xml
index ecf7fbb..8a30358 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values-night/colors.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/res/values/styles.xml
@@ -16,7 +16,11 @@
   -->
 
 <resources>
-    <color name="icon_color">#E8EAED</color>
-    <color name="disabled_icon_color">#80868B</color>
-    <color name="play_pause_ic_bg_color">#000000</color>
-</resources>
\ No newline at end of file
+    <!-- Styles for play/pause action buttons -->
+    <style name="Widget.ActionButton.PlayPause">
+        <item name="android:layout_width">@dimen/play_pause_image_size</item>
+        <item name="android:layout_height">@dimen/play_pause_image_size</item>
+        <item name="android:scaleType">fitCenter</item>
+        <item name="android:tint">@color/action_button_icon_tint</item>
+    </style>
+</resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/res/xml/overlays.xml b/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/res/xml/overlays.xml
index bce2c92..b634e79 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/res/xml/overlays.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitAppsCommonLauncherRRO/res/xml/overlays.xml
@@ -25,4 +25,6 @@
     <item target="bool/enable_control_bar_overflow" value="@bool/enable_control_bar_overflow"/>
 
     <item target="drawable/ic_overflow_button" value="@drawable/ic_overflow_button"/>
+
+    <item target="style/Widget.ActionButton.PlayPause" value="@style/Widget.ActionButton.PlayPause" />
 </overlay>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/Android.bp b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/Android.bp
index e4345e9..ef0dc31 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/Android.bp
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/Android.bp
@@ -22,4 +22,7 @@
         "--no-resource-deduping",
         "--no-resource-removal"
     ],
+    static_libs: [
+        "car-portrait-ui-common",
+    ],
 }
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/ic_play_arrow_off.xml b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/ic_play_arrow_off.xml
index 3f006bf..86b47c4 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/ic_play_arrow_off.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/ic_play_arrow_off.xml
@@ -18,8 +18,8 @@
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/play_pause_ic_bg_color"/>
-            <corners android:radius="@dimen/play_pause_button_bg_radius"/>
+            <solid android:color="@color/disabled_ic_bg_color"/>
+            <corners android:radius="@dimen/play_pause_disabled_button_bg_radius"/>
         </shape>
     </item>
     <item android:gravity="center"
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/pause_icon.xml b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/pause_icon.xml
index 470bbf0..986fa14 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/pause_icon.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/pause_icon.xml
@@ -21,5 +21,5 @@
         android:viewportHeight="88">
     <path
         android:pathData="M58,58H46V30H58V58ZM50,54H54V34H50V54ZM42,58H30V30H42V58ZM34,54H38V34H34V54Z"
-        android:fillColor="@color/icon_color"/>
+        android:fillColor="@color/play_pause_icon_color"/>
 </vector>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/play_arrow_icon.xml b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/play_arrow_icon.xml
index 3524d17..9535cf0 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/play_arrow_icon.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/play_arrow_icon.xml
@@ -21,5 +21,5 @@
         android:viewportHeight="88">
     <path
         android:pathData="M60,44L32,62V26L60,44ZM50.52,44L37.1,35.36V52.64L50.52,44Z"
-        android:fillColor="@color/icon_color"/>
+        android:fillColor="@color/play_pause_icon_color"/>
 </vector>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/stop_icon.xml b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/stop_icon.xml
index e296f77..2acdcdb 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/stop_icon.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/drawable/stop_icon.xml
@@ -21,6 +21,6 @@
     android:viewportWidth="48"
     android:viewportHeight="48">
     <path
-        android:fillColor="@color/icon_color"
+        android:fillColor="@color/play_pause_icon_color"
         android:pathData="M15,15V33ZM12,36V12H36V36ZM15,33H33V15H15Z"/>
 </vector>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/bools.xml b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/bools.xml
index 7efb325..4d543a0 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/bools.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/bools.xml
@@ -19,7 +19,7 @@
     <!-- Whether to show a linear progress bar in minimized control bar or not. -->
     <bool name="show_linear_progress_bar">false</bool>
     <!-- Whether to show a circular progress bar in control bar and minimized control bar or not. -->
-    <bool name="show_circular_progress_bar">true</bool>
+    <bool name="show_circular_progress_bar">false</bool>
     <!-- Whether to show circular progress bar only when progress is active. -->
-    <bool name="show_circular_progress_bar_only_when_active">true</bool>
+    <bool name="show_circular_progress_bar_only_when_active">false</bool>
 </resources>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/colors.xml
index c9c4c1c..762671b 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/colors.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/colors.xml
@@ -16,7 +16,9 @@
   -->
 
 <resources>
-    <color name="icon_color">#202124</color>
-    <color name="disabled_icon_color">#9AA0A6</color>
-    <color name="play_pause_ic_bg_color">#ffffff</color>
+    <color name="icon_color">@color/car_on_surface</color>
+    <color name="disabled_icon_color">@color/car_on_secondary_container</color>
+    <color name="disabled_ic_bg_color">@color/car_secondary_container</color>
+    <color name="play_pause_ic_bg_color">@color/car_primary</color>
+    <color name="play_pause_icon_color">@color/car_on_primary</color>
 </resources>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/dimens.xml b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/dimens.xml
index 6273724..57174ce 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/dimens.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitMediaCommonLauncherRRO/res/values/dimens.xml
@@ -16,4 +16,7 @@
   -->
 <resources>
     <dimen name="play_pause_button_bg_radius">24dp</dimen>
+    <dimen name="play_pause_button_bg_width">104dp</dimen>
+    <dimen name="play_pause_button_bg_height">104dp</dimen>
+    <dimen name="play_pause_disabled_button_bg_radius">16dp</dimen>
 </resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitNotificationRRO/res/values-en-rCA/strings.xml b/car_product/car_ui_portrait/rro/CarUiPortraitNotificationRRO/res/values-en-rCA/strings.xml
index 7813aa2..1fad4f1 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitNotificationRRO/res/values-en-rCA/strings.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitNotificationRRO/res/values-en-rCA/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_header" msgid="7197574085752162581">"Notification Center"</string>
+    <string name="notification_header" msgid="7197574085752162581">"Notification centre"</string>
 </resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/Android.bp b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/Android.bp
index 001ca5a..f6fae45 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/Android.bp
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/Android.bp
@@ -22,4 +22,8 @@
         "--no-resource-deduping",
         "--no-resource-removal"
     ],
+    static_libs: [
+        "car-portrait-ui-common",
+        "car-ui-lib",
+    ],
 }
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_background.xml b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_background.xml
index 59391e2..24dc308 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_background.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_background.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ Copyright (C) 2022 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.
@@ -14,20 +14,44 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:state_pressed="true">
-        <shape android:shape="rectangle">
-            <solid android:color="?android:attr/colorBackground"/>
-        </shape>
-    </item>
-    <item android:state_focused="true">
-        <shape android:shape="rectangle">
-            <solid android:color="?android:attr/colorBackground"/>
-        </shape>
-    </item>
+
+<ripple
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/car_secondary_container">
     <item>
-        <shape android:shape="rectangle">
-            <solid android:color="?android:attr/colorBackground"/>
+        <selector>
+            <item android:state_activated="true">
+                <shape>
+                    <solid android:color="@color/car_secondary_container"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+            <item android:state_pressed="true">
+                <shape>
+                    <solid android:color="@android:color/transparent"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+            <item android:state_focused="true">
+                <shape>
+                    <stroke android:width="2dp" android:color="@color/car_secondary_container"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+            <item>
+                <shape>
+                    <solid android:color="@android:color/transparent"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+        </selector>
+    </item>
+
+    <item android:id="@android:id/mask">
+        <shape>
+            <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+            <!-- This is a mask color and needs to be set. Would not show in UI. -->
+            <solid android:color="@android:color/white"/>
         </shape>
     </item>
-</selector>
+</ripple>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_highlight.xml b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_highlight.xml
index 0f72dd2..5d366da 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_highlight.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/drawable/top_level_preference_highlight.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ Copyright (C) 2022 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.
@@ -14,18 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
-    <item
-        android:right="100dip">
-        <shape
-            android:shape="rectangle" >
-            <solid android:color="#91AFC6" />
-        </shape>
-    </item>
-    <item android:left="8dip">
-        <shape
-            android:shape="rectangle" >
-            <solid android:color="@color/top_level_preference_highlight_background_color" />
-        </shape>
-    </item>
-</layer-list>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/car_secondary_container"/>
+    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+</shape>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/layout/top_level_preference.xml b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/layout/top_level_preference.xml
index 65b753a..783bc67 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/layout/top_level_preference.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/layout/top_level_preference.xml
@@ -17,14 +17,13 @@
 
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
+    android:layout_width="@dimen/car_portrait_ui_tab_width"
     android:layout_height="wrap_content"
-    android:background="@drawable/top_level_preference_background"
+    android:layout_marginHorizontal="@dimen/car_portrait_ui_tab_margin_horizontal"
+    android:background="?android:attr/selectableItemBackground"
     android:clipToPadding="false"
-    android:minHeight="96dp"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:tag="carUiPreference"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart">
+    android:minHeight="@dimen/car_portrait_ui_tab_height"
+    android:tag="carUiPreference">
 
     <com.android.car.ui.uxr.DrawableStateImageView
         android:id="@android:id/icon"
@@ -48,12 +47,14 @@
             android:id="@android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:singleLine="true"/>
+            android:singleLine="false"
+            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"/>
 
         <com.android.car.ui.uxr.DrawableStateTextView
             android:id="@android:id/summary"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"/>
 
     </LinearLayout>
 
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values-night/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values-night/colors.xml
deleted file mode 100644
index 74014e9..0000000
--- a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values-night/colors.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 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.
-  -->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <color name="top_level_preference_highlight_background_color">#282A2D</color>
-</resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values/dimens.xml
similarity index 90%
rename from car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values/colors.xml
rename to car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values/dimens.xml
index d209af4..2dd4fdb 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values/colors.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/values/dimens.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <color name="top_level_preference_highlight_background_color">#E8EAED</color>
+    <dimen name="top_level_menu_width">362dp</dimen>
 </resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/xml/overlays.xml b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/xml/overlays.xml
index 5494140..5097014 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/xml/overlays.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitSettingsRRO/res/xml/overlays.xml
@@ -26,4 +26,7 @@
     <item target="animator/trans_left_out" value="@animator/trans_fade_out"/>
     <item target="animator/trans_right_in" value="@animator/trans_fade_in"/>
     <item target="animator/trans_right_out" value="@animator/trans_fade_out"/>
+
+    <item target="dimen/top_level_menu_width" value="@dimen/top_level_menu_width"/>
+
 </overlay>
diff --git a/car_product/car_ui_portrait/rro/android/res/drawable/selectable_item_background.xml b/car_product/car_ui_portrait/rro/android/res/drawable/selectable_item_background.xml
new file mode 100644
index 0000000..24dc308
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/android/res/drawable/selectable_item_background.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 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.
+  -->
+
+<ripple
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/car_secondary_container">
+    <item>
+        <selector>
+            <item android:state_activated="true">
+                <shape>
+                    <solid android:color="@color/car_secondary_container"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+            <item android:state_pressed="true">
+                <shape>
+                    <solid android:color="@android:color/transparent"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+            <item android:state_focused="true">
+                <shape>
+                    <stroke android:width="2dp" android:color="@color/car_secondary_container"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+            <item>
+                <shape>
+                    <solid android:color="@android:color/transparent"/>
+                    <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+                </shape>
+            </item>
+        </selector>
+    </item>
+
+    <item android:id="@android:id/mask">
+        <shape>
+            <corners android:radius="@dimen/car_portrait_ui_selectable_item_radius"/>
+            <!-- This is a mask color and needs to be set. Would not show in UI. -->
+            <solid android:color="@android:color/white"/>
+        </shape>
+    </item>
+</ripple>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/android/res/values/themes_device_defaults.xml b/car_product/car_ui_portrait/rro/android/res/values/themes_device_defaults.xml
index 1ca7ce6..41f42e0 100644
--- a/car_product/car_ui_portrait/rro/android/res/values/themes_device_defaults.xml
+++ b/car_product/car_ui_portrait/rro/android/res/values/themes_device_defaults.xml
@@ -35,7 +35,7 @@
         <item name="android:listPreferredItemHeightSmall">@*android:dimen/car_single_line_list_item_height</item>
 
 
-        <item name="android:selectableItemBackground">@*android:drawable/item_background</item>
+        <item name="android:selectableItemBackground">@drawable/selectable_item_background</item>
 
         <item name="android:actionBarSize">@*android:dimen/car_app_bar_height</item>
 
diff --git a/car_product/car_ui_portrait/rro/car-ui-customizations/Android.bp b/car_product/car_ui_portrait/rro/car-ui-customizations/Android.bp
index 21656dd..2081f51 100644
--- a/car_product/car_ui_portrait/rro/car-ui-customizations/Android.bp
+++ b/car_product/car_ui_portrait/rro/car-ui-customizations/Android.bp
@@ -30,6 +30,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.ui.paintbooth.googlecaruiportrait.rro",
     target_package_name: "com.android.car.ui.paintbooth",
+    category: "caruiportrait.paintbooth",
 }
 
 override_runtime_resource_overlay {
@@ -37,6 +38,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.rotaryplayground.googlecaruiportrait.rro",
     target_package_name: "com.android.car.rotaryplayground",
+    category: "caruiportrait.rotaryplayground",
 }
 
 override_runtime_resource_overlay {
@@ -44,6 +46,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.themeplayground.googlecaruiportrait.rro",
     target_package_name: "com.android.car.themeplayground",
+    category: "caruiportrait.themeplayground",
 }
 
 override_runtime_resource_overlay {
@@ -51,6 +54,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.carlauncher.googlecaruiportrait.rro",
     target_package_name: "com.android.car.carlauncher",
+    category: "caruiportrait.carlauncher",
 }
 
 override_runtime_resource_overlay {
@@ -58,6 +62,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.home.googlecaruiportrait.rro",
     target_package_name: "com.android.car.home",
+    category: "caruiportrait.home",
 }
 
 override_runtime_resource_overlay {
@@ -65,6 +70,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.media.googlecaruiportrait.rro",
     target_package_name: "com.android.car.media",
+    category: "caruiportrait.media",
 }
 
 override_runtime_resource_overlay {
@@ -72,6 +78,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.messenger.googlecaruiportrait.rro",
     target_package_name: "com.android.car.messenger",
+    category: "caruiportrait.messenger",
 }
 
 override_runtime_resource_overlay {
@@ -79,6 +86,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.radio.googlecaruiportrait.rro",
     target_package_name: "com.android.car.radio",
+    category: "caruiportrait.radio",
 }
 
 override_runtime_resource_overlay {
@@ -86,6 +94,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.calendar.googlecaruiportrait.rro",
     target_package_name: "com.android.car.calendar",
+    category: "caruiportrait.calendar",
 }
 
 override_runtime_resource_overlay {
@@ -93,6 +102,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.systemupdater.googlecaruiportrait.rro",
     target_package_name: "com.android.car.systemupdater",
+    category: "caruiportrait.systemupdater",
 }
 
 override_runtime_resource_overlay {
@@ -100,6 +110,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.dialer.googlecaruiportrait.rro",
     target_package_name: "com.android.car.dialer",
+    category: "caruiportrait.dialer",
 }
 
 override_runtime_resource_overlay {
@@ -107,6 +118,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.linkviewer.googlecaruiportrait.rro",
     target_package_name: "com.android.car.linkviewer",
+    category: "caruiportrait.linkviewer",
 }
 
 override_runtime_resource_overlay {
@@ -114,6 +126,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.settings.googlecaruiportrait.rro",
     target_package_name: "com.android.car.settings",
+    category: "caruiportrait.settings",
 }
 
 override_runtime_resource_overlay {
@@ -121,6 +134,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.voicecontrol.googlecaruiportrait.rro",
     target_package_name: "com.android.car.voicecontrol",
+    category: "caruiportrait.voicecontrol",
 }
 
 override_runtime_resource_overlay {
@@ -128,6 +142,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.faceenroll.googlecaruiportrait.rro",
     target_package_name: "com.android.car.faceenroll",
+    category: "caruiportrait.faceenroll",
 }
 
 override_runtime_resource_overlay {
@@ -135,6 +150,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.developeroptions.googlecaruiportrait.rro",
     target_package_name: "com.android.car.developeroptions",
+    category: "caruiportrait.developeroptions",
 }
 
 override_runtime_resource_overlay {
@@ -142,6 +158,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.managedprovisioning.googlecaruiportrait.rro",
     target_package_name: "com.android.managedprovisioning",
+    category: "caruiportrait.managedprovisioning",
 }
 
 override_runtime_resource_overlay {
@@ -149,6 +166,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.settings.intelligence.googlecaruiportrait.rro",
     target_package_name: "com.android.settings.intelligence",
+    category: "caruiportrait.intelligence",
 }
 
 override_runtime_resource_overlay {
@@ -156,6 +174,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.htmlviewer.googlecaruiportrait.rro",
     target_package_name: "com.android.htmlviewer",
+    category: "caruiportrait.htmlviewer",
 }
 
 override_runtime_resource_overlay {
@@ -163,6 +182,7 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.permissioncontroller.googlecaruiportrait.rro",
     target_package_name: "com.android.permissioncontroller",
+    category: "caruiportrait.permissioncontroller",
 }
 
 override_runtime_resource_overlay {
@@ -170,5 +190,5 @@
     base: "GoogleCarUiPortraitBase",
     package_name: "com.android.car.portraitlauncher.googlecaruiportrait.rro",
     target_package_name: "com.android.car.portraitlauncher",
+    category: "caruiportrait.portraitlauncher",
 }
-
diff --git a/car_product/car_ui_portrait/rro/car-ui-customizations/AndroidManifest.xml b/car_product/car_ui_portrait/rro/car-ui-customizations/AndroidManifest.xml
index 68828d5..a129c2a 100644
--- a/car_product/car_ui_portrait/rro/car-ui-customizations/AndroidManifest.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-customizations/AndroidManifest.xml
@@ -22,7 +22,7 @@
              android:targetName="car-ui-lib"
              android:targetPackage="will.be.replaced.too"
              android:resourcesMap="@xml/overlays"
-             android:isStatic="true"
+             android:isStatic="false"
              android:requiredSystemPropertyName="ro.build.car_ui_rros_enabled"
              android:requiredSystemPropertyValue="true"/>
 </manifest>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/car-ui-customizations/res/layout/car_ui_base_layout_toolbar.xml b/car_product/car_ui_portrait/rro/car-ui-customizations/res/layout/car_ui_base_layout_toolbar.xml
index 618344e..2fe6549 100644
--- a/car_product/car_ui_portrait/rro/car-ui-customizations/res/layout/car_ui_base_layout_toolbar.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-customizations/res/layout/car_ui_base_layout_toolbar.xml
@@ -164,15 +164,6 @@
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"/>
-
-            <!-- Hairline across bottom of toolbar -->
-            <View
-                android:layout_width="match_parent"
-                android:layout_height="2dp"
-                android:background="@color/divider_color"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent" />
         </androidx.constraintlayout.widget.ConstraintLayout>
     </com.android.car.ui.FocusArea>
 
diff --git a/car_product/car_ui_portrait/rro/car-ui-customizations/res/values/styles.xml b/car_product/car_ui_portrait/rro/car-ui-customizations/res/values/styles.xml
index 64cebee..df8df11 100644
--- a/car_product/car_ui_portrait/rro/car-ui-customizations/res/values/styles.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-customizations/res/values/styles.xml
@@ -16,28 +16,22 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <style name="TextAppearance_CarUi_AlertDialog_Title" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textSize">36sp</item>
-        <item name="android:textStyle">bold</item>
+    <style name="TextAppearance_CarUi_AlertDialog_Title" parent="TextAppearance.Car.Subhead.Large">
     </style>
-    <style name="TextAppearance_CarUi_AlertDialog_Subtitle" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textSize">24sp</item>
+    <style name="TextAppearance_CarUi_AlertDialog_Subtitle" parent="TextAppearance.Car.Body.Medium">
     </style>
 
-    <style name="TextAppearance.CarUi.PreferenceCategoryTitle" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:fontFamily">sans-serif-medium</item>
-        <item name="android:textColor">?android:attr/colorAccent</item>
-        <item name="android:textSize">24sp</item>
+    <style name="TextAppearance.CarUi.PreferenceCategoryTitle"
+           parent="TextAppearance.Car.Subhead.Medium">
+        <item name="android:textColor">@color/car_on_surface_variant</item>
     </style>
 
-    <style name="TextAppearance.CarUi.PreferenceSummary" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textColor">?android:attr/textColorSecondary</item>
-        <item name="android:textSize">24sp</item>
+    <style name="TextAppearance.CarUi.PreferenceSummary" parent="TextAppearance.Car.Body.Small">
+        <item name="android:textColor">@color/car_on_surface_variant</item>
     </style>
 
-    <style name="TextAppearance.CarUi.PreferenceTitle" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
-        <item name="android:textSize">32sp</item>
+    <style name="TextAppearance.CarUi.PreferenceTitle" parent="TextAppearance.Car.Body.Small">
+        <item name="android:textColor">@color/car_on_surface_variant</item>
     </style>
 
     <style name="TextAppearance.CarUi.Widget" parent="android:TextAppearance.DeviceDefault.Widget">
@@ -46,9 +40,10 @@
 
     <style name="TextAppearance.CarUi.Widget.Toolbar"/>
 
-    <style name="TextAppearance.CarUi.Widget.Toolbar.Title">
+    <style name="TextAppearance.CarUi.Widget.Toolbar.Title"
+           parent="TextAppearance.Car.Subhead.Large">
         <item name="android:singleLine">true</item>
-        <item name="android:textSize">32sp</item>
+        <item name="android:textColor">@color/car_on_surface</item>
     </style>
 
     <style name="Widget.CarUi.Toolbar.Container"/>
@@ -60,7 +55,7 @@
         <item name="android:showDividers">beginning|middle|end</item>
     </style>
     <style name="Widget.CarUi.Toolbar.Subtitle">
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:textAppearance">@style/TextAppearance.Car.Subhead.Medium</item>
         <item name="android:textAlignment">viewStart</item>
     </style>
     <style name="Widget.CarUi.Toolbar.Title">
@@ -75,7 +70,7 @@
     <style name="Widget.CarUi" parent="android:Widget.DeviceDefault"/>
     <style name="Widget.CarUi.Toolbar.MenuItem"/>
     <style name="Widget.CarUi.Toolbar.NavIcon">
-        <item name="android:tint">@color/car_ui_toolbar_nav_icon_color</item>
+        <item name="android:tint">@color/car_on_surface</item>
         <item name="android:background">@drawable/car_ui_toolbar_menu_item_icon_ripple</item>
     </style>
 </resources>
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/Android.bp b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/Android.bp
index 4a371d7..411b2e1 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/Android.bp
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/Android.bp
@@ -20,6 +20,9 @@
     name: "GoogleCarUiPortraitToolbarBase",
     manifest: "AndroidManifest.xml",
     resource_dirs: ["res"],
+    static_libs: [
+        "car-portrait-ui-common"
+    ],
 }
 
 override_runtime_resource_overlay {
@@ -27,6 +30,7 @@
     base: "GoogleCarUiPortraitToolbarBase",
     package_name: "com.android.car.media.googlecaruiportrait.toolbar.rro",
     target_package_name: "com.android.car.media",
+    category: "caruiportrait.toolbar.media",
 }
 
 override_runtime_resource_overlay {
@@ -34,4 +38,5 @@
     base: "GoogleCarUiPortraitToolbarBase",
     package_name: "com.android.car.dialer.googlecaruiportrait.toolbar.rro",
     target_package_name: "com.android.car.dialer",
+    category: "caruiportrait.toolbar.dialer",
 }
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/AndroidManifest.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/AndroidManifest.xml
index d17c0d0..6c56042 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/AndroidManifest.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/AndroidManifest.xml
@@ -23,7 +23,7 @@
              android:targetName="car-ui-lib"
              android:targetPackage="will.be.replaced.too"
              android:resourcesMap="@xml/overlays"
-             android:isStatic="true"
+             android:isStatic="false"
              android:requiredSystemPropertyName="ro.build.car_ui_rros_enabled"
              android:requiredSystemPropertyValue="true"/>
 </manifest>
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
index b5e7d77..9d28c93 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
@@ -159,15 +159,6 @@
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent" />
 
-            <!-- Hairline across bottom of toolbar -->
-            <View
-                android:layout_width="match_parent"
-                android:layout_height="2dp"
-                android:background="@color/divider_color"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent" />
-
         </androidx.constraintlayout.widget.ConstraintLayout>
     </com.android.car.ui.FocusArea>
 
@@ -190,9 +181,9 @@
     <!-- Hairline to the right of the tabs -->
     <View
         android:id="@+id/car_ui_base_layout_divider"
-        android:layout_width="2dp"
+        android:layout_width="1dp"
         android:layout_height="0dp"
-        android:background="@color/divider_color"
+        android:background="@android:color/transparent"
         android:focusable="false"
         android:tag="car_ui_left_inset"
         app:layout_constraintLeft_toRightOf="@id/left_part_of_toolbar_focus_area"
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_toolbar_tab_item.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_toolbar_tab_item.xml
index 63ac2b4..66f9b11 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_toolbar_tab_item.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_toolbar_tab_item.xml
@@ -17,17 +17,10 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="320dp"
-    android:layout_height="96dp"
-    android:background="@drawable/tab_background">
-
-    <View
-        android:layout_width="8dp"
-        android:layout_height="match_parent"
-        android:background="@color/tab_side_indicator_color"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintStart_toStartOf="parent" />
+    android:layout_width="@dimen/car_portrait_ui_tab_width"
+    android:layout_height="@dimen/car_portrait_ui_tab_height"
+    android:layout_marginHorizontal="@dimen/car_portrait_ui_tab_margin_horizontal"
+    android:background="?android:attr/selectableItemBackground">
 
     <ImageView
         android:id="@+id/car_ui_toolbar_tab_item_icon"
diff --git a/car_product/car_ui_portrait/rro/car_ui_portrait_rro.mk b/car_product/car_ui_portrait/rro/car_ui_portrait_rro.mk
index 31d9282..5f5f889 100644
--- a/car_product/car_ui_portrait/rro/car_ui_portrait_rro.mk
+++ b/car_product/car_ui_portrait/rro/car_ui_portrait_rro.mk
@@ -46,4 +46,4 @@
 endif
 
 PRODUCT_PROPERTY_OVERRIDES += \
-    ro.boot.vendor.overlay.theme=com.android.car.dialer.caruiportrait.rro;com.google.android.car.evs.caruiportrait.rro;com.android.car.carlauncher.apps.caruiportrait.rro;com.android.car.caruiportrait.rro;com.android.car.carlauncher.media.caruiportrait.rro;com.android.car.media.common.caruiportrait.rro;com.android.car.media.caruiportrait.rro;com.android.car.notification.caruiportrait.rro;com.android.providers.settings.caruiportrait.emu.rro;com.android.providers.settings.caruiportrait.rro;com.android.car.settings.caruiportrait.rro;com.android.car.portraitlauncher.rro
+    ro.boot.vendor.overlay.theme=com.android.car.dialer.caruiportrait.rro;com.google.android.car.evs.caruiportrait.rro;com.android.car.carlauncher.apps.caruiportrait.rro;com.android.car.caruiportrait.rro;com.android.car.carlauncher.media.caruiportrait.rro;com.android.car.media.common.caruiportrait.rro;com.android.car.media.caruiportrait.rro;com.android.car.notification.caruiportrait.rro;com.android.providers.settings.caruiportrait.emu.rro;com.android.providers.settings.caruiportrait.rro;com.android.car.settings.caruiportrait.rro;com.android.car.portraitlauncher.rro;com.android.car.ui.paintbooth.googlecaruiportrait.rro;com.android.car.rotaryplayground.googlecaruiportrait.rro;com.android.car.themeplayground.googlecaruiportrait.rro;com.android.car.carlauncher.googlecaruiportrait.rro;com.android.car.home.googlecaruiportrait.rro;com.android.car.media.googlecaruiportrait.rro;com.android.car.messenger.googlecaruiportrait.rro;com.android.car.radio.googlecaruiportrait.rro;com.android.car.calendar.googlecaruiportrait.rro;com.android.car.systemupdater.googlecaruiportrait.rro;com.android.car.dialer.googlecaruiportrait.rro;com.android.car.linkviewer.googlecaruiportrait.rro;com.android.car.settings.googlecaruiportrait.rro;com.android.car.voicecontrol.googlecaruiportrait.rro;com.android.car.faceenroll.googlecaruiportrait.rro;com.android.car.developeroptions.googlecaruiportrait.rro;com.android.managedprovisioning.googlecaruiportrait.rro;com.android.settings.intelligence.googlecaruiportrait.rro;com.android.htmlviewer.googlecaruiportrait.rro;com.android.permissioncontroller.googlecaruiportrait.rro;com.android.car.portraitlauncher.googlecaruiportrait.rro;com.android.car.media.googlecaruiportrait.toolbar.rro;com.android.car.dialer.googlecaruiportrait.toolbar.rro
diff --git a/car_product/overlay/frameworks/base/core/res/res/xml/config_user_types.xml b/car_product/overlay/frameworks/base/core/res/res/xml/config_user_types.xml
index 1baae68..1ae8e14 100644
--- a/car_product/overlay/frameworks/base/core/res/res/xml/config_user_types.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/xml/config_user_types.xml
@@ -24,4 +24,8 @@
                   no_modify_accounts="true" no_install_apps="true" no_install_unknown_sources="true"
                   no_uninstall_apps="true"/>
     </full-type>
+
+    <profile-type name="android.os.usertype.profile.CLONE"
+        enabled='0' >
+    </profile-type>
 </user-types>
diff --git a/cpp/evs/apps/default/Android.bp b/cpp/evs/apps/default/Android.bp
index 6d0ca59..1e55d53 100644
--- a/cpp/evs/apps/default/Android.bp
+++ b/cpp/evs/apps/default/Android.bp
@@ -21,108 +21,79 @@
 
 cc_binary {
     name: "evs_app",
-
-    srcs: [
-        "evs_app.cpp",
-        "EvsStateControl.cpp",
-        "EvsStats.cpp",
-        "RenderBase.cpp",
-        "RenderDirectView.cpp",
-        "RenderTopView.cpp",
-        "ConfigManager.cpp",
-        "glError.cpp",
-        "shader.cpp",
-        "TexWrapper.cpp",
-        "VideoTex.cpp",
-        "StreamHandler.cpp",
-        "FormatConvert.cpp",
-        "RenderPixelCopy.cpp",
+    defaults: [
+        "android.hardware.graphics.common-ndk_shared",
+        "vhalclient_defaults",
     ],
-
+    local_include_dirs: ["inc"],
+    srcs: ["src/*.cpp"],
     shared_libs: [
+        "android.hardware.automotive.vehicle@2.0",
+        "android.hardware.camera.device@3.2",
+        "libEGL",
+        "libGLESv2",
         "libbase",
         "libbinder",
         "libbinder_ndk",
+        "libcamera_metadata",
+        "libcartelemetry-evs-proto",
         "libcutils",
-        "libutils",
-        "libui",
-        "libhidlbase",
-        "libEGL",
-        "libGLESv2",
         "libhardware",
         "libpng",
-        "libcamera_metadata",
-        "android.frameworks.automotive.telemetry-V1-ndk",
-        "android.hardware.camera.device@3.2",
-        "android.hardware.automotive.evs@1.0",
-        "android.hardware.automotive.evs@1.1",
-        "android.hardware.automotive.vehicle@2.0",
-        "libcartelemetry-evs-proto",
         "libprotobuf-cpp-lite",
+        "libui",
+        "libutils",
     ],
-
     static_libs: [
+        "android.frameworks.automotive.telemetry-V1-ndk",
+        "android.hardware.automotive.evs-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "libaidlcommonsupport",
         "libmath",
         "libjsoncpp",
         "libvhalclient",
     ],
-
     required: [
         "config.json",
         "CarFromTop.png",
         "LabeledChecker.png",
     ],
-
     init_rc: ["evs_app.rc"],
-
-    defaults: ["vhalclient_defaults"],
-
-    cflags: ["-DLOG_TAG=\"EvsApp\""] + [
+    cflags: [
+        "-DLOG_TAG=\"EvsApp\"",
         "-DGL_GLEXT_PROTOTYPES",
         "-DEGL_EGLEXT_PROTOTYPES",
-    ] + [
         "-Wall",
         "-Werror",
         "-Wunused",
         "-Wunreachable-code",
     ],
-
 }
 
 cc_library {
     name: "libcartelemetry-evs-proto",
-    srcs: [
-        ":cartelemetry-evs-proto-srcs",
-    ],
+    srcs: [":cartelemetry-evs-proto-srcs"],
     proto: {
         export_proto_headers: true,
         type: "lite",
     },
-    shared_libs: [
-        "libprotobuf-cpp-lite",
-    ],
+    shared_libs: ["libprotobuf-cpp-lite"],
 }
 
 prebuilt_etc {
     name: "config.json",
-
-    src: "config.json",
+    src: "res/config.json",
     sub_dir: "automotive/evs",
-
 }
 
 prebuilt_etc {
     name: "CarFromTop.png",
-
-    src: "CarFromTop.png",
+    src: "res/CarFromTop.png",
     sub_dir: "automotive/evs",
-
 }
 
 prebuilt_etc {
     name: "LabeledChecker.png",
-
-    src: "LabeledChecker.png",
+    src: "res/LabeledChecker.png",
     sub_dir: "automotive/evs",
-
 }
diff --git a/cpp/evs/apps/default/StreamHandler.h b/cpp/evs/apps/default/StreamHandler.h
deleted file mode 100644
index 1089046..0000000
--- a/cpp/evs/apps/default/StreamHandler.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2017 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 EVS_VTS_STREAMHANDLER_H
-#define EVS_VTS_STREAMHANDLER_H
-
-#include "ui/GraphicBuffer.h"
-
-#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
-#include <android/hardware/automotive/evs/1.1/IEvsCameraStream.h>
-#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
-
-#include <queue>
-
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::automotive::evs::V1_1::EvsEventDesc;
-using ::android::hardware::automotive::evs::V1_1::IEvsCamera;
-using ::android::hardware::automotive::evs::V1_1::IEvsCameraStream;
-using ::android::hardware::automotive::evs::V1_1::IEvsDisplay;
-
-using EvsDisplayState = ::android::hardware::automotive::evs::V1_0::DisplayState;
-using BufferDesc_1_0 = ::android::hardware::automotive::evs::V1_0::BufferDesc;
-using BufferDesc_1_1 = ::android::hardware::automotive::evs::V1_1::BufferDesc;
-
-/*
- * StreamHandler:
- * This class can be used to receive camera imagery from an IEvsCamera implementation.  It will
- * hold onto the most recent image buffer, returning older ones.
- * Note that the video frames are delivered on a background thread, while the control interface
- * is actuated from the applications foreground thread.
- */
-class StreamHandler : public IEvsCameraStream {
-public:
-    virtual ~StreamHandler() { shutdown(); };
-
-    StreamHandler(android::sp<IEvsCamera> pCamera, uint32_t numBuffers = 2,
-                  bool useOwnBuffers = false,
-                  android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888, int32_t width = 640,
-                  int32_t height = 360);
-    void shutdown();
-
-    bool startStream();
-    void asyncStopStream();
-    void blockingStopStream();
-
-    bool isRunning();
-
-    bool newFrameAvailable();
-    const BufferDesc_1_1& getNewFrame();
-    void doneWithFrame(const BufferDesc_1_1& buffer);
-
-private:
-    // Implementation for ::android::hardware::automotive::evs::V1_0::IEvsCameraStream
-    Return<void> deliverFrame(const BufferDesc_1_0& buffer) override;
-
-    // Implementation for ::android::hardware::automotive::evs::V1_1::IEvsCameraStream
-    Return<void> deliverFrame_1_1(const hidl_vec<BufferDesc_1_1>& buffer) override;
-    Return<void> notify(const EvsEventDesc& event) override;
-
-    // Values initialized as startup
-    android::sp<IEvsCamera> mCamera;
-
-    // Since we get frames delivered to us asnchronously via the ICarCameraStream interface,
-    // we need to protect all member variables that may be modified while we're streaming
-    // (ie: those below)
-    std::mutex mLock;
-    std::condition_variable mSignal;
-
-    bool mRunning = false;
-
-    BufferDesc_1_1 mBuffers[2];
-    int mHeldBuffer = -1;   // Index of the one currently held by the client
-    int mReadyBuffer = -1;  // Index of the newest available buffer
-    hidl_vec<BufferDesc_1_1> mOwnBuffers;
-    bool mUseOwnBuffers;
-};
-
-#endif  // EVS_VTS_STREAMHANDLER_H
diff --git a/cpp/evs/apps/default/VideoTex.h b/cpp/evs/apps/default/VideoTex.h
deleted file mode 100644
index 4d82950..0000000
--- a/cpp/evs/apps/default/VideoTex.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2017 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 VIDEOTEX_H
-#define VIDEOTEX_H
-
-#include "StreamHandler.h"
-#include "TexWrapper.h"
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
-
-#include <system/graphics-base.h>
-
-using ::android::hardware::automotive::evs::V1_1::BufferDesc;
-using ::android::hardware::automotive::evs::V1_1::IEvsCamera;
-using ::android::hardware::automotive::evs::V1_1::IEvsEnumerator;
-using ::android::hardware::camera::device::V3_2::Stream;
-
-class VideoTex : public TexWrapper {
-    friend VideoTex* createVideoTexture(android::sp<IEvsEnumerator> pEnum, const char* evsCameraId,
-                                        std::unique_ptr<Stream> streamCfg, EGLDisplay glDisplay,
-                                        bool useExternalMemory, android_pixel_format_t format);
-
-public:
-    VideoTex() = delete;
-    virtual ~VideoTex();
-
-    bool refresh();  // returns true if the texture contents were updated
-
-private:
-    VideoTex(android::sp<IEvsEnumerator> pEnum, android::sp<IEvsCamera> pCamera,
-             android::sp<StreamHandler> pStreamHandler, EGLDisplay glDisplay);
-
-    android::sp<IEvsEnumerator> mEnumerator;
-    android::sp<IEvsCamera> mCamera;
-    android::sp<StreamHandler> mStreamHandler;
-    BufferDesc mImageBuffer;
-
-    EGLDisplay mDisplay;
-    EGLImageKHR mKHRimage = EGL_NO_IMAGE_KHR;
-};
-
-// Creates a video texture to draw the camera preview.  format is effective only
-// when useExternalMemory is true.
-VideoTex* createVideoTexture(android::sp<IEvsEnumerator> pEnum, const char* deviceName,
-                             std::unique_ptr<Stream> streamCfg, EGLDisplay glDisplay,
-                             bool useExternalMemory = false,
-                             android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888);
-
-#endif  // VIDEOTEX_H
diff --git a/cpp/evs/apps/default/ConfigManager.h b/cpp/evs/apps/default/inc/ConfigManager.h
similarity index 99%
rename from cpp/evs/apps/default/ConfigManager.h
rename to cpp/evs/apps/default/inc/ConfigManager.h
index 6251b6b..8df0c4c 100644
--- a/cpp/evs/apps/default/ConfigManager.h
+++ b/cpp/evs/apps/default/inc/ConfigManager.h
@@ -22,7 +22,7 @@
 
 #include <system/graphics-base.h>
 
-class ConfigManager {
+class ConfigManager final {
 public:
     struct CameraInfo {
         std::string cameraId = "";  // The name of the camera from the point of view of the HAL
diff --git a/cpp/evs/apps/default/EvsStateControl.h b/cpp/evs/apps/default/inc/EvsStateControl.h
similarity index 76%
rename from cpp/evs/apps/default/EvsStateControl.h
rename to cpp/evs/apps/default/inc/EvsStateControl.h
index e852a8d..cbc7c0a 100644
--- a/cpp/evs/apps/default/EvsStateControl.h
+++ b/cpp/evs/apps/default/inc/EvsStateControl.h
@@ -22,34 +22,28 @@
 #include "RenderBase.h"
 #include "StreamHandler.h"
 
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
 #include <aidl/android/hardware/automotive/vehicle/VehiclePropValues.h>
-#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
-#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
 
 #include <IVhalClient.h>
 
 #include <thread>
 
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::automotive::evs::V1_1::CameraDesc;
-using ::android::hardware::automotive::evs::V1_1::IEvsDisplay;
-using ::android::hardware::automotive::evs::V1_1::IEvsEnumerator;
-using ::android::hardware::camera::device::V3_2::Stream;
-
 /*
  * This class runs the main update loop for the EVS application.  It will sleep when it has
  * nothing to do.  It provides a thread safe way for other threads to wake it and pass commands
  * to it.
  */
-class EvsStateControl {
+class EvsStateControl final {
 public:
-    EvsStateControl(std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> pVnet,
-                    android::sp<IEvsEnumerator> pEvs, android::sp<IEvsDisplay> pDisplay,
-                    const ConfigManager& config);
+    EvsStateControl(
+            std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> pVnet,
+            std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> pEvs,
+            const std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsDisplay>& pDisplay,
+            const ConfigManager& config);
 
     enum State {
         OFF = 0,
@@ -89,8 +83,8 @@
     bool configureEvsPipeline(State desiredState);  // Only call from one thread!
 
     std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> mVehicle;
-    android::sp<IEvsEnumerator> mEvs;
-    android::wp<IEvsDisplay> mDisplay;
+    std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> mEvs;
+    std::weak_ptr<aidl::android::hardware::automotive::evs::IEvsDisplay> mDisplay;
     const ConfigManager& mConfig;
 
     aidl::android::hardware::automotive::vehicle::VehiclePropValue mGearValue;
@@ -104,7 +98,7 @@
     std::vector<ConfigManager::CameraInfo> mCameraList[NUM_STATES];
     std::unique_ptr<RenderBase> mCurrentRenderer;
     std::unique_ptr<RenderBase> mDesiredRenderer;
-    std::vector<CameraDesc> mCameraDescList[NUM_STATES];
+    std::vector<aidl::android::hardware::automotive::evs::CameraDesc> mCameraDescList[NUM_STATES];
 
     std::thread mRenderThread;  // The thread that runs the main rendering loop
 
diff --git a/cpp/evs/apps/default/EvsStats.h b/cpp/evs/apps/default/inc/EvsStats.h
similarity index 99%
rename from cpp/evs/apps/default/EvsStats.h
rename to cpp/evs/apps/default/inc/EvsStats.h
index 0d9d47f..2e3416b 100644
--- a/cpp/evs/apps/default/EvsStats.h
+++ b/cpp/evs/apps/default/inc/EvsStats.h
@@ -29,7 +29,7 @@
 //
 // Not thread-safe. Methods `startComputingFirstFrameLatency`, `finishComputingFirstFrameLatency`
 // and `sendCollectedDataBlocking` must be called from the same thread.
-class EvsStats {
+class EvsStats final {
 public:
     // Instantiates EvsStats.
     static EvsStats build();
diff --git a/cpp/evs/apps/default/EvsVehicleListener.h b/cpp/evs/apps/default/inc/EvsVehicleListener.h
similarity index 95%
rename from cpp/evs/apps/default/EvsVehicleListener.h
rename to cpp/evs/apps/default/inc/EvsVehicleListener.h
index 9269e8e..f804395 100644
--- a/cpp/evs/apps/default/EvsVehicleListener.h
+++ b/cpp/evs/apps/default/inc/EvsVehicleListener.h
@@ -28,7 +28,8 @@
  * applications is active, it can poll the vehicle state directly.  However, when it goes to
  * sleep, we need these notifications to bring it active again.
  */
-class EvsVehicleListener : public android::frameworks::automotive::vhal::ISubscriptionCallback {
+class EvsVehicleListener final :
+      public android::frameworks::automotive::vhal::ISubscriptionCallback {
 public:
     void onPropertyEvent([[maybe_unused]] const std::vector<
                          std::unique_ptr<android::frameworks::automotive::vhal::IHalPropValue>>&
diff --git a/cpp/evs/apps/default/FormatConvert.h b/cpp/evs/apps/default/inc/FormatConvert.h
similarity index 87%
rename from cpp/evs/apps/default/FormatConvert.h
rename to cpp/evs/apps/default/inc/FormatConvert.h
index c506b88..2993a34 100644
--- a/cpp/evs/apps/default/FormatConvert.h
+++ b/cpp/evs/apps/default/inc/FormatConvert.h
@@ -17,16 +17,10 @@
 #ifndef EVS_VTS_FORMATCONVERT_H
 #define EVS_VTS_FORMATCONVERT_H
 
-#include <android/hardware/automotive/evs/1.0/types.h>
-#include <android/hardware/automotive/evs/1.1/types.h>
-
 #include <stdint.h>
 
 #include <queue>
 
-using BufferDesc_1_0 = ::android::hardware::automotive::evs::V1_0::BufferDesc;
-using BufferDesc_1_1 = ::android::hardware::automotive::evs::V1_1::BufferDesc;
-
 // Given an image buffer in NV21 format (HAL_PIXEL_FORMAT_YCRCB_420_SP), output 32bit RGBx values.
 // The NV21 format provides a Y array of 8bit values, followed by a 1/2 x 1/2 interleaved
 // U/V array.  It assumes an even width and height for the overall image, and a horizontal
@@ -56,7 +50,4 @@
                                    unsigned srcStridePixels, void* dst, unsigned dstStridePixels,
                                    unsigned pixelSize);
 
-// Fill BufferDesc v1.1 with a given BufferDesc v1.0 data.
-BufferDesc_1_1 convertBufferDesc(const BufferDesc_1_0& src);
-
 #endif  // EVS_VTS_FORMATCONVERT_H
diff --git a/cpp/evs/apps/default/RenderBase.h b/cpp/evs/apps/default/inc/RenderBase.h
similarity index 84%
rename from cpp/evs/apps/default/RenderBase.h
rename to cpp/evs/apps/default/inc/RenderBase.h
index e15f705..8f594a1 100644
--- a/cpp/evs/apps/default/RenderBase.h
+++ b/cpp/evs/apps/default/inc/RenderBase.h
@@ -23,9 +23,7 @@
 #include <GLES2/gl2ext.h>
 #include <GLES3/gl3.h>
 #include <GLES3/gl3ext.h>
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
-
-using ::android::hardware::automotive::evs::V1_1::BufferDesc;
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
 
 /*
  * Abstract base class for the workhorse classes that handle the user interaction and display for
@@ -38,12 +36,14 @@
     virtual bool activate() = 0;
     virtual void deactivate() = 0;
 
-    virtual bool drawFrame(const BufferDesc& tgtBuffer) = 0;
+    virtual bool drawFrame(
+            const aidl::android::hardware::automotive::evs::BufferDesc& tgtBuffer) = 0;
 
 protected:
     static bool prepareGL();
 
-    static bool attachRenderTarget(const BufferDesc& tgtBuffer);
+    static bool attachRenderTarget(
+            const aidl::android::hardware::automotive::evs::BufferDesc& tgtBuffer);
     static void detachRenderTarget();
 
     // OpenGL state shared among all renderers
diff --git a/cpp/evs/apps/default/RenderDirectView.h b/cpp/evs/apps/default/inc/RenderDirectView.h
similarity index 62%
rename from cpp/evs/apps/default/RenderDirectView.h
rename to cpp/evs/apps/default/inc/RenderDirectView.h
index 151e148..4eb47b3 100644
--- a/cpp/evs/apps/default/RenderDirectView.h
+++ b/cpp/evs/apps/default/inc/RenderDirectView.h
@@ -21,30 +21,30 @@
 #include "RenderBase.h"
 #include "VideoTex.h"
 
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
 #include <math/mat2.h>
 
-using ::android::hardware::automotive::evs::V1_1::BufferDesc;
-using ::android::hardware::automotive::evs::V1_1::CameraDesc;
-using ::android::hardware::automotive::evs::V1_1::IEvsEnumerator;
-
 /*
  * Renders the view from a single specified camera directly to the full display.
  */
-class RenderDirectView : public RenderBase {
+class RenderDirectView final : public RenderBase {
 public:
-    RenderDirectView(android::sp<IEvsEnumerator> enumerator, const CameraDesc& camDesc,
-                     const ConfigManager& config);
+    RenderDirectView(
+            std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> enumerator,
+            const aidl::android::hardware::automotive::evs::CameraDesc& camDesc,
+            const ConfigManager& config);
 
     virtual bool activate() override;
     virtual void deactivate() override;
 
-    virtual bool drawFrame(const BufferDesc& tgtBuffer);
+    virtual bool drawFrame(const aidl::android::hardware::automotive::evs::BufferDesc& tgtBuffer);
 
 protected:
-    android::sp<IEvsEnumerator> mEnumerator;
+    std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> mEnumerator;
     ConfigManager::CameraInfo mCameraInfo;
-    CameraDesc mCameraDesc;
+    aidl::android::hardware::automotive::evs::CameraDesc mCameraDesc;
     const ConfigManager& mConfig;
 
     std::unique_ptr<VideoTex> mTexture;
diff --git a/cpp/evs/apps/default/RenderPixelCopy.h b/cpp/evs/apps/default/inc/RenderPixelCopy.h
similarity index 64%
rename from cpp/evs/apps/default/RenderPixelCopy.h
rename to cpp/evs/apps/default/inc/RenderPixelCopy.h
index 283b9c8..f8da412 100644
--- a/cpp/evs/apps/default/RenderPixelCopy.h
+++ b/cpp/evs/apps/default/inc/RenderPixelCopy.h
@@ -21,27 +21,28 @@
 #include "RenderBase.h"
 #include "VideoTex.h"
 
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
-
-using ::android::hardware::automotive::evs::V1_1::IEvsEnumerator;
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
 
 /*
  * Renders the view from a single specified camera directly to the full display.
  */
-class RenderPixelCopy : public RenderBase {
+class RenderPixelCopy final : public RenderBase {
 public:
-    RenderPixelCopy(android::sp<IEvsEnumerator> enumerator, const ConfigManager::CameraInfo& cam);
+    RenderPixelCopy(
+            std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> enumerator,
+            const ConfigManager::CameraInfo& cam);
 
     virtual bool activate() override;
     virtual void deactivate() override;
 
-    virtual bool drawFrame(const BufferDesc& tgtBuffer);
+    virtual bool drawFrame(const aidl::android::hardware::automotive::evs::BufferDesc& tgtBuffer);
 
 protected:
-    android::sp<IEvsEnumerator> mEnumerator;
+    std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> mEnumerator;
     ConfigManager::CameraInfo mCameraInfo;
 
-    android::sp<StreamHandler> mStreamHandler;
+    std::shared_ptr<StreamHandler> mStreamHandler;
 };
 
 #endif  // CAR_EVS_APP_RENDERPIXELCOPY_H
diff --git a/cpp/evs/apps/default/RenderTopView.h b/cpp/evs/apps/default/inc/RenderTopView.h
similarity index 74%
rename from cpp/evs/apps/default/RenderTopView.h
rename to cpp/evs/apps/default/inc/RenderTopView.h
index cd9ca30..d9cccc6 100644
--- a/cpp/evs/apps/default/RenderTopView.h
+++ b/cpp/evs/apps/default/inc/RenderTopView.h
@@ -21,24 +21,23 @@
 #include "RenderBase.h"
 #include "VideoTex.h"
 
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
 #include <math/mat4.h>
 
-using ::android::hardware::automotive::evs::V1_1::BufferDesc;
-
 /*
  * Combines the views from all available cameras into one reprojected top down view.
  */
-class RenderTopView : public RenderBase {
+class RenderTopView final : public RenderBase {
 public:
-    RenderTopView(android::sp<IEvsEnumerator> enumerator,
-                  const std::vector<ConfigManager::CameraInfo>& camList,
-                  const ConfigManager& config);
+    RenderTopView(
+            std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> enumerator,
+            const std::vector<ConfigManager::CameraInfo>& camList, const ConfigManager& config);
 
     virtual bool activate() override;
     virtual void deactivate() override;
 
-    virtual bool drawFrame(const BufferDesc& tgtBuffer);
+    virtual bool drawFrame(const aidl::android::hardware::automotive::evs::BufferDesc& tgtBuffer);
 
 protected:
     struct ActiveCamera {
@@ -51,7 +50,7 @@
     void renderCarTopView();
     void renderCameraOntoGroundPlane(const ActiveCamera& cam);
 
-    android::sp<IEvsEnumerator> mEnumerator;
+    std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> mEnumerator;
     const ConfigManager& mConfig;
     std::vector<ActiveCamera> mActiveCameras;
 
diff --git a/cpp/evs/apps/default/inc/StreamHandler.h b/cpp/evs/apps/default/inc/StreamHandler.h
new file mode 100644
index 0000000..3d291e2
--- /dev/null
+++ b/cpp/evs/apps/default/inc/StreamHandler.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 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 EVS_VTS_STREAMHANDLER_H
+#define EVS_VTS_STREAMHANDLER_H
+
+#include <aidl/android/hardware/automotive/evs/BnEvsCameraStream.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/DisplayState.h>
+#include <aidl/android/hardware/automotive/evs/EvsEventDesc.h>
+#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
+#include <aidl/android/hardware/graphics/common/HardwareBuffer.h>
+#include <ui/GraphicBuffer.h>
+
+#include <queue>
+
+/*
+ * StreamHandler:
+ * This class can be used to receive camera imagery from an IEvsCamera implementation.  It will
+ * hold onto the most recent image buffer, returning older ones.
+ * Note that the video frames are delivered on a background thread, while the control interface
+ * is actuated from the applications foreground thread.
+ */
+class StreamHandler final : public aidl::android::hardware::automotive::evs::BnEvsCameraStream {
+public:
+    virtual ~StreamHandler() { shutdown(); };
+
+    StreamHandler(
+            const std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsCamera>& cameraObj,
+            uint32_t numBuffers = 2, bool useOwnBuffers = false,
+            android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888, int32_t width = 640,
+            int32_t height = 360);
+    void shutdown();
+
+    bool startStream();
+    void asyncStopStream();
+    void blockingStopStream();
+
+    bool isRunning();
+
+    bool newFrameAvailable();
+    const aidl::android::hardware::automotive::evs::BufferDesc& getNewFrame();
+    void doneWithFrame(const aidl::android::hardware::automotive::evs::BufferDesc& buffer);
+
+private:
+    // Implementation for aidl::android::hardware::automotive::evs::IEvsCameraStream
+    ndk::ScopedAStatus deliverFrame(
+            const std::vector<aidl::android::hardware::automotive::evs::BufferDesc>& buffers)
+            override;
+    ndk::ScopedAStatus notify(
+            const aidl::android::hardware::automotive::evs::EvsEventDesc& event) override;
+
+    // Values initialized as startup
+    std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsCamera> mCamera;
+
+    // Since we get frames delivered to us asnchronously via the IEvsCameraStream interface,
+    // we need to protect all member variables that may be modified while we're streaming
+    // (i.e.: those below)
+    std::mutex mLock;
+    std::condition_variable mSignal;
+
+    bool mRunning = false;
+
+    aidl::android::hardware::automotive::evs::BufferDesc mBuffers[2];
+    int mHeldBuffer = -1;   // Index of the one currently held by the client
+    int mReadyBuffer = -1;  // Index of the newest available buffer
+    std::vector<aidl::android::hardware::automotive::evs::BufferDesc> mOwnBuffers;
+    bool mUseOwnBuffers;
+};
+
+#endif  // EVS_VTS_STREAMHANDLER_H
diff --git a/cpp/evs/apps/default/TexWrapper.h b/cpp/evs/apps/default/inc/TexWrapper.h
similarity index 100%
rename from cpp/evs/apps/default/TexWrapper.h
rename to cpp/evs/apps/default/inc/TexWrapper.h
diff --git a/cpp/evs/apps/default/inc/Utils.h b/cpp/evs/apps/default/inc/Utils.h
new file mode 100644
index 0000000..ed17d00
--- /dev/null
+++ b/cpp/evs/apps/default/inc/Utils.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <cutils/native_handle.h>
+
+aidl::android::hardware::automotive::evs::BufferDesc dupBufferDesc(
+        const aidl::android::hardware::automotive::evs::BufferDesc& src);
+native_handle_t* getNativeHandle(
+        const aidl::android::hardware::automotive::evs::BufferDesc& buffer);
diff --git a/cpp/evs/apps/default/inc/VideoTex.h b/cpp/evs/apps/default/inc/VideoTex.h
new file mode 100644
index 0000000..0667bc0
--- /dev/null
+++ b/cpp/evs/apps/default/inc/VideoTex.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 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 VIDEOTEX_H
+#define VIDEOTEX_H
+
+#include "StreamHandler.h"
+#include "TexWrapper.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
+#include <aidl/android/hardware/automotive/evs/Stream.h>
+
+#include <system/graphics-base.h>
+
+class VideoTex final : public TexWrapper {
+    friend VideoTex* createVideoTexture(
+            const std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator>& pEnum,
+            const char* evsCameraId,
+            std::unique_ptr<aidl::android::hardware::automotive::evs::Stream> streamCfg,
+            EGLDisplay glDisplay, bool useExternalMemory, android_pixel_format_t format);
+
+public:
+    VideoTex() = delete;
+    virtual ~VideoTex();
+
+    bool refresh();  // returns true if the texture contents were updated
+
+private:
+    VideoTex(std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> pEnum,
+             std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsCamera> pCamera,
+             std::shared_ptr<StreamHandler> pStreamHandler, EGLDisplay glDisplay);
+
+    std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> mEnumerator;
+    std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsCamera> mCamera;
+    std::shared_ptr<StreamHandler> mStreamHandler;
+    aidl::android::hardware::automotive::evs::BufferDesc mImageBuffer;
+
+    EGLDisplay mDisplay;
+    EGLImageKHR mKHRimage = EGL_NO_IMAGE_KHR;
+};
+
+// Creates a video texture to draw the camera preview.  format is effective only
+// when useExternalMemory is true.
+VideoTex* createVideoTexture(
+        const std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator>& pEnum,
+        const char* deviceName,
+        std::unique_ptr<aidl::android::hardware::automotive::evs::Stream> streamCfg,
+        EGLDisplay glDisplay, bool useExternalMemory = false,
+        android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888);
+
+#endif  // VIDEOTEX_H
diff --git a/cpp/evs/apps/default/glError.h b/cpp/evs/apps/default/inc/glError.h
similarity index 100%
rename from cpp/evs/apps/default/glError.h
rename to cpp/evs/apps/default/inc/glError.h
diff --git a/cpp/evs/apps/default/shader.h b/cpp/evs/apps/default/inc/shader.h
similarity index 100%
rename from cpp/evs/apps/default/shader.h
rename to cpp/evs/apps/default/inc/shader.h
diff --git a/cpp/evs/apps/default/shader_projectedTex.h b/cpp/evs/apps/default/inc/shader_projectedTex.h
similarity index 100%
rename from cpp/evs/apps/default/shader_projectedTex.h
rename to cpp/evs/apps/default/inc/shader_projectedTex.h
diff --git a/cpp/evs/apps/default/shader_simpleTex.h b/cpp/evs/apps/default/inc/shader_simpleTex.h
similarity index 100%
rename from cpp/evs/apps/default/shader_simpleTex.h
rename to cpp/evs/apps/default/inc/shader_simpleTex.h
diff --git a/cpp/evs/apps/default/CarFromTop.png b/cpp/evs/apps/default/res/CarFromTop.png
similarity index 100%
rename from cpp/evs/apps/default/CarFromTop.png
rename to cpp/evs/apps/default/res/CarFromTop.png
Binary files differ
diff --git a/cpp/evs/apps/default/LabeledChecker.png b/cpp/evs/apps/default/res/LabeledChecker.png
similarity index 100%
rename from cpp/evs/apps/default/LabeledChecker.png
rename to cpp/evs/apps/default/res/LabeledChecker.png
Binary files differ
diff --git a/cpp/evs/apps/default/config.json b/cpp/evs/apps/default/res/config.json
similarity index 100%
rename from cpp/evs/apps/default/config.json
rename to cpp/evs/apps/default/res/config.json
diff --git a/cpp/evs/apps/default/config.json.readme b/cpp/evs/apps/default/res/config.json.readme
similarity index 100%
rename from cpp/evs/apps/default/config.json.readme
rename to cpp/evs/apps/default/res/config.json.readme
diff --git a/cpp/evs/apps/default/ConfigManager.cpp b/cpp/evs/apps/default/src/ConfigManager.cpp
similarity index 100%
rename from cpp/evs/apps/default/ConfigManager.cpp
rename to cpp/evs/apps/default/src/ConfigManager.cpp
diff --git a/cpp/evs/apps/default/EvsStateControl.cpp b/cpp/evs/apps/default/src/EvsStateControl.cpp
similarity index 74%
rename from cpp/evs/apps/default/EvsStateControl.cpp
rename to cpp/evs/apps/default/src/EvsStateControl.cpp
index e2cdba4..dbcd58a 100644
--- a/cpp/evs/apps/default/EvsStateControl.cpp
+++ b/cpp/evs/apps/default/src/EvsStateControl.cpp
@@ -20,6 +20,10 @@
 #include "RenderPixelCopy.h"
 #include "RenderTopView.h"
 
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/DisplayState.h>
+#include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleGear.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
 #include <aidl/android/hardware/automotive/vehicle/VehiclePropertyType.h>
@@ -32,23 +36,25 @@
 #include <stdio.h>
 #include <string.h>
 
-using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
-using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
-using ::aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
-using ::android::base::Result;
-using ::android::frameworks::automotive::vhal::ErrorCode;
-using ::android::frameworks::automotive::vhal::IHalPropValue;
-using ::android::frameworks::automotive::vhal::IVhalClient;
-using ::android::frameworks::automotive::vhal::VhalClientResult;
-using ::android::hardware::automotive::evs::V1_0::EvsResult;
-using EvsDisplayState = ::android::hardware::automotive::evs::V1_0::DisplayState;
-using BufferDesc_1_0 = ::android::hardware::automotive::evs::V1_0::BufferDesc;
-using BufferDesc_1_1 = ::android::hardware::automotive::evs::V1_1::BufferDesc;
+namespace {
 
-static bool isSfReady() {
-    return ::ndk::SpAIBinder(::AServiceManager_getService("SurfaceFlinger")).get() != nullptr;
+using aidl::android::hardware::automotive::evs::BufferDesc;
+using aidl::android::hardware::automotive::evs::CameraDesc;
+using aidl::android::hardware::automotive::evs::DisplayState;
+using aidl::android::hardware::automotive::evs::IEvsDisplay;
+using aidl::android::hardware::automotive::evs::IEvsEnumerator;
+using aidl::android::hardware::automotive::vehicle::VehicleGear;
+using aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
+using aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
+using android::frameworks::automotive::vhal::ErrorCode;
+using android::frameworks::automotive::vhal::IHalPropValue;
+using android::frameworks::automotive::vhal::IVhalClient;
+using android::frameworks::automotive::vhal::VhalClientResult;
+
+bool isSfReady() {
+    return ndk::SpAIBinder(AServiceManager_getService("SurfaceFlinger")).get() != nullptr;
 }
 
 inline constexpr VehiclePropertyType getPropType(VehicleProperty prop) {
@@ -56,9 +62,12 @@
                                             static_cast<int32_t>(VehiclePropertyType::MASK));
 }
 
+}  // namespace
+
 EvsStateControl::EvsStateControl(std::shared_ptr<IVhalClient> pVnet,
-                                 android::sp<IEvsEnumerator> pEvs,
-                                 android::sp<IEvsDisplay> pDisplay, const ConfigManager& config) :
+                                 std::shared_ptr<IEvsEnumerator> pEvs,
+                                 const std::shared_ptr<IEvsDisplay>& pDisplay,
+                                 const ConfigManager& config) :
       mVehicle(pVnet),
       mEvs(pEvs),
       mDisplay(pDisplay),
@@ -77,48 +86,52 @@
     // This way we only ever deal with cameras which exist in the system
     // Build our set of cameras for the states we support
     LOG(DEBUG) << "Requesting camera list";
-    mEvs->getCameraList_1_1([this, &config](hidl_vec<CameraDesc> cameraList) {
-        LOG(INFO) << "Camera list callback received " << cameraList.size() << "cameras.";
-        for (auto&& cam : cameraList) {
-            LOG(DEBUG) << "Found camera " << cam.v1.cameraId;
-            bool cameraConfigFound = false;
+    std::vector<CameraDesc> cameraList;
+    if (auto status = mEvs->getCameraList(&cameraList); !status.isOk()) {
+        LOG(ERROR) << "Failed to get the camera list.";
+        return;
+    }
 
-            // Check our configuration for information about this camera
-            // Note that a camera can have a compound function string
-            // such that a camera can be "right/reverse" and be used for both.
-            // If more than one camera is listed for a given function, we'll
-            // list all of them and let the UX/rendering logic use one, some
-            // or all of them as appropriate.
-            for (auto&& info : config.getCameras()) {
-                if (cam.v1.cameraId == info.cameraId) {
-                    // We found a match!
-                    if (info.function.find("reverse") != std::string::npos) {
-                        mCameraList[State::REVERSE].emplace_back(info);
-                        mCameraDescList[State::REVERSE].emplace_back(cam);
-                    }
-                    if (info.function.find("right") != std::string::npos) {
-                        mCameraList[State::RIGHT].emplace_back(info);
-                        mCameraDescList[State::RIGHT].emplace_back(cam);
-                    }
-                    if (info.function.find("left") != std::string::npos) {
-                        mCameraList[State::LEFT].emplace_back(info);
-                        mCameraDescList[State::LEFT].emplace_back(cam);
-                    }
-                    if (info.function.find("park") != std::string::npos) {
-                        mCameraList[State::PARKING].emplace_back(info);
-                        mCameraDescList[State::PARKING].emplace_back(cam);
-                    }
-                    cameraConfigFound = true;
-                    break;
+    LOG(INFO) << "Camera list callback received " << cameraList.size() << "cameras.";
+    for (auto&& cam : cameraList) {
+        LOG(DEBUG) << "Found camera " << cam.id;
+        bool cameraConfigFound = false;
+
+        // Check our configuration for information about this camera
+        // Note that a camera can have a compound function string
+        // such that a camera can be "right/reverse" and be used for both.
+        // If more than one camera is listed for a given function, we'll
+        // list all of them and let the UX/rendering logic use one, some
+        // or all of them as appropriate.
+        for (auto&& info : config.getCameras()) {
+            if (cam.id == info.cameraId) {
+                // We found a match!
+                if (info.function.find("reverse") != std::string::npos) {
+                    mCameraList[State::REVERSE].emplace_back(info);
+                    mCameraDescList[State::REVERSE].emplace_back(cam);
                 }
-            }
-            if (!cameraConfigFound) {
-                LOG(WARNING) << "No config information for hardware camera " << cam.v1.cameraId;
+                if (info.function.find("right") != std::string::npos) {
+                    mCameraList[State::RIGHT].emplace_back(info);
+                    mCameraDescList[State::RIGHT].emplace_back(cam);
+                }
+                if (info.function.find("left") != std::string::npos) {
+                    mCameraList[State::LEFT].emplace_back(info);
+                    mCameraDescList[State::LEFT].emplace_back(cam);
+                }
+                if (info.function.find("park") != std::string::npos) {
+                    mCameraList[State::PARKING].emplace_back(info);
+                    mCameraDescList[State::PARKING].emplace_back(cam);
+                }
+                cameraConfigFound = true;
+                break;
             }
         }
-    });
+        if (!cameraConfigFound) {
+            LOG(WARNING) << "No config information for hardware camera " << cam.id;
+        }
+    }
 
-    LOG(DEBUG) << "State controller ready";
+    LOG(INFO) << "State controller ready";
 }
 
 bool EvsStateControl::startUpdateLoop() {
@@ -158,9 +171,9 @@
     bool run = true;
     while (run) {
         // Process incoming commands
-        android::sp<IEvsDisplay> displayHandle;
+        std::shared_ptr<IEvsDisplay> displayHandle;
         {
-            std::lock_guard<std::mutex> lock(mLock);
+            std::lock_guard lock(mLock);
             while (!mCommandQueue.empty()) {
                 const Command& cmd = mCommandQueue.front();
                 switch (cmd.operation) {
@@ -177,7 +190,7 @@
                 mCommandQueue.pop();
             }
 
-            displayHandle = mDisplay.promote();
+            displayHandle = mDisplay.lock();
         }
 
         if (!displayHandle) {
@@ -194,16 +207,13 @@
         // If we have an active renderer, give it a chance to draw
         if (mCurrentRenderer) {
             // Get the output buffer we'll use to display the imagery
-            BufferDesc_1_0 tgtBuffer = {};
-            displayHandle->getTargetBuffer(
-                    [&tgtBuffer](const BufferDesc_1_0& buff) { tgtBuffer = buff; });
-
-            if (tgtBuffer.memHandle == nullptr) {
+            BufferDesc tgtBuffer;
+            if (auto status = displayHandle->getTargetBuffer(&tgtBuffer); !status.isOk()) {
                 LOG(ERROR) << "Didn't get requested output buffer -- skipping this frame.";
                 run = false;
             } else {
                 // Generate our output image
-                if (!mCurrentRenderer->drawFrame(convertBufferDesc(tgtBuffer))) {
+                if (!mCurrentRenderer->drawFrame(tgtBuffer)) {
                     // If drawing failed, we want to exit quickly so an app restart can happen
                     run = false;
                 }
@@ -365,20 +375,20 @@
     }
 
     // Since we're changing states, shut down the current renderer
-    if (mCurrentRenderer != nullptr) {
+    if (mCurrentRenderer) {
         mCurrentRenderer->deactivate();
-        mCurrentRenderer = nullptr;  // It's a smart pointer, so destructs on assignment to null
+        mCurrentRenderer.reset();
     }
 
     // Now set the display state based on whether we have a video feed to show
-    android::sp<IEvsDisplay> displayHandle = mDisplay.promote();
+    std::shared_ptr<IEvsDisplay> displayHandle = mDisplay.lock();
     if (!displayHandle) {
         return false;
     }
 
-    if (mDesiredRenderer == nullptr) {
+    if (!mDesiredRenderer) {
         LOG(DEBUG) << "Turning off the display";
-        displayHandle->setDisplayState(EvsDisplayState::NOT_VISIBLE);
+        displayHandle->setDisplayState(DisplayState::NOT_VISIBLE);
     } else {
         mCurrentRenderer = std::move(mDesiredRenderer);
 
@@ -393,10 +403,9 @@
         // Activate the display
         LOG(DEBUG) << "EvsActivateDisplayTiming start time: " << android::elapsedRealtime()
                    << " ms.";
-        Return<EvsResult> result =
-                displayHandle->setDisplayState(EvsDisplayState::VISIBLE_ON_NEXT_FRAME);
-        if (result != EvsResult::OK) {
-            LOG(ERROR) << "setDisplayState returned an error " << result.description();
+        if (auto status = displayHandle->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME);
+            !status.isOk()) {
+            LOG(ERROR) << "Failed to set a display state as VISIBLE_ON_NEXT_FRAME.";
             return false;
         }
     }
@@ -407,7 +416,7 @@
 
     mFirstFrameIsDisplayed = false;  // Got a new renderer, mark first frame is not displayed.
 
-    if (mCurrentRenderer != nullptr && desiredState == State::REVERSE) {
+    if (mCurrentRenderer && desiredState == State::REVERSE) {
         // Start computing the latency when the evs state changes.
         mEvsStats.startComputingFirstFrameLatency(desiredStateTimeMillis);
     }
diff --git a/cpp/evs/apps/default/EvsStats.cpp b/cpp/evs/apps/default/src/EvsStats.cpp
similarity index 100%
rename from cpp/evs/apps/default/EvsStats.cpp
rename to cpp/evs/apps/default/src/EvsStats.cpp
diff --git a/cpp/evs/apps/default/FormatConvert.cpp b/cpp/evs/apps/default/src/FormatConvert.cpp
similarity index 91%
rename from cpp/evs/apps/default/FormatConvert.cpp
rename to cpp/evs/apps/default/src/FormatConvert.cpp
index 499d405..768c489 100644
--- a/cpp/evs/apps/default/FormatConvert.cpp
+++ b/cpp/evs/apps/default/src/FormatConvert.cpp
@@ -152,20 +152,3 @@
         dst = (uint8_t*)dst + dstStridePixels * pixelSize;
     }
 }
-
-BufferDesc_1_1 convertBufferDesc(const BufferDesc_1_0& src) {
-    BufferDesc_1_1 dst = {};
-    AHardwareBuffer_Desc* pDesc = reinterpret_cast<AHardwareBuffer_Desc*>(&dst.buffer.description);
-    pDesc->width = src.width;
-    pDesc->height = src.height;
-    pDesc->layers = 1;
-    pDesc->format = src.format;
-    pDesc->usage = static_cast<uint64_t>(src.usage);
-    pDesc->stride = src.stride;
-
-    dst.buffer.nativeHandle = src.memHandle;
-    dst.pixelSize = src.pixelSize;
-    dst.bufferId = src.bufferId;
-
-    return dst;
-}
diff --git a/cpp/evs/apps/default/RenderBase.cpp b/cpp/evs/apps/default/src/RenderBase.cpp
similarity index 90%
rename from cpp/evs/apps/default/RenderBase.cpp
rename to cpp/evs/apps/default/src/RenderBase.cpp
index f4728a4..4d009f6 100644
--- a/cpp/evs/apps/default/RenderBase.cpp
+++ b/cpp/evs/apps/default/src/RenderBase.cpp
@@ -16,16 +16,26 @@
 
 #include "RenderBase.h"
 
+#include "Utils.h"
 #include "glError.h"
 
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidlcommonsupport/NativeHandle.h>
 #include <android-base/logging.h>
+#include <android-base/scopeguard.h>
 #include <ui/GraphicBuffer.h>
 
+namespace {
+
+using aidl::android::hardware::automotive::evs::BufferDesc;
+
 // Eventually we shouldn't need this dependency, but for now the
 // graphics allocator interface isn't fully supported on all platforms
 // and this is our work around.
 using ::android::GraphicBuffer;
 
+}  // namespace
+
 // OpenGL state shared among all renderers
 EGLDisplay RenderBase::sDisplay = EGL_NO_DISPLAY;
 EGLContext RenderBase::sContext = EGL_NO_CONTEXT;
@@ -131,6 +141,14 @@
 }
 
 bool RenderBase::attachRenderTarget(const BufferDesc& tgtBuffer) {
+    native_handle_t* nativeHandle = getNativeHandle(tgtBuffer);
+    if (nativeHandle == nullptr) {
+        LOG(ERROR) << "Target buffer is invalid.";
+        return false;
+    }
+
+    const auto handleGuard =
+            android::base::make_scope_guard([nativeHandle] { free(nativeHandle); });
     const AHardwareBuffer_Desc* pDesc =
             reinterpret_cast<const AHardwareBuffer_Desc*>(&tgtBuffer.buffer.description);
     // Hardcoded to RGBx for now
@@ -141,9 +159,9 @@
 
     // create a GraphicBuffer from the existing handle
     android::sp<GraphicBuffer> pGfxBuffer =
-            new GraphicBuffer(tgtBuffer.buffer.nativeHandle, GraphicBuffer::CLONE_HANDLE,
-                              pDesc->width, pDesc->height, pDesc->format, pDesc->layers,
-                              GRALLOC_USAGE_HW_RENDER, pDesc->stride);
+            new GraphicBuffer(nativeHandle, GraphicBuffer::CLONE_HANDLE, pDesc->width,
+                              pDesc->height, pDesc->format, pDesc->layers, GRALLOC_USAGE_HW_RENDER,
+                              pDesc->stride);
     if (pGfxBuffer.get() == nullptr) {
         LOG(ERROR) << "Failed to allocate GraphicBuffer to wrap image handle";
         return false;
diff --git a/cpp/evs/apps/default/RenderDirectView.cpp b/cpp/evs/apps/default/src/RenderDirectView.cpp
similarity index 90%
rename from cpp/evs/apps/default/RenderDirectView.cpp
rename to cpp/evs/apps/default/src/RenderDirectView.cpp
index 5df2db1..806b559 100644
--- a/cpp/evs/apps/default/RenderDirectView.cpp
+++ b/cpp/evs/apps/default/src/RenderDirectView.cpp
@@ -21,13 +21,20 @@
 #include "shader.h"
 #include "shader_simpleTex.h"
 
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
+#include <aidl/android/hardware/automotive/evs/Stream.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
 #include <android-base/logging.h>
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
 #include <math/mat4.h>
 #include <system/camera_metadata.h>
 
-using ::android::hardware::camera::device::V3_2::Stream;
-using ::android::hardware::graphics::common::V1_0::PixelFormat;
+namespace {
+
+using aidl::android::hardware::automotive::evs::BufferDesc;
+using aidl::android::hardware::automotive::evs::CameraDesc;
+using aidl::android::hardware::automotive::evs::IEvsEnumerator;
+using aidl::android::hardware::automotive::evs::Stream;
 
 typedef struct {
     int32_t id;
@@ -40,14 +47,16 @@
 
 const size_t kStreamCfgSz = sizeof(RawStreamConfig) / sizeof(int32_t);
 
-RenderDirectView::RenderDirectView(android::sp<IEvsEnumerator> enumerator,
+}  // namespace
+
+RenderDirectView::RenderDirectView(std::shared_ptr<IEvsEnumerator> enumerator,
                                    const CameraDesc& camDesc, const ConfigManager& config) :
       mEnumerator(enumerator), mCameraDesc(camDesc), mConfig(config) {
     // Find and store the target camera configuration
     const auto& camList = mConfig.getCameras();
     const auto target = std::find_if(camList.begin(), camList.end(),
                                      [this](const ConfigManager::CameraInfo& info) {
-                                         return info.cameraId == mCameraDesc.v1.cameraId;
+                                         return info.cameraId == mCameraDesc.id;
                                      });
     if (target != camList.end()) {
         // Store the info
@@ -114,15 +123,15 @@
     }
 
     // This client always wants below input data format
-    targetCfg->format = static_cast<PixelFormat>(HAL_PIXEL_FORMAT_RGBA_8888);
+    targetCfg->format = aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888;
 
     // Construct our video texture
-    mTexture.reset(createVideoTexture(mEnumerator, mCameraDesc.v1.cameraId.c_str(),
+    mTexture.reset(createVideoTexture(mEnumerator, mCameraDesc.id.c_str(),
                                       foundCfg ? std::move(targetCfg) : nullptr, sDisplay,
                                       mConfig.getUseExternalMemory(),
                                       mConfig.getExternalMemoryFormat()));
     if (!mTexture) {
-        LOG(ERROR) << "Failed to set up video texture for " << mCameraDesc.v1.cameraId;
+        LOG(ERROR) << "Failed to set up video texture for " << mCameraDesc.id;
         // TODO(b/237904870): We may want to return false here.
     }
 
diff --git a/cpp/evs/apps/default/RenderPixelCopy.cpp b/cpp/evs/apps/default/src/RenderPixelCopy.cpp
similarity index 72%
rename from cpp/evs/apps/default/RenderPixelCopy.cpp
rename to cpp/evs/apps/default/src/RenderPixelCopy.cpp
index e264e1e..04b7f36 100644
--- a/cpp/evs/apps/default/RenderPixelCopy.cpp
+++ b/cpp/evs/apps/default/src/RenderPixelCopy.cpp
@@ -17,10 +17,26 @@
 #include "RenderPixelCopy.h"
 
 #include "FormatConvert.h"
+#include "Utils.h"
 
+#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
+#include <aidl/android/hardware/automotive/evs/Stream.h>
+#include <aidlcommonsupport/NativeHandle.h>
 #include <android-base/logging.h>
+#include <android-base/scopeguard.h>
+#include <android/binder_manager.h>
 
-RenderPixelCopy::RenderPixelCopy(android::sp<IEvsEnumerator> enumerator,
+namespace {
+
+using aidl::android::hardware::automotive::evs::BufferDesc;
+using aidl::android::hardware::automotive::evs::IEvsCamera;
+using aidl::android::hardware::automotive::evs::IEvsEnumerator;
+using aidl::android::hardware::automotive::evs::Stream;
+
+}  // namespace
+
+RenderPixelCopy::RenderPixelCopy(std::shared_ptr<IEvsEnumerator> enumerator,
                                  const ConfigManager::CameraInfo& cam) {
     mEnumerator = enumerator;
     mCameraInfo = cam;
@@ -28,18 +44,18 @@
 
 bool RenderPixelCopy::activate() {
     // Set up the camera to feed this texture
-    android::sp<IEvsCamera> pCamera =
-            IEvsCamera::castFrom(mEnumerator->openCamera(mCameraInfo.cameraId.c_str()))
-                    .withDefault(nullptr);
-
-    if (pCamera.get() == nullptr) {
+    Stream emptyConfig;
+    std::shared_ptr<IEvsCamera> pCamera;
+    if (auto status = mEnumerator->openCamera(mCameraInfo.cameraId.c_str(), emptyConfig, &pCamera);
+        !status.isOk()) {
         LOG(ERROR) << "Failed to allocate new EVS Camera interface";
         return false;
     }
 
     // Initialize the stream that will help us update this texture's contents
-    android::sp<StreamHandler> pStreamHandler = new StreamHandler(pCamera);
-    if (pStreamHandler.get() == nullptr) {
+    std::shared_ptr<StreamHandler> pStreamHandler =
+            ndk::SharedRefBase::make<StreamHandler>(pCamera);
+    if (!pStreamHandler) {
         LOG(ERROR) << "Failed to allocate FrameHandler";
         return false;
     }
@@ -51,21 +67,27 @@
     }
 
     mStreamHandler = pStreamHandler;
-
     return true;
 }
 
 void RenderPixelCopy::deactivate() {
-    mStreamHandler = nullptr;
+    mStreamHandler.reset();
 }
 
 bool RenderPixelCopy::drawFrame(const BufferDesc& tgtBuffer) {
     bool success = true;
+    native_handle_t* targetBufferNativeHandle = getNativeHandle(tgtBuffer);
+    if (targetBufferNativeHandle == nullptr) {
+        LOG(ERROR) << "Target buffer has an invalid native handle.";
+        return false;
+    }
+
+    const auto handleGuard = android::base::make_scope_guard(
+            [targetBufferNativeHandle] { free(targetBufferNativeHandle); });
     const AHardwareBuffer_Desc* pTgtDesc =
             reinterpret_cast<const AHardwareBuffer_Desc*>(&tgtBuffer.buffer.description);
-
     android::sp<android::GraphicBuffer> tgt =
-            new android::GraphicBuffer(tgtBuffer.buffer.nativeHandle,
+            new android::GraphicBuffer(targetBufferNativeHandle,
                                        android::GraphicBuffer::CLONE_HANDLE, pTgtDesc->width,
                                        pTgtDesc->height, pTgtDesc->format, pTgtDesc->layers,
                                        pTgtDesc->usage, pTgtDesc->stride);
@@ -83,6 +105,14 @@
             // Make sure we have the latest frame data
             if (mStreamHandler->newFrameAvailable()) {
                 const BufferDesc& srcBuffer = mStreamHandler->getNewFrame();
+                native_handle_t* srcBufferNativeHandle = getNativeHandle(srcBuffer);
+                if (srcBufferNativeHandle == nullptr) {
+                    LOG(ERROR) << "Target buffer has an invalid native handle.";
+                    return false;
+                }
+
+                const auto handleGuard = android::base::make_scope_guard(
+                        [srcBufferNativeHandle] { free(srcBufferNativeHandle); });
                 const AHardwareBuffer_Desc* pSrcDesc =
                         reinterpret_cast<const AHardwareBuffer_Desc*>(
                                 &srcBuffer.buffer.description);
@@ -90,7 +120,7 @@
                 // Lock our source buffer for reading (current expectation are for this to be NV21
                 // format)
                 android::sp<android::GraphicBuffer> src =
-                        new android::GraphicBuffer(srcBuffer.buffer.nativeHandle,
+                        new android::GraphicBuffer(srcBufferNativeHandle,
                                                    android::GraphicBuffer::CLONE_HANDLE,
                                                    pSrcDesc->width, pSrcDesc->height,
                                                    pSrcDesc->format, pSrcDesc->layers,
@@ -113,7 +143,7 @@
                     } else if (pSrcDesc->format == pTgtDesc->format) {  // 32bit RGBA
                         copyMatchedInterleavedFormats(width, height, srcPixels, pSrcDesc->stride,
                                                       tgtPixels, pTgtDesc->stride,
-                                                      tgtBuffer.pixelSize);
+                                                      tgtBuffer.pixelSizeBytes);
                     }
                 } else {
                     LOG(ERROR) << "Failed to get pointer into src image data";
diff --git a/cpp/evs/apps/default/RenderTopView.cpp b/cpp/evs/apps/default/src/RenderTopView.cpp
similarity index 95%
rename from cpp/evs/apps/default/RenderTopView.cpp
rename to cpp/evs/apps/default/src/RenderTopView.cpp
index b8afd9d..398cfb8 100644
--- a/cpp/evs/apps/default/RenderTopView.cpp
+++ b/cpp/evs/apps/default/src/RenderTopView.cpp
@@ -23,20 +23,21 @@
 #include "shader_simpleTex.h"
 
 #include <android-base/logging.h>
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
 #include <math/mat4.h>
 #include <math/vec3.h>
 
-using ::android::hardware::camera::device::V3_2::Stream;
+namespace {
+
+using aidl::android::hardware::automotive::evs::BufferDesc;
+using aidl::android::hardware::automotive::evs::IEvsEnumerator;
 
 // Simple aliases to make geometric math using vectors more readable
-static const unsigned X = 0;
-static const unsigned Y = 1;
-static const unsigned Z = 2;
-// static const unsigned W = 3;
+const unsigned X = 0;
+const unsigned Y = 1;
+const unsigned Z = 2;
 
 // Since we assume no roll in these views, we can simplify the required math
-static android::vec3 unitVectorFromPitchAndYaw(float pitch, float yaw) {
+android::vec3 unitVectorFromPitchAndYaw(float pitch, float yaw) {
     float sinPitch, cosPitch;
     sincosf(pitch, &sinPitch, &cosPitch);
     float sinYaw, cosYaw;
@@ -46,7 +47,7 @@
 
 // Helper function to set up a perspective matrix with independent horizontal and vertical
 // angles of view.
-static android::mat4 perspective(float hfov, float vfov, float near, float far) {
+android::mat4 perspective(float hfov, float vfov, float near, float far) {
     const float tanHalfFovX = tanf(hfov * 0.5f);
     const float tanHalfFovY = tanf(vfov * 0.5f);
 
@@ -62,7 +63,7 @@
 // Helper function to set up a view matrix for a camera given it's yaw & pitch & location
 // Yes, with a bit of work, we could use lookAt, but it does a lot of extra work
 // internally that we can short cut.
-static android::mat4 cameraLookMatrix(const ConfigManager::CameraInfo& cam) {
+android::mat4 cameraLookMatrix(const ConfigManager::CameraInfo& cam) {
     float sinYaw, cosYaw;
     sincosf(cam.yaw, &sinYaw, &cosYaw);
 
@@ -88,7 +89,9 @@
     return Result;
 }
 
-RenderTopView::RenderTopView(android::sp<IEvsEnumerator> enumerator,
+}  // namespace
+
+RenderTopView::RenderTopView(std::shared_ptr<IEvsEnumerator> enumerator,
                              const std::vector<ConfigManager::CameraInfo>& camList,
                              const ConfigManager& mConfig) :
       mEnumerator(enumerator), mConfig(mConfig) {
diff --git a/cpp/evs/apps/default/StreamHandler.cpp b/cpp/evs/apps/default/src/StreamHandler.cpp
similarity index 61%
rename from cpp/evs/apps/default/StreamHandler.cpp
rename to cpp/evs/apps/default/src/StreamHandler.cpp
index 28b3b9a..f37ecf5 100644
--- a/cpp/evs/apps/default/StreamHandler.cpp
+++ b/cpp/evs/apps/default/src/StreamHandler.cpp
@@ -16,6 +16,12 @@
 
 #include "StreamHandler.h"
 
+#include "Utils.h"
+
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/EvsEventDesc.h>
+#include <aidl/android/hardware/automotive/evs/EvsEventType.h>
+#include <aidlcommonsupport/NativeHandle.h>
 #include <android-base/logging.h>
 #include <cutils/native_handle.h>
 #include <ui/GraphicBufferAllocator.h>
@@ -23,12 +29,16 @@
 #include <stdio.h>
 #include <string.h>
 
-using ::android::hardware::automotive::evs::V1_0::EvsResult;
-using ::android::hardware::automotive::evs::V1_1::EvsEventType;
-using ::android::hardware::automotive::evs::V1_1::IEvsCameraStream;
+namespace {
 
-buffer_handle_t memHandle = nullptr;
-StreamHandler::StreamHandler(android::sp<IEvsCamera> pCamera, uint32_t numBuffers,
+using aidl::android::hardware::automotive::evs::BufferDesc;
+using aidl::android::hardware::automotive::evs::EvsEventDesc;
+using aidl::android::hardware::automotive::evs::EvsEventType;
+using aidl::android::hardware::automotive::evs::IEvsCamera;
+
+}  // namespace
+
+StreamHandler::StreamHandler(const std::shared_ptr<IEvsCamera>& pCamera, uint32_t numBuffers,
                              bool useOwnBuffers, android_pixel_format_t format, int32_t width,
                              int32_t height) :
       mCamera(pCamera), mUseOwnBuffers(useOwnBuffers) {
@@ -40,6 +50,7 @@
         mOwnBuffers.resize(numBuffers);
 
         // Acquire the graphics buffer allocator
+        buffer_handle_t memHandle = nullptr;
         android::GraphicBufferAllocator& alloc(android::GraphicBufferAllocator::get());
         const auto usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_RARELY |
                 GRALLOC_USAGE_SW_WRITE_OFTEN;
@@ -50,7 +61,7 @@
             if (result != android::NO_ERROR) {
                 LOG(ERROR) << __FUNCTION__ << " failed to allocate memory.";
             } else {
-                BufferDesc_1_1 buf;
+                BufferDesc buf;
                 AHardwareBuffer_Desc* pDesc =
                         reinterpret_cast<AHardwareBuffer_Desc*>(&buf.buffer.description);
                 pDesc->width = width;
@@ -60,18 +71,17 @@
                 pDesc->usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_RARELY |
                         GRALLOC_USAGE_SW_WRITE_OFTEN;
                 pDesc->stride = pixelsPerLine;
-                buf.buffer.nativeHandle = memHandle;
+                buf.buffer.handle = android::dupToAidl(memHandle);
                 buf.bufferId = i;  // Unique number to identify this buffer
-                mOwnBuffers[i] = buf;
+                mOwnBuffers[i] = std::move(buf);
             }
         }
 
         int delta = 0;
-        EvsResult result = EvsResult::OK;
-        pCamera->importExternalBuffers(mOwnBuffers, [&](auto _result, auto _delta) {
-            result = _result;
-            delta = _delta;
-        });
+        if (auto status = pCamera->importExternalBuffers(mOwnBuffers, &delta); !status.isOk()) {
+            PLOG(ERROR) << "Failed to import buffers.";
+            return;
+        }
 
         LOG(INFO) << delta << " buffers are imported by EVS.";
     }
@@ -85,37 +95,41 @@
     // our remote object references so they can be freed
     mCamera = nullptr;
 
-    if (mUseOwnBuffers) {
-        android::GraphicBufferAllocator& alloc(android::GraphicBufferAllocator::get());
-        for (auto& b : mOwnBuffers) {
-            alloc.free(b.buffer.nativeHandle);
-        }
-
-        mOwnBuffers.resize(0);
+    if (!mUseOwnBuffers) {
+        return;
     }
+
+    android::GraphicBufferAllocator& alloc(android::GraphicBufferAllocator::get());
+    for (auto& b : mOwnBuffers) {
+        alloc.free(android::makeFromAidl(b.buffer.handle));
+    }
+
+    mOwnBuffers.resize(0);
 }
 
 bool StreamHandler::startStream() {
-    std::unique_lock<std::mutex> lock(mLock);
-
-    if (!mRunning) {
-        // Tell the camera to start streaming
-        Return<EvsResult> result = mCamera->startVideoStream(this);
-        if (result != EvsResult::OK) {
-            return false;
-        }
-
-        // Mark ourselves as running
-        mRunning = true;
+    std::lock_guard lock(mLock);
+    if (mRunning) {
+        return true;
     }
 
+    // Tell the camera to start streaming
+    if (auto status = mCamera->startVideoStream(ref<StreamHandler>()); !status.isOk()) {
+        LOG(ERROR) << "Failed to request a video stream.";
+        return false;
+    }
+
+    // Mark ourselves as running
+    mRunning = true;
     return true;
 }
 
 void StreamHandler::asyncStopStream() {
     // Tell the camera to stop streaming.
     // This will result in a null frame being delivered when the stream actually stops.
-    mCamera->stopVideoStream();
+    if (auto status = mCamera->stopVideoStream(); !status.isOk()) {
+        LOG(WARNING) << "Failed to stop a video stream.";
+    }
 }
 
 void StreamHandler::blockingStopStream() {
@@ -123,24 +137,24 @@
     asyncStopStream();
 
     // Wait until the stream has actually stopped
-    std::unique_lock<std::mutex> lock(mLock);
+    std::unique_lock lock(mLock);
     if (mRunning) {
         mSignal.wait(lock, [this]() { return !mRunning; });
     }
 }
 
 bool StreamHandler::isRunning() {
-    std::unique_lock<std::mutex> lock(mLock);
+    std::lock_guard lock(mLock);
     return mRunning;
 }
 
 bool StreamHandler::newFrameAvailable() {
-    std::unique_lock<std::mutex> lock(mLock);
+    std::lock_guard lock(mLock);
     return (mReadyBuffer >= 0);
 }
 
-const BufferDesc_1_1& StreamHandler::getNewFrame() {
-    std::unique_lock<std::mutex> lock(mLock);
+const BufferDesc& StreamHandler::getNewFrame() {
+    std::lock_guard lock(mLock);
 
     if (mHeldBuffer >= 0) {
         LOG(ERROR) << "Ignored call for new frame while still holding the old one.";
@@ -159,20 +173,25 @@
     return mBuffers[mHeldBuffer];
 }
 
-void StreamHandler::doneWithFrame(const BufferDesc_1_1& bufDesc_1_1) {
-    std::unique_lock<std::mutex> lock(mLock);
+void StreamHandler::doneWithFrame(const BufferDesc& bufDesc) {
+    std::lock_guard lock(mLock);
 
     // We better be getting back the buffer we original delivered!
-    if ((mHeldBuffer < 0) || (bufDesc_1_1.bufferId != mBuffers[mHeldBuffer].bufferId)) {
-        LOG(ERROR) << "StreamHandler::doneWithFrame got an unexpected bufDesc_1_1!";
+    if (mHeldBuffer < 0) {
+        // Safely ignores a call with an invalid buffer reference.
+        return;
+    }
+
+    if (bufDesc.bufferId != mBuffers[mHeldBuffer].bufferId) {
+        LOG(WARNING) << __FUNCTION__ << " ignores an unexpected buffer; expected = "
+                     << mBuffers[mHeldBuffer].bufferId << ", received = " << bufDesc.bufferId;
+        return;
     }
 
     // Send the buffer back to the underlying camera
-    hidl_vec<BufferDesc_1_1> frames;
-    frames.resize(1);
-    frames[0] = mBuffers[mHeldBuffer];
-    auto ret = mCamera->doneWithFrame_1_1(frames);
-    if (!ret.isOk()) {
+    std::vector<BufferDesc> frames(1);
+    frames[0] = std::move(mBuffers[mHeldBuffer]);
+    if (auto status = mCamera->doneWithFrame(frames); !status.isOk()) {
         LOG(WARNING) << __FUNCTION__ << " fails to return a buffer";
     }
 
@@ -180,59 +199,42 @@
     mHeldBuffer = -1;
 }
 
-Return<void> StreamHandler::deliverFrame(const BufferDesc_1_0& bufDesc_1_0) {
-    LOG(INFO) << "Ignores a frame delivered from v1.0 EVS service.";
-    auto ret = mCamera->doneWithFrame(bufDesc_1_0);
-    if (!ret.isOk()) {
-        LOG(WARNING) << __FUNCTION__ << " fails to return a buffer";
-    }
-
-    return Void();
-}
-
-Return<void> StreamHandler::deliverFrame_1_1(const hidl_vec<BufferDesc_1_1>& buffers) {
+ndk::ScopedAStatus StreamHandler::deliverFrame(const std::vector<BufferDesc>& buffers) {
     LOG(DEBUG) << "Received frames from the camera";
 
     // Take the lock to protect our frame slots and running state variable
-    std::unique_lock<std::mutex> lock(mLock);
-    BufferDesc_1_1 bufDesc = buffers[0];
-    if (bufDesc.buffer.nativeHandle.getNativeHandle() == nullptr) {
-        // Signal that the last frame has been received and the stream is stopped
-        LOG(WARNING) << "Invalid null frame (id: " << std::hex << bufDesc.bufferId
-                     << ") is ignored";
-    } else {
-        // Do we already have a "ready" frame?
-        if (mReadyBuffer >= 0) {
-            // Send the previously saved buffer back to the camera unused
-            hidl_vec<BufferDesc_1_1> frames;
-            frames.resize(1);
-            frames[0] = mBuffers[mReadyBuffer];
-            auto ret = mCamera->doneWithFrame_1_1(frames);
-            if (!ret.isOk()) {
-                LOG(WARNING) << __FUNCTION__ << " fails to return a buffer";
-            }
+    std::unique_lock lock(mLock);
+    const BufferDesc& bufferToUse = buffers[0];
 
-            // We'll reuse the same ready buffer index
-        } else if (mHeldBuffer >= 0) {
-            // The client is holding a buffer, so use the other slot for "on deck"
-            mReadyBuffer = 1 - mHeldBuffer;
-        } else {
-            // This is our first buffer, so just pick a slot
-            mReadyBuffer = 0;
+    // Do we already have a "ready" frame?
+    if (mReadyBuffer >= 0) {
+        // Send the previously saved buffer back to the camera unused
+        std::vector<BufferDesc> frames(1);
+        frames[0] = std::move(mBuffers[mReadyBuffer]);
+        if (auto status = mCamera->doneWithFrame(frames); !status.isOk()) {
+            LOG(WARNING) << __FUNCTION__ << " fails to return a buffer";
         }
 
-        // Save this frame until our client is interested in it
-        mBuffers[mReadyBuffer] = bufDesc;
+        // We'll reuse the same ready buffer index
+    } else if (mHeldBuffer >= 0) {
+        // The client is holding a buffer, so use the other slot for "on deck"
+        mReadyBuffer = 1 - mHeldBuffer;
+    } else {
+        // This is our first buffer, so just pick a slot
+        mReadyBuffer = 0;
     }
 
-    // Notify anybody who cares that things have changed
-    lock.unlock();
-    mSignal.notify_all();
+    // Save this frame until our client is interested in it
+    mBuffers[mReadyBuffer] = dupBufferDesc(bufferToUse);
 
-    return Void();
+    // Notify anybody who cares that things have changed
+    mSignal.notify_all();
+    lock.unlock();
+
+    return ndk::ScopedAStatus::ok();
 }
 
-Return<void> StreamHandler::notify(const EvsEventDesc& event) {
+ndk::ScopedAStatus StreamHandler::notify(const EvsEventDesc& event) {
     switch (event.aType) {
         case EvsEventType::STREAM_STOPPED: {
             {
@@ -264,5 +266,5 @@
             break;
     }
 
-    return Void();
+    return ndk::ScopedAStatus::ok();
 }
diff --git a/cpp/evs/apps/default/TexWrapper.cpp b/cpp/evs/apps/default/src/TexWrapper.cpp
similarity index 100%
rename from cpp/evs/apps/default/TexWrapper.cpp
rename to cpp/evs/apps/default/src/TexWrapper.cpp
diff --git a/cpp/evs/apps/default/src/Utils.cpp b/cpp/evs/apps/default/src/Utils.cpp
new file mode 100644
index 0000000..47e7356
--- /dev/null
+++ b/cpp/evs/apps/default/src/Utils.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 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 "Utils.h"
+
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android-base/logging.h>
+
+namespace {
+
+using aidl::android::hardware::automotive::evs::BufferDesc;
+using aidl::android::hardware::common::NativeHandle;
+using aidl::android::hardware::graphics::common::HardwareBuffer;
+
+NativeHandle dupNativeHandle(const NativeHandle& handle) {
+    NativeHandle dup;
+
+    dup.fds = std::vector<::ndk::ScopedFileDescriptor>(handle.fds.size());
+    const size_t n = handle.fds.size();
+    for (size_t i = 0; i < n; ++i) {
+        dup.fds[i] = std::move(handle.fds[i].dup());
+    }
+    dup.ints = handle.ints;
+
+    return std::move(dup);
+}
+
+HardwareBuffer dupHardwareBuffer(const HardwareBuffer& buffer) {
+    HardwareBuffer dup = {
+            .description = buffer.description,
+            .handle = dupNativeHandle(buffer.handle),
+    };
+
+    return std::move(dup);
+}
+
+}  // namespace
+
+BufferDesc dupBufferDesc(const BufferDesc& src) {
+    BufferDesc dup = {
+            .buffer = dupHardwareBuffer(src.buffer),
+            .pixelSizeBytes = src.pixelSizeBytes,
+            .bufferId = src.bufferId,
+            .deviceId = src.deviceId,
+            .timestamp = src.timestamp,
+            .metadata = src.metadata,
+    };
+
+    return std::move(dup);
+}
+
+native_handle_t* getNativeHandle(const BufferDesc& buffer) {
+    native_handle_t* nativeHandle = android::makeFromAidl(buffer.buffer.handle);
+    if (nativeHandle == nullptr ||
+        !std::all_of(nativeHandle->data + 0, nativeHandle->data + nativeHandle->numFds,
+                     [](int fd) { return fd >= 0; })) {
+        LOG(ERROR) << "Buffer " << buffer.bufferId << " contains an invalid native handle.";
+        free(nativeHandle);
+        return nullptr;
+    }
+
+    return nativeHandle;
+}
diff --git a/cpp/evs/apps/default/VideoTex.cpp b/cpp/evs/apps/default/src/VideoTex.cpp
similarity index 68%
rename from cpp/evs/apps/default/VideoTex.cpp
rename to cpp/evs/apps/default/src/VideoTex.cpp
index df795c5..07abbee 100644
--- a/cpp/evs/apps/default/VideoTex.cpp
+++ b/cpp/evs/apps/default/src/VideoTex.cpp
@@ -15,10 +15,14 @@
  */
 #include "VideoTex.h"
 
+#include "Utils.h"
 #include "glError.h"
 
+#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
+#include <aidlcommonsupport/NativeHandle.h>
 #include <android-base/logging.h>
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android-base/scopeguard.h>
 #include <ui/GraphicBuffer.h>
 
 #include <alloca.h>
@@ -29,15 +33,18 @@
 #include <sys/ioctl.h>
 #include <unistd.h>
 
-#include <vector>
+namespace {
 
-// Eventually we shouldn't need this dependency, but for now the
-// graphics allocator interface isn't fully supported on all platforms
-// and this is our work around.
-using ::android::GraphicBuffer;
+using aidl::android::hardware::automotive::evs::BufferDesc;
+using aidl::android::hardware::automotive::evs::IEvsCamera;
+using aidl::android::hardware::automotive::evs::IEvsEnumerator;
+using aidl::android::hardware::automotive::evs::Stream;
+using android::GraphicBuffer;
 
-VideoTex::VideoTex(android::sp<IEvsEnumerator> pEnum, android::sp<IEvsCamera> pCamera,
-                   android::sp<StreamHandler> pStreamHandler, EGLDisplay glDisplay) :
+}  // namespace
+
+VideoTex::VideoTex(std::shared_ptr<IEvsEnumerator> pEnum, std::shared_ptr<IEvsCamera> pCamera,
+                   std::shared_ptr<StreamHandler> pStreamHandler, EGLDisplay glDisplay) :
       TexWrapper(),
       mEnumerator(pEnum),
       mCamera(pCamera),
@@ -68,7 +75,7 @@
     }
 
     // If we already have an image backing us, then it's time to return it
-    if (mImageBuffer.buffer.nativeHandle.getNativeHandle() != nullptr) {
+    if (getNativeHandle(mImageBuffer) != nullptr) {
         // Drop our device texture image
         if (mKHRimage != EGL_NO_IMAGE_KHR) {
             eglDestroyImageKHR(mDisplay, mKHRimage);
@@ -80,17 +87,25 @@
     }
 
     // Get the new image we want to use as our contents
-    mImageBuffer = mStreamHandler->getNewFrame();
+    mImageBuffer = dupBufferDesc(mStreamHandler->getNewFrame());
 
     // create a GraphicBuffer from the existing handle
+    native_handle_t* nativeHandle = getNativeHandle(mImageBuffer);
+    const auto handleGuard =
+            android::base::make_scope_guard([nativeHandle] { free(nativeHandle); });
+    if (nativeHandle == nullptr) {
+        // New frame contains an invalid native handle.
+        return false;
+    }
+
     const AHardwareBuffer_Desc* pDesc =
             reinterpret_cast<const AHardwareBuffer_Desc*>(&mImageBuffer.buffer.description);
-    android::sp<GraphicBuffer> pGfxBuffer =
-            new GraphicBuffer(mImageBuffer.buffer.nativeHandle, GraphicBuffer::CLONE_HANDLE,
-                              pDesc->width, pDesc->height, pDesc->format,
+    android::sp<GraphicBuffer> pGfxBuffer =  // AHardwareBuffer_to_GraphicBuffer?
+            new GraphicBuffer(nativeHandle, GraphicBuffer::CLONE_HANDLE, pDesc->width,
+                              pDesc->height, pDesc->format,
                               1,  // pDesc->layers,
                               GRALLOC_USAGE_HW_TEXTURE, pDesc->stride);
-    if (pGfxBuffer.get() == nullptr) {
+    if (!pGfxBuffer) {
         LOG(ERROR) << "Failed to allocate GraphicBuffer to wrap image handle";
         // Returning "true" in this error condition because we already released the
         // previous image (if any) and so the texture may change in unpredictable ways now!
@@ -124,35 +139,27 @@
     return true;
 }
 
-VideoTex* createVideoTexture(android::sp<IEvsEnumerator> pEnum, const char* evsCameraId,
+VideoTex* createVideoTexture(const std::shared_ptr<IEvsEnumerator>& pEnum, const char* evsCameraId,
                              std::unique_ptr<Stream> streamCfg, EGLDisplay glDisplay,
                              bool useExternalMemory, android_pixel_format_t format) {
     // Set up the camera to feed this texture
-    android::sp<IEvsCamera> pCamera = nullptr;
-    android::sp<StreamHandler> pStreamHandler = nullptr;
-    if (streamCfg != nullptr) {
-        pCamera = pEnum->openCamera_1_1(evsCameraId, *streamCfg);
-
-        // Initialize the stream that will help us update this texture's contents
-        pStreamHandler =
-                new StreamHandler(pCamera,
-                                  2,  // number of buffers
-                                  useExternalMemory, format, streamCfg->width, streamCfg->height);
-    } else {
-        pCamera = IEvsCamera::castFrom(pEnum->openCamera(evsCameraId)).withDefault(nullptr);
-
-        // Initialize the stream with the default resolution
-        pStreamHandler = new StreamHandler(pCamera,
-                                           2,  // number of buffers
-                                           useExternalMemory, format);
-    }
-
-    if (pCamera == nullptr) {
-        LOG(ERROR) << "Failed to allocate new EVS Camera interface for " << evsCameraId;
+    std::shared_ptr<IEvsCamera> pCamera;
+    std::shared_ptr<StreamHandler> pStreamHandler;
+    if (!streamCfg) {
+        LOG(ERROR) << "Given stream configuration is invalid.";
         return nullptr;
     }
 
-    if (pStreamHandler == nullptr) {
+    if (auto status = pEnum->openCamera(evsCameraId, *streamCfg, &pCamera); !status.isOk()) {
+        LOG(ERROR) << "Failed to open a camera " << evsCameraId;
+        return nullptr;
+    }
+
+    // Initialize the stream that will help us update this texture's contents
+    pStreamHandler =
+            ndk::SharedRefBase::make<StreamHandler>(pCamera, /* numBuffers= */ 2, useExternalMemory,
+                                                    format, streamCfg->width, streamCfg->height);
+    if (!pStreamHandler) {
         LOG(ERROR) << "Failed to allocate FrameHandler";
         return nullptr;
     }
diff --git a/cpp/evs/apps/default/evs_app.cpp b/cpp/evs/apps/default/src/evs_app.cpp
similarity index 82%
rename from cpp/evs/apps/default/evs_app.cpp
rename to cpp/evs/apps/default/src/evs_app.cpp
index 27bca9f..d4385d5 100644
--- a/cpp/evs/apps/default/evs_app.cpp
+++ b/cpp/evs/apps/default/src/evs_app.cpp
@@ -18,17 +18,16 @@
 #include "EvsStateControl.h"
 #include "EvsVehicleListener.h"
 
+#include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
 #include <aidl/android/hardware/automotive/vehicle/SubscribeOptions.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleGear.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
 #include <android-base/logging.h>
-#include <android-base/macros.h>  // arraysize
 #include <android-base/strings.h>
-#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
@@ -39,27 +38,23 @@
 
 namespace {
 
-using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
-using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
-using ::android::base::EqualsIgnoreCase;
+using aidl::android::hardware::automotive::evs::IEvsDisplay;
+using aidl::android::hardware::automotive::evs::IEvsEnumerator;
+using aidl::android::hardware::automotive::vehicle::VehicleGear;
+using aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using android::base::EqualsIgnoreCase;
+using android::frameworks::automotive::vhal::ISubscriptionClient;
+using android::frameworks::automotive::vhal::IVhalClient;
 
-// libhidl:
-using ::android::frameworks::automotive::vhal::ISubscriptionClient;
-using ::android::frameworks::automotive::vhal::IVhalClient;
-using ::android::hardware::configureRpcThreadpool;
-using ::android::hardware::joinRpcThreadpool;
+const char CONFIG_DEFAULT_PATH[] = "/system/etc/automotive/evs/config.json";
+const char CONFIG_OVERRIDE_PATH[] = "/system/etc/automotive/evs/config_override.json";
 
-const char* CONFIG_DEFAULT_PATH = "/system/etc/automotive/evs/config.json";
-const char* CONFIG_OVERRIDE_PATH = "/system/etc/automotive/evs/config_override.json";
-
-android::sp<IEvsEnumerator> pEvs;
-android::sp<IEvsDisplay> pDisplay;
+std::shared_ptr<IEvsEnumerator> pEvsService;
+std::shared_ptr<IEvsDisplay> pDisplay;
 EvsStateControl* pStateController;
 
-}  // namespace
-
-// Helper to subscribe to VHal notifications
-static bool subscribeToVHal(ISubscriptionClient* client, VehicleProperty propertyId) {
+// Helper to subscribe to Vhal notifications
+bool subscribeToVHal(ISubscriptionClient* client, VehicleProperty propertyId) {
     assert(pVnet != nullptr);
     assert(listener != nullptr);
 
@@ -80,7 +75,7 @@
     return true;
 }
 
-static bool convertStringToFormat(const char* str, android_pixel_format_t* output) {
+bool convertStringToFormat(const char* str, android_pixel_format_t* output) {
     bool result = true;
     if (EqualsIgnoreCase(str, "RGBA8888")) {
         *output = HAL_PIXEL_FORMAT_RGBA_8888;
@@ -97,6 +92,8 @@
     return result;
 }
 
+}  // namespace
+
 // Main entry point
 int main(int argc, char** argv) {
     LOG(INFO) << "EVS app starting";
@@ -192,16 +189,28 @@
     // This pool will handle the EvsCameraStream callbacks.
     // Note:  This _will_ run in parallel with the EvsListener run() loop below which
     // runs the application logic that reacts to the async events.
-    configureRpcThreadpool(1, false /* callerWillJoin */);
+    if (!ABinderProcess_setThreadPoolMaxThreadCount(/* numThreads= */ 1)) {
+        LOG(ERROR) << "Failed to confgiure the binder thread pool.";
+        return EXIT_FAILURE;
+    }
+    ABinderProcess_startThreadPool();
 
     // Construct our async helper object
     std::shared_ptr<EvsVehicleListener> pEvsListener = std::make_shared<EvsVehicleListener>();
 
     // Get the EVS manager service
     LOG(INFO) << "Acquiring EVS Enumerator";
-    pEvs = IEvsEnumerator::getService(evsServiceName);
-    if (pEvs.get() == nullptr) {
-        LOG(ERROR) << "getService(" << evsServiceName << ") returned NULL.  Exiting.";
+    std::string serviceName =
+            std::string(IEvsEnumerator::descriptor) + "/" + std::string(evsServiceName);
+    if (!AServiceManager_isDeclared(serviceName.c_str())) {
+        LOG(ERROR) << serviceName << " is not declared. Exiting.";
+        return EXIT_FAILURE;
+    }
+
+    pEvsService = IEvsEnumerator::fromBinder(
+            ndk::SpAIBinder(AServiceManager_checkService(serviceName.c_str())));
+    if (!pEvsService) {
+        LOG(ERROR) << "Failed to get " << serviceName << ". Exiting.";
         return EXIT_FAILURE;
     }
 
@@ -215,8 +224,7 @@
         return EXIT_FAILURE;
     }
 
-    pDisplay = pEvs->openDisplay_1_1(displayId);
-    if (pDisplay.get() == nullptr) {
+    if (auto status = pEvsService->openDisplay(displayId, &pDisplay); !status.isOk()) {
         LOG(ERROR) << "EVS Display unavailable.  Exiting.";
         return EXIT_FAILURE;
     }
@@ -253,7 +261,7 @@
 
     // Configure ourselves for the current vehicle state at startup
     LOG(INFO) << "Constructing state controller";
-    pStateController = new EvsStateControl(pVnet, pEvs, pDisplay, config);
+    pStateController = new EvsStateControl(pVnet, pEvsService, pDisplay, config);
     if (!pStateController->startUpdateLoop()) {
         LOG(ERROR) << "Initial configuration failed.  Exiting.";
         return EXIT_FAILURE;
diff --git a/cpp/evs/apps/default/glError.cpp b/cpp/evs/apps/default/src/glError.cpp
similarity index 100%
rename from cpp/evs/apps/default/glError.cpp
rename to cpp/evs/apps/default/src/glError.cpp
diff --git a/cpp/evs/apps/default/shader.cpp b/cpp/evs/apps/default/src/shader.cpp
similarity index 85%
rename from cpp/evs/apps/default/shader.cpp
rename to cpp/evs/apps/default/src/shader.cpp
index aa993c0..90fd1d0 100644
--- a/cpp/evs/apps/default/shader.cpp
+++ b/cpp/evs/apps/default/src/shader.cpp
@@ -100,27 +100,30 @@
         return 0;
     }
 
-#if 0  // Debug output to diagnose shader parameters
+#if defined(DEBUG)  // Debug output to diagnose shader parameters
     GLint numShaderParams;
     GLchar paramName[128];
     GLint paramSize;
     GLenum paramType;
-    const char *typeName = "?";
+    const char* typeName = "?";
     printf("Shader parameters for %s:\n", name);
     glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numShaderParams);
-    for (GLint i=0; i<numShaderParams; i++) {
-        glGetActiveUniform(program,
-                           i,
-                           sizeof(paramName),
-                           nullptr,
-                           &paramSize,
-                           &paramType,
+    for (GLint i = 0; i < numShaderParams; i++) {
+        glGetActiveUniform(program, i, sizeof(paramName), nullptr, &paramSize, &paramType,
                            paramName);
         switch (paramType) {
-            case GL_FLOAT:      typeName = "GL_FLOAT"; break;
-            case GL_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break;
-            case GL_FLOAT_MAT4: typeName = "GL_FLOAT_MAT4"; break;
-            case GL_SAMPLER_2D: typeName = "GL_SAMPLER_2D"; break;
+            case GL_FLOAT:
+                typeName = "GL_FLOAT";
+                break;
+            case GL_FLOAT_VEC4:
+                typeName = "GL_FLOAT_VEC4";
+                break;
+            case GL_FLOAT_MAT4:
+                typeName = "GL_FLOAT_MAT4";
+                break;
+            case GL_SAMPLER_2D:
+                typeName = "GL_SAMPLER_2D";
+                break;
         }
 
         printf("  %2d: %s\t (%d) of type %s(%d)\n", i, paramName, paramSize, typeName, paramType);
diff --git a/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp b/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp
index 4fc382e..201d932 100644
--- a/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp
+++ b/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp
@@ -427,13 +427,17 @@
     }
 
     // Create a new display interface and return it
-    if (sDisplayPortList.find(id) == sDisplayPortList.end()) {
-        LOG(ERROR) << "No display is available on the port " << static_cast<int32_t>(id);
-        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    uint64_t targetDisplayId = mInternalDisplayId;
+    auto it = sDisplayPortList.find(id);
+    if (it != sDisplayPortList.end()) {
+        targetDisplayId = it->second;
+    } else {
+        LOG(WARNING) << "No display is available on the port " << static_cast<int32_t>(id)
+                     << ". The main display " << mInternalDisplayId << " will be used instead";
     }
 
     // Create a new display interface and return it.
-    pActiveDisplay = ::ndk::SharedRefBase::make<EvsGlDisplay>(sDisplayProxy, mInternalDisplayId);
+    pActiveDisplay = ::ndk::SharedRefBase::make<EvsGlDisplay>(sDisplayProxy, targetDisplayId);
     sActiveDisplay = pActiveDisplay;
 
     LOG(DEBUG) << "Returning new EvsGlDisplay object " << pActiveDisplay.get();
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.cpp b/cpp/watchdog/server/src/WatchdogProcessService.cpp
index 914d462..01c746e 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.cpp
+++ b/cpp/watchdog/server/src/WatchdogProcessService.cpp
@@ -71,6 +71,7 @@
 using ::android::binder::Status;
 using ::android::frameworks::automotive::vhal::HalPropError;
 using ::android::frameworks::automotive::vhal::IHalPropValue;
+using ::android::frameworks::automotive::vhal::ISubscriptionClient;
 using ::android::frameworks::automotive::vhal::IVhalClient;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::interfacesEqual;
@@ -535,39 +536,45 @@
 }
 
 void WatchdogProcessService::terminate() {
-    Mutex::Autolock lock(mMutex);
-    if (!mServiceStarted) {
-        return;
-    }
-    for (auto& [_, clients] : mClientsByTimeout) {
-        for (auto& [_, client] : clients) {
-            client.unlinkToDeath(mBinderDeathRecipient.get());
+    std::unique_ptr<ISubscriptionClient> propertySubscriptionClient;
+    {
+        Mutex::Autolock lock(mMutex);
+        if (!mServiceStarted) {
+            return;
         }
-        clients.clear();
+        for (auto& [_, clients] : mClientsByTimeout) {
+            for (auto& [_, client] : clients) {
+                client.unlinkToDeath(mBinderDeathRecipient.get());
+            }
+            clients.clear();
+        }
+        mClientsByTimeout.clear();
+        mWatchdogServiceHelper.clear();
+        if (mMonitor != nullptr) {
+            AIBinder* aiBinder = mMonitor->asBinder().get();
+            mDeathRegistrationWrapper->unlinkToDeath(aiBinder, mBinderDeathRecipient.get(),
+                                                     static_cast<void*>(aiBinder));
+            mMonitor.reset();
+        }
+        mHandlerLooper->removeMessages(mMessageHandler, MSG_VHAL_HEALTH_CHECK);
+        mServiceStarted = false;
+        if (mVhalService == nullptr) {
+            return;
+        }
+        if (mNotSupportedVhalProperties.count(VehicleProperty::VHAL_HEARTBEAT) == 0) {
+            propertySubscriptionClient =
+                    mVhalService->getSubscriptionClient(mPropertyChangeListener);
+        }
+        mVhalService->removeOnBinderDiedCallback(mOnBinderDiedCallback);
+        mVhalService.reset();
     }
-    mClientsByTimeout.clear();
-    mWatchdogServiceHelper.clear();
-    if (mMonitor != nullptr) {
-        AIBinder* aiBinder = mMonitor->asBinder().get();
-        mDeathRegistrationWrapper->unlinkToDeath(aiBinder, mBinderDeathRecipient.get(),
-                                                 static_cast<void*>(aiBinder));
-        mMonitor.reset();
-    }
-    mHandlerLooper->removeMessages(mMessageHandler, MSG_VHAL_HEALTH_CHECK);
-    mServiceStarted = false;
-    if (mVhalService == nullptr) {
-        return;
-    }
-    if (mNotSupportedVhalProperties.count(VehicleProperty::VHAL_HEARTBEAT) == 0) {
+    if (propertySubscriptionClient != nullptr) {
         std::vector<int32_t> propIds = {static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT)};
-        auto result =
-                mVhalService->getSubscriptionClient(mPropertyChangeListener)->unsubscribe(propIds);
+        auto result = propertySubscriptionClient->unsubscribe(propIds);
         if (!result.ok()) {
             ALOGW("Failed to unsubscribe from VHAL_HEARTBEAT.");
         }
     }
-    mVhalService->removeOnBinderDiedCallback(mOnBinderDiedCallback);
-    mVhalService.reset();
 }
 
 ScopedAStatus WatchdogProcessService::registerClient(const ClientInfo& clientInfo,
@@ -839,25 +846,29 @@
 }
 
 Result<void> WatchdogProcessService::updateVhal(const VehiclePropValue& value) {
-    Mutex::Autolock lock(mMutex);
-    const auto& connectRet = connectToVhalLocked();
+    const auto& connectRet = connectToVhal();
     if (!connectRet.ok()) {
         std::string errorMsg = "VHAL is not connected: " + connectRet.error().message();
         ALOGW("%s", errorMsg.c_str());
         return Error() << errorMsg;
     }
     int32_t propId = value.prop;
-    if (mNotSupportedVhalProperties.count(static_cast<VehicleProperty>(propId)) > 0) {
-        std::string errorMsg = StringPrintf("VHAL doesn't support property(id: %d)", propId);
-        ALOGW("%s", errorMsg.c_str());
-        return Error() << errorMsg;
+    std::shared_ptr<IVhalClient> vhalService;
+    {
+        Mutex::Autolock lock(mMutex);
+        if (mNotSupportedVhalProperties.count(static_cast<VehicleProperty>(propId)) > 0) {
+            std::string errorMsg = StringPrintf("VHAL doesn't support property(id: %d)", propId);
+            ALOGW("%s", errorMsg.c_str());
+            return Error() << errorMsg;
+        }
+        vhalService = mVhalService;
     }
 
-    auto halPropValue = mVhalService->createHalPropValue(propId);
+    auto halPropValue = vhalService->createHalPropValue(propId);
     halPropValue->setInt32Values(value.value.int32Values);
     halPropValue->setInt64Values(value.value.int64Values);
     halPropValue->setStringValue(value.value.stringValue);
-    if (auto result = mVhalService->setValueSync(*halPropValue); !result.ok()) {
+    if (auto result = vhalService->setValueSync(*halPropValue); !result.ok()) {
         return Error() << "Failed to set propValue(" << propId
                        << ") to VHAL, error: " << result.error().message();
     }
@@ -876,55 +887,65 @@
     return Error() << "Failed to read " << cmdLinePath;
 }
 
-Result<void> WatchdogProcessService::connectToVhalLocked() {
-    if (mVhalService != nullptr) {
-        return {};
+Result<void> WatchdogProcessService::connectToVhal() {
+    {
+        Mutex::Autolock lock(mMutex);
+        if (mVhalService != nullptr) {
+            return {};
+        }
+        mVhalService = IVhalClient::tryCreate();
+        if (mVhalService == nullptr) {
+            return Error() << "Failed to connect to VHAL.";
+        }
+        mVhalService->addOnBinderDiedCallback(mOnBinderDiedCallback);
     }
-    mVhalService = IVhalClient::tryCreate();
-    if (mVhalService == nullptr) {
-        return Error() << "Failed to connect to VHAL.";
-    }
-    mVhalService->addOnBinderDiedCallback(mOnBinderDiedCallback);
-    queryVhalPropertiesLocked();
-    subscribeToVhalHeartBeatLocked();
+    queryVhalProperties();
+    subscribeToVhalHeartBeat();
     ALOGI("Successfully connected to VHAL.");
     return {};
 }
 
-void WatchdogProcessService::queryVhalPropertiesLocked() {
-    mNotSupportedVhalProperties.clear();
+void WatchdogProcessService::queryVhalProperties() {
+    std::shared_ptr<IVhalClient> vhalService;
+    {
+        Mutex::Autolock lock(mMutex);
+        vhalService = mVhalService;
+    }
+    std::unordered_set<VehicleProperty> notSupportedProperties;
     std::vector<VehicleProperty> propIds = {VehicleProperty::WATCHDOG_ALIVE,
                                             VehicleProperty::WATCHDOG_TERMINATED_PROCESS,
                                             VehicleProperty::VHAL_HEARTBEAT};
     for (const auto& propId : propIds) {
-        if (!isVhalPropertySupportedLocked(propId)) {
-            mNotSupportedVhalProperties.insert(propId);
+        if (auto result = vhalService->getPropConfigs({static_cast<int32_t>(propId)});
+            !result.ok()) {
+            notSupportedProperties.insert(propId);
         }
     }
-}
-
-bool WatchdogProcessService::isVhalPropertySupportedLocked(VehicleProperty propId) {
-    auto result = mVhalService->getPropConfigs({static_cast<int32_t>(propId)});
-    return result.ok();
-}
-
-void WatchdogProcessService::subscribeToVhalHeartBeatLocked() {
-    if (mNotSupportedVhalProperties.count(VehicleProperty::VHAL_HEARTBEAT) > 0) {
-        ALOGW("VHAL doesn't support VHAL_HEARTBEAT. Checking VHAL health is disabled.");
-        return;
+    {
+        Mutex::Autolock lock(mMutex);
+        mNotSupportedVhalProperties = std::move(notSupportedProperties);
     }
+}
 
-    mVhalHeartBeat = {
-            .eventTime = 0,
-            .value = 0,
-    };
+void WatchdogProcessService::subscribeToVhalHeartBeat() {
+    std::unique_ptr<ISubscriptionClient> propertySubscriptionClient;
+    {
+        Mutex::Autolock lock(mMutex);
+        if (mNotSupportedVhalProperties.count(VehicleProperty::VHAL_HEARTBEAT) > 0) {
+            ALOGW("VHAL doesn't support VHAL_HEARTBEAT. Checking VHAL health is disabled.");
+            return;
+        }
 
+        mVhalHeartBeat = {
+                .eventTime = 0,
+                .value = 0,
+        };
+        propertySubscriptionClient = mVhalService->getSubscriptionClient(mPropertyChangeListener);
+    }
     std::vector<SubscribeOptions> options = {
             {.propId = static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT), .areaIds = {}},
     };
-    if (auto result =
-                mVhalService->getSubscriptionClient(mPropertyChangeListener)->subscribe(options);
-        !result.ok()) {
+    if (auto result = propertySubscriptionClient->subscribe(options); !result.ok()) {
         ALOGW("Failed to subscribe to VHAL_HEARTBEAT. Checking VHAL health is disabled. '%s'",
               result.error().message().c_str());
         return;
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.h b/cpp/watchdog/server/src/WatchdogProcessService.h
index 5a942e0..d76f235 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.h
+++ b/cpp/watchdog/server/src/WatchdogProcessService.h
@@ -249,8 +249,8 @@
     int32_t getNewSessionId();
     android::base::Result<void> updateVhal(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
-    android::base::Result<void> connectToVhalLocked();
-    void subscribeToVhalHeartBeatLocked();
+    android::base::Result<void> connectToVhal();
+    void subscribeToVhalHeartBeat();
     std::optional<aidl::android::automotive::watchdog::internal::ProcessIdentifier>
     cacheVhalProcessIdentifier();
     void reportWatchdogAliveToVhal();
@@ -259,9 +259,7 @@
                     processesNotResponding);
     android::base::Result<std::string> readProcCmdLine(int32_t pid);
     void handleVhalDeath();
-    void queryVhalPropertiesLocked();
-    bool isVhalPropertySupportedLocked(
-            aidl::android::hardware::automotive::vehicle::VehicleProperty propId);
+    void queryVhalProperties();
     void updateVhalHeartBeat(int64_t value);
     void checkVhalHealth();
     void terminateVhal();
diff --git a/data/etc/com.android.car.shell.xml b/data/etc/com.android.car.shell.xml
index 7097fb3..1abb205 100644
--- a/data/etc/com.android.car.shell.xml
+++ b/data/etc/com.android.car.shell.xml
@@ -71,5 +71,6 @@
         <permission name="android.car.permission.CONTROL_CAR_DISPLAY_UNITS" />
         <permission name="android.car.permission.ADJUST_RANGE_REMAINING" />
         <permission name="android.car.permission.MANAGE_OCCUPANT_ZONE"/>
+        <permission name="android.car.permission.CONTROL_STEERING_WHEEL"/>
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/com.google.android.car.kitchensink.xml b/data/etc/com.google.android.car.kitchensink.xml
index 4e1984a..bee026c 100644
--- a/data/etc/com.google.android.car.kitchensink.xml
+++ b/data/etc/com.google.android.car.kitchensink.xml
@@ -92,6 +92,7 @@
         <permission name="android.car.permission.READ_CAR_STEERING"/>
         <permission name="android.car.permission.SET_CAR_VENDOR_CATEGORY_INFO"/>
         <permission name="android.car.permission.STORAGE_MONITORING"/>
+        <permission name="android.car.permission.CONTROL_STEERING_WHEEL"/>
         <!-- use for CarWatchdogReliabilityTest -->
         <permission name="android.car.permission.USE_CAR_WATCHDOG"/>
         <permission name="android.car.permission.VMS_PUBLISHER"/>
diff --git a/packages/CarDeveloperOptions/res/values-en-rCA/strings.xml b/packages/CarDeveloperOptions/res/values-en-rCA/strings.xml
index 8441876..f0ad804 100644
--- a/packages/CarDeveloperOptions/res/values-en-rCA/strings.xml
+++ b/packages/CarDeveloperOptions/res/values-en-rCA/strings.xml
@@ -18,6 +18,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="car_pref_category_title" msgid="5776370242269122076">"Car"</string>
-    <string name="car_ui_plugin_enabled_pref_title" msgid="606705126746748119">"Enable Car UI library plugin"</string>
-    <string name="car_ui_plugin_not_found_text" msgid="7654699744630868262">"Car UI plugin not found"</string>
+    <string name="car_ui_plugin_enabled_pref_title" msgid="606705126746748119">"Enable car UI library plug-in"</string>
+    <string name="car_ui_plugin_not_found_text" msgid="7654699744630868262">"Car UI plug-in not found"</string>
 </resources>
diff --git a/packages/CarManagedProvisioning/res/values-en-rCA/strings.xml b/packages/CarManagedProvisioning/res/values-en-rCA/strings.xml
index 83f9d28..adfd848 100644
--- a/packages/CarManagedProvisioning/res/values-en-rCA/strings.xml
+++ b/packages/CarManagedProvisioning/res/values-en-rCA/strings.xml
@@ -17,30 +17,30 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="brand_screen_header" msgid="4382251935798018352">"This vehicle belongs to the organization"</string>
-    <string name="contact_device_provider" msgid="338577979231875837">"To learn more, contact the <xliff:g id="IT_ADMIN">%1$s</xliff:g>."</string>
-    <string name="organization_admin" msgid="6551608903069550652">"organization manager"</string>
-    <string name="if_questions_contact_admin" msgid="4645510019575736238">"If you have questions, contact the organization manager"</string>
-    <string name="admin_has_ability_to_monitor_device" msgid="3132155961508293345">"The organization manager has the ability to monitor and manage settings, corporate access, apps, permissions, and data associated with this vehicle, including network activity, as well as this vehicle\'s location.<xliff:g id="LINE_BREAK">
+    <string name="brand_screen_header" msgid="4382251935798018352">"This vehicle belongs to the organisation"</string>
+    <string name="contact_device_provider" msgid="338577979231875837">"To find out more, contact the <xliff:g id="IT_ADMIN">%1$s</xliff:g>."</string>
+    <string name="organization_admin" msgid="6551608903069550652">"organisation manager"</string>
+    <string name="if_questions_contact_admin" msgid="4645510019575736238">"If you have questions, contact the organisation manager"</string>
+    <string name="admin_has_ability_to_monitor_device" msgid="3132155961508293345">"The organisation manager has the ability to monitor and manage settings, corporate access, apps, permissions and data associated with this vehicle, including network activity, as well as this vehicle\'s location.<xliff:g id="LINE_BREAK">
 
-</xliff:g>Contact the organization manager for more information, including the organization\'s privacy policies."</string>
-    <string name="contact_your_admin_for_more_info" msgid="1419852317652804536">"Contact the organization manager for more information, including the organization\'s privacy policies."</string>
+</xliff:g>Contact the organisation manager for more information, including the organisation\'s privacy policies."</string>
+    <string name="contact_your_admin_for_more_info" msgid="1419852317652804536">"Contact the organisation manager for more information, including the organisation\'s privacy policies."</string>
     <string name="managed_device_info" msgid="2134697391634083944">"This is a managed vehicle"</string>
-    <string name="contact_your_admin_for_help" msgid="1741496631607502730">"Contact the organization manager for help"</string>
+    <string name="contact_your_admin_for_help" msgid="1741496631607502730">"Contact the organisation manager for help"</string>
     <string name="fully_managed_device_provisioning_accept_header" msgid="8767138982035307813">"Set up the managed vehicle"</string>
-    <string name="fully_managed_device_provisioning_step_1_header" msgid="8704166635032524345">"Access your organization\'s apps"</string>
-    <string name="fully_managed_device_provisioning_step_1_description" msgid="5960961281295355254">"Setting up infotainment system..."</string>
+    <string name="fully_managed_device_provisioning_step_1_header" msgid="8704166635032524345">"Access your organisation\'s apps"</string>
+    <string name="fully_managed_device_provisioning_step_1_description" msgid="5960961281295355254">"Setting up infotainment system…"</string>
     <string name="fully_managed_device_provisioning_step_2_header" msgid="5888602026900289468">"Infotainment system data isn\'t private"</string>
     <string name="fully_managed_device_provisioning_step_2_subheader_title" msgid="1421575203782743214">"Your activity and data"</string>
-    <string name="fully_managed_device_provisioning_step_2_subheader" msgid="4881961368653838979">"The organization manager may be able to see your activity and data on this vehicle."</string>
-    <string name="fully_managed_device_provisioning_permissions_secondary_subheader" msgid="8955791361423166123">"The organization manager can set permissions for apps on this vehicle, such as microphone and location permissions."</string>
-    <string name="fully_managed_device_with_permission_control_provisioning_summary" msgid="2503568673345133100">"Use this vehicle\'s infotainment system to easily access your work apps. This vehicle isn’t private, so the organization manager may be able to see your activity and data. The organization manager can also set permissions for apps on this vehicle, such as microphone and location permissions."</string>
-    <string name="fully_managed_device_provisioning_summary" msgid="4323948058344613817">"Use this vehicle\'s infotainment system to easily access your work apps. This vehicle isn\'t private, so the organization manager may be able to see your data and activity."</string>
+    <string name="fully_managed_device_provisioning_step_2_subheader" msgid="4881961368653838979">"The organisation manager may be able to see your activity and data on this vehicle."</string>
+    <string name="fully_managed_device_provisioning_permissions_secondary_subheader" msgid="8955791361423166123">"The organisation manager can set permissions for apps on this vehicle, such as microphone and location permissions."</string>
+    <string name="fully_managed_device_with_permission_control_provisioning_summary" msgid="2503568673345133100">"Use this vehicle\'s infotainment system to easily access your work apps. This vehicle isn’t private, so the organisation manager may be able to see your activity and data. The organisation manager can also set permissions for apps on this vehicle, such as microphone and location permissions."</string>
+    <string name="fully_managed_device_provisioning_summary" msgid="4323948058344613817">"Use this vehicle\'s infotainment system to easily access your work apps. This vehicle isn\'t private, so the organisation manager may be able to see your data and activity."</string>
     <string name="fully_managed_device_provisioning_progress_label" msgid="988594700479673633">"Setting up managed vehicle"</string>
     <string name="fully_managed_device_provisioning_return_device_title" msgid="1578111657911434819">"Cancel setup and return vehicle"</string>
-    <string name="fully_managed_device_provisioning_return_device_subheader" msgid="5809488930429106172">"Reset and return this vehicle to the organization manager, or go back to the previous screen to continue setup."</string>
+    <string name="fully_managed_device_provisioning_return_device_subheader" msgid="5809488930429106172">"Reset and return this vehicle to the organisation manager, or go back to the previous screen to continue setup."</string>
     <string name="fully_managed_device_cancel_setup_button" msgid="4113790677940440998">"Cancel setup"</string>
     <string name="fully_managed_device_reset_and_return_button" msgid="4951274590516561428">"Reset &amp; return"</string>
-    <string name="fully_managed_device_provisioning_privacy_title" msgid="4789425994893472324">"Privacy notice"</string>
-    <string name="fully_managed_device_provisioning_privacy_body" msgid="5549745709511179391">"The organization manager may be able to see your data and activity on this vehicle."</string>
+    <string name="fully_managed_device_provisioning_privacy_title" msgid="4789425994893472324">"Privacy Notice"</string>
+    <string name="fully_managed_device_provisioning_privacy_body" msgid="5549745709511179391">"The organisation manager may be able to see your data and activity on this vehicle."</string>
 </resources>
diff --git a/packages/CarShell/AndroidManifest.xml b/packages/CarShell/AndroidManifest.xml
index fe6bd7e..eab3ad0 100644
--- a/packages/CarShell/AndroidManifest.xml
+++ b/packages/CarShell/AndroidManifest.xml
@@ -94,6 +94,7 @@
     <uses-permission android:name="android.car.permission.READ_CAR_DISPLAY_UNITS" />
     <uses-permission android:name="android.car.permission.CONTROL_CAR_DISPLAY_UNITS" />
     <uses-permission android:name="android.car.permission.ADJUST_RANGE_REMAINING" />
+    <uses-permission android:name="android.car.permission.CONTROL_STEERING_WHEEL" />
     <!-- Permissions required for CTS test - CarPerformanceManagerTest -->
     <uses-permission android:name="android.car.permission.MANAGE_THREAD_PRIORITY" />
     <!-- Permissions required for CTS test - CarOccupantZoneManagerTest -->
diff --git a/packages/ScriptExecutor/src/BundleWrapper.cpp b/packages/ScriptExecutor/src/BundleWrapper.cpp
index 01c4d24..799f37c 100644
--- a/packages/ScriptExecutor/src/BundleWrapper.cpp
+++ b/packages/ScriptExecutor/src/BundleWrapper.cpp
@@ -107,6 +107,37 @@
     return {};  // ok result
 }
 
+Result<void> BundleWrapper::putBooleanArray(const char* key,
+                                            const std::vector<unsigned char>& value) {
+    ScopedLocalRef<jstring> keyStringRef(mJNIEnv, mJNIEnv->NewStringUTF(key));
+    if (keyStringRef == nullptr) {
+        return Error() << "Failed to create a string for a key=" << key << " due to OOM error";
+    }
+
+    jmethodID putBooleanArrayMethod =
+            mJNIEnv->GetMethodID(mBundleClass, "putBooleanArray", "(Ljava/lang/String;[Z)V");
+
+    ScopedLocalRef<jbooleanArray> arrayRef(mJNIEnv, mJNIEnv->NewBooleanArray(value.size()));
+    mJNIEnv->SetBooleanArrayRegion(arrayRef.get(), 0, value.size(), &value.at(0));
+    mJNIEnv->CallVoidMethod(mBundle, putBooleanArrayMethod, keyStringRef.get(), arrayRef.get());
+    return {};  // ok result
+}
+
+Result<void> BundleWrapper::putDoubleArray(const char* key, const std::vector<double>& value) {
+    ScopedLocalRef<jstring> keyStringRef(mJNIEnv, mJNIEnv->NewStringUTF(key));
+    if (keyStringRef == nullptr) {
+        return Error() << "Failed to create a string for a key=" << key << " due to OOM error";
+    }
+
+    jmethodID putDoubleArrayMethod =
+            mJNIEnv->GetMethodID(mBundleClass, "putDoubleArray", "(Ljava/lang/String;[D)V");
+
+    ScopedLocalRef<jdoubleArray> arrayRef(mJNIEnv, mJNIEnv->NewDoubleArray(value.size()));
+    mJNIEnv->SetDoubleArrayRegion(arrayRef.get(), 0, value.size(), &value[0]);
+    mJNIEnv->CallVoidMethod(mBundle, putDoubleArrayMethod, keyStringRef.get(), arrayRef.get());
+    return {};  // ok result
+}
+
 Result<void> BundleWrapper::putLongArray(const char* key, const std::vector<int64_t>& value) {
     ScopedLocalRef<jstring> keyStringRef(mJNIEnv, mJNIEnv->NewStringUTF(key));
     if (keyStringRef == nullptr) {
diff --git a/packages/ScriptExecutor/src/BundleWrapper.h b/packages/ScriptExecutor/src/BundleWrapper.h
index 094f1dd..e7473d8 100644
--- a/packages/ScriptExecutor/src/BundleWrapper.h
+++ b/packages/ScriptExecutor/src/BundleWrapper.h
@@ -45,6 +45,9 @@
     ::android::base::Result<void> putLong(const char* key, int64_t value);
     ::android::base::Result<void> putDouble(const char* key, double value);
     ::android::base::Result<void> putString(const char* key, const char* value);
+    ::android::base::Result<void> putBooleanArray(const char* key,
+                                                  const std::vector<unsigned char>& value);
+    ::android::base::Result<void> putDoubleArray(const char* key, const std::vector<double>& value);
     ::android::base::Result<void> putLongArray(const char* key, const std::vector<int64_t>& value);
     ::android::base::Result<void> putStringArray(const char* key,
                                                  const std::vector<std::string>& value);
diff --git a/packages/ScriptExecutor/src/JniUtils.cpp b/packages/ScriptExecutor/src/JniUtils.cpp
index b33bfc2..119debd 100644
--- a/packages/ScriptExecutor/src/JniUtils.cpp
+++ b/packages/ScriptExecutor/src/JniUtils.cpp
@@ -55,12 +55,11 @@
     ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long"));
     ScopedLocalRef<jclass> numberClass(env, env->FindClass("java/lang/Number"));
     ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String"));
+    ScopedLocalRef<jclass> booleanArrayClass(env, env->FindClass("[Z"));
     ScopedLocalRef<jclass> intArrayClass(env, env->FindClass("[I"));
     ScopedLocalRef<jclass> longArrayClass(env, env->FindClass("[J"));
     ScopedLocalRef<jclass> doubleArrayClass(env, env->FindClass("[D"));
     ScopedLocalRef<jclass> stringArrayClass(env, env->FindClass("[Ljava/lang/String;"));
-    // TODO(b/188816922): Handle more types such as float and integer arrays,
-    // and perhaps nested Bundles.
 
     jmethodID getMethod = env->GetMethodID(persistableBundleClass.get(), "get",
                                            "(Ljava/lang/String;)Ljava/lang/Object;");
@@ -100,6 +99,23 @@
                     env->GetStringUTFChars(static_cast<jstring>(value.get()), nullptr);
             lua_pushstring(lua, rawStringValue);
             env->ReleaseStringUTFChars(static_cast<jstring>(value.get()), rawStringValue);
+        } else if (env->IsInstanceOf(value.get(), booleanArrayClass.get())) {
+            jbooleanArray booleanArray = static_cast<jbooleanArray>(value.get());
+            const auto kLength = env->GetArrayLength(booleanArray);
+            // Arrays are represented as a table of sequential elements in Lua.
+            // We are creating a nested table to represent this array. We specify number of elements
+            // in the Java array to preallocate memory accordingly.
+            lua_createtable(lua, kLength, 0);
+            jboolean* rawBooleanArray = env->GetBooleanArrayElements(booleanArray, nullptr);
+            // Fills in the table at stack idx -2 with key value pairs, where key is a
+            // Lua index and value is an integer from the long array at that index
+            for (int i = 0; i < kLength; i++) {
+                lua_pushboolean(lua, rawBooleanArray[i]);
+                lua_rawseti(lua, /* idx= */ -2,
+                            i + 1);  // lua index starts from 1
+            }
+            // JNI_ABORT is used because we do not need to copy back elements.
+            env->ReleaseBooleanArrayElements(booleanArray, rawBooleanArray, JNI_ABORT);
         } else if (env->IsInstanceOf(value.get(), intArrayClass.get())) {
             jintArray intArray = static_cast<jintArray>(value.get());
             const auto kLength = env->GetArrayLength(intArray);
@@ -264,6 +280,8 @@
                            "is unrecoverable.";
             }
 
+            std::vector<unsigned char> boolArray;
+            std::vector<double> doubleArray;
             std::vector<int64_t> longArray;
             std::vector<std::string> stringArray;
             int originalLuaType = LUA_TNIL;
@@ -289,13 +307,15 @@
                                "unrecoverable.";
                 }
                 switch (currentType) {
+                    case LUA_TBOOLEAN:
+                        boolArray.push_back(
+                                static_cast<unsigned char>(lua_toboolean(lua, /* index = */ -1)));
+                        break;
                     case LUA_TNUMBER:
-                        if (!lua_isinteger(lua, /* index = */ -1)) {
-                            return Error() << "Returned value for key=" << key
-                                           << " contains a floating number array, which is not "
-                                              "supported yet.";
-                        } else {
+                        if (lua_isinteger(lua, /* index = */ -1)) {
                             longArray.push_back(lua_tointeger(lua, /* index = */ -1));
+                        } else {
+                            doubleArray.push_back(lua_tonumber(lua, /* index = */ -1));
                         }
                         break;
                     case LUA_TSTRING:
@@ -313,8 +333,15 @@
                 lua_pop(lua, 1);
             }
             switch (originalLuaType) {
+                case LUA_TBOOLEAN:
+                    bundleInsertionResult = bundleWrapper->putBooleanArray(key, boolArray);
+                    break;
                 case LUA_TNUMBER:
-                    bundleInsertionResult = bundleWrapper->putLongArray(key, longArray);
+                    if (longArray.size() > 0) {
+                        bundleInsertionResult = bundleWrapper->putLongArray(key, longArray);
+                    } else {
+                        bundleInsertionResult = bundleWrapper->putDoubleArray(key, doubleArray);
+                    }
                     break;
                 case LUA_TSTRING:
                     bundleInsertionResult = bundleWrapper->putStringArray(key, stringArray);
diff --git a/packages/ScriptExecutor/tests/functional/src/com/android/car/scriptexecutortest/functional/ScriptExecutorFunctionalTest.java b/packages/ScriptExecutor/tests/functional/src/com/android/car/scriptexecutortest/functional/ScriptExecutorFunctionalTest.java
index 16837cf..4f30cf6 100644
--- a/packages/ScriptExecutor/tests/functional/src/com/android/car/scriptexecutortest/functional/ScriptExecutorFunctionalTest.java
+++ b/packages/ScriptExecutor/tests/functional/src/com/android/car/scriptexecutortest/functional/ScriptExecutorFunctionalTest.java
@@ -282,16 +282,22 @@
         String script =
                 "function arrays(data, state)\n"
                         + "    result = {}\n"
+                        + "    result.boolean_array = state.boolean_array\n"
+                        + "    result.double_array = state.double_array\n"
                         + "    result.int_array = state.int_array\n"
                         + "    result.long_array = state.long_array\n"
                         + "    result.string_array = state.string_array\n"
                         + "    on_success(result)\n"
                         + "end\n";
         PersistableBundle previousState = new PersistableBundle();
+        boolean[] boolean_array = new boolean[] {true, true, false};
+        double[] double_array = new double[] {1.5, 2.222};
         int[] int_array = new int[] {1, 2};
         long[] int_array_in_long = new long[] {1, 2};
         long[] long_array = new long[] {1, 2, 3};
         String[] string_array = new String[] {"one", "two", "three"};
+        previousState.putBooleanArray("boolean_array", boolean_array);
+        previousState.putDoubleArray("double_array", double_array);
         previousState.putIntArray("int_array", int_array);
         previousState.putLongArray("long_array", long_array);
         previousState.putStringArray("string_array", string_array);
@@ -299,9 +305,12 @@
         runScriptAndWaitForResponse(script, "arrays", mEmptyPublishedData, previousState);
 
         // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mListener.mInterimResult.size()).isEqualTo(3);
+        assertThat(mListener.mInterimResult.size()).isEqualTo(5);
         // Lua has only one lua_Integer. Here Java long is used to represent it when data is
         // transferred from Lua to CarTelemetryService.
+        assertThat(mListener.mInterimResult.getBooleanArray("boolean_array"))
+                .isEqualTo(boolean_array);
+        assertThat(mListener.mInterimResult.getDoubleArray("double_array")).isEqualTo(double_array);
         assertThat(mListener.mInterimResult.getLongArray("int_array")).isEqualTo(int_array_in_long);
         assertThat(mListener.mInterimResult.getLongArray("long_array")).isEqualTo(long_array);
         assertThat(mListener.mInterimResult.getStringArray("string_array")).isEqualTo(string_array);
@@ -884,52 +893,6 @@
     }
 
     @Test
-    public void invokeScript_returnedFloatingArraysNotSupported()
-            throws RemoteException, InterruptedException {
-        // Verifies that we do not support return values that contain floating number arrays.
-        String script =
-                "function floating_point_arrays(data, state)\n"
-                        + "    array = {}\n"
-                        + "    array[0] = 1.1\n"
-                        + "    array[1] = 1.2\n"
-                        + "    result = {data = array}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(
-                script, "floating_point_arrays", mEmptyPublishedData, mEmptyIterimResult);
-
-        // Verify that the expected error is received.
-        assertThat(mListener.mErrorType)
-                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mListener.mMessage)
-                .contains("a floating number array, which is not supported yet");
-    }
-
-    @Test
-    public void invokeScript_returnedBooleanArraysNotSupported()
-            throws RemoteException, InterruptedException {
-        // Verifies that we do not yet support return values that contain boolean arrays.
-        String script =
-                "function array_of_booleans(data, state)\n"
-                        + "    array = {}\n"
-                        + "    array[0] = false\n"
-                        + "    array[1] = true\n"
-                        + "    result = {data = array}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(
-                script, "array_of_booleans", mEmptyPublishedData, mEmptyIterimResult);
-
-        // Verify that the expected error is received.
-        assertThat(mListener.mErrorType)
-                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mListener.mMessage)
-                .contains("is an array with values of type=boolean, which is not supported yet");
-    }
-
-    @Test
     public void invokeScript_onMetricsReport_returnsReport() throws Exception {
         String returnFinalResultScript =
                 "function script_completes(data, state)\n"
diff --git a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTest.java b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTest.java
index be10d69..3e4f33e 100644
--- a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTest.java
+++ b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTest.java
@@ -38,6 +38,7 @@
     private static final String INT_KEY = "int_key";
     private static final String STRING_KEY = "string_key";
     private static final String NUMBER_KEY = "number_key";
+    private static final String BOOLEAN_ARRAY_KEY = "boolean_array_key";
     private static final String INT_ARRAY_KEY = "int_array_key";
     private static final String LONG_ARRAY_KEY = "long_array_key";
     private static final String DOUBLE_ARRAY_KEY = "double_array_key";
@@ -48,6 +49,7 @@
     private static final int INT_VALUE = 10;
     private static final int INT_VALUE_2 = 20;
     private static final String STRING_VALUE = "test";
+    private static final boolean[] BOOLEAN_ARRAY_VALUE = new boolean[]{true, false, true};
     private static final int[] INT_ARRAY_VALUE = new int[]{1, 2, 3};
     private static final long[] LONG_ARRAY_VALUE = new long[]{1, 2, 3, 4};
     private static final double[] DOUBLE_ARRAY_VALUE = new double[]{1.1d, 2.2d, 3.3d, 4.4d};
@@ -97,6 +99,9 @@
 
     private native boolean nativeHasIntValue(long luaEnginePtr, String key, int value);
 
+    private native boolean nativeHasBooleanArrayValue(
+            long luaEnginePtr, String key, boolean[] value);
+
     private native boolean nativeHasDoubleValue(long luaEnginePtr, String key, double value);
 
     private native boolean nativeHasIntArrayValue(long luaEnginePtr, String key, int[] value);
@@ -163,6 +168,7 @@
     @Test
     public void pushBundleToLuaTable_arrays() {
         PersistableBundle bundle = new PersistableBundle();
+        bundle.putBooleanArray(BOOLEAN_ARRAY_KEY, BOOLEAN_ARRAY_VALUE);
         bundle.putIntArray(INT_ARRAY_KEY, INT_ARRAY_VALUE);
         bundle.putLongArray(LONG_ARRAY_KEY, LONG_ARRAY_VALUE);
         bundle.putDoubleArray(DOUBLE_ARRAY_KEY, DOUBLE_ARRAY_VALUE);
@@ -174,6 +180,8 @@
         // Check contents of Lua table.
         // Java int and long arrays both end up being arrays of Lua's Integer type,
         // which is interpreted as a 8-byte int type.
+        assertThat(nativeHasBooleanArrayValue(
+                mLuaEnginePtr, BOOLEAN_ARRAY_KEY, BOOLEAN_ARRAY_VALUE)).isTrue();
         assertThat(nativeHasIntArrayValue(mLuaEnginePtr, INT_ARRAY_KEY, INT_ARRAY_VALUE)).isTrue();
         assertThat(nativeHasLongArrayValue(mLuaEnginePtr, LONG_ARRAY_KEY, LONG_ARRAY_VALUE))
                 .isTrue();
diff --git a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp
index ce3be66..5597e50 100644
--- a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp
+++ b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp
@@ -72,6 +72,44 @@
     return result;
 }
 
+template <typename T>
+bool hasValidBooleanArray(JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key,
+                          T rawInputArray, const int arrayLength) {
+    const char* rawKey = env->GetStringUTFChars(key, nullptr);
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    // Assumes the table is on top of the stack.
+    auto* luaState = engine->getLuaState();
+    lua_pushstring(luaState, rawKey);
+    env->ReleaseStringUTFChars(key, rawKey);
+    lua_gettable(luaState, -2);
+    bool result = false;
+    if (!lua_istable(luaState, -1)) {
+        result = false;
+    } else {
+        // First, compare the input and Lua array sizes.
+        const auto kActualLength = lua_rawlen(luaState, -1);
+        if (arrayLength != kActualLength) {
+            // No need to compare further if number of elements in the two arrays are not equal.
+            result = false;
+        } else {
+            // Do element by element comparison.
+            bool is_equal = true;
+            for (int i = 0; i < arrayLength; ++i) {
+                lua_rawgeti(luaState, -1, i + 1);
+                is_equal = lua_isboolean(luaState, /* idx = */ -1) &&
+                        lua_toboolean(luaState, /* idx = */ -1) ==
+                                static_cast<bool>(rawInputArray[i]);
+                lua_pop(luaState, 1);
+                if (!is_equal) break;
+            }
+            result = is_equal;
+        }
+    }
+    lua_pop(luaState, 1);
+    return result;
+}
+
 extern "C" {
 
 #include "lua.h"
@@ -198,6 +236,16 @@
 }
 
 JNIEXPORT bool JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasBooleanArrayValue(
+        JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jbooleanArray value) {
+    jboolean* rawInputArray = env->GetBooleanArrayElements(value, nullptr);
+    const auto kInputLength = env->GetArrayLength(value);
+    bool result = hasValidBooleanArray(env, object, luaEnginePtr, key, rawInputArray, kInputLength);
+    env->ReleaseBooleanArrayElements(value, rawInputArray, JNI_ABORT);
+    return result;
+}
+
+JNIEXPORT bool JNICALL
 Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasIntArrayValue(
         JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jintArray value) {
     jint* rawInputArray = env->GetIntArrayElements(value, nullptr);
diff --git a/service-builtin/res/values-en-rCA/strings.xml b/service-builtin/res/values-en-rCA/strings.xml
index 595ab67..25bed2a 100644
--- a/service-builtin/res/values-en-rCA/strings.xml
+++ b/service-builtin/res/values-en-rCA/strings.xml
@@ -20,12 +20,12 @@
     <string name="car_permission_desc_bind_projection_service" msgid="4610418233070289810">"Allows the holder to bind to the top-level interface of a projection service. Should never be needed for normal apps."</string>
     <string name="car_permission_label_bind_vms_client" msgid="1298928874094319701">"VMS Client Service"</string>
     <string name="car_permission_desc_bind_vms_client" msgid="7758142590449847602">"Bind to VMS clients"</string>
-    <string name="car_permission_label_bind_instrument_cluster_rendering" msgid="6723392540805279625">"Instrument Cluster Rendering"</string>
+    <string name="car_permission_label_bind_instrument_cluster_rendering" msgid="6723392540805279625">"Instrument cluster rendering"</string>
     <string name="car_permission_desc_bind_instrument_cluster_rendering" msgid="2583711303360788080">"Receive instrument cluster data"</string>
-    <string name="car_permission_label_bind_input_service" msgid="6647238478703096557">"Car Input Service"</string>
+    <string name="car_permission_label_bind_input_service" msgid="6647238478703096557">"Car input service"</string>
     <string name="car_permission_desc_bind_input_service" msgid="8460218104132496613">"Handle input events"</string>
     <string name="activity_blocked_text" msgid="5991043857905412794">"You can’t use this feature while driving"</string>
-    <string name="exit_button_message" msgid="5375678491245394542">"To start over with safe app features, select <xliff:g id="EXIT_BUTTON">%s</xliff:g>."</string>
+    <string name="exit_button_message" msgid="5375678491245394542">"To start again with safe app features, select <xliff:g id="EXIT_BUTTON">%s</xliff:g>."</string>
     <string name="exit_button" msgid="3491899413031549265">"Back"</string>
     <string name="exit_button_close_application" msgid="5153716684207539041">"Close app"</string>
     <string name="exit_button_go_back" msgid="6921595432375141935">"Back"</string>
@@ -36,9 +36,9 @@
     <string name="factory_reset_notification_text" msgid="6051393302193696102">"All data in the infotainment system will be erased. After reset, you can set up a new profile."</string>
     <string name="factory_reset_notification_button" msgid="6926734587145351076">"More"</string>
     <string name="factory_reset_warning" msgid="8463356329619149262">"Your device will be erased"</string>
-    <string name="factory_reset_message" msgid="1972536809866779972">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organization\'s admin."</string>
+    <string name="factory_reset_message" msgid="1972536809866779972">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="resource_overuse_notification_title" msgid="1622015333965744463">"<xliff:g id="ID_1">^1</xliff:g> is affecting your system performance"</string>
-    <string name="resource_overuse_notification_text_disabled_app" msgid="9058683477901746549">"This app has been prevented from running in the background. Prioritize app to continue background usage."</string>
+    <string name="resource_overuse_notification_text_disabled_app" msgid="9058683477901746549">"This app has been prevented from running in the background. Prioritise app to continue background usage."</string>
     <string name="resource_overuse_notification_button_close_app" msgid="131355952730826999">"Close"</string>
-    <string name="resource_overuse_notification_button_prioritize_app" msgid="1093325910457794796">"Prioritize app"</string>
+    <string name="resource_overuse_notification_button_prioritize_app" msgid="1093325910457794796">"Prioritise app"</string>
 </resources>
diff --git a/service-builtin/src/com/android/car/CarService.java b/service-builtin/src/com/android/car/CarService.java
index 30f57b9..42c3636 100644
--- a/service-builtin/src/com/android/car/CarService.java
+++ b/service-builtin/src/com/android/car/CarService.java
@@ -18,10 +18,19 @@
 
 import android.content.Intent;
 
+import com.android.internal.os.BinderInternal;
+
 /** Proxy service for CarServciceImpl */
 public class CarService extends ServiceProxy {
+
+    // Binder threads are set to 31. system_server is also using 31.
+    // check sMaxBinderThreads in SystemServer.java
+    private  static final int MAX_BINDER_THREADS = 31;
+
     public CarService() {
         super(UpdatablePackageDependency.CAR_SERVICE_IMPL_CLASS);
+        // Increase the number of binder threads in car service
+        BinderInternal.setMaxThreads(MAX_BINDER_THREADS);
     }
 
     @Override
diff --git a/service/AndroidManifest.xml b/service/AndroidManifest.xml
index c7eff38..36e7c41 100644
--- a/service/AndroidManifest.xml
+++ b/service/AndroidManifest.xml
@@ -277,14 +277,6 @@
                 android:label="@string/car_permission_label_car_epoch_time"
                 android:description="@string/car_permission_desc_car_epoch_time"/>
 
-    <!-- Allows an application to read and write car's storage encryption binding seed.
-         <p>Protection level: signature|privileged
-    -->
-    <permission android:name="android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED"
-                android:protectionLevel="signature|privileged"
-                android:label="@string/car_permission_label_encryption_binding_seed"
-                android:description="@string/car_permission_desc_encryption_binding_seed"/>
-
     <!-- Allows an application to read the vehicle exterior lights state.
          <p>Protection level: signature|privileged
     -->
@@ -946,6 +938,14 @@
         android:label="@string/car_permission_label_control_remote_access"
         android:description="@string/car_permission_desc_control_remote_access"/>
 
+     <!-- Allows an application to control the vehicle's steering wheel.
+         <p>Protection level: signature|privileged
+      -->
+     <permission android:name="android.car.permission.CONTROL_STEERING_WHEEL"
+        android:protectionLevel="signature|privileged"
+        android:label="@string/car_permission_label_control_steering_wheel"
+        android:description="@string/car_permission_desc_control_steering_wheel"/>
+
     <!-- NOTE: when you're adding a new permission, you should edit
          cts/tests/tests/permission2/res/raw/automotive_android_manifest.xml accordingly and run
          the test with 'atest android.permission2.cts.PermissionPolicyTest' to verify it.
diff --git a/service/jni/evs/EvsServiceContext.cpp b/service/jni/evs/EvsServiceContext.cpp
index eaeee5e..d7bfeba 100644
--- a/service/jni/evs/EvsServiceContext.cpp
+++ b/service/jni/evs/EvsServiceContext.cpp
@@ -318,7 +318,8 @@
         LOG(WARNING) << "Failed to close a current camera device.";
     }
 
-    // Reset a camera id in use.
+    // Reset a camera reference and id in use.
+    mCamera.reset();
     mCameraIdInUse.clear();
 }
 
diff --git a/service/proto/android/car/telemetry/atoms.proto b/service/proto/android/car/telemetry/atoms.proto
index 4aad716..cd504f1 100644
--- a/service/proto/android/car/telemetry/atoms.proto
+++ b/service/proto/android/car/telemetry/atoms.proto
@@ -37,6 +37,7 @@
   oneof pulled {
     ProcessMemoryState process_memory_state = 10013;
     ProcessCpuTime process_cpu_time = 10035;
+    ProcessMemorySnapshot process_memory_snapshot = 10064;
   }
 }
 
@@ -167,6 +168,19 @@
   optional ErrorSource error_source = 5;
 }
 
+message ProcessMemorySnapshot {
+  optional int32 uid = 1;
+  optional string process_name = 2;
+  optional int32 pid = 3;
+  optional int32 oom_score_adj = 4;
+  optional int32 rss_in_kilobytes = 5;
+  optional int32 anon_rss_in_kilobytes = 6;
+  optional int32 swap_in_kilobytes = 7;
+  optional int32 anon_rss_and_swap_in_kilobytes = 8;
+  optional int32 gpu_memory_kb = 9;
+  optional bool has_foreground_services = 10;
+}
+
 message CarPowerStateChanged {
   enum State {
     WAIT_FOR_VHAL = 0;
diff --git a/service/res/values-af/strings.xml b/service/res/values-af/strings.xml
index 7ca9fc3..7655eb8 100644
--- a/service/res/values-af/strings.xml
+++ b/service/res/values-af/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Bestuur draadprioriteit."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"bestuur insittendesone"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Bestuur insittendesone."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"gebruik afstandtoegang"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Gebruik afstandtoegang."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"beheer afstandtoegang"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Beheer afstandtoegang."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-bus het misluk"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-bus reageer nie. Ontprop hoofeenheidkas, prop dit weer in, en herbegin die motor"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Toestel"</string>
diff --git a/service/res/values-am/strings.xml b/service/res/values-am/strings.xml
index db39114..f585926 100644
--- a/service/res/values-am/strings.xml
+++ b/service/res/values-am/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"የተከታታይ ቅድሚያን ያስተዳድሩ።"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"የነዋሪን ዞን አስተዳድር"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"የነዋሪን ዞን አስተዳድር።"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN አውቶብስ አልተሳካም"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN አውቶብስ ምላሽ አይሰጥም። የጭንቅላት አሃድ መያዣ ሳጥኑን ይሰኩ እና ይንቀሉ በመቀጠል መኪናውን ዳግም ያስጀምሩ"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"የእኔ መሣሪያ"</string>
diff --git a/service/res/values-ar/strings.xml b/service/res/values-ar/strings.xml
index 9353647..060a137 100644
--- a/service/res/values-ar/strings.xml
+++ b/service/res/values-ar/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"يمكنك إدارة أولوية سلسلة المحادثات."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"إدارة منطقة الإشغال"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"إدارة منطقة الإشغال"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"حدث خطأ في موصّل CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"لا استجابة من موصّل CAN. يمكنك فصل صندوق وحدة الرأس وإعادة تشغيل السيارة."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"جهازي"</string>
diff --git a/service/res/values-as/strings.xml b/service/res/values-as/strings.xml
index 070763b..cd6a7f3 100644
--- a/service/res/values-as/strings.xml
+++ b/service/res/values-as/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"থ্ৰেডৰ অগ্ৰাধিকাৰ পৰিচালনা কৰক।"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"আৰোহীৰ স্থান পৰিচালনা কৰক"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"আৰোহীৰ স্থান পৰিচালনা কৰক।"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN বাছ বিফল হৈছে"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN বাছে সঁহাৰি দিয়া নাই। হে’ড ইউনিট বাকচটো আঁতৰাই পুনৰ লগাওক"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"মোৰ ডিভাইচ"</string>
diff --git a/service/res/values-az/strings.xml b/service/res/values-az/strings.xml
index 8e68f87..646d33f 100644
--- a/service/res/values-az/strings.xml
+++ b/service/res/values-az/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Mövzu prioritetini idarə edin."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"istifadəçi zonasını idarə edin"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"İstifadəçi zonasını idarə edin."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN idarəetmə mexanizmi uğursuz oldu"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN mexanizmi cavab vermir. Əsas cihaz panelini ayırın və yenidən qoşun, sonra avtomobili yenidən işə salın"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Cihazım"</string>
diff --git a/service/res/values-b+sr+Latn/strings.xml b/service/res/values-b+sr+Latn/strings.xml
index 89e397c..ba501db 100644
--- a/service/res/values-b+sr+Latn/strings.xml
+++ b/service/res/values-b+sr+Latn/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Upravljanje prioritetom niti."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"upravljanje zonom prisutnosti"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Upravljanje zonom prisutnosti."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"koriste daljinski pristup"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Koriste daljinski pristup."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"kontrolišu daljinski pristup"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Kontrolišu daljinski pristup."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Greška CAN magistrale"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN magistrala ne reaguje. Isključite i ponovo uključite glavnu jedinicu i ponovo pokrenite automobil"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moj uređaj"</string>
diff --git a/service/res/values-be/strings.xml b/service/res/values-be/strings.xml
index 07c37a6..fa375e6 100644
--- a/service/res/values-be/strings.xml
+++ b/service/res/values-be/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Кіраваць прыярытэтам патокаў."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"кіраванне зонай пасажыра"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Кіраванне зонай пасажыра."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-шына парушана"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-шына не адказвае. Перападключыце канектар, а затым выключыце запальванне і паўторна завядзіце аўтамабіль"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мая прылада"</string>
diff --git a/service/res/values-bg/strings.xml b/service/res/values-bg/strings.xml
index 60bf08e..9552d3d 100644
--- a/service/res/values-bg/strings.xml
+++ b/service/res/values-bg/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Управление на приоритета на нишката."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"управление на зоната на пътниците"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Управление на зоната на пътниците."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Грешка в CAN шината"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN шината не реагира. Изключете и включете отново захранването на основното устройство и рестартирайте автомобила"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Моето устройство"</string>
diff --git a/service/res/values-bn/strings.xml b/service/res/values-bn/strings.xml
index d1131c8..e98d52f 100644
--- a/service/res/values-bn/strings.xml
+++ b/service/res/values-bn/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"থ্রেডের অগ্রাধিকার ম্যানেজ করুন।"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"অকুপ্যান্ট জোন ম্যানেজ করুন"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"অকুপ্যান্ট জোন ম্যানেজ করুন।"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN বাস কাজ করছে না"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN বাস কাজ করছে না। হেডইউনিট বক্স খুলে নিয়ে আবার লাগান ও গাড়ি রিস্টার্ট করুন"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"আমার ডিভাইস"</string>
diff --git a/service/res/values-bs/strings.xml b/service/res/values-bs/strings.xml
index 10dc58a..417a909 100644
--- a/service/res/values-bs/strings.xml
+++ b/service/res/values-bs/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Upravljanje prioritetom niti."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"upravljaju zonom prisutnih"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Upravljaju zonom prisutnih."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"koriste daljinski pristup"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Koriste daljinski pristup."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"upravljaju daljinskim pristupom"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Upravljaju daljinskim pristupom."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Greška CAN busa"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus ne reagira. Isključite i ponovo uključite glavnu jedinicu i ponovo pokrenite automobil"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moj uređaj"</string>
diff --git a/service/res/values-ca/strings.xml b/service/res/values-ca/strings.xml
index 659eeb3..69a076e 100644
--- a/service/res/values-ca/strings.xml
+++ b/service/res/values-ca/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Gestiona la prioritat de les converses."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"gestionar la zona d\'ocupació"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Gestionar la zona d\'ocupació."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Ha fallat el bus CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"El bus CAN no respon. Desendolla i torna a endollar el capçal i torna a engegar el cotxe."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"El meu dispositiu"</string>
diff --git a/service/res/values-cs/strings.xml b/service/res/values-cs/strings.xml
index bd6f989..c3b6bb7 100644
--- a/service/res/values-cs/strings.xml
+++ b/service/res/values-cs/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Správa priority vlákna."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"spravovat zónu cestujících"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Spravovat zónu cestujících."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"použití vzdáleného přístupu"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Použití vzdáleného přístupu."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"ovládání vzdáleného přístupu"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Ovládání vzdáleného přístupu."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Sběrnice CAN selhala"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Sběrnice CAN neodpovídá. Odpojte a opět zapojte autorádio a znovu nastartujte auto"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moje zařízení"</string>
diff --git a/service/res/values-da/strings.xml b/service/res/values-da/strings.xml
index 7396642..21f41de 100644
--- a/service/res/values-da/strings.xml
+++ b/service/res/values-da/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Administrer trådprioritet."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"administrer tilstedeværelseszone"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Administrer tilstedeværelseszone."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-bus (Controller Area Network) mislykkedes"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-bus (Controller Area Network) svarer ikke. Afbryd forbindelsen til bilens hovedenhed, tilslut den igen, og genstart bilen"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Min enhed"</string>
diff --git a/service/res/values-de/strings.xml b/service/res/values-de/strings.xml
index cbcb7c1..299948d 100644
--- a/service/res/values-de/strings.xml
+++ b/service/res/values-de/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Thread-Priorität verwalten."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"Insassenbereich verwalten"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Insassenbereich verwalten."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-Bus ausgefallen"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-Bus reagiert nicht. Trenne die Haupteinheit vom Stromnetz, schließe sie wieder an und starte das Auto."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mein Gerät"</string>
diff --git a/service/res/values-el/strings.xml b/service/res/values-el/strings.xml
index 88062aa..93cdba8 100644
--- a/service/res/values-el/strings.xml
+++ b/service/res/values-el/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Διαχείριση προτεραιότητας νημάτων."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"διαχείριση χώρου επιβατών οχήματος"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Διαχείριση χώρου επιβατών οχήματος."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"χρήση απομακρυσμένης πρόσβασης"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Χρήση απομακρυσμένης πρόσβασης."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"έλεγχος απομακρυσμένης πρόσβασης"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Έλεγχος απομακρυσμένης πρόσβασης."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Αποτυχία διαύλου CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Ο δίαυλος CAN δεν αποκρίνεται. Αποσυνδέστε και συνδέστε ξανά το πλαίσιο μονάδας κεφαλής και έπειτα επανεκκινήστε το αυτοκίνητο"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Η συσκευή μου"</string>
diff --git a/service/res/values-en-rAU/strings.xml b/service/res/values-en-rAU/strings.xml
index af7ab50..a5e5a0f 100644
--- a/service/res/values-en-rAU/strings.xml
+++ b/service/res/values-en-rAU/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Manage thread priority."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"manage occupant zone"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Manage occupant zone."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"use remote access"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Use remote access."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"control remote access"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Control remote access."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus failed"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus does not respond. Unplug and plug back in head unit box and restart the car"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
diff --git a/service/res/values-en-rCA/strings.xml b/service/res/values-en-rCA/strings.xml
index 1873c8b..a5e5a0f 100644
--- a/service/res/values-en-rCA/strings.xml
+++ b/service/res/values-en-rCA/strings.xml
@@ -27,7 +27,7 @@
     <string name="car_permission_label_adjust_range_remaining" msgid="839033553999920138">"adjust car’s range remaining"</string>
     <string name="car_permission_desc_adjust_range_remaining" msgid="2369321650437370673">"Adjust car’s range remaining value."</string>
     <string name="car_permission_label_hvac" msgid="1499454192558727843">"access car’s hvac"</string>
-    <string name="car_permission_desc_hvac" msgid="3754229695589774195">"Access your car’s hvac."</string>
+    <string name="car_permission_desc_hvac" msgid="3754229695589774195">"Access your car’s HVAC."</string>
     <string name="car_permission_label_mileage" msgid="4661317074631150551">"access car’s mileage information"</string>
     <string name="car_permission_desc_mileage" msgid="7179735693278681090">"Access your car’s mileage information."</string>
     <string name="car_permission_label_speed" msgid="1149027717860529745">"read car’s speed"</string>
@@ -52,7 +52,7 @@
     <string name="car_permission_desc_audio_settings" msgid="7192007170677915937">"Control your car’s audio settings."</string>
     <string name="car_permission_label_control_app_blocking" msgid="9112678596919993386">"Application blocking"</string>
     <string name="car_permission_desc_control_app_blocking" msgid="7539378161760696190">"Control application blocking while driving."</string>
-    <string name="car_permission_car_navigation_manager" msgid="5895461364007854077">"Navigation Manager"</string>
+    <string name="car_permission_car_navigation_manager" msgid="5895461364007854077">"Navigation manager"</string>
     <string name="car_permission_desc_car_navigation_manager" msgid="6188751054665471537">"Report navigation data to instrument cluster"</string>
     <string name="car_permission_car_display_in_cluster" msgid="4005987646292458684">"Direct rendering to instrument cluster"</string>
     <string name="car_permission_desc_car_display_in_cluster" msgid="2668300546822672927">"Allow an application to declare activities to be displayed in the instrument cluster"</string>
@@ -60,16 +60,16 @@
     <string name="car_permission_desc_car_cluster_control" msgid="9222776665281176031">"Launch apps in the instrument cluster"</string>
     <string name="car_permission_car_monitor_cluster_navigation_state" msgid="7025307242306902441">"Instrument cluster navigation state"</string>
     <string name="car_permission_desc_car_monitor_cluster_navigation_state" msgid="8745047153878713339">"Listen for instrument cluster navigation state changes"</string>
-    <string name="car_permission_label_car_ux_restrictions_configuration" msgid="6801393970411049725">"UX Restrictions Configuration"</string>
-    <string name="car_permission_desc_car_ux_restrictions_configuration" msgid="5711926927484813777">"Configure UX Restrictions"</string>
-    <string name="car_permission_label_access_private_display_id" msgid="6712116114341634316">"Read access to private display id"</string>
-    <string name="car_permission_desc_access_private_display_id" msgid="8535974477610944721">"Allows read access to private display id"</string>
+    <string name="car_permission_label_car_ux_restrictions_configuration" msgid="6801393970411049725">"UX restrictions configuration"</string>
+    <string name="car_permission_desc_car_ux_restrictions_configuration" msgid="5711926927484813777">"Configure UX restrictions"</string>
+    <string name="car_permission_label_access_private_display_id" msgid="6712116114341634316">"Read access to private display ID"</string>
+    <string name="car_permission_desc_access_private_display_id" msgid="8535974477610944721">"Allows read access to private display ID"</string>
     <string name="car_permission_label_car_handle_usb_aoap_device" msgid="72783989504378036">"Communicate with USB device in AOAP mode"</string>
     <string name="car_permission_desc_car_handle_usb_aoap_device" msgid="273505990971317034">"Allows an app to communicate with a device in AOAP mode"</string>
-    <string name="car_permission_label_read_car_occupant_awareness_state" msgid="125517953575032758">"Occupant Awareness System Read Access"</string>
-    <string name="car_permission_desc_read_car_occupant_awareness_state" msgid="188865882598414986">"Allows reading status and detection data for Occupant Awareness System"</string>
-    <string name="car_permission_label_control_car_occupant_awareness_system" msgid="7163330266691094542">"Control Occupant Awareness System Graph"</string>
-    <string name="car_permission_desc_control_car_occupant_awareness_system" msgid="7123482622084531911">"Allows controlling the start and stopping of the Occupant Awareness System detection graph"</string>
+    <string name="car_permission_label_read_car_occupant_awareness_state" msgid="125517953575032758">"Occupant awareness system read access"</string>
+    <string name="car_permission_desc_read_car_occupant_awareness_state" msgid="188865882598414986">"Allows reading status and detection data for occupant awareness system"</string>
+    <string name="car_permission_label_control_car_occupant_awareness_system" msgid="7163330266691094542">"Control occupant awareness system graph"</string>
+    <string name="car_permission_desc_control_car_occupant_awareness_system" msgid="7123482622084531911">"Allows controlling the start and stop of the occupant awareness system detection graph"</string>
     <string name="car_permission_label_diag_read" msgid="7248894224877702604">"read diagnostic data"</string>
     <string name="car_permission_desc_diag_read" msgid="1121426363040966178">"Read diagnostic data from the car."</string>
     <string name="car_permission_label_diag_clear" msgid="4783070510879698157">"clear diagnostic data"</string>
@@ -81,15 +81,15 @@
     <string name="car_permission_label_storage_monitoring" msgid="2327639346522530549">"Flash storage monitoring"</string>
     <string name="car_permission_desc_storage_monitoring" msgid="2075712271139671318">"Monitor flash storage usage"</string>
     <string name="car_permission_label_driving_state" msgid="7754624599537393650">"listen to driving state"</string>
-    <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Listen to Driving state changes."</string>
-    <string name="car_permission_label_use_telemetry_service" msgid="948005838683758846">"Use Car Telemetry Service"</string>
+    <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Listen to driving state changes."</string>
+    <string name="car_permission_label_use_telemetry_service" msgid="948005838683758846">"Use car telemetry service"</string>
     <string name="car_permission_desc_use_telemetry_service" msgid="3633214312435700766">"Collect car system health data."</string>
-    <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Use Car EVS Service"</string>
+    <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Use car EVS service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Subscribe to EVS video streams"</string>
     <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Request the EVS preview activity"</string>
     <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Request the system to launch the EVS preview activity"</string>
     <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Control the EVS preview activity"</string>
-    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Control the EVS preview activity of the sytsem"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Control the EVS preview activity of the system"</string>
     <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Use the EVS camera"</string>
     <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Subscribe to EVS camera streams"</string>
     <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitor the status of the EVS service"</string>
@@ -131,7 +131,7 @@
     <string name="car_permission_label_car_exterior_environment" msgid="3385924985991299436">"read car’s exterior temperature"</string>
     <string name="car_permission_desc_car_exterior_environment" msgid="1716656004731603379">"Access car’s exterior temperature."</string>
     <string name="car_permission_label_car_tires" msgid="4379255261197836840">"access car’s tires information"</string>
-    <string name="car_permission_desc_car_tires" msgid="8134496466769810134">"Access car’s tire information."</string>
+    <string name="car_permission_desc_car_tires" msgid="8134496466769810134">"Access car’s tyre information."</string>
     <string name="car_permission_label_car_steering" msgid="7779530447441232479">"read car’s steering angle information"</string>
     <string name="car_permission_desc_car_steering" msgid="1357331844530708138">"Access car’s steering angle information."</string>
     <string name="car_permission_label_read_car_display_units" msgid="7617008314862097183">"read car display units"</string>
@@ -142,7 +142,7 @@
     <string name="car_permission_desc_car_powertrain" msgid="1116007372551797796">"Access car’s powertrain information."</string>
     <string name="car_permission_label_car_power" msgid="8111448088314368268">"read car’s power state"</string>
     <string name="car_permission_desc_car_power" msgid="9202079903668652864">"Access car’s power state."</string>
-    <string name="car_permission_label_enroll_trust" msgid="3512907900486690218">"Enroll Trusted Device"</string>
+    <string name="car_permission_label_enroll_trust" msgid="3512907900486690218">"Enrol Trusted Device"</string>
     <string name="car_permission_desc_enroll_trust" msgid="4148649994602185130">"Allow Trusted Device Enrollment"</string>
     <string name="car_permission_label_car_test_service" msgid="9159328930558208708">"Control car’s test mode"</string>
     <string name="car_permission_desc_car_test_service" msgid="7426844534110145843">"Control car’s test mode"</string>
@@ -168,8 +168,12 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Manage thread priority."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"manage occupant zone"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Manage occupant zone."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"use remote access"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Use remote access."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"control remote access"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Control remote access."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus failed"</string>
-    <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus does not respond. Unplug and plug back headunit box and restart the car"</string>
+    <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus does not respond. Unplug and plug back in head unit box and restart the car"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
     <string name="default_guest_name" msgid="2912812799433131476">"Guest"</string>
 </resources>
diff --git a/service/res/values-en-rGB/strings.xml b/service/res/values-en-rGB/strings.xml
index af7ab50..a5e5a0f 100644
--- a/service/res/values-en-rGB/strings.xml
+++ b/service/res/values-en-rGB/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Manage thread priority."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"manage occupant zone"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Manage occupant zone."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"use remote access"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Use remote access."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"control remote access"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Control remote access."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus failed"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus does not respond. Unplug and plug back in head unit box and restart the car"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
diff --git a/service/res/values-en-rIN/strings.xml b/service/res/values-en-rIN/strings.xml
index af7ab50..a5e5a0f 100644
--- a/service/res/values-en-rIN/strings.xml
+++ b/service/res/values-en-rIN/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Manage thread priority."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"manage occupant zone"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Manage occupant zone."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"use remote access"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Use remote access."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"control remote access"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Control remote access."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus failed"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus does not respond. Unplug and plug back in head unit box and restart the car"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
diff --git a/service/res/values-en-rXC/strings.xml b/service/res/values-en-rXC/strings.xml
index 749d77e..3968f55 100644
--- a/service/res/values-en-rXC/strings.xml
+++ b/service/res/values-en-rXC/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎Manage thread priority.‎‏‎‎‏‎"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎manage occupant zone‎‏‎‎‏‎"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎Manage occupant zone.‎‏‎‎‏‎"</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎use remote access‎‏‎‎‏‎"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‏‏‎Use remote access.‎‏‎‎‏‎"</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎control remote access‎‏‎‎‏‎"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎Control remote access.‎‏‎‎‏‎"</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎CAN bus failed‎‏‎‎‏‎"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎CAN bus does not respond. Unplug and plug back headunit box and restart the car‎‏‎‎‏‎"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎My Device‎‏‎‎‏‎"</string>
diff --git a/service/res/values-es-rUS/strings.xml b/service/res/values-es-rUS/strings.xml
index 06afcd8..9d6a597 100644
--- a/service/res/values-es-rUS/strings.xml
+++ b/service/res/values-es-rUS/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Administra la prioridad de subprocesos."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"administrar zona de ocupación"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Administrar zona de ocupación."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"uso del acceso remoto"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Uso del acceso remoto"</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"acceso al control remoto"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Control del acceso remoto"</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Error de bus CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus no responde. Desconecta y vuelve a conectar la caja de la unidad central y enciende nuevamente el auto"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mi dispositivo"</string>
diff --git a/service/res/values-es/strings.xml b/service/res/values-es/strings.xml
index ceb1e2b..4151062 100644
--- a/service/res/values-es/strings.xml
+++ b/service/res/values-es/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Gestionar la prioridad de las conversaciones."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"gestionar la zona de los pasajeros"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Gestionar la zona de los pasajeros."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Fallo de bus CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"El bus CAN no responde. Desconecta el cabezal, conéctalo de nuevo y reinicia el coche"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mi dispositivo"</string>
diff --git a/service/res/values-et/strings.xml b/service/res/values-et/strings.xml
index be78dff..daa23bd 100644
--- a/service/res/values-et/strings.xml
+++ b/service/res/values-et/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Ohu prioriteedi haldamine."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"reisijatsooni haldamine"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Reisijatsooni haldamine."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-siin ebaõnnestus"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-siin ei reageeri. Eemaldage autoraadio üksus ja pange see tagasi ning taaskäivitage auto"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Minu seade"</string>
diff --git a/service/res/values-eu/strings.xml b/service/res/values-eu/strings.xml
index f66dae8..b4c4025 100644
--- a/service/res/values-eu/strings.xml
+++ b/service/res/values-eu/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Kudeatu elkarrizketa-harien lehentasuna."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"kudeatu bidaiarien eremua"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Kudeatu bidaiarien eremua."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"erabili urruneko sarbidea"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Urruneko sarbidea erabili."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"kontrolatu urruneko sarbidea"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Urruneko sarbidea kontrolatu."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN autobusak huts egin du"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus-ak ez du erantzuten. Desentxufatu eta entxufatu berriro gailu nagusia eta berrabiarazi autoa."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Nire gailua"</string>
diff --git a/service/res/values-fa/strings.xml b/service/res/values-fa/strings.xml
index 4ca7ab8..b6bee48 100644
--- a/service/res/values-fa/strings.xml
+++ b/service/res/values-fa/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"مدیریت اولویت رشته."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"مدیریت ناحیه سرنشین"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"مدیریت ناحیه سرنشین."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"استفاده از دسترسی ازراه‌دور"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"استفاده از دسترسی ازراه‌دور."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"کنترل دسترسی ازراه‌دور"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"کنترل دسترسی ازراه‌دور."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"گذرگاه CAN ناموفق بود"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"گذرگاه CAN پاسخ نمی‌دهد. محفظه ضبط‌وپخش را جدا و سپس وصل کنید و خودرو را دوباره روشن کنید"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"دستگاه من"</string>
diff --git a/service/res/values-fi/strings.xml b/service/res/values-fi/strings.xml
index c580e05..c3fc8fd 100644
--- a/service/res/values-fi/strings.xml
+++ b/service/res/values-fi/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Hallitsee ketjujen priorisointia."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"hallitse paikallaoloaluetta"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Hallitse paikallaoloaluetta."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-väylä hylättiin"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-väylä ei vastaa. Irrota pääyksikkö ja liitä se takaisin. Käynnistä auto sitten uudelleen."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Oma laite"</string>
diff --git a/service/res/values-fr-rCA/strings.xml b/service/res/values-fr-rCA/strings.xml
index 927524a..110f97a 100644
--- a/service/res/values-fr-rCA/strings.xml
+++ b/service/res/values-fr-rCA/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Gérer la priorité du fil d\'exécution."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"gérer la zone des occupants"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Gérer la zone des occupants."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Défaillance du bus de données CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Le bus de données CAN ne répond pas. Débranchez et rebranchez le boîtier de l\'unité centrale, puis redémarrez la voiture"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mon appareil"</string>
diff --git a/service/res/values-fr/strings.xml b/service/res/values-fr/strings.xml
index a15a52e..35b660d 100644
--- a/service/res/values-fr/strings.xml
+++ b/service/res/values-fr/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Gérer la priorité des threads."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"gérer la zone de l\'occupant"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Gérer la zone de l\'occupant."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Échec du bus de données CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Le bus de données CAN ne répond pas. Débranchez et rebranchez le boîtier de l\'unité principale, puis redémarrez la voiture"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mon appareil"</string>
diff --git a/service/res/values-gl/strings.xml b/service/res/values-gl/strings.xml
index 8a97a79..b6cfe7e 100644
--- a/service/res/values-gl/strings.xml
+++ b/service/res/values-gl/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Xestionar prioridade das conversas."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"xestionar zona dos pasaxeiros"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Xestiona a zona dos pasaxeiros."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Produciuse un erro no bus CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"O bus CAN non responde. Desconecta a caixa da unidade principal, conéctaa de novo e reinicia o coche"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Dispositivo"</string>
diff --git a/service/res/values-gu/strings.xml b/service/res/values-gu/strings.xml
index 1d50f1f..da57481 100644
--- a/service/res/values-gu/strings.xml
+++ b/service/res/values-gu/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"થ્રેડની પ્રાધાન્યતા મેનેજ કરો."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"કુલ વ્યક્તિ ઝોન મેનેજ કરો"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"કુલ વ્યક્તિ ઝોન મેનેજ કરો."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN બસ નિષ્ફળ રહી"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN બસ પ્રતિસાદ આપતી નથી. હેડયુનિટ બોક્સને અનપ્લગ કરી ફરી પ્લગ કરો અને કારને ફરી શરૂ કરો"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"મારું ડિવાઇસ"</string>
diff --git a/service/res/values-hi/strings.xml b/service/res/values-hi/strings.xml
index c10dec5..261db93 100644
--- a/service/res/values-hi/strings.xml
+++ b/service/res/values-hi/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"थ्रेड की प्राथमिकता मैनेज करने की अनुमति दें."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ऑक्यूपंट ज़ोन मैनेज करें"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ऑक्यूपंट ज़ोन मैनेज करें."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"\'CAN बस\' काम नहीं कर पा रहा है"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"\'CAN बस\' जवाब नहीं दे रहा है. हेडयूनिट बॉक्स का प्लग निकालकर वापस लगाएं और कार को रीस्टार्ट करें"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"मेरा डिवाइस"</string>
diff --git a/service/res/values-hr/strings.xml b/service/res/values-hr/strings.xml
index d559a3f..a18224d 100644
--- a/service/res/values-hr/strings.xml
+++ b/service/res/values-hr/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Upravljanje prioritetom niti."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"upravljanje putničkom zonom"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Upravljanje putničkom zonom."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"koriste daljinski pristup"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Koriste daljinski pristup."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"upravljaju daljinskim pristupom"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Upravljaju daljinskim pristupom."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Pogreška CAN busa"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus ne odgovara. Iskopčajte i ponovo ukopčajte glavnu jedinicu i ponovo pokrenite automobil"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moj uređaj"</string>
diff --git a/service/res/values-hu/strings.xml b/service/res/values-hu/strings.xml
index 23debed..78d8475 100644
--- a/service/res/values-hu/strings.xml
+++ b/service/res/values-hu/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Témaszál-prioritás kezelése."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"Utastér kezelése"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Utastér kezelése."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"távoli hozzáférés használata"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Távoli hozzáférés használata."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"távoli hozzáférés vezérlése"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Távoli hozzáférés vezérlése."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"A CAN-busz hibát észlelt"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"A CAN-busz nem válaszol. Csatlakoztassa újra a fejegységet, és indítsa újra az autót."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Saját eszköz"</string>
diff --git a/service/res/values-hy/strings.xml b/service/res/values-hy/strings.xml
index e9dc53c..e41e40c 100644
--- a/service/res/values-hy/strings.xml
+++ b/service/res/values-hy/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Կառավարել Тhread-ի առաջնահերթությունը։"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"կառավարել ուղևորային գոտին"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Կառավարել ուղևորային գոտին։"</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"հեռակա մուտքի օգտագործում"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Հեռակա մուտքի օգտագործում։"</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"հեռակա մուտքի կառավարում"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Հեռակա մուտքի կառավարում։"</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN անվադողի սխալ"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN անվադողը չի պատասխանում: Անջատեք և նորից միացրեք միակցիչը, ապա անջատեք վառոցքը և վերագործարկեք մեքենան:"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Իմ սարքը"</string>
diff --git a/service/res/values-in/strings.xml b/service/res/values-in/strings.xml
index 10bcfe7..bdb6b75 100644
--- a/service/res/values-in/strings.xml
+++ b/service/res/values-in/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Mengelola prioritas thread."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"kelola zona penumpang"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Kelola zona penumpang."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"menggunakan akses jarak jauh"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Menggunakan akses jarak jauh."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"mengontrol akses jarak jauh"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Mengontrol akses jarak jauh."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus gagal"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus tidak merespons. Cabut dan colokkan kembali boks headunit, lalu nyalakan ulang mobil"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Perangkat Saya"</string>
diff --git a/service/res/values-is/strings.xml b/service/res/values-is/strings.xml
index bd72593..2972a1b 100644
--- a/service/res/values-is/strings.xml
+++ b/service/res/values-is/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Stjórna forgangi þráða."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"stjórna farþegasvæði"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Stjórna farþegasvæði."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Bilun í CAN-gagnabraut"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-gagnabraut svarar ekki. Taktu stjórneiningarboxið úr sambandi, settu það aftur í samband og gangsettu bílinn aftur."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Tækið mitt"</string>
diff --git a/service/res/values-it/strings.xml b/service/res/values-it/strings.xml
index 496c440..ba2eefc 100644
--- a/service/res/values-it/strings.xml
+++ b/service/res/values-it/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Gestione della priorità dei thread."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"Gestione della zona degli occupanti"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Consente di gestire la zona degli occupanti."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Comunicazione tramite bus CAN non riuscita"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Il bus CAN non risponde. Scollega e ricollega l\'unità principale e riaccendi il motore."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mio dispositivo"</string>
diff --git a/service/res/values-iw/strings.xml b/service/res/values-iw/strings.xml
index 331b5fd..ca9c0d3 100644
--- a/service/res/values-iw/strings.xml
+++ b/service/res/values-iw/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"ניהול העדיפות של השרשורים."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ניהול אזור התפוסה"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ניהול אזור התפוסה."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"שימוש בגישה מרחוק"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"שימוש בגישה מרחוק."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"שליטה בגישה מרחוק"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"שליטה בגישה מרחוק."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"פרוטוקול CAN bus נכשל"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"פרוטוקול CAN bus לא מגיב. יש לנתק ולחבר שוב את מערכת הסטריאו ולהתניע מחדש את הרכב"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"המכשיר שלי"</string>
diff --git a/service/res/values-ja/strings.xml b/service/res/values-ja/strings.xml
index f767f9a..8334e16 100644
--- a/service/res/values-ja/strings.xml
+++ b/service/res/values-ja/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"スレッドの優先度の管理"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"乗員ゾーンの管理"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"乗員ゾーンの管理。"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN バスでエラーが発生しました"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN バスが応答しません。ヘッドユニット ボックスのプラグを抜いて接続し直し、車を再始動してください"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"自分のデバイス"</string>
diff --git a/service/res/values-ka/strings.xml b/service/res/values-ka/strings.xml
index c8a5f43..0bef629 100644
--- a/service/res/values-ka/strings.xml
+++ b/service/res/values-ka/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"თემატური გზავნილების პრიორიტეტულობის მართვა."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"საოკუპაციო ზონის მართვა"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"საოკუპაციო ზონის მართვა."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"წარმოიშვა CAN-სალტის შეცდომა"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-სალტე არ რეაგირებს. გამოაერთეთ და ხელახლა მიაერთეთ საინფორმაციო-გასართობი მოწყობილობა, შემდეგ კი ხელახლა დაქოქეთ მანქანა"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ჩემი მოწყობილობა"</string>
diff --git a/service/res/values-kk/strings.xml b/service/res/values-kk/strings.xml
index f12bf1a..e5a28e6 100644
--- a/service/res/values-kk/strings.xml
+++ b/service/res/values-kk/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Тізбек басымдығын басқарыңыз."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"бос емес жерлерді басқару"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Бос емес жерлерді басқару."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN шинасы істен шықты"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN шинасы жауап бермейді. Негізгі модульді ажыратып, қайта жалғаңыз және көлікті қайта оталдырыңыз"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Құрылғым"</string>
diff --git a/service/res/values-km/strings.xml b/service/res/values-km/strings.xml
index 4de016b..2e1adc8 100644
--- a/service/res/values-km/strings.xml
+++ b/service/res/values-km/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"គ្រប់គ្រង​អាទិភាព​កម្រងសារ"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"គ្រប់គ្រងតំបន់អ្នកជិះក្នុងរថយន្ត"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"គ្រប់គ្រងតំបន់អ្នកជិះក្នុងរថយន្ត។"</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"ប្រើប្រាស់សិទ្ធិចូលប្រើប្រាស់ពីចម្ងាយ"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"ប្រើប្រាស់សិទ្ធិចូលប្រើប្រាស់ពីចម្ងាយ។"</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"គ្រប់គ្រងសិទ្ធិចូលប្រើប្រាស់ពីចម្ងាយ"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"គ្រប់គ្រងសិទ្ធិចូលប្រើប្រាស់ពីចម្ងាយ។"</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"មិនអាច​ដំណើរការ CAN bus បានទេ"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus មិនឆ្លើយតបទេ។ សូមផ្ដាច់ រួចភ្ជាប់​ប្រអប់​ឧបករណ៍ចាក់តន្ត្រី​ម្តងទៀត បន្ទាប់មក​បញ្ឆេះ​រថយន្ត​ឡើងវិញ"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ឧបករណ៍របស់ខ្ញុំ"</string>
diff --git a/service/res/values-kn/strings.xml b/service/res/values-kn/strings.xml
index 44b66fe..607946a 100644
--- a/service/res/values-kn/strings.xml
+++ b/service/res/values-kn/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"ಥ್ರೆಡ್ ಆದ್ಯತೆಯನ್ನು ನಿರ್ವಹಿಸಿ."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ಸಿಬ್ಬಂದಿ ವಲಯದ ನಿರ್ವಹಣೆ"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ಸಿಬ್ಬಂದಿ ವಲಯದ ನಿರ್ವಹಣೆ."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"ರಿಮೋಟ್ ಆ್ಯಕ್ಸೆಸ್ ಬಳಸಿ"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"ರಿಮೋಟ್ ಆ್ಯಕ್ಸೆಸ್ ಬಳಸಿ."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"ರಿಮೋಟ್ ಆ್ಯಕ್ಸೆಸ್ ನಿಯಂತ್ರಿಸಿ"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"ರಿಮೋಟ್ ಆ್ಯಕ್ಸೆಸ್ ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"ಸಿಎಎನ್ ಬಸ್ ಕೆಟ್ಟಿದೆ"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN ಬಸ್ ಸ್ಪಂದಿಸುತ್ತಿಲ್ಲ. ಹೆಡ್ ಯುನಿಟ್ ಪೆಟ್ಟಿಗೆಯನ್ನು ಅನ್‌ಪ್ಲಗ್ ಮಾಡಿ ಮತ್ತೆ ಪ್ಲಗ್ ಮಾಡಿ ಕಾರನ್ನು ಪುನರಾರಂಭಿಸಿ"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ನನ್ನ ಸಾಧನ"</string>
diff --git a/service/res/values-ko/strings.xml b/service/res/values-ko/strings.xml
index d953cc2..7c5eeb2 100644
--- a/service/res/values-ko/strings.xml
+++ b/service/res/values-ko/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"대화목록 우선순위를 관리합니다."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"승객 점유 영역 관리"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"승객 점유 영역 관리"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN 버스 실패"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN 버스가 응답하지 않습니다. 헤드유닛 박스를 분리한 후 다시 연결한 다음 시동을 다시 걸어 보세요."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"내 기기"</string>
diff --git a/service/res/values-ky/strings.xml b/service/res/values-ky/strings.xml
index 7c4c225..b5cd1a8 100644
--- a/service/res/values-ky/strings.xml
+++ b/service/res/values-ky/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Маектин маанилүүлүгүн башкаруу."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"унаадагы орундарды тескөө"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Унаадагы орундарды тескеңиз."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN иштебей калды"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN жооп бербей жатат. Башкы шайман блогун сууруп, кайра сайгандан кийин унааны кайра жүргүзүңүз"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Түзмөгүм"</string>
diff --git a/service/res/values-lo/strings.xml b/service/res/values-lo/strings.xml
index dc1168d..87bf7a6 100644
--- a/service/res/values-lo/strings.xml
+++ b/service/res/values-lo/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"ຈັດການຄວາມສຳຄັນຂອງຫົວຂໍ້."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ຈັດການເຂດປົກຄອງ"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ຈັດການເຂດປົກຄອງ."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"ໃຊ້ສິດເຂົ້າເຖິງທາງໄກ"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"ໃຊ້ສິດເຂົ້າເຖິງທາງໄກ."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"ຄວບຄຸມສິດເຂົ້າເຖິງທາງໄກ"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"ຄວບຄຸມສິດເຂົ້າເຖິງທາງໄກ."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus ບໍ່ສຳເລັດ"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus ບໍ່ຕອບສະໜອງ. ຖອດປລັກກ່ອງເຄື່ອງຫຼິ້ນວິທະຍຸ (Headunit) ແລ້ວສຽບເຂົ້າຄືນໃໝ່ ແລະ ຣິສະຕາດລົດ"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ອຸປະກອນຂອງຂ້ອຍ"</string>
diff --git a/service/res/values-lt/strings.xml b/service/res/values-lt/strings.xml
index fdbe6e9..adb0c7b 100644
--- a/service/res/values-lt/strings.xml
+++ b/service/res/values-lt/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Tvarkyti instrukcijų sekos prioritetą."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"tvarkyti buvimo namuose zoną"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Tvarkyti buvimo namuose zoną."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN BUS klaida"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN BUS nereaguoja. Atjunkite ir vėl prijunkite pagrindinio įtaiso dėžutę."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mano įrenginys"</string>
diff --git a/service/res/values-lv/strings.xml b/service/res/values-lv/strings.xml
index e6ef4d4..1e4d159 100644
--- a/service/res/values-lv/strings.xml
+++ b/service/res/values-lv/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Pārvaldīt pavediena prioritāti."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"pārvaldīt pasažieru zonu"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Pārvaldīt pasažieru zonu."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Radās atteice datu maģistrālē"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Datu maģistrāle nereaģē. Atvienojiet un atkal pievienojiet stereosistēmas paneļa kabeli un atkārtoti iedarbiniet automašīnu"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mana ierīce"</string>
diff --git a/service/res/values-mk/strings.xml b/service/res/values-mk/strings.xml
index 070db74..b206465 100644
--- a/service/res/values-mk/strings.xml
+++ b/service/res/values-mk/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"да управуваат со приоритетот на thread"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"да управуваат со зоните на присуство"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"да управуваат со зоните на присуство"</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"користење далечински пристап"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Користење далечински пристап"</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"контрола на далечинскиот пристап"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Контрола на далечинскиот пристап."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-магистралата не успеа"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-магистралата не реагира. Откачете ја и повторно прикачете ја кутијата на главната единица и рестартирајте го автомобилот"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мојот уред"</string>
diff --git a/service/res/values-ml/strings.xml b/service/res/values-ml/strings.xml
index a7818f2..8f894da 100644
--- a/service/res/values-ml/strings.xml
+++ b/service/res/values-ml/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"ത്രെഡ് മുൻഗണന മാനേജ് ചെയ്യുക."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ഒക്യുപന്റ് സോൺ മാനേജ് ചെയ്യുക"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ഒക്യുപന്റ് സോൺ മാനേജ് ചെയ്യുക."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN ബസ് പരാജയപ്പെട്ടു"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN ബസ് പ്രതികരിക്കുന്നില്ല. ഹെഡ്‌യൂണിറ്റ് ബോക്‌സ്, അൺപ്ലഗ് ചെയ്‌ത്, വീണ്ടും പ്ലഗ് ചെയ്‌ത്, കാർ റീസ്‌റ്റാർട്ട് ചെയ്യുക"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"എന്റെ ഉപകരണം"</string>
diff --git a/service/res/values-mn/strings.xml b/service/res/values-mn/strings.xml
index 5091324..8c8faa9 100644
--- a/service/res/values-mn/strings.xml
+++ b/service/res/values-mn/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Хуулбар процессыг чухалчлахыг удирдах."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"оршин суугчийн бүсийг удирдана"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Оршин суугчийн бүсийг удирдана."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"алсын хандалтыг ашиглах"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Алсын хандалтыг ашигладаг."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"алсын хандалтыг хянах"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Алсын хандалтыг хянадаг."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus амжилтгүй болсон"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus хариу өгөхгүй байна. Хөгжим тоглуулагчийн хайрцгийг салгаад, дахин залгаж, машиныг дахин эхлүүлнэ үү"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Миний төхөөрөмж"</string>
diff --git a/service/res/values-mr/strings.xml b/service/res/values-mr/strings.xml
index 636245c..834fdae 100644
--- a/service/res/values-mr/strings.xml
+++ b/service/res/values-mr/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"थ्रेडशी संबंधित प्राधान्य व्यवस्थापित करा."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"निवासी झोन व्यवस्थापित करा"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"निवासी झोन व्यवस्थापित करा"</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"रिमोटचा अ‍ॅक्सेस वापरा"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"रिमोटचा अ‍ॅक्सेस वापरा."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"रिमोटचा अ‍ॅक्सेस नियंत्रित करा"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"रिमोटचा अ‍ॅक्सेस नियंत्रित करा."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN बस अयशस्वी"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN बस प्रतिसाद देत नाही. हेडयुनिट बॉक्स अनप्लग करून पुन्हा प्लग करा आणि कार रीस्टार्ट करा"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"माझे डिव्हाइस"</string>
diff --git a/service/res/values-ms/strings.xml b/service/res/values-ms/strings.xml
index 6ddc9b8..29555f0 100644
--- a/service/res/values-ms/strings.xml
+++ b/service/res/values-ms/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Urus keutamaan urutan."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"urus zon penumpang"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Urus zon penumpang."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"gunakan akses jauh"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Gunakan akses jauh."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"kawal akses jauh"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Kawal akses jauh."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Bas CAN gagal"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Bas CAN tidak bertindak balas. Cabut dan palamkan kembali kotak unit stereo dan mulakan semula kereta"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Peranti Saya"</string>
diff --git a/service/res/values-my/strings.xml b/service/res/values-my/strings.xml
index d9f6a79..7de9e26 100644
--- a/service/res/values-my/strings.xml
+++ b/service/res/values-my/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"ဦးစားပေး Thread စီမံနိုင်သည်။"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"လူရှိသောဇုန်ကို စီမံရန်"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"လူရှိသောဇုန်ကို စီမံနိုင်သည်။"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"\"CAN bus\" စနစ် အသုံးပြုမှု မအောင်မြင်ပါ"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus စနစ်က တုန့်ပြန်မှုမရှိပါ။ စက်အထိုင်ဘောက်စ်ကို ပလတ်ဖြုတ်ပြီး ပြန်တပ်ကာ ကားကို ပြန်လည်စတင်ပါ"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ကျွန်ုပ်၏စက်"</string>
diff --git a/service/res/values-nb/strings.xml b/service/res/values-nb/strings.xml
index 0a673b0..d20a5b3 100644
--- a/service/res/values-nb/strings.xml
+++ b/service/res/values-nb/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Administrer trådprioritet"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"administrer passasjersonen"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Administrer passasjersonen."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-bus mislyktes"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-bus svarer ikke. Koble bilens hovedenhet ut og inn igjen, og start bilen på nytt"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Enheten min"</string>
diff --git a/service/res/values-ne/strings.xml b/service/res/values-ne/strings.xml
index 8999eb8..4259cb4 100644
--- a/service/res/values-ne/strings.xml
+++ b/service/res/values-ne/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"थ्रेडको प्राथमिकता व्यवस्थापन गर्ने।"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"व्यवसायको क्षेत्र व्यवस्थापन गर्नुहोस्"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"व्यवसायको क्षेत्र व्यवस्थापन गर्नुहोस्।"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus असफल भयो"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus ले प्रतिक्रिया जनाएन। हेडयुनिट बाकसलाई प्लगबाट निकालेर फेरि प्लगमा घुसाउनुहोस् र कार पुनःसुरु गर्नुहोस्‌"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"मेरो डिभाइस"</string>
diff --git a/service/res/values-nl/strings.xml b/service/res/values-nl/strings.xml
index 3bdc265..12b1a8e 100644
--- a/service/res/values-nl/strings.xml
+++ b/service/res/values-nl/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Thread-prioriteit beheren."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"passagierszone beheren"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Passagierszone beheren."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN-bus is mislukt"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-bus reageert niet. Koppel de hoofdeenheid los en sluit deze vervolgens weer aan. Start de auto daarna opnieuw."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mijn apparaat"</string>
diff --git a/service/res/values-or/strings.xml b/service/res/values-or/strings.xml
index a9ca7ee..0ab2791 100644
--- a/service/res/values-or/strings.xml
+++ b/service/res/values-or/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"ଥ୍ରେଡ ପ୍ରାଥମିକତାକୁ ପରିଚାଳନା କରନ୍ତୁ।"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ଅକ୍ୟୁପେଣ୍ଟ ଜୋନକୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ଅକ୍ୟୁପେଣ୍ଟ ଜୋନକୁ ପରିଚାଳନା କରନ୍ତୁ।"</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"ରିମୋଟ ଆକ୍ସେସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"ରିମୋଟ ଆକ୍ସେସ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"ରିମୋଟ ଆକ୍ସେସକୁ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"ରିମୋଟ ଆକ୍ସେସକୁ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ।"</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN ବସ୍ ବିଫଳ ହେଲା"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN ବସ୍ ପ୍ରତିକ୍ରିୟା ଦେଉନାହିଁ। ହେଡୟୁନିଟ୍ ବାକ୍ସର ପ୍ଲଗ୍ କାଢ଼ି ପୁଣି ଲଗାନ୍ତୁ ଏବଂ କାର୍‍କୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ମୋ ଡିଭାଇସ୍"</string>
diff --git a/service/res/values-pa/strings.xml b/service/res/values-pa/strings.xml
index 5073d80..75d626f 100644
--- a/service/res/values-pa/strings.xml
+++ b/service/res/values-pa/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"ਥ੍ਰੈੱਡ ਸੰਬੰਧੀ ਤਰਜੀਹ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ।"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ਭਰੇ ਖੇਤਰ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ਭਰੇ ਖੇਤਰ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ।"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN ਬੱਸ ਅਸਫਲ ਰਹੀ"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN ਬੱਸ ਕੰਮ ਨਹੀਂ ਕਰਦੀ। ਹੈੱਡ ਯੂਨਿਟ ਬਾਕਸ ਨੂੰ ਅਨਪਲੱਗ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਪਲੱਗ ਲਗਾ ਕੇ ਕਾਰ ਨੂੰ ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ਮੇਰਾ ਡੀਵਾਈਸ"</string>
diff --git a/service/res/values-pl/strings.xml b/service/res/values-pl/strings.xml
index b615483..573ad2a 100644
--- a/service/res/values-pl/strings.xml
+++ b/service/res/values-pl/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Zarządzanie priorytetem wątków."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"zarządzaj miejscem"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Zarządzaj miejscem."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"używaj zdalnego dostępu"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Używaj zdalnego dostępu."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"kontroluj zdalny dostęp"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Kontroluj zdalny dostęp."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Błąd magistrali CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Magistrala CAN nie odpowiada. Odłącz i jeszcze raz podłącz moduł główny i ponownie uruchom samochód."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moje urządzenie"</string>
diff --git a/service/res/values-pt-rPT/strings.xml b/service/res/values-pt-rPT/strings.xml
index e37f852..12fa881 100644
--- a/service/res/values-pt-rPT/strings.xml
+++ b/service/res/values-pt-rPT/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Faça a gestão da prioridade das discussões."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"gerir zona dos ocupantes"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Gerir zona dos ocupantes."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"usar o acesso remoto"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Use o acesso remoto."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"controlar o acesso remoto"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Controle o acesso remoto."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Falha no CAN bus."</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"O CAN bus não responde. Desligue e volte a ligar a caixa da unidade principal e reinicie o automóvel."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Dispositivo"</string>
diff --git a/service/res/values-pt/strings.xml b/service/res/values-pt/strings.xml
index 6c069a4..95ab231 100644
--- a/service/res/values-pt/strings.xml
+++ b/service/res/values-pt/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Gerenciar prioridade da conversa."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"gerenciar a zona de ocupantes"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Gerenciar a zona de ocupantes."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Falha no barramento CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"O barramento CAN parou de responder. Desconecte e conecte novamente a caixa da unidade principal, depois ligue o carro"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Meu dispositivo"</string>
diff --git a/service/res/values-ro/strings.xml b/service/res/values-ro/strings.xml
index 4c26020..821a15a 100644
--- a/service/res/values-ro/strings.xml
+++ b/service/res/values-ro/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Gestionează prioritatea firelor."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"gestionează zona pentru ocupanți"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Gestionează zona pentru ocupanți."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"folosesc accesul la distanță"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Folosesc accesul la distanță."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"controlează accesul la distanță"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Controlează accesul la distanță."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Magistrala CAN nu a reușit"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Magistrala CAN nu răspunde. Deconectează și reconectează unitatea radio, apoi repornește mașina"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Dispozitivul meu"</string>
diff --git a/service/res/values-ru/strings.xml b/service/res/values-ru/strings.xml
index 14c2bb8..428ef20 100644
--- a/service/res/values-ru/strings.xml
+++ b/service/res/values-ru/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Управление приоритетом цепочек"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"управление зоной пассажиров"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Управление зоной пассажиров."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Произошла ошибка шины CAN."</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Шина CAN не отвечает. Переподключите коннектор, а затем выключите зажигание и заведите машину снова."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мое устройство"</string>
diff --git a/service/res/values-si/strings.xml b/service/res/values-si/strings.xml
index b0bd81c..bf33da1 100644
--- a/service/res/values-si/strings.xml
+++ b/service/res/values-si/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"පොට ප්‍රමුඛතාවය කළමනාකරණය කරන්න."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"පදිංචි කලාපය කළමනාකරණය කරන්න"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"පදිංචි කලාපය කළමනාකරණය කරන්න."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN බස් අසාර්ථකයි"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN බස් ප්‍රතිචාර නොදක්වයි. හෙඩ්යුනිට් පෙට්ටිය පේනු ඉවත් කර ආපසු පේනුගත කර, මෝටර් රථය යළි අරඹන්න"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"මගේ උපාංගය"</string>
diff --git a/service/res/values-sk/strings.xml b/service/res/values-sk/strings.xml
index bc2993f..4ec6a20 100644
--- a/service/res/values-sk/strings.xml
+++ b/service/res/values-sk/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Správa priority vlákna."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"spravovať zónu cestujúcich"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Spravovať zónu cestujúcich."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"používanie vzdialeného prístupu"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Použite vzdialený prístup."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"ovládanie vzdialeného prístupu"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Ovládajte vzdialený prístup."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Zbernica CAN zlyhala"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Zbernica CAN nereaguje. Odpojte autorádio a znova ho pripojte. Potom auto znova naštartujte."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moje zariadenie"</string>
diff --git a/service/res/values-sl/strings.xml b/service/res/values-sl/strings.xml
index 7634d66..cd32bc6 100644
--- a/service/res/values-sl/strings.xml
+++ b/service/res/values-sl/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Upravljanje prednosti niti."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"upravljanje območja potnikov"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Upravljanje območja potnikov."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Napaka vodila CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Vodilo CAN se ne odziva. Odklopite in znova priklopite ohišje avtomobilskega vmesnika ter znova zaženite avtomobil"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moja naprava"</string>
diff --git a/service/res/values-sq/strings.xml b/service/res/values-sq/strings.xml
index f5f76c6..202a0e4 100644
--- a/service/res/values-sq/strings.xml
+++ b/service/res/values-sq/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Menaxho përparësinë në bashkëbisedim."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"menaxho zonën e pasagjerëve"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Menaxho zonën e pasagjerëve."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Kanali i komunikimit CAN dështoi"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Kanali i komunikimit CAN nuk përgjigjet. Shkëput dhe lidh përsëri kutinë e njësisë kryesore dhe rindiz makinës"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Pajisja ime"</string>
diff --git a/service/res/values-sr/strings.xml b/service/res/values-sr/strings.xml
index 18b8f95..93e172a 100644
--- a/service/res/values-sr/strings.xml
+++ b/service/res/values-sr/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Управљање приоритетом нити."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"управљање зоном присутности"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Управљање зоном присутности."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"користе даљински приступ"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Користе даљински приступ."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"контролишу даљински приступ"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Контролишу даљински приступ."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Грешка CAN магистрале"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN магистрала не реагује. Искључите и поново укључите главну јединицу и поново покрените аутомобил"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мој уређај"</string>
diff --git a/service/res/values-sv/strings.xml b/service/res/values-sv/strings.xml
index be573f5..304a721 100644
--- a/service/res/values-sv/strings.xml
+++ b/service/res/values-sv/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Hantera trådprioritet."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"hantera närvarozon"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Hantera närvarozon."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Fel i CAN-bussen"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-bussen svarar inte. Koppla från huvudenheten och koppla in den igen. Starta sedan om bilen"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Min enhet"</string>
diff --git a/service/res/values-sw/strings.xml b/service/res/values-sw/strings.xml
index c2e9b26..3944cbe 100644
--- a/service/res/values-sw/strings.xml
+++ b/service/res/values-sw/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Dhibiti kipaumbele cha mazungumzo."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"dhibiti eneo anapoketi abiria"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Dhibiti eneo anapoketi abiria."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Imeshindwa kuleta maelezo ya kebo CAN"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Kebo ya CAN haifanyi kazi. Ondoa kisha urudishe tena kisanduku cha sehemu kuu na uzime kisha uwashe gari"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Kifaa Changu"</string>
diff --git a/service/res/values-ta/strings.xml b/service/res/values-ta/strings.xml
index 4cc24e8..f65a2bf 100644
--- a/service/res/values-ta/strings.xml
+++ b/service/res/values-ta/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"மெசேஜ் தொடருக்கான முன்னுரிமையை நிர்வகித்தல்."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"பயணிப் பகுதியை நிர்வகித்தல்"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"பயணிப் பகுதியை நிர்வகிக்கலாம்."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN bus அமைப்பு தோல்வியடைந்தது"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN bus அமைப்பு இயங்கவில்லை. ஹெட்யூனிட் பாக்ஸைப் பிளக்கில் இருந்து அகற்றிச் செருகியபின் காரை மீண்டும் தொடங்கவும்"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"எனது சாதனம்"</string>
diff --git a/service/res/values-te/strings.xml b/service/res/values-te/strings.xml
index 78a6fef..835749d 100644
--- a/service/res/values-te/strings.xml
+++ b/service/res/values-te/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"థ్రెడ్ ప్రాధాన్యతను మేనేజ్ చేయడానికి అనుమతి ఇవ్వండి."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"బస చేసే జోన్‌ను మేనేజ్ చేయండి"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"బస చేసే జోన్‌ను మేనేజ్ చేయండి."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"రిమోట్ యాక్సెస్‌ను ఉపయోగించండి"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"రిమోట్ యాక్సెస్‌ను ఉపయోగించండి."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"రిమోట్ యాక్సెస్‌ను కంట్రోల్ చేయండి"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"రిమోట్ యాక్సెస్‌ను కంట్రోల్ చేయండి."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN బస్సు విఫలమైంది"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN బస్సు స్పందించలేదు. హెడ్ యూనిట్ బాక్స్‌‍‌ని ప్లగ్ మరియు అన్‌ప్లగ్ చేసి కారుని పునఃప్రారంభించుము"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"నా పరికరం"</string>
diff --git a/service/res/values-th/strings.xml b/service/res/values-th/strings.xml
index 8043d12..9da115d 100644
--- a/service/res/values-th/strings.xml
+++ b/service/res/values-th/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"จัดการลำดับความสำคัญของชุดข้อความ"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"จัดการโซนผู้โดยสาร"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"จัดการโซนผู้โดยสาร"</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"ใช้การเข้าถึงจากระยะไกล"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"ใช้การเข้าถึงจากระยะไกล"</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"ควบคุมการเข้าถึงจากระยะไกล"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"ควบคุมการเข้าถึงจากระยะไกล"</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN Bus ล้มเหลว"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN Bus ไม่ตอบสนอง ถอดปลั๊กกล่องเครื่องเล่นวิทยุ (Headunit) แล้วเสียบกลับเข้าไป สตาร์ทรถอีกครั้ง"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"อุปกรณ์ของฉัน"</string>
diff --git a/service/res/values-tl/strings.xml b/service/res/values-tl/strings.xml
index 6cc71de..98f9aab 100644
--- a/service/res/values-tl/strings.xml
+++ b/service/res/values-tl/strings.xml
@@ -168,6 +168,10 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Pamahalaan ang priyoridad ng thread."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"pamahalaan ang occupant zone"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Pamahalaan ang occupant zone."</string>
+    <string name="car_permission_label_use_remote_access" msgid="4192095854784769805">"gamitin ang malayuang access"</string>
+    <string name="car_permission_desc_use_remote_access" msgid="7287637348044911791">"Gamitin ang malayuang access."</string>
+    <string name="car_permission_label_control_remote_access" msgid="4247590162299914718">"kontrolin ang malayuang access"</string>
+    <string name="car_permission_desc_control_remote_access" msgid="127215188256669260">"Kontrolin ang malayuang access."</string>
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Hindi gumana ang CAN bus"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Hindi tumugon ang CAN bus. Hugutin at muling isaksak ang headunit box at i-restart ang sasakyan"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Aking Device"</string>
diff --git a/service/res/values-tr/strings.xml b/service/res/values-tr/strings.xml
index 3d6ab3f..6970c17 100644
--- a/service/res/values-tr/strings.xml
+++ b/service/res/values-tr/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"İleti dizisi önceliğini yönetin."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"yolcu bölgesini yönet"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Yolcu bölgesini yönet."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN veri yolu başarısız"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN veri yolu yanıt vermiyor. Ana birim kutusunu söküp tekrar takın ve aracı yeniden çalıştırın"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Cihazım"</string>
diff --git a/service/res/values-uk/strings.xml b/service/res/values-uk/strings.xml
index 472a208..58e35fd 100644
--- a/service/res/values-uk/strings.xml
+++ b/service/res/values-uk/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Керувати пріоритетом ланцюжка."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"керувати зоною пасажирів"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Керуйте зоною пасажирів."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Помилка CAN-шини"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN-шина не відповідає. Від’єднайте та знову під’єднайте головний пристрій аудіосистеми й заведіть автомобіль ще раз"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мій пристрій"</string>
diff --git a/service/res/values-ur/strings.xml b/service/res/values-ur/strings.xml
index 0674aee..3a663d2 100644
--- a/service/res/values-ur/strings.xml
+++ b/service/res/values-ur/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"سلسلے کی ترجیح کا نظم کریں۔"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"ساکن کے زون کا نظم کریں"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"ساکن کے زون کا نظم کریں۔"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"کین بس ناکام ہو گئی"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"کین بس جواب نہیں دیتی ہے۔ ہیڈیونٹ باکس کو ان پلگ کر کے دوبارہ پلگ کریں اور کار کو دوبارہ شروع کریں"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"میرا آلہ"</string>
diff --git a/service/res/values-uz/strings.xml b/service/res/values-uz/strings.xml
index f00f4ac..ac7862a 100644
--- a/service/res/values-uz/strings.xml
+++ b/service/res/values-uz/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Mavzu ustuvorligini boshqarish."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"yashash hududini boshqaring"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Yashash hududini boshqaring."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN shinalarida xatolik yuz berdi"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN javob bermayapti. Konnektorni chiqaring va qayta ulang, keyin avtomobilni oʻt oldiring"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Qurilmam"</string>
diff --git a/service/res/values-vi/strings.xml b/service/res/values-vi/strings.xml
index 82f7de4..9ec73f8 100644
--- a/service/res/values-vi/strings.xml
+++ b/service/res/values-vi/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Quản lý mức độ ưu tiên của chuỗi."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"quản lý khu vực có người"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Quản lý khu vực có người."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Đường dẫn chính CAN không hoạt động"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Đường dẫn chính CAN không phản hồi. Rút rồi cắm lại hộp bộ đầu và khởi động lại ô tô"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Thiết bị của tôi"</string>
diff --git a/service/res/values-zh-rCN/strings.xml b/service/res/values-zh-rCN/strings.xml
index 7c5f9f6..5429dd8 100644
--- a/service/res/values-zh-rCN/strings.xml
+++ b/service/res/values-zh-rCN/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"管理会话优先级。"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"管理乘员区"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"管理乘员区。"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"CAN 总线故障"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"CAN 总线没有响应。请将主机盒插头拔下并插回,然后重新启动汽车"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"我的设备"</string>
diff --git a/service/res/values-zh-rHK/strings.xml b/service/res/values-zh-rHK/strings.xml
index bc2fa5c..1fed9000 100644
--- a/service/res/values-zh-rHK/strings.xml
+++ b/service/res/values-zh-rHK/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"管理郵件串優先次序。"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"管理乘客區"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"管理乘客區。"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"控制器區域網路操作失敗"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"控制器區域網路未有回覆。請拔除並重新插上汽車音響主機,然後重新啟動汽車"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"我的裝置"</string>
diff --git a/service/res/values-zh-rTW/strings.xml b/service/res/values-zh-rTW/strings.xml
index 740b629..2dc8ef9 100644
--- a/service/res/values-zh-rTW/strings.xml
+++ b/service/res/values-zh-rTW/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"管理會話串優先順序。"</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"管理乘客區域"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"管理乘客區域。"</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"控制器區域網路發生問題"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"控制器區域網路無回應。請將主機盒插頭拔下並插回,然後重新啟動車輛"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"我的裝置"</string>
diff --git a/service/res/values-zu/strings.xml b/service/res/values-zu/strings.xml
index 068be2d..c8469a2 100644
--- a/service/res/values-zu/strings.xml
+++ b/service/res/values-zu/strings.xml
@@ -168,6 +168,14 @@
     <string name="car_permission_desc_manage_thread_priority" msgid="3833845502119615929">"Phatha okubalulekile kochungechunge."</string>
     <string name="car_permission_label_manage_occupant_zone" msgid="1390420387640478679">"phatha indawo yokuhlala"</string>
     <string name="car_permission_desc_manage_occupant_zone" msgid="1641484205694436465">"Phatha indawo yokuhlala."</string>
+    <!-- no translation found for car_permission_label_use_remote_access (4192095854784769805) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_use_remote_access (7287637348044911791) -->
+    <skip />
+    <!-- no translation found for car_permission_label_control_remote_access (4247590162299914718) -->
+    <skip />
+    <!-- no translation found for car_permission_desc_control_remote_access (127215188256669260) -->
+    <skip />
     <string name="car_can_bus_failure" msgid="2334035748788283914">"Ibhasi ye-CAN yehlulekile"</string>
     <string name="car_can_bus_failure_desc" msgid="4125516222786484733">"Ibhasi ye-CAN ayiphenduli. Nqamula futhi uxhume ibhokisi le-headunit ukuze uqalise kabusha imoto"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Idivayisi yami"</string>
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index f701543..82b530a 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -529,4 +529,9 @@
     <!-- Related to OEM customization service. Default timeout for critical calls made by CarService
          to OEM service. After this timeout, CarService would itself and OEM Service. -->
     <integer name="config_oemCarService_crashCall_timeout_ms">10000</integer>
+
+    <!-- Related to OEM customization service. Default thread pool size for communicating with the
+         OEM Service. The value can only be between 8 and 16. If value is higher than 16, thread
+         pool size will be 16. If value is lower than 8, thread pool size will be 8.-->
+    <integer name="config_oemCarService_thread_pool_size">8</integer>
 </resources>
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index 7b95ed1..7925093 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -115,6 +115,7 @@
           <item type="integer" name="config_oemCarService_serviceReady_timeout_ms"/>
           <item type="integer" name="config_oemCarService_regularCall_timeout_ms"/>
           <item type="integer" name="config_oemCarService_crashCall_timeout_ms"/>
+          <item type="integer" name="config_oemCarService_thread_pool_size"/>
           <!-- Params from config.xml that can be overlaid -->
 
           <!-- XML files that can be overlaid -->
diff --git a/service/res/values/strings.xml b/service/res/values/strings.xml
index d5b31e3..7358cfc 100644
--- a/service/res/values/strings.xml
+++ b/service/res/values/strings.xml
@@ -245,11 +245,6 @@
     <!-- Permission text: apps access car's epoch time [CHAR LIMIT=NONE] -->
     <string name="car_permission_desc_car_epoch_time">Access car\u2019s epoch time.</string>
 
-    <!-- Permission text: apps access car's encryption binding seed [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_encryption_binding_seed">access car\u2019s encryption binding seed </string>
-    <!-- Permission text: apps access car's encryption binding seed [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_encryption_binding_seed">Access car\u2019s encryption binding seed.</string>
-
     <!-- Permission text: apps control car's exterior lights [CHAR LIMIT=NONE] -->
     <string name="car_permission_label_control_car_exterior_lights">read car\u2019s exterior lights</string>
     <!-- Permission text: apps control car's exterior lights [CHAR LIMIT=NONE] -->
@@ -558,6 +553,11 @@
     <!-- Permission text: apps control remote access [CHAR LIMIT=NONE] -->
     <string name="car_permission_desc_control_remote_access">Control remote access.</string>
 
+    <!-- Permission text: apps can control car steering wheel [CHAR LIMIT=NONE] -->
+    <string name="car_permission_label_control_steering_wheel">control car\u2019s steering wheel</string>
+    <!-- Permission text: apps can control car steering wheel [CHAR LIMIT=NONE] -->
+    <string name="car_permission_desc_control_steering_wheel">Control car\u2019s steering wheel.</string>
+
     <!-- Notification messages -->
     <!-- Notification text: Notification shown to the user when vehicle CAN bus fails -->
     <string name="car_can_bus_failure">CAN bus failed</string>
diff --git a/service/src/com/android/car/AidlVehicleStub.java b/service/src/com/android/car/AidlVehicleStub.java
index aa99188..7fcf642 100644
--- a/service/src/com/android/car/AidlVehicleStub.java
+++ b/service/src/com/android/car/AidlVehicleStub.java
@@ -48,10 +48,10 @@
 import android.util.LongSparseArray;
 
 import com.android.car.hal.AidlHalPropConfig;
-import com.android.car.hal.HalClientCallback;
 import com.android.car.hal.HalPropConfig;
 import com.android.car.hal.HalPropValue;
 import com.android.car.hal.HalPropValueBuilder;
+import com.android.car.hal.VehicleHalCallback;
 import com.android.car.internal.LargeParcelable;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -244,7 +244,7 @@
      * @return a {@code SubscriptionClient} that could be used to subscribe/unsubscribe.
      */
     @Override
-    public SubscriptionClient newSubscriptionClient(HalClientCallback callback) {
+    public SubscriptionClient newSubscriptionClient(VehicleHalCallback callback) {
         return new AidlSubscriptionClient(callback, mPropValueBuilder);
     }
 
@@ -524,10 +524,10 @@
 
     private class AidlSubscriptionClient extends IVehicleCallback.Stub
             implements SubscriptionClient {
-        private final HalClientCallback mCallback;
+        private final VehicleHalCallback mCallback;
         private final HalPropValueBuilder mBuilder;
 
-        AidlSubscriptionClient(HalClientCallback callback, HalPropValueBuilder builder) {
+        AidlSubscriptionClient(VehicleHalCallback callback, HalPropValueBuilder builder) {
             mCallback = callback;
             mBuilder = builder;
         }
@@ -1028,7 +1028,12 @@
             // added and then remove them all.
             try {
                 clientCallback.linkToDeath(() -> {
-                    mPendingAsyncRequestPool.removeRequestsForCallback(clientCallback);
+                    // This function will be invoked from a different thread. It needs to be
+                    // guarded by a lock so that the whole 'prepareAndConvertAsyncRequests' finishes
+                    // before we remove the callback.
+                    synchronized (mLock) {
+                        mPendingAsyncRequestPool.removeRequestsForCallback(clientCallback);
+                    }
                 });
             } catch (RemoteException e) {
                 // The binder is already died.
diff --git a/service/src/com/android/car/CarShellCommand.java b/service/src/com/android/car/CarShellCommand.java
index 8ab5426..032e529 100644
--- a/service/src/com/android/car/CarShellCommand.java
+++ b/service/src/com/android/car/CarShellCommand.java
@@ -273,6 +273,7 @@
 
     private static final String COMMAND_SET_PROCESS_GROUP = "set-process-group";
     private static final String COMMAND_GET_PROCESS_GROUP = "get-process-group";
+    private static final String COMMAND_SET_PROCESS_PROFILE = "set-process-profile";
 
     private static final String COMMAND_GET_DISPLAY_BY_USER = "get-display-by-user";
     private static final String COMMAND_GET_USER_BY_DISPLAY = "get-user-by-display";
@@ -800,6 +801,9 @@
         pw.printf("\t%s <PID>", COMMAND_GET_PROCESS_GROUP);
         pw.println("\t Get the CPU group of a process. Check android.os.Process.getProcessGroup "
                 + "for details on the parameters.");
+        pw.printf("\t%s <PID> <UID> <CPU_PROFILE>", COMMAND_SET_PROCESS_PROFILE);
+        pw.println("\t Change CPU profile (=CPUSet) of a process. Check "
+                + "android.os.Process.setProcessProfile for details on the parameters.");
 
         pw.printf("\t%s <USER>", COMMAND_GET_DISPLAY_BY_USER);
         pw.println("\t Gets the display associated to the given user");
@@ -1194,6 +1198,9 @@
             case COMMAND_GET_PROCESS_GROUP:
                 getProcessGroup(args, writer);
                 break;
+            case COMMAND_SET_PROCESS_PROFILE:
+                setProcessProfile(args, writer);
+                break;
             case COMMAND_GET_DISPLAY_BY_USER:
                 getDisplayByUser(args, writer);
                 break;
@@ -3439,6 +3446,32 @@
         writer.printf("%d\n", group);
     }
 
+    private void setProcessProfile(String[] args, IndentingPrintWriter writer) {
+        if (args.length != 4) {
+            showInvalidArguments(writer);
+            return;
+        }
+
+        int pid = Integer.parseInt(args[1]);
+        int uid = Integer.parseInt(args[2]);
+        String profile = args[3];
+
+        Slogf.d(TAG, "Setting process profile for pid %d, uid %d, profile %s", pid, uid, profile);
+
+        ICarServiceHelper helper = CarLocalServices.getService(ICarServiceHelper.class);
+        if (helper == null) {
+            writer.printf("  CarServiceHelper not connected yet");
+            return;
+        }
+        try {
+            helper.setProcessProfile(pid, uid, profile);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+
+        writer.printf("  Successfully set pid %d uid %d to profile %s\n", pid, uid, profile);
+    }
+
     private void getDisplayByUser(String[] args, IndentingPrintWriter writer) {
         if (args.length != 2) {
             showInvalidArguments(writer);
diff --git a/service/src/com/android/car/HidlVehicleStub.java b/service/src/com/android/car/HidlVehicleStub.java
index 12d0f30..4631c34 100644
--- a/service/src/com/android/car/HidlVehicleStub.java
+++ b/service/src/com/android/car/HidlVehicleStub.java
@@ -35,11 +35,11 @@
 import android.os.ServiceSpecificException;
 import android.os.SystemProperties;
 
-import com.android.car.hal.HalClientCallback;
 import com.android.car.hal.HalPropConfig;
 import com.android.car.hal.HalPropValue;
 import com.android.car.hal.HalPropValueBuilder;
 import com.android.car.hal.HidlHalPropConfig;
+import com.android.car.hal.VehicleHalCallback;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.FileDescriptor;
@@ -185,7 +185,7 @@
      * @return a {@code SubscriptionClient} that could be used to subscribe/unsubscribe.
      */
     @Override
-    public SubscriptionClient newSubscriptionClient(HalClientCallback callback) {
+    public SubscriptionClient newSubscriptionClient(VehicleHalCallback callback) {
         return new HidlSubscriptionClient(callback, mPropValueBuilder);
     }
 
@@ -347,10 +347,10 @@
 
     private class HidlSubscriptionClient extends IVehicleCallback.Stub
             implements SubscriptionClient {
-        private final HalClientCallback mCallback;
+        private final VehicleHalCallback mCallback;
         private final HalPropValueBuilder mBuilder;
 
-        HidlSubscriptionClient(HalClientCallback callback, HalPropValueBuilder builder) {
+        HidlSubscriptionClient(VehicleHalCallback callback, HalPropValueBuilder builder) {
             mCallback = callback;
             mBuilder = builder;
         }
diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java
index 2f0c07b..4b3405b 100644
--- a/service/src/com/android/car/ICarImpl.java
+++ b/service/src/com/android/car/ICarImpl.java
@@ -219,7 +219,7 @@
         t.traceBegin("VHAL.earlyInit");
         // Do this before any other service components to allow feature check. It should work
         // even without init. For that, vhal get is retried as it can be too early.
-        HalPropValue disabledOptionalFeatureValue = mHal.getIfAvailableOrFailForEarlyStage(
+        HalPropValue disabledOptionalFeatureValue = mHal.getIfSupportedOrFailForEarlyStage(
                 VehicleProperty.DISABLED_OPTIONAL_FEATURES, INITIAL_VHAL_GET_RETRY);
         t.traceEnd();
 
diff --git a/service/src/com/android/car/VehicleStub.java b/service/src/com/android/car/VehicleStub.java
index ed56d37..c2fc790 100644
--- a/service/src/com/android/car/VehicleStub.java
+++ b/service/src/com/android/car/VehicleStub.java
@@ -26,10 +26,10 @@
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 
-import com.android.car.hal.HalClientCallback;
 import com.android.car.hal.HalPropConfig;
 import com.android.car.hal.HalPropValue;
 import com.android.car.hal.HalPropValueBuilder;
+import com.android.car.hal.VehicleHalCallback;
 import com.android.car.hal.fakevhal.FakeVehicleStub;
 
 import java.io.FileDescriptor;
@@ -79,7 +79,7 @@
     public @interface VehicleStubErrorCode {}
 
     /**
-     * A request for {@link com.android.car.hal.HalClient#getValuesAsync}
+     * A request for {@link VehicleStub#getAsync} or {@link VehicleStub#setAsync}.
      */
     public static class AsyncGetSetRequest {
         private final int mServiceRequestId;
@@ -325,7 +325,7 @@
      * @param callback A callback that could be used to receive events.
      * @return a {@code SubscriptionClient} that could be used to subscribe/unsubscribe.
      */
-    public abstract SubscriptionClient newSubscriptionClient(HalClientCallback callback);
+    public abstract SubscriptionClient newSubscriptionClient(VehicleHalCallback callback);
 
     /**
      * Gets a property.
diff --git a/service/src/com/android/car/audio/CarAudioFocus.java b/service/src/com/android/car/audio/CarAudioFocus.java
index a241b2e..65625b6 100644
--- a/service/src/com/android/car/audio/CarAudioFocus.java
+++ b/service/src/com/android/car/audio/CarAudioFocus.java
@@ -32,7 +32,10 @@
 import static com.android.car.audio.CarAudioContext.isCriticalAudioAudioAttribute;
 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
 
+import android.annotation.Nullable;
 import android.car.builtin.util.Slogf;
+import android.car.oem.AudioFocusEntry;
+import android.car.oem.OemCarAudioFocusResult;
 import android.content.pm.PackageManager;
 import android.media.AudioAttributes;
 import android.media.AudioFocusInfo;
@@ -196,27 +199,17 @@
             }
         }
 
-        // Is this a request for premanant focus?
+        // Is this a request for permanent focus?
         // AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE -- Means Notifications should be denied
         // AUDIOFOCUS_GAIN_TRANSIENT -- Means current focus holders should get transient loss
         // AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK -- Means other can duck (no loss message from us)
         // NOTE:  We expect that in practice it will be permanent for all media requests and
         //        transient for everything else, but that isn't currently an enforced requirement.
-        final boolean permanent =
-                (afi.getGainRequest() == AUDIOFOCUS_GAIN);
-        final boolean allowDucking =
-                (afi.getGainRequest() == AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
-
-        boolean delayFocusForCurrentRequest = false;
+        boolean permanent = (afi.getGainRequest() == AUDIOFOCUS_GAIN);
+        boolean allowDucking = (afi.getGainRequest() == AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
 
         int requestedContext = mCarAudioContext.getContextForAttributes(afi.getAttributes());
 
-        // If we happen to find entries that this new request should replace, we'll store them here.
-        // This happens when a client makes a second AF request on the same listener.
-        // After we've granted audio focus to our current request, we'll abandon these requests.
-        FocusEntry replacedCurrentEntry = null;
-        FocusEntry replacedBlockedEntry = null;
-
         boolean allowDelayedFocus = canReceiveDelayedFocus(afi);
 
         // We don't allow sharing listeners (client IDs) between two concurrent requests
@@ -235,123 +228,29 @@
             }
         }
 
-        // Scan all active and pending focus requests.  If any should cause rejection of
-        // this new request, then we're done.  Keep a list of those against whom we're exclusive
-        // so we can update the relationships if/when we are sure we won't get rejected.
-        Slogf.i(TAG, "Scanning focus holders...");
-        final ArrayList<FocusEntry> losers = new ArrayList<FocusEntry>();
-        for (FocusEntry entry : mFocusHolders.values()) {
-            Slogf.d(TAG, "Evaluating focus holder: " + entry.getClientId());
-
-            // If this request is for Notifications and a current focus holder has specified
-            // AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE, then reject the request.
-            // This matches the hardwired behavior in the default audio policy engine which apps
-            // might expect (The interaction matrix doesn't have any provision for dealing with
-            // override flags like this).
-            if (CarAudioContext.isNotificationAudioAttribute(afi.getAttributes())
-                    && (entry.getAudioFocusInfo().getGainRequest()
-                    == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
-                return AUDIOFOCUS_REQUEST_FAILED;
-            }
-
-            // We don't allow sharing listeners (client IDs) between two concurrent requests
-            // (because the app would have no way to know to which request a later event applied)
-            if (afi.getClientId().equals(entry.getAudioFocusInfo().getClientId())) {
-                if ((entry.getAudioContext() == requestedContext)
-                        || canSwapCallOrRingerClientRequest(afi.getClientId(),
-                        entry.getAudioFocusInfo().getAttributes(), afi.getAttributes())) {
-                    // This is a request from a current focus holder.
-                    // Abandon the previous request (without sending a LOSS notification to it),
-                    // and don't check the interaction matrix for it.
-                    Slogf.i(TAG, "Replacing accepted request from same client: %s",
-                            afi.getClientId());
-                    replacedCurrentEntry = entry;
-                    continue;
-                } else {
-                    // Trivially reject a request for a different USAGE
-                    Slogf.e(TAG, "Client %s has already requested focus for %s - cannot request "
-                            + "focus for %s on same listener.", entry.getClientId(),
-                            usageToString(entry.getAudioFocusInfo().getAttributes().getUsage()),
-                            usageToString(afi.getAttributes().getUsage()));
-                    return AUDIOFOCUS_REQUEST_FAILED;
-                }
-            }
-
-            int interactionResult = mFocusInteraction.evaluateRequest(requestedContext, entry,
-                    losers, allowDucking, allowDelayedFocus);
-            if (interactionResult == AUDIOFOCUS_REQUEST_FAILED) {
-                return interactionResult;
-            }
-            if (interactionResult == AUDIOFOCUS_REQUEST_DELAYED) {
-                delayFocusForCurrentRequest = true;
-            }
-        }
-        Slogf.i(TAG, "Scanning those who've already lost focus...");
-        final ArrayList<FocusEntry> blocked = new ArrayList<FocusEntry>();
-        for (FocusEntry entry : mFocusLosers.values()) {
-            Slogf.i(TAG, entry.getAudioFocusInfo().getClientId());
-
-            // If this request is for Notifications and a pending focus holder has specified
-            // AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE, then reject the request
-            if ((CarAudioContext.isNotificationAudioAttribute(afi.getAttributes()))
-                    && (entry.getAudioFocusInfo().getGainRequest()
-                    == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
-                return AUDIOFOCUS_REQUEST_FAILED;
-            }
-
-            // We don't allow sharing listeners (client IDs) between two concurrent requests
-            // (because the app would have no way to know to which request a later event applied)
-            if (afi.getClientId().equals(entry.getAudioFocusInfo().getClientId())) {
-                if (entry.getAudioContext() == requestedContext) {
-                    // This is a repeat of a request that is currently blocked.
-                    // Evaluate it as if it were a new request, but note that we should remove
-                    // the old pending request, and move it.
-                    // We do not want to evaluate the new request against itself.
-                    Slogf.i(TAG, "Replacing pending request from same client");
-                    replacedBlockedEntry = entry;
-                    continue;
-                } else {
-                    // Trivially reject a request for a different USAGE
-                    Slogf.e(TAG, "Client %s has already requested focus for %s - cannot request "
-                            + "focus for %s on same listener.", entry.getClientId(),
-                            usageToString(entry.getAudioFocusInfo().getAttributes().getUsage()),
-                            usageToString(afi.getAttributes().getUsage()));
-                    return AUDIOFOCUS_REQUEST_FAILED;
-                }
-            }
-
-            int interactionResult = mFocusInteraction
-                    .evaluateRequest(requestedContext, entry, blocked, allowDucking,
-                            allowDelayedFocus);
-            if (interactionResult == AUDIOFOCUS_REQUEST_FAILED) {
-                return interactionResult;
-            }
-            if (interactionResult == AUDIOFOCUS_REQUEST_DELAYED) {
-                delayFocusForCurrentRequest = true;
-            }
-        }
-
-
-        // Now that we've decided we'll grant focus, construct our new FocusEntry
-        FocusEntry newEntry = new FocusEntry(afi, requestedContext, mPackageManager);
-
         // These entries have permanently lost focus as a result of this request, so they
         // should be removed from all blocker lists.
         ArrayList<FocusEntry> permanentlyLost = new ArrayList<>();
 
-        if (replacedCurrentEntry != null) {
-            mFocusHolders.remove(replacedCurrentEntry.getClientId());
-            permanentlyLost.add(replacedCurrentEntry);
-        }
-        if (replacedBlockedEntry != null) {
-            mFocusLosers.remove(replacedBlockedEntry.getClientId());
-            permanentlyLost.add(replacedBlockedEntry);
+        OemCarAudioFocusResult evaluationResults =
+                evaluateFocusRequestLocked(permanentlyLost, afi,
+                        allowDucking, allowDelayedFocus);
+
+        if (evaluationResults.equals(OemCarAudioFocusResult.EMPTY_OEM_CAR_AUDIO_FOCUS_RESULTS)) {
+            return AUDIOFOCUS_REQUEST_FAILED;
         }
 
+        // Now that we've decided we'll grant focus, construct our new FocusEntry
+        AudioFocusEntry focusEntry = evaluationResults.getAudioFocusEntry();
+        FocusEntry newEntry = new FocusEntry(focusEntry.getAudioFocusInfo(),
+                focusEntry.getAudioContextId(), mPackageManager);
 
         // Now that we're sure we'll accept this request, update any requests which we would
         // block but are already out of focus but waiting to come back
-        for (FocusEntry entry : blocked) {
+        List<AudioFocusEntry> blocked = evaluationResults.getNewlyBlockedAudioFocusEntries();
+        for (int index = 0; index < blocked.size(); index++) {
+            AudioFocusEntry newlyBlocked = blocked.get(index);
+            FocusEntry entry = mFocusLosers.get(newlyBlocked.getAudioFocusInfo().getClientId());
             // If we're out of focus it must be because somebody is blocking us
             assert !entry.isUnblocked();
 
@@ -359,7 +258,7 @@
                 // This entry has now lost focus forever
                 sendFocusLossLocked(entry.getAudioFocusInfo(), AUDIOFOCUS_LOSS);
                 entry.setDucked(false);
-                final FocusEntry deadEntry = mFocusLosers.remove(
+                FocusEntry deadEntry = mFocusLosers.remove(
                         entry.getAudioFocusInfo().getClientId());
                 assert deadEntry != null;
                 permanentlyLost.add(entry);
@@ -377,7 +276,10 @@
         }
 
         // Notify and update any requests which are now losing focus as a result of the new request
-        for (FocusEntry entry : losers) {
+        List<AudioFocusEntry> loss = evaluationResults.getNewlyLossAudioFocusEntries();
+        for (int index = 0; index < loss.size(); index++) {
+            AudioFocusEntry newlyLoss = loss.get(index);
+            FocusEntry entry = mFocusHolders.get(newlyLoss.getAudioFocusInfo().getClientId());
             // If we have focus (but are about to loose it), nobody should be blocking us yet
             assert entry.isUnblocked();
 
@@ -405,7 +307,7 @@
             }
         }
 
-        if (!delayFocusForCurrentRequest) {
+        if (evaluationResults.getAudioFocusResult() != AUDIOFOCUS_REQUEST_DELAYED) {
             // If the entry is replacing an existing one, and if a delayed Request is pending
             // this replaced entry is not a blocker of the delayed.
             // So add it before reconsidering the delayed.
@@ -417,12 +319,13 @@
         // any blocker lists, remove them. If any focus requests become unblocked as a result,
         // re-grant them. (This can happen when a GAIN_TRANSIENT_MAY_DUCK request replaces a
         // GAIN_TRANSIENT request from the same listener.)
-        for (FocusEntry entry : permanentlyLost) {
+        for (int index = 0; index < permanentlyLost.size(); index++) {
+            FocusEntry entry = permanentlyLost.get(index);
             Slogf.d(TAG, "Cleaning up entry " + entry.getClientId());
             removeBlockerAndRestoreUnblockedWaitersLocked(entry);
         }
 
-        if (delayFocusForCurrentRequest) {
+        if (evaluationResults.getAudioFocusResult() == AUDIOFOCUS_REQUEST_DELAYED) {
             swapDelayedAudioFocusRequestLocked(afi);
             return AUDIOFOCUS_REQUEST_DELAYED;
         }
@@ -431,6 +334,187 @@
         return AUDIOFOCUS_REQUEST_GRANTED;
     }
 
+    @GuardedBy("mLock")
+    private OemCarAudioFocusResult evaluateFocusRequestLocked(
+            ArrayList<FocusEntry> permanentlyLost,
+            AudioFocusInfo audioFocusInfo, boolean allowDucking,
+            boolean allowDelayedFocus) {
+
+        int requestedContext =
+                mCarAudioContext.getContextForAttributes(audioFocusInfo.getAttributes());
+        FocusEvaluation holdersEvaluation = evaluateAgainstFocusHoldersLocked(audioFocusInfo,
+                requestedContext, allowDucking, allowDelayedFocus);
+
+        if (holdersEvaluation.equals(FocusEvaluation.FOCUS_EVALUATION_FAILED)) {
+            return OemCarAudioFocusResult.EMPTY_OEM_CAR_AUDIO_FOCUS_RESULTS;
+        }
+
+        FocusEvaluation losersEvaluation = evaluateAgainstFocusLosersLocked(audioFocusInfo,
+                requestedContext, allowDucking, allowDelayedFocus);
+
+        if (losersEvaluation.equals(FocusEvaluation.FOCUS_EVALUATION_FAILED)) {
+            return OemCarAudioFocusResult.EMPTY_OEM_CAR_AUDIO_FOCUS_RESULTS;
+        }
+
+        if (holdersEvaluation.mReplacedEntry != null) {
+            mFocusHolders.remove(holdersEvaluation.mReplacedEntry.getClientId());
+            permanentlyLost.add(holdersEvaluation.mReplacedEntry);
+        }
+        if (losersEvaluation.mReplacedEntry != null) {
+            mFocusLosers.remove(losersEvaluation.mReplacedEntry.getClientId());
+            permanentlyLost.add(losersEvaluation.mReplacedEntry);
+        }
+
+        boolean delayFocus = holdersEvaluation.mAudioFocusEvalResults == AUDIOFOCUS_REQUEST_DELAYED
+                || losersEvaluation.mAudioFocusEvalResults == AUDIOFOCUS_REQUEST_DELAYED;
+
+        int results = delayFocus ? AUDIOFOCUS_REQUEST_DELAYED : AUDIOFOCUS_REQUEST_GRANTED;
+
+        AudioFocusEntry focusEntry =
+                new AudioFocusEntry.Builder(audioFocusInfo, requestedContext,
+                getVolumeGroupForAttribute(audioFocusInfo.getAttributes()),
+                AudioManager.AUDIOFOCUS_GAIN).build();
+
+        return new OemCarAudioFocusResult.Builder(
+                convertAudioFocusEntries(holdersEvaluation.mChangedEntries),
+                convertAudioFocusEntries(losersEvaluation.mChangedEntries),
+                results).setAudioFocusEntry(focusEntry)
+                .build();
+    }
+
+    private List<AudioFocusEntry> convertAudioFocusEntries(List<FocusEntry> changedEntries) {
+        List<AudioFocusEntry> audioFocusEntries = new ArrayList<>(changedEntries.size());
+        for (int index = 0; index < changedEntries.size(); index++) {
+            AudioFocusInfo info = changedEntries.get(index).getAudioFocusInfo();
+            audioFocusEntries.add(new AudioFocusEntry.Builder(info,
+                    mCarAudioContext.getContextForAudioAttribute(info.getAttributes()),
+                    getVolumeGroupForAttribute(info.getAttributes()),
+                    AUDIOFOCUS_LOSS_TRANSIENT).build());
+        }
+        return audioFocusEntries;
+    }
+
+    private int getVolumeGroupForAttribute(AudioAttributes attributes) {
+        //TODO(b/240615622): Get volume group info from service
+        return 0;
+    }
+
+    @GuardedBy("mLock")
+    private FocusEvaluation evaluateAgainstFocusLosersLocked(AudioFocusInfo afi,
+            int requestedContext, boolean allowDucking, boolean allowDelayedFocus) {
+        Slogf.i(TAG, "Scanning those who've already lost focus...");
+        boolean delayFocusForCurrentRequest = false;
+        FocusEntry replacedBlockedEntry = null;
+        ArrayList<FocusEntry> blocked = new ArrayList<FocusEntry>();
+        for (FocusEntry entry : mFocusLosers.values()) {
+            Slogf.i(TAG, entry.getAudioFocusInfo().getClientId());
+
+            // If this request is for Notifications and a pending focus holder has specified
+            // AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE, then reject the request
+            if ((CarAudioContext.isNotificationAudioAttribute(afi.getAttributes()))
+                    && (entry.getAudioFocusInfo().getGainRequest()
+                    == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
+                return FocusEvaluation.FOCUS_EVALUATION_FAILED;
+            }
+
+            // We don't allow sharing listeners (client IDs) between two concurrent requests
+            // (because the app would have no way to know to which request a later event applied)
+            if (afi.getClientId().equals(entry.getAudioFocusInfo().getClientId())) {
+                if (entry.getAudioContext() == requestedContext) {
+                    // This is a repeat of a request that is currently blocked.
+                    // Evaluate it as if it were a new request, but note that we should remove
+                    // the old pending request, and move it.
+                    // We do not want to evaluate the new request against itself.
+                    Slogf.i(TAG, "Replacing pending request from same client");
+                    replacedBlockedEntry = entry;
+                    continue;
+                } else {
+                    // Trivially reject a request for a different USAGE
+                    Slogf.e(TAG, "Client %s has already requested focus for %s - cannot request "
+                                    + "focus for %s on same listener.", entry.getClientId(),
+                            usageToString(entry.getAudioFocusInfo().getAttributes().getUsage()),
+                            usageToString(afi.getAttributes().getUsage()));
+                    return FocusEvaluation.FOCUS_EVALUATION_FAILED;
+                }
+            }
+
+            int interactionResult = mFocusInteraction
+                    .evaluateRequest(requestedContext, entry, blocked, allowDucking,
+                            allowDelayedFocus);
+            if (interactionResult == AUDIOFOCUS_REQUEST_FAILED) {
+                return FocusEvaluation.FOCUS_EVALUATION_FAILED;
+            }
+            if (interactionResult == AUDIOFOCUS_REQUEST_DELAYED) {
+                delayFocusForCurrentRequest = true;
+            }
+        }
+        int results = delayFocusForCurrentRequest
+                ? AUDIOFOCUS_REQUEST_DELAYED : AUDIOFOCUS_REQUEST_GRANTED;
+        return new FocusEvaluation(blocked, replacedBlockedEntry, results);
+    }
+
+    @GuardedBy("mLock")
+    private FocusEvaluation evaluateAgainstFocusHoldersLocked(AudioFocusInfo afi,
+            int requestedContext, boolean allowDucking, boolean allowDelayedFocus) {
+        // Scan all active and pending focus requests.  If any should cause rejection of
+        // this new request, then we're done.  Keep a list of those against whom we're exclusive
+        // so we can update the relationships if/when we are sure we won't get rejected.
+        Slogf.i(TAG, "Scanning focus holders...");
+        boolean delayFocusForCurrentRequest = false;
+        FocusEntry replacedCurrentEntry = null;
+        ArrayList<FocusEntry> losers = new ArrayList<FocusEntry>();
+        for (FocusEntry entry : mFocusHolders.values()) {
+            Slogf.d(TAG, "Evaluating focus holder: " + entry.getClientId());
+
+            // If this request is for Notifications and a current focus holder has specified
+            // AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE, then reject the request.
+            // This matches the hardwired behavior in the default audio policy engine which apps
+            // might expect (The interaction matrix doesn't have any provision for dealing with
+            // override flags like this).
+            if (CarAudioContext.isNotificationAudioAttribute(afi.getAttributes())
+                    && (entry.getAudioFocusInfo().getGainRequest()
+                    == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
+                return FocusEvaluation.FOCUS_EVALUATION_FAILED;
+            }
+
+            // We don't allow sharing listeners (client IDs) between two concurrent requests
+            // (because the app would have no way to know to which request a later event applied)
+            if (afi.getClientId().equals(entry.getAudioFocusInfo().getClientId())) {
+                if ((entry.getAudioContext() == requestedContext)
+                        || canSwapCallOrRingerClientRequest(afi.getClientId(),
+                        entry.getAudioFocusInfo().getAttributes(), afi.getAttributes())) {
+                    // This is a request from a current focus holder.
+                    // Abandon the previous request (without sending a LOSS notification to it),
+                    // and don't check the interaction matrix for it.
+                    Slogf.i(TAG, "Replacing accepted request from same client: %s",
+                            afi.getClientId());
+                    replacedCurrentEntry = entry;
+                    continue;
+                } else {
+                    // Trivially reject a request for a different USAGE
+                    Slogf.e(TAG, "Client %s has already requested focus for %s - cannot request "
+                                    + "focus for %s on same listener.", entry.getClientId(),
+                            usageToString(entry.getAudioFocusInfo().getAttributes().getUsage()),
+                            usageToString(afi.getAttributes().getUsage()));
+                    return FocusEvaluation.FOCUS_EVALUATION_FAILED;
+                }
+            }
+
+            int interactionResult = mFocusInteraction.evaluateRequest(requestedContext, entry,
+                    losers, allowDucking, allowDelayedFocus);
+            if (interactionResult == AUDIOFOCUS_REQUEST_FAILED) {
+                return FocusEvaluation.FOCUS_EVALUATION_FAILED;
+            }
+            if (interactionResult == AUDIOFOCUS_REQUEST_DELAYED) {
+                delayFocusForCurrentRequest = true;
+            }
+        }
+
+        int results = delayFocusForCurrentRequest
+                ? AUDIOFOCUS_REQUEST_DELAYED : AUDIOFOCUS_REQUEST_GRANTED;
+        return new FocusEvaluation(losers, replacedCurrentEntry, results);
+    }
+
     private static boolean canSwapCallOrRingerClientRequest(String clientId,
             AudioAttributes currentAttributes, AudioAttributes requestedAttributes) {
         return isCallFocusRequestClientId(clientId)
@@ -793,4 +877,31 @@
     public FocusInteraction getFocusInteraction() {
         return mFocusInteraction;
     }
+
+    private static final class FocusEvaluation {
+
+        private static final FocusEvaluation FOCUS_EVALUATION_FAILED =
+                new FocusEvaluation(/* changedEntries= */ new ArrayList<>(/* initialCap= */ 0),
+                        /* replacedEntry= */ null, AUDIOFOCUS_REQUEST_FAILED);
+
+        private final List<FocusEntry> mChangedEntries;
+        @Nullable
+        private final FocusEntry mReplacedEntry;
+        private final int mAudioFocusEvalResults;
+
+        FocusEvaluation(List<FocusEntry> changedEntries,
+                @Nullable FocusEntry replacedEntry, int audioFocusEvalResults) {
+            mChangedEntries = changedEntries;
+            mReplacedEntry = replacedEntry;
+            mAudioFocusEvalResults = audioFocusEvalResults;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder().append("{Changed Entries: ").append(mChangedEntries)
+                    .append(", Replace Entry: ").append(mReplacedEntry)
+                    .append(", Results: ").append(mAudioFocusEvalResults)
+                    .append(" }").toString();
+        }
+    }
 }
diff --git a/service/src/com/android/car/audio/CarAudioService.java b/service/src/com/android/car/audio/CarAudioService.java
index 551a57d..a1a586f 100644
--- a/service/src/com/android/car/audio/CarAudioService.java
+++ b/service/src/com/android/car/audio/CarAudioService.java
@@ -30,6 +30,8 @@
 import static com.android.car.audio.hal.AudioControlWrapper.AUDIOCONTROL_FEATURE_AUDIO_DUCKING;
 import static com.android.car.audio.hal.AudioControlWrapper.AUDIOCONTROL_FEATURE_AUDIO_FOCUS;
 import static com.android.car.audio.hal.AudioControlWrapper.AUDIOCONTROL_FEATURE_AUDIO_GAIN_CALLBACK;
+import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DEBUGGING_CODE;
+import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DEPRECATED_CODE;
 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
 
 import android.annotation.NonNull;
@@ -213,11 +215,12 @@
             };
 
     public CarAudioService(Context context) {
-        this(context, getAudioConfigurationPath());
+        this(context, getAudioConfigurationPath(), new CarVolumeCallbackHandler());
     }
 
     @VisibleForTesting
-    CarAudioService(Context context, @Nullable String audioConfigurationPath) {
+    CarAudioService(Context context, @Nullable String audioConfigurationPath,
+            CarVolumeCallbackHandler carVolumeCallbackHandler) {
         mContext = Objects.requireNonNull(context,
                 "Context to create car audio service can not be null");
         mCarAudioConfigurationPath = audioConfigurationPath;
@@ -231,7 +234,7 @@
                 R.bool.audioUseHalDuckingSignals);
 
         mUidToZoneMap = new HashMap<>();
-        mCarVolumeCallbackHandler = new CarVolumeCallbackHandler();
+        mCarVolumeCallbackHandler = carVolumeCallbackHandler;
         mCarAudioSettings = new CarAudioSettings(mContext);
         mAudioZoneIdToUserIdMapping = new SparseIntArray();
         mAudioVolumeAdjustmentContextsVersion =
@@ -579,6 +582,7 @@
     }
 
     @GuardedBy("mImplLock")
+    @ExcludeFromCodeCoverageGeneratedReport(reason = DEPRECATED_CODE)
     private SparseArray<CarAudioZone> loadVolumeGroupConfigurationWithAudioControlLocked(
             List<CarAudioDeviceInfo> carAudioDeviceInfos, AudioDeviceInfo[] inputDevices) {
         AudioControlWrapper audioControlWrapper = getAudioControlWrapperLocked();
@@ -1607,6 +1611,7 @@
     /**
      * Resets the last selected volume context.
      */
+    @ExcludeFromCodeCoverageGeneratedReport(reason = DEBUGGING_CODE)
     public void resetSelectedVolumeContext() {
         enforcePermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME);
         synchronized (mImplLock) {
diff --git a/service/src/com/android/car/audio/CarZonesAudioFocus.java b/service/src/com/android/car/audio/CarZonesAudioFocus.java
index 04f001b..2a693e4 100644
--- a/service/src/com/android/car/audio/CarZonesAudioFocus.java
+++ b/service/src/com/android/car/audio/CarZonesAudioFocus.java
@@ -35,7 +35,6 @@
 import com.android.car.CarLog;
 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
 import com.android.car.internal.util.IndentingPrintWriter;
-import com.android.car.oem.CarOemAudioFocusProxyService;
 import com.android.car.oem.CarOemProxyService;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
@@ -224,21 +223,15 @@
         mCarFocusCallback.onFocusChange(zoneIds, focusHoldersByZoneId);
     }
 
-    private CarOemAudioFocusProxyService getOemAudioFocusService() {
-        CarOemProxyService oemProxyService = CarLocalServices.getService(CarOemProxyService.class);
-        if (oemProxyService == null) {
-            return null;
-        }
-        return oemProxyService.getCarOemAudioFocusService();
-    }
-
     private void sendFocusChangeToOemService(CarAudioFocus carAudioFocus, int zoneId) {
-        CarOemAudioFocusProxyService proxy = getOemAudioFocusService();
-        if (proxy == null) {
+        CarOemProxyService proxy = CarLocalServices.getService(CarOemProxyService.class);
+        if (!proxy.isOemServiceEnabled() || !proxy.isOemServiceReady()
+                || proxy.getCarOemAudioFocusService() == null) {
             return;
         }
-        proxy.audioFocusChanged(carAudioFocus.getAudioFocusHolders(),
-                carAudioFocus.getAudioFocusLosers(), zoneId);
+
+        proxy.getCarOemAudioFocusService().notifyAudioFocusChange(
+                carAudioFocus.getAudioFocusHolders(), carAudioFocus.getAudioFocusLosers(), zoneId);
     }
 
     @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
diff --git a/service/src/com/android/car/evs/CarEvsService.java b/service/src/com/android/car/evs/CarEvsService.java
index 569abd8..3abf997 100644
--- a/service/src/com/android/car/evs/CarEvsService.java
+++ b/service/src/com/android/car/evs/CarEvsService.java
@@ -469,11 +469,7 @@
                         return ERROR_BUSY;
                     }
 
-                    if (callback != null) {
-                        stopVideoStreamAndUnregisterCallback(callback);
-                    } else {
-                        stopService();
-                    }
+                    stopService(callback);
                     break;
 
                 default:
@@ -602,6 +598,7 @@
                     if (mStreamCallback != null) {
                         // keep old reference for Runnable.
                         ICarEvsStreamCallback previousCallback = mStreamCallback;
+                        mStreamCallback = null;
                         mHandler.post(() -> notifyStreamStopped(previousCallback));
                     }
 
@@ -685,7 +682,7 @@
     // Stops a current video stream and unregisters a callback
     private void stopVideoStreamAndUnregisterCallback(ICarEvsStreamCallback callback) {
         synchronized (mLock) {
-            if (callback.asBinder() != mStreamCallback.asBinder()) {
+            if (callback == null || callback.asBinder() != mStreamCallback.asBinder()) {
                 Slogf.i(TAG_EVS, "Declines a request to stop a video not from a current client.");
                 return;
             }
@@ -1024,7 +1021,6 @@
     public void stopVideoStream(@NonNull ICarEvsStreamCallback callback) {
         CarServiceUtils.assertPermission(mContext, Car.PERMISSION_USE_CAR_EVS_CAMERA);
         Objects.requireNonNull(callback);
-
         synchronized (mLock) {
             if (mStreamCallback == null || callback.asBinder() != mStreamCallback.asBinder()) {
                 Slogf.i(TAG_EVS, "Ignores a video stream request not from current stream client.");
@@ -1282,16 +1278,32 @@
 
     /** Stops a current service */
     private void stopService() {
+        stopService(/* callback= */ null);
+    }
+
+    private void stopService(ICarEvsStreamCallback callback) {
         try {
+            synchronized (mLock) {
+                if (callback != null && callback.asBinder() != mStreamCallback.asBinder()) {
+                    Slogf.w(TAG_EVS, "Decline a request to stop a video from an unknown client.");
+                    return;
+                }
+
+                unlinkToDeathStreamCallbackLocked();
+                mStreamCallback = null;
+            }
+            Slogf.i(TAG_EVS, "Last stream client has been disconnected.");
+
+            // Notify the client that the stream has ended.
+            if (callback != null) {
+                notifyStreamStopped(callback);
+            }
+
+            // Request to stop a video stream if it is active.
             mHalWrapper.requestToStopVideoStream();
         } catch (RuntimeException e) {
             Slogf.w(TAG_EVS, Log.getStackTraceString(e));
         } finally {
-            // Unregister all stream callbacks.
-            synchronized (mLock) {
-                mStreamCallback = null;
-            }
-
             // We simply drop all buffer records; the native method will return all pending buffers
             // to the native Extended System View service if it is alive.
             synchronized (mBufferRecords) {
@@ -1300,6 +1312,9 @@
 
             // Cancel a pending message to check a request timeout
             mHandler.removeCallbacks(mActivityRequestTimeoutRunnable);
+
+            // Close current camera
+            mHalWrapper.closeCamera();
         }
     }
 
diff --git a/service/src/com/android/car/hal/HalClient.java b/service/src/com/android/car/hal/HalClient.java
deleted file mode 100644
index 5135b35..0000000
--- a/service/src/com/android/car/hal/HalClient.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.car.hal;
-
-import static android.os.SystemClock.elapsedRealtime;
-
-import android.car.builtin.util.Slogf;
-import android.hardware.automotive.vehicle.StatusCode;
-import android.hardware.automotive.vehicle.SubscribeOptions;
-import android.hardware.automotive.vehicle.VehiclePropError;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-
-import com.android.car.CarLog;
-import com.android.car.VehicleStub;
-import com.android.car.VehicleStub.SubscriptionClient;
-import com.android.car.internal.util.DebugUtils;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Vehicle HAL client. Interacts directly with Vehicle HAL interface {@link IVehicle}. Contains
- * some logic for retriable properties, redirects Vehicle notifications into given looper thread.
- */
-final class HalClient {
-
-    @VisibleForTesting
-    static final String TAG = CarLog.tagFor(HalClient.class);
-
-    /**
-     * If call to vehicle HAL returns StatusCode.TRY_AGAIN, than {@link HalClient} will retry to
-     * invoke that method again for this amount of milliseconds.
-     */
-    private static final int WAIT_CAP_FOR_RETRIABLE_RESULT_MS = 2000;
-
-    private static final int SLEEP_BETWEEN_RETRIABLE_INVOKES_MS = 50;
-
-    private final VehicleStub mVehicle;
-    private final SubscriptionClient mSubscriptionClient;
-    private final VehicleCallback mInternalCallback;
-    private final int mWaitCapMs;
-    private final int mSleepMs;
-
-    /**
-     * Create HalClient object
-     *
-     * @param vehicle interface to the vehicle HAL
-     * @param looper looper that will be used to propagate notifications from vehicle HAL
-     * @param callback to propagate notifications from Vehicle HAL in the provided looper thread
-     */
-    HalClient(VehicleStub vehicle, Looper looper, HalClientCallback callback) {
-        this(
-                vehicle,
-                looper,
-                callback,
-                WAIT_CAP_FOR_RETRIABLE_RESULT_MS,
-                SLEEP_BETWEEN_RETRIABLE_INVOKES_MS);
-    }
-
-    @VisibleForTesting
-    HalClient(VehicleStub vehicle, Looper looper, HalClientCallback callback, int waitCapMs,
-            int sleepMs) {
-        mVehicle = vehicle;
-        Handler handler = new CallbackHandler(looper, callback);
-        mInternalCallback = new VehicleCallback(handler);
-        mSubscriptionClient = vehicle.newSubscriptionClient(mInternalCallback);
-        mWaitCapMs = waitCapMs;
-        mSleepMs = sleepMs;
-    }
-
-    HalClientCallback getInternalCallback() {
-        return mInternalCallback;
-    }
-
-    HalPropConfig[] getAllPropConfigs()
-            throws RemoteException, ServiceSpecificException {
-        return mVehicle.getAllPropConfigs();
-    }
-
-    public void subscribe(SubscribeOptions... options)
-            throws RemoteException, ServiceSpecificException {
-        mSubscriptionClient.subscribe(options);
-    }
-
-    public void unsubscribe(int prop) throws RemoteException, ServiceSpecificException {
-        mSubscriptionClient.unsubscribe(prop);
-    }
-
-    public void setValue(HalPropValue propValue)
-            throws IllegalArgumentException, ServiceSpecificException {
-        ObjectWrapper<String> errorMsgWrapper = new ObjectWrapper<>();
-        errorMsgWrapper.object = new String();
-
-        int status = invokeRetriable(() -> {
-            try {
-                mVehicle.set(propValue);
-                errorMsgWrapper.object = new String();
-                return StatusCode.OK;
-            } catch (RemoteException e) {
-                errorMsgWrapper.object = e.toString();
-                return StatusCode.TRY_AGAIN;
-            } catch (ServiceSpecificException e) {
-                errorMsgWrapper.object = e.toString();
-                return e.errorCode;
-            }
-        }, mWaitCapMs, mSleepMs);
-
-        String errorMsg = errorMsgWrapper.object;
-
-        if (StatusCode.INVALID_ARG == status) {
-            throw new IllegalArgumentException(getValueErrorMessage("set", propValue, errorMsg));
-        }
-
-        if (StatusCode.OK != status) {
-            throw new ServiceSpecificException(
-                    status, getValueErrorMessage("set", propValue, errorMsg));
-        }
-    }
-
-    public HalPropValueBuilder getHalPropValueBuilder() {
-        return mVehicle.getHalPropValueBuilder();
-    }
-
-    private String getValueErrorMessage(String action, HalPropValue propValue, String errorMsg) {
-        return "Failed to " + action + " value for: 0x"
-                + Integer.toHexString(propValue.getPropId()) + ", areaId: 0x"
-                + Integer.toHexString(propValue.getAreaId()) + ", error: " + errorMsg;
-    }
-
-    HalPropValue getValue(HalPropValue requestedPropValue)
-            throws IllegalArgumentException, ServiceSpecificException {
-        // Use a wrapper to create a final object passed to lambda.
-        ObjectWrapper<ValueResult> resultWrapper = new ObjectWrapper<>();
-        resultWrapper.object = new ValueResult();
-        int status = invokeRetriable(() -> {
-            resultWrapper.object = internalGet(requestedPropValue);
-            return resultWrapper.object.status;
-        }, mWaitCapMs, mSleepMs);
-
-        ValueResult result = resultWrapper.object;
-
-        if (StatusCode.INVALID_ARG == status) {
-            throw new IllegalArgumentException(
-                    getValueErrorMessage("get", requestedPropValue, result.errorMsg));
-        }
-
-        if (StatusCode.OK != status || result.propValue == null) {
-            // If propValue is null and status is StatusCode.Ok, change the status to be
-            // NOT_AVAILABLE.
-            if (StatusCode.OK == status) {
-                status = StatusCode.NOT_AVAILABLE;
-            }
-            throw new ServiceSpecificException(
-                    status, getValueErrorMessage("get", requestedPropValue, result.errorMsg));
-        }
-
-        return result.propValue;
-    }
-
-    private ValueResult internalGet(HalPropValue requestedPropValue) {
-        final ValueResult result = new ValueResult();
-        try {
-            result.propValue = mVehicle.get(requestedPropValue);
-            result.status = StatusCode.OK;
-            result.errorMsg = new String();
-        } catch (ServiceSpecificException e) {
-            result.status = e.errorCode;
-            result.errorMsg = e.toString();
-        } catch (RemoteException e) {
-            result.status = StatusCode.TRY_AGAIN;
-            result.errorMsg = e.toString();
-        }
-
-        return result;
-    }
-
-    interface RetriableCallback {
-        /** Returns {@link StatusCode} */
-        int action();
-    }
-
-    private static int invokeRetriable(RetriableCallback callback, long timeoutMs, long sleepMs) {
-        int status = callback.action();
-        long startTime = elapsedRealtime();
-        while (StatusCode.TRY_AGAIN == status && (elapsedRealtime() - startTime) < timeoutMs) {
-            Slogf.d(TAG, "Status before sleeping %d ms: %d", sleepMs, status);
-            try {
-                Thread.sleep(sleepMs);
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                Slogf.w(TAG, "Thread was interrupted while waiting for vehicle HAL.", e);
-                break;
-            }
-
-            status = callback.action();
-            Slogf.d(TAG, "Status after waking up: %s", DebugUtils.constantToString(
-                    StatusCode.class, status));
-        }
-        Slogf.d(TAG, "Returning status: %s", DebugUtils.constantToString(
-                StatusCode.class, status));
-        return status;
-    }
-
-    private static final class ObjectWrapper<T> {
-        public T object;
-    }
-
-    private static final class ValueResult {
-        public int status;
-        public String errorMsg = new String();
-        public HalPropValue propValue;
-    }
-
-    private static final class CallbackHandler extends Handler {
-        private static final int MSG_ON_PROPERTY_EVENT = 1;
-        private static final int MSG_ON_SET_ERROR = 2;
-
-        private final WeakReference<HalClientCallback> mCallback;
-
-        CallbackHandler(Looper looper, HalClientCallback callback) {
-            super(looper);
-            mCallback = new WeakReference<HalClientCallback>(callback);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            HalClientCallback callback = mCallback.get();
-            if (callback == null) {
-                Slogf.i(TAG, "handleMessage null callback");
-                return;
-            }
-
-            switch (msg.what) {
-                case MSG_ON_PROPERTY_EVENT:
-                    callback.onPropertyEvent((ArrayList<HalPropValue>) msg.obj);
-                    break;
-                case MSG_ON_SET_ERROR:
-                    callback.onPropertySetError((ArrayList<VehiclePropError>) msg.obj);
-                    break;
-                default:
-                    Slogf.e(TAG, "Unexpected message: %d", msg.what);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    static final class VehicleCallback implements HalClientCallback {
-        private final Handler mHandler;
-
-        VehicleCallback(Handler handler) {
-            mHandler = handler;
-        }
-
-        @Override
-        public void onPropertyEvent(ArrayList<HalPropValue> propValues) {
-            mHandler.sendMessage(Message.obtain(
-                    mHandler, CallbackHandler.MSG_ON_PROPERTY_EVENT, propValues));
-        }
-
-        @Override
-        public void onPropertySetError(ArrayList<VehiclePropError> errors) {
-            mHandler.sendMessage(Message.obtain(
-                        mHandler, CallbackHandler.MSG_ON_SET_ERROR, errors));
-        }
-    }
-
-    /**
-     * Query a list of {@link HalPropValue} with a list of
-     * {@link VehicleStub.AsyncGetSetRequest} asynchronously.
-     */
-    public void getValuesAsync(
-            List<VehicleStub.AsyncGetSetRequest> getVehicleStubAsyncRequests,
-            VehicleStub.VehicleStubCallbackInterface getVehicleStubAsyncCallback) {
-        mVehicle.getAsync(getVehicleStubAsyncRequests, getVehicleStubAsyncCallback);
-    }
-
-    /**
-     * Cancel all the on-going async requests with the given request IDs.
-     */
-    public void cancelRequests(List<Integer> vehicleStubRequestIds) {
-        mVehicle.cancelRequests(vehicleStubRequestIds);
-    }
-}
diff --git a/service/src/com/android/car/hal/PropertyHalService.java b/service/src/com/android/car/hal/PropertyHalService.java
index d3a0d83..da70d39 100644
--- a/service/src/com/android/car/hal/PropertyHalService.java
+++ b/service/src/com/android/car/hal/PropertyHalService.java
@@ -122,7 +122,7 @@
     // The request ID passed by CarPropertyService (ManagerRequestId) is directly passed from
     // CarPropertyManager. Multiple CarPropertyManagers use the same car service instance, thus,
     // the ManagerRequestId is not unique. We have to create another unique ID called
-    // ServiceRequestId and pass it to underlying layer (VehicleHal, HalClient and VehicleStub).
+    // ServiceRequestId and pass it to underlying layer (VehicleHal and VehicleStub).
     // Internally, we will map ManagerRequestId to ServiceRequestId.
     private final AtomicInteger mServiceRequestIdCounter = new AtomicInteger(0);
     // Only contains property ID if value is different for the CarPropertyManager and the HAL.
diff --git a/service/src/com/android/car/hal/PropertyHalServiceIds.java b/service/src/com/android/car/hal/PropertyHalServiceIds.java
index 61aab6c..b2091c4 100644
--- a/service/src/com/android/car/hal/PropertyHalServiceIds.java
+++ b/service/src/com/android/car/hal/PropertyHalServiceIds.java
@@ -180,6 +180,9 @@
         mHalPropIdToPermissions.put(VehicleProperty.DOOR_LOCK, new Pair<>(
                 Car.PERMISSION_CONTROL_CAR_DOORS,
                 Car.PERMISSION_CONTROL_CAR_DOORS));
+        mHalPropIdToPermissions.put(VehicleProperty.DOOR_CHILD_LOCK_ENABLED, new Pair<>(
+                Car.PERMISSION_CONTROL_CAR_DOORS,
+                Car.PERMISSION_CONTROL_CAR_DOORS));
         mHalPropIdToPermissions.put(VehicleProperty.MIRROR_Z_POS, new Pair<>(
                 Car.PERMISSION_CONTROL_CAR_MIRRORS,
                 Car.PERMISSION_CONTROL_CAR_MIRRORS));
@@ -291,6 +294,12 @@
         mHalPropIdToPermissions.put(VehicleProperty.WINDOW_LOCK, new Pair<>(
                 Car.PERMISSION_CONTROL_CAR_WINDOWS,
                 Car.PERMISSION_CONTROL_CAR_WINDOWS));
+        mHalPropIdToPermissions.put(VehicleProperty.STEERING_WHEEL_DEPTH_POS, new Pair<>(
+                Car.PERMISSION_CONTROL_STEERING_WHEEL,
+                Car.PERMISSION_CONTROL_STEERING_WHEEL));
+        mHalPropIdToPermissions.put(VehicleProperty.STEERING_WHEEL_DEPTH_MOVE, new Pair<>(
+                Car.PERMISSION_CONTROL_STEERING_WHEEL,
+                Car.PERMISSION_CONTROL_STEERING_WHEEL));
 
         // HVAC properties
         mHalPropIdToPermissions.put(VehicleProperty.HVAC_FAN_SPEED, new Pair<>(
@@ -554,9 +563,6 @@
         mHalPropIdToPermissions.put(VehicleProperty.ANDROID_EPOCH_TIME, new Pair<>(
                 null,
                 Car.PERMISSION_CAR_EPOCH_TIME));
-        mHalPropIdToPermissions.put(VehicleProperty.STORAGE_ENCRYPTION_BINDING_SEED, new Pair<>(
-                Car.PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED,
-                Car.PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED));
         // Display_Units
         mHalPropIdToPermissions.put(VehicleProperty.DISTANCE_DISPLAY_UNITS, new Pair<>(
                 Car.PERMISSION_READ_DISPLAY_UNITS,
diff --git a/service/src/com/android/car/hal/UserHalService.java b/service/src/com/android/car/hal/UserHalService.java
index 7976acc..ad0730a 100644
--- a/service/src/com/android/car/hal/UserHalService.java
+++ b/service/src/com/android/car/hal/UserHalService.java
@@ -1172,7 +1172,7 @@
             if (numberPendingCallbacks == 0) {
                 writer.println("no pending callbacks");
             } else {
-                writer.printf("%d pending callbacks: %s\n", numberPendingCallbacks);
+                writer.printf("%d pending callbacks:\n", numberPendingCallbacks);
                 for (int i = 0; i < numberPendingCallbacks; i++) {
                     writer.print(indent);
                     mPendingRequests.valueAt(i).dump(writer);
diff --git a/service/src/com/android/car/hal/VehicleHal.java b/service/src/com/android/car/hal/VehicleHal.java
index 34304f8..9f52806 100644
--- a/service/src/com/android/car/hal/VehicleHal.java
+++ b/service/src/com/android/car/hal/VehicleHal.java
@@ -16,16 +16,17 @@
 
 package com.android.car.hal;
 
+import static android.os.SystemClock.uptimeMillis;
+
 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE;
 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
 
-import static java.lang.Integer.toHexString;
-
 import android.annotation.CheckResult;
 import android.annotation.Nullable;
 import android.car.VehiclePropertyIds;
 import android.car.builtin.util.Slogf;
 import android.content.Context;
+import android.hardware.automotive.vehicle.StatusCode;
 import android.hardware.automotive.vehicle.SubscribeOptions;
 import android.hardware.automotive.vehicle.VehiclePropError;
 import android.hardware.automotive.vehicle.VehicleProperty;
@@ -47,6 +48,7 @@
 import com.android.car.CarServiceUtils;
 import com.android.car.CarSystemService;
 import com.android.car.VehicleStub;
+import com.android.car.VehicleStub.SubscriptionClient;
 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
 import com.android.car.internal.util.IndentingPrintWriter;
 import com.android.car.internal.util.Lists;
@@ -54,7 +56,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -71,7 +72,7 @@
  * implementation. It is the responsibility of {@link HalServiceBase} to convert data to
  * corresponding Car*Service for Car*Manager API.
  */
-public class VehicleHal implements HalClientCallback, CarSystemService {
+public class VehicleHal implements VehicleHalCallback, CarSystemService {
 
     private static final boolean DBG = false;
 
@@ -84,8 +85,18 @@
     public static final int NO_AREA = -1;
     public static final float NO_SAMPLE_RATE = -1;
 
+    /**
+     * If call to vehicle HAL returns StatusCode.TRY_AGAIN, we will retry to invoke that method
+     * again for this amount of milliseconds.
+     */
+    private static final int MAX_DURATION_FOR_RETRIABLE_RESULT_MS = 2000;
+
+    private static final int SLEEP_BETWEEN_RETRIABLE_INVOKES_MS = 100;
+
     private final HandlerThread mHandlerThread;
     private final Handler mHandler;
+    private final SubscriptionClient mSubscriptionClient;
+
     private final PowerHalService mPowerHal;
     private final PropertyHalService mPropertyHal;
     private final InputHalService mInputHal;
@@ -100,8 +111,10 @@
 
     private final Object mLock = new Object();
 
-    /** Might be re-assigned if Vehicle HAL is reconnected. */
-    private volatile HalClient mHalClient;
+    // Only changed for test.
+    private int mMaxDurationForRetryMs = MAX_DURATION_FOR_RETRIABLE_RESULT_MS;
+    // Only changed for test.
+    private int mSleepBetweenRetryMs = SLEEP_BETWEEN_RETRIABLE_INVOKES_MS;
 
     /** Stores handler for each HAL property. Property events are sent to handler. */
     @GuardedBy("mLock")
@@ -128,13 +141,13 @@
         this(context, /* powerHal= */ null, /* propertyHal= */ null,
                 /* inputHal= */ null, /* vmsHal= */ null, /* userHal= */ null,
                 /* diagnosticHal= */ null, /* clusterHalService= */ null,
-                /* timeHalService= */ null, /* halClient= */ null,
+                /* timeHalService= */ null,
                 CarServiceUtils.getHandlerThread(VehicleHal.class.getSimpleName()), vehicle);
     }
 
     /**
-     * Constructs a new {@link VehicleHal} object given the services and {@link HalClient} factory
-     * function passed as parameters. This method must be used by tests only.
+     * Constructs a new {@link VehicleHal} object given the services passed as parameters.
+     * This method must be used by tests only.
      */
     @VisibleForTesting
     VehicleHal(Context context,
@@ -146,7 +159,6 @@
             DiagnosticHalService diagnosticHal,
             ClusterHalService clusterHalService,
             TimeHalService timeHalService,
-            HalClient halClient,
             HandlerThread handlerThread,
             VehicleStub vehicle) {
         // Must be initialized before HalService so that HalService could use this.
@@ -173,13 +185,21 @@
                 mClusterHalService,
                 mEvsHal,
                 mTimeHalService,
+                // mPropertyHal must be the last so that on init/release it can be used for all
+                // other HAL services properties.
                 mPropertyHal);
-        // mPropertyHal must be the last so that on init/release
-        // it can be used for all other HAL services properties.
-        mHalClient = halClient != null
-                ? halClient : new HalClient(vehicle, mHandlerThread.getLooper(),
-                /* callback= */ this);
         mVehicleStub = vehicle;
+        mSubscriptionClient = vehicle.newSubscriptionClient(this);
+    }
+
+    @VisibleForTesting
+    void setMaxDurationForRetryMs(int maxDurationForRetryMs) {
+        mMaxDurationForRetryMs = maxDurationForRetryMs;
+    }
+
+    @VisibleForTesting
+    void setSleepBetweenRetryMs(int sleepBetweenRetryMs) {
+        mSleepBetweenRetryMs = sleepBetweenRetryMs;
     }
 
     private void fetchAllPropConfigs() {
@@ -191,7 +211,7 @@
         }
         HalPropConfig[] configs;
         try {
-            configs = mHalClient.getAllPropConfigs();
+            configs = mVehicleStub.getAllPropConfigs();
             if (configs == null || configs.length == 0) {
                 Slogf.e(CarLog.TAG_HAL, "getAllPropConfigs returned empty configs");
                 return;
@@ -204,14 +224,113 @@
             // Create map of all properties
             for (HalPropConfig p : configs) {
                 if (DBG) {
-                    Slogf.i(CarLog.TAG_HAL, "Add config for prop:"
-                            + Integer.toHexString(p.getPropId()) + " config:" + p.toString());
+                    Slogf.i(CarLog.TAG_HAL, "Add config for prop: 0x%x config: %s", p.getPropId(),
+                            p.toString());
                 }
                 mAllProperties.put(p.getPropId(), p);
             }
         }
     }
 
+    private void handleOnPropertyEvent(List<HalPropValue> propValues) {
+        synchronized (mLock) {
+            for (int i = 0; i < propValues.size(); i++) {
+                HalPropValue v = propValues.get(i);
+                int propId = v.getPropId();
+                HalServiceBase service = mPropertyHandlers.get(propId);
+                if (service == null) {
+                    Slogf.e(CarLog.TAG_HAL,
+                            "handleOnPropertyEvent: HalService not found for prop: 0x%x", propId);
+                    continue;
+                }
+                service.getDispatchList().add(v);
+                mServicesToDispatch.add(service);
+                VehiclePropertyEventInfo info = mEventLog.get(propId);
+                if (info == null) {
+                    info = new VehiclePropertyEventInfo(v);
+                    mEventLog.put(propId, info);
+                } else {
+                    info.addNewEvent(v);
+                }
+            }
+        }
+        for (HalServiceBase s : mServicesToDispatch) {
+            s.onHalEvents(s.getDispatchList());
+            s.getDispatchList().clear();
+        }
+        mServicesToDispatch.clear();
+    }
+
+    private void handleOnPropertySetError(List<VehiclePropError> errors) {
+        SparseArray<ArrayList<VehiclePropError>> errorsByPropId =
+                new SparseArray<ArrayList<VehiclePropError>>();
+        for (int i = 0; i < errors.size(); i++) {
+            VehiclePropError error = errors.get(i);
+            int errorCode = error.errorCode;
+            int propId = error.propId;
+            int areaId = error.areaId;
+            Slogf.w(CarLog.TAG_HAL, "onPropertySetError, errorCode: %d, prop: 0x%x, area: 0x%x",
+                    errorCode, propId, areaId);
+            if (propId == VehicleProperty.INVALID) {
+                continue;
+            }
+
+            ArrayList<VehiclePropError> propErrors;
+            if (errorsByPropId.get(propId) == null) {
+                propErrors = new ArrayList<VehiclePropError>();
+                errorsByPropId.put(propId, propErrors);
+            } else {
+                propErrors = errorsByPropId.get(propId);
+            }
+            propErrors.add(error);
+        }
+
+        for (int i = 0; i < errorsByPropId.size(); i++) {
+            int propId = errorsByPropId.keyAt(i);
+            HalServiceBase service;
+            synchronized (mLock) {
+                service = mPropertyHandlers.get(propId);
+            }
+            if (service == null) {
+                Slogf.e(CarLog.TAG_HAL,
+                        "handleOnPropertySetError: HalService not found for prop: 0x%x", propId);
+                continue;
+            }
+
+            ArrayList<VehiclePropError> propErrors = errorsByPropId.get(propId);
+            service.onPropertySetError(propErrors);
+        }
+    }
+
+    private static String errorMessage(String action, HalPropValue propValue, String errorMsg) {
+        return String.format("Failed to %s value for: 0x%x, areaId: 0x%x, error: %s", action,
+                propValue.getPropId(), propValue.getAreaId(), errorMsg);
+    }
+
+    private HalPropValue getValueWithRetry(HalPropValue value) {
+        return getValueWithRetry(value, /* maxRetries= */ 0);
+    }
+
+    private HalPropValue getValueWithRetry(HalPropValue value, int maxRetries) {
+        HalPropValue result = invokeRetriable((requestValue) -> {
+            return mVehicleStub.get(requestValue);
+        }, "get", value, mMaxDurationForRetryMs, mSleepBetweenRetryMs, maxRetries);
+
+        if (result == null) {
+            // If VHAL returns null result, but the status is OKAY. We treat that as NOT_AVAILABLE.
+            throw new ServiceSpecificException(StatusCode.NOT_AVAILABLE,
+                    errorMessage("get", value, "VHAL returns null for property value"));
+        }
+        return result;
+    }
+
+    private void setValueWithRetry(HalPropValue value)  {
+        invokeRetriable((requestValue) -> {
+            mVehicleStub.set(requestValue);
+            return null;
+        }, "set", value, mMaxDurationForRetryMs, mSleepBetweenRetryMs, /* maxRetries= */ 0);
+    }
+
     /**
      * Inits the vhal configurations.
      *
@@ -281,7 +400,7 @@
         }
         for (int i = 0; i < subscribedProperties.size(); i++) {
             try {
-                mHalClient.unsubscribe(subscribedProperties.get(i));
+                mSubscriptionClient.unsubscribe(subscribedProperties.get(i));
             } catch (RemoteException | ServiceSpecificException e) {
                 //  Ignore exceptions on shutdown path.
                 Slogf.w(CarLog.TAG_HAL, "Failed to unsubscribe", e);
@@ -333,8 +452,8 @@
     @GuardedBy("mLock")
     private void assertServiceOwnerLocked(HalServiceBase service, int property) {
         if (service != mPropertyHandlers.get(property)) {
-            throw new IllegalArgumentException("Property 0x" + toHexString(property)
-                    + " is not owned by service: " + service);
+            throw new IllegalArgumentException(String.format(
+                    "Property 0x%x  is not owned by service: %s", property, service));
         }
     }
 
@@ -369,8 +488,8 @@
         }
 
         if (config == null) {
-            throw new IllegalArgumentException("subscribe error: config is null for property 0x"
-                    + toHexString(property));
+            throw new IllegalArgumentException(
+                    String.format("subscribe error: config is null for property 0x%x", property));
         } else if (isPropertySubscribable(config)) {
             SubscribeOptions opts = new SubscribeOptions();
             opts.propId = property;
@@ -381,7 +500,7 @@
                 mSubscribedProperties.put(property, opts);
             }
             try {
-                mHalClient.subscribe(opts);
+                mSubscriptionClient.subscribe(new SubscribeOptions[]{opts});
             } catch (RemoteException | ServiceSpecificException e) {
                 Slogf.w(CarLog.TAG_HAL, "Failed to subscribe to " + toCarPropertyLog(property),
                         e);
@@ -414,7 +533,7 @@
                 mSubscribedProperties.remove(property);
             }
             try {
-                mHalClient.unsubscribe(property);
+                mSubscriptionClient.unsubscribe(property);
             } catch (RemoteException | ServiceSpecificException e) {
                 Slogf.w(CarLog.TAG_SERVICE, "Failed to unsubscribe: "
                         + toCarPropertyLog(property), e);
@@ -437,30 +556,23 @@
      * Gets given property with retries.
      *
      * <p>If getting the property fails after all retries, it will throw
-     * {@code IllegalStateException}. If the property does not exist, it will simply return
+     * {@code IllegalStateException}. If the property is not supported, it will simply return
      * {@code null}.
      */
     @Nullable
-    public HalPropValue getIfAvailableOrFail(int propertyId, int numberOfRetries) {
+    public HalPropValue getIfSupportedOrFail(int propertyId, int maxRetries) {
         if (!isPropertySupported(propertyId)) {
             return null;
         }
-        Exception lastException = null;
-        for (int i = 0; i < numberOfRetries; i++) {
-            try {
-                return get(propertyId);
-            } catch (Exception e) {
-                Slogf.w(CarLog.TAG_HAL, "Cannot get " + toCarPropertyLog(propertyId), e);
-                lastException = e;
-            }
+        try {
+            return getValueWithRetry(mPropValueBuilder.build(propertyId, NO_AREA), maxRetries);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
         }
-        throw new IllegalStateException("Cannot get property: 0x" + toHexString(propertyId)
-                + " after " + numberOfRetries + " retries" + ", last exception: "
-                + lastException);
     }
 
     /**
-     * This works similar to {@link #getIfAvailableOrFail(int, int)} except that this can be called
+     * This works similar to {@link #getIfSupportedOrFail(int, int)} except that this can be called
      * before {@code init()} is called.
      *
      * <p>This call will check if requested vhal property is supported by querying directly to vhal
@@ -468,10 +580,9 @@
      * {@code ICarImpl.init()} phase.
      */
     @Nullable
-    public HalPropValue getIfAvailableOrFailForEarlyStage(int propertyId,
-            int numberOfRetries) {
+    public HalPropValue getIfSupportedOrFailForEarlyStage(int propertyId, int maxRetries) {
         fetchAllPropConfigs();
-        return getIfAvailableOrFail(propertyId, numberOfRetries);
+        return getIfSupportedOrFail(propertyId, maxRetries);
     }
 
     /**
@@ -499,7 +610,7 @@
             Slogf.i(CarLog.TAG_HAL, "get, " + toCarPropertyLog(propertyId)
                     + toCarAreaLog(areaId));
         }
-        return mHalClient.getValue(mPropValueBuilder.build(propertyId, areaId));
+        return getValueWithRetry(mPropValueBuilder.build(propertyId, areaId));
     }
 
     /**
@@ -537,7 +648,7 @@
     public <T> T get(Class clazz, HalPropValue requestedPropValue)
             throws IllegalArgumentException, ServiceSpecificException {
         HalPropValue propValue;
-        propValue = mHalClient.getValue(requestedPropValue);
+        propValue = getValueWithRetry(requestedPropValue);
 
         if (clazz == Long.class || clazz == long.class) {
             Long value = propValue.getInt64Value(0);
@@ -611,7 +722,7 @@
      */
     public HalPropValue get(HalPropValue requestedPropValue)
             throws IllegalArgumentException, ServiceSpecificException {
-        return mHalClient.getValue(requestedPropValue);
+        return getValueWithRetry(requestedPropValue);
     }
 
     /**
@@ -640,7 +751,7 @@
      */
     public void set(HalPropValue propValue)
             throws IllegalArgumentException, ServiceSpecificException {
-        mHalClient.setValue(propValue);
+        setValueWithRetry(propValue);
     }
 
     @CheckResult
@@ -650,7 +761,7 @@
 
     @CheckResult
     HalPropValueSetter set(int propId, int areaId) {
-        return new HalPropValueSetter(mHalClient, propId, areaId);
+        return new HalPropValueSetter(propId, areaId);
     }
 
     static boolean isPropertySubscribable(HalPropConfig config) {
@@ -679,80 +790,14 @@
 
     private final ArraySet<HalServiceBase> mServicesToDispatch = new ArraySet<>();
 
-    // should be posted to the mHandlerThread
     @Override
     public void onPropertyEvent(ArrayList<HalPropValue> propValues) {
-        synchronized (mLock) {
-            for (int i = 0; i < propValues.size(); i++) {
-                HalPropValue v = propValues.get(i);
-                int propId = v.getPropId();
-                HalServiceBase service = mPropertyHandlers.get(propId);
-                if (service == null) {
-                    Slogf.e(CarLog.TAG_HAL, "HalService not found for prop: 0x"
-                            + toHexString(propId));
-                    continue;
-                }
-                service.getDispatchList().add(v);
-                mServicesToDispatch.add(service);
-                VehiclePropertyEventInfo info = mEventLog.get(propId);
-                if (info == null) {
-                    info = new VehiclePropertyEventInfo(v);
-                    mEventLog.put(propId, info);
-                } else {
-                    info.addNewEvent(v);
-                }
-            }
-        }
-        for (HalServiceBase s : mServicesToDispatch) {
-            s.onHalEvents(s.getDispatchList());
-            s.getDispatchList().clear();
-        }
-        mServicesToDispatch.clear();
+        mHandler.post(() -> handleOnPropertyEvent(propValues));
     }
 
-    // should be posted to the mHandlerThread
     @Override
     public void onPropertySetError(ArrayList<VehiclePropError> errors) {
-        SparseArray<ArrayList<VehiclePropError>> errorsByPropId =
-                new SparseArray<ArrayList<VehiclePropError>>();
-        for (int i = 0; i < errors.size(); i++) {
-            VehiclePropError error = errors.get(i);
-            int errorCode = error.errorCode;
-            int propId = error.propId;
-            int areaId = error.areaId;
-            Slogf.w(
-                    CarLog.TAG_HAL,
-                    "onPropertySetError, errorCode: %d, prop: 0x%x, area: 0x%x",
-                    errorCode,
-                    propId,
-                    areaId);
-            if (propId == VehicleProperty.INVALID) {
-                continue;
-            }
-
-            ArrayList<VehiclePropError> propErrors;
-            if (errorsByPropId.get(propId) == null) {
-                propErrors = new ArrayList<VehiclePropError>();
-                errorsByPropId.put(propId, propErrors);
-            } else {
-                propErrors = errorsByPropId.get(propId);
-            }
-            propErrors.add(error);
-        }
-
-        for (int i = 0; i < errorsByPropId.size(); i++) {
-            int propId = errorsByPropId.keyAt(i);
-            HalServiceBase service;
-            synchronized (mLock) {
-                service = mPropertyHandlers.get(propId);
-            }
-            if (service == null) {
-                continue;
-            }
-
-            ArrayList<VehiclePropError> propErrors = errorsByPropId.get(propId);
-            service.onPropertySetError(propErrors);
-        }
+        mHandler.post(() -> handleOnPropertySetError(errors));
     }
 
     @Override
@@ -977,7 +1022,7 @@
         if (v == null) {
             return;
         }
-        mHandler.post(() -> onPropertyEvent(Lists.newArrayList(v)));
+        mHandler.post(() -> handleOnPropertyEvent(Lists.newArrayList(v)));
     }
 
     /**
@@ -1017,7 +1062,7 @@
                             + TimeUnit.SECONDS.toNanos(timeDurationInSec);
                     HalPropValue v = createPropValueForInjecting(mPropValueBuilder, property, zone,
                             new ArrayList<>(Arrays.asList(value.split(DATA_DELIMITER))), timestamp);
-                    mHandler.post(() -> onPropertyEvent(Lists.newArrayList(v)));
+                    mHandler.post(() -> handleOnPropertyEvent(Lists.newArrayList(v)));
                 }
             }
         }, /* delay= */0, period);
@@ -1080,12 +1125,10 @@
     }
 
     final class HalPropValueSetter {
-        final WeakReference<HalClient> mClient;
         final int mPropId;
         final int mAreaId;
 
-        private HalPropValueSetter(HalClient client, int propId, int areaId) {
-            mClient = new WeakReference<>(client);
+        private HalPropValueSetter(int propId, int areaId) {
             mPropId = propId;
             mAreaId = areaId;
         }
@@ -1142,14 +1185,11 @@
 
         void submit(HalPropValue propValue)
                 throws IllegalArgumentException, ServiceSpecificException {
-            HalClient client = mClient.get();
-            if (client != null) {
-                if (DBG) {
-                    Slogf.i(CarLog.TAG_HAL, "set, " + toCarPropertyLog(mPropId)
-                            + toCarAreaLog(mAreaId));
-                }
-                client.setValue(propValue);
+            if (DBG) {
+                Slogf.i(CarLog.TAG_HAL, "set, " + toCarPropertyLog(mPropId)
+                        + toCarAreaLog(mAreaId));
             }
+            setValueWithRetry(propValue);
         }
     }
 
@@ -1181,6 +1221,98 @@
         return String.format("areaId: %d // 0x%x", areaId, areaId);
     }
 
+    interface RetriableAction {
+        @Nullable HalPropValue run(HalPropValue requestValue)
+                throws ServiceSpecificException, RemoteException;
+    }
+
+    private static HalPropValue invokeRetriable(RetriableAction action,
+            String operation, HalPropValue requestValue, long maxDurationForRetryMs,
+            long sleepBetweenRetryMs, int maxRetries)
+            throws ServiceSpecificException, IllegalArgumentException {
+        Retrier retrier = new Retrier(action, operation, requestValue, maxDurationForRetryMs,
+                sleepBetweenRetryMs, maxRetries);
+        return retrier.invokeAction();
+    }
+
+    private static final class Retrier {
+        private final RetriableAction mAction;
+        private final String mOperation;
+        private final HalPropValue mRequestValue;
+        private final long mMaxDurationForRetryMs;
+        private final long mSleepBetweenRetryMs;
+        private final int mMaxRetries;
+        private final long mStartTime;
+        private int mRetryCount = 0;
+
+        Retrier(RetriableAction action,
+                String operation, HalPropValue requestValue, long maxDurationForRetryMs,
+                long sleepBetweenRetryMs, int maxRetries) {
+            mAction = action;
+            mOperation = operation;
+            mRequestValue = requestValue;
+            mMaxDurationForRetryMs = maxDurationForRetryMs;
+            mSleepBetweenRetryMs = sleepBetweenRetryMs;
+            mMaxRetries = maxRetries;
+            mStartTime = uptimeMillis();
+        }
+
+        HalPropValue invokeAction()
+                throws ServiceSpecificException, IllegalArgumentException {
+            mRetryCount++;
+
+            try {
+                return mAction.run(mRequestValue);
+            } catch (ServiceSpecificException e) {
+                switch (e.errorCode) {
+                    case StatusCode.INVALID_ARG:
+                        throw new IllegalArgumentException(errorMessage(mOperation, mRequestValue,
+                            e.toString()));
+                    case StatusCode.TRY_AGAIN:
+                        return sleepAndTryAgain(e);
+                    default:
+                        throw e;
+                }
+            } catch (RemoteException e) {
+                return sleepAndTryAgain(e);
+            }
+        }
+
+        private HalPropValue sleepAndTryAgain(Exception e)
+                throws ServiceSpecificException, IllegalArgumentException {
+            Slogf.d(CarLog.TAG_HAL, "trying the request: "
+                    + toCarPropertyLog(mRequestValue.getPropId()) + ", "
+                    + toCarAreaLog(mRequestValue.getAreaId()) + " again...");
+            try {
+                Thread.sleep(mSleepBetweenRetryMs);
+            } catch (InterruptedException interruptedException) {
+                Thread.currentThread().interrupt();
+                Slogf.w(CarLog.TAG_HAL, "Thread was interrupted while waiting for vehicle HAL.",
+                        interruptedException);
+                throw new ServiceSpecificException(StatusCode.INTERNAL_ERROR,
+                        errorMessage(mOperation, mRequestValue, interruptedException.toString()));
+            }
+
+            if (mMaxRetries != 0) {
+                // If mMaxRetries is specified, check the retry count.
+                if (mMaxRetries == mRetryCount) {
+                    throw new ServiceSpecificException(StatusCode.TRY_AGAIN,
+                            errorMessage(mOperation, mRequestValue,
+                                    "cannot get property after " + mRetryCount + " retires, "
+                                    + "last exception: " + e));
+                }
+            } else if ((uptimeMillis() - mStartTime) >= mMaxDurationForRetryMs) {
+                // Otherwise, check whether we have reached timeout.
+                throw new ServiceSpecificException(StatusCode.TRY_AGAIN,
+                        errorMessage(mOperation, mRequestValue,
+                                "cannot get property within " + mMaxDurationForRetryMs
+                                + "ms, last exception: " + e));
+            }
+            return invokeAction();
+        }
+    }
+
+
     /**
      * Query HalPropValue with list of GetVehicleHalRequest objects.
      *
@@ -1188,13 +1320,13 @@
      */
     public void getAsync(List<VehicleStub.AsyncGetSetRequest> getVehicleStubAsyncRequests,
             VehicleStub.VehicleStubCallbackInterface getVehicleStubAsyncCallback) {
-        mHalClient.getValuesAsync(getVehicleStubAsyncRequests, getVehicleStubAsyncCallback);
+        mVehicleStub.getAsync(getVehicleStubAsyncRequests, getVehicleStubAsyncCallback);
     }
 
     /**
      * Cancel all the on-going async requests with the given request IDs.
      */
     public void cancelRequests(List<Integer> vehicleStubRequestIds) {
-        mHalClient.cancelRequests(vehicleStubRequestIds);
+        mVehicleStub.cancelRequests(vehicleStubRequestIds);
     }
 }
diff --git a/service/src/com/android/car/hal/HalClientCallback.java b/service/src/com/android/car/hal/VehicleHalCallback.java
similarity index 89%
rename from service/src/com/android/car/hal/HalClientCallback.java
rename to service/src/com/android/car/hal/VehicleHalCallback.java
index 6950a4f..15ef6b7 100644
--- a/service/src/com/android/car/hal/HalClientCallback.java
+++ b/service/src/com/android/car/hal/VehicleHalCallback.java
@@ -21,9 +21,9 @@
 import java.util.ArrayList;
 
 /**
- * HalClientCallback is the callback functions that HalClient supports.
+ * VehicleHalCallback is the callback functions that VehicleHal supports.
  */
-public interface HalClientCallback {
+public interface VehicleHalCallback {
     /**
      * Called when new property events happen.
      */
diff --git a/service/src/com/android/car/hal/fakevhal/FakeVehicleStub.java b/service/src/com/android/car/hal/fakevhal/FakeVehicleStub.java
index 4bd42ac..238ab9f 100644
--- a/service/src/com/android/car/hal/fakevhal/FakeVehicleStub.java
+++ b/service/src/com/android/car/hal/fakevhal/FakeVehicleStub.java
@@ -44,10 +44,10 @@
 import com.android.car.VehicleStub;
 import com.android.car.hal.AidlHalPropConfig;
 import com.android.car.hal.HalAreaConfig;
-import com.android.car.hal.HalClientCallback;
 import com.android.car.hal.HalPropConfig;
 import com.android.car.hal.HalPropValue;
 import com.android.car.hal.HalPropValueBuilder;
+import com.android.car.hal.VehicleHalCallback;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -265,7 +265,7 @@
      * @return a {@code SubscriptionClient} that could be used to subscribe/unsubscribe.
      */
     @Override
-    public SubscriptionClient newSubscriptionClient(HalClientCallback callback) {
+    public SubscriptionClient newSubscriptionClient(VehicleHalCallback callback) {
         return new FakeVhalSubscriptionClient(callback,
                 mRealVehicle.newSubscriptionClient(callback));
     }
@@ -395,10 +395,10 @@
     }
 
     private final class FakeVhalSubscriptionClient implements SubscriptionClient {
-        private final HalClientCallback mCallBack;
+        private final VehicleHalCallback mCallBack;
         private final SubscriptionClient mRealClient;
 
-        FakeVhalSubscriptionClient(HalClientCallback callback,
+        FakeVhalSubscriptionClient(VehicleHalCallback callback,
                 SubscriptionClient realVehicleClient) {
             mCallBack = callback;
             mRealClient = realVehicleClient;
diff --git a/service/src/com/android/car/oem/CarOemAudioFocusProxyService.java b/service/src/com/android/car/oem/CarOemAudioFocusProxyService.java
index 87c632a..7c37283 100644
--- a/service/src/com/android/car/oem/CarOemAudioFocusProxyService.java
+++ b/service/src/com/android/car/oem/CarOemAudioFocusProxyService.java
@@ -50,12 +50,12 @@
     /**
      * Updates audio focus changes.
      */
-    public void audioFocusChanged(List<AudioFocusInfo> currentFocusHolders,
+    public void notifyAudioFocusChange(List<AudioFocusInfo> currentFocusHolders,
             List<AudioFocusInfo> currentFocusLosers, int zoneId) {
         mHelper.doBinderOneWayCall(CALLER_TAG, () -> {
             try {
                 mOemCarAudioFocusService
-                        .audioFocusChanged(currentFocusHolders, currentFocusLosers, zoneId);
+                        .notifyAudioFocusChange(currentFocusHolders, currentFocusLosers, zoneId);
             } catch (RemoteException e) {
                 Slogf.e(TAG, e,
                         "audioFocusChanged call received RemoteException- currentFocusHolders:%s, "
diff --git a/service/src/com/android/car/oem/CarOemProxyService.java b/service/src/com/android/car/oem/CarOemProxyService.java
index 8e339c4..380270d 100644
--- a/service/src/com/android/car/oem/CarOemProxyService.java
+++ b/service/src/com/android/car/oem/CarOemProxyService.java
@@ -46,9 +46,12 @@
 import com.android.car.R;
 import com.android.car.internal.util.IndentingPrintWriter;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Manages access to OemCarService.
@@ -67,7 +70,7 @@
     private static final boolean DBG = Slogf.isLoggable(TAG, Log.DEBUG);
     // mock component name for testing if system property is set.
     private static final String PROPERTY_EMULATED_OEM_CAR_SERVICE =
-            "com.android.car.internal.debug.oem_car_service";
+            "persist.com.android.car.internal.debug.oem_car_service";
 
     private final int mOemServiceConnectionTimeoutMs;
     private final int mOemServiceReadyTimeoutMs;
@@ -78,6 +81,9 @@
     private final CarOemProxyServiceHelper mHelper;
     private final HandlerThread mHandlerThread;
     private final Handler mHandler;
+    @GuardedBy("mLock")
+    private final ArrayList<CarOemProxyServiceCallback> mCallbacks = new ArrayList<>();
+
 
     private String mComponentName;
 
@@ -127,7 +133,17 @@
 
     private final IOemCarServiceCallback mOemCarServiceCallback = new IOemCarServiceCallbackImpl();
 
+    @VisibleForTesting
     public CarOemProxyService(Context context) {
+        this(context, null);
+    }
+
+    @VisibleForTesting
+    public CarOemProxyService(Context context, CarOemProxyServiceHelper helper) {
+        this(context, helper, null);
+    }
+
+    public CarOemProxyService(Context context, CarOemProxyServiceHelper helper, Handler handler) {
         // Bind to the OemCarService
         mContext = context;
         Resources res = mContext.getResources();
@@ -172,7 +188,7 @@
 
         Slogf.i(TAG, "Binding to Oem Service with intent: %s", intent);
         mHandlerThread = CarServiceUtils.getHandlerThread("car_oem_service");
-        mHandler = new Handler(mHandlerThread.getLooper());
+        mHandler = handler == null ? new Handler(mHandlerThread.getLooper()) : handler;
 
         mIsOemServiceBound = mContext.bindServiceAsUser(intent, mCarOemServiceConnection,
                 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM);
@@ -185,7 +201,7 @@
             Slogf.e(TAG,
                     "Couldn't bound to OemCarService. Oem service feature is marked disabled.");
         }
-        mHelper = new CarOemProxyServiceHelper(mContext);
+        mHelper = helper ==  null ? new CarOemProxyServiceHelper(mContext) : helper;
     }
 
     private boolean isInvalidComponentName(Context context, String componentName) {
@@ -227,6 +243,36 @@
         return false;
     }
 
+    /**
+     * Registers callback to be called once OEM service is ready.
+     *
+     * <p>Other CarService components cannot call OEM service. But they can register a callback
+     * which would be called as soon as OEM Service is ready./
+     */
+    public void registerCallback(CarOemProxyServiceCallback callback) {
+        synchronized (mLock) {
+            mCallbacks.add(callback);
+        }
+    }
+
+    /**
+     * Informs if OEM service is enabled.
+     */
+    public boolean isOemServiceEnabled() {
+        synchronized (mLock) {
+            return mIsFeatureEnabled;
+        }
+    }
+
+    /**
+     * Informs if OEM service is ready.
+     */
+    public boolean isOemServiceReady() {
+        synchronized (mLock) {
+            return mIsOemServiceReady;
+        }
+    }
+
     @Override
     public void init() {
         // Nothing to be done as OemCarService was initialized in the constructor.
@@ -255,6 +301,17 @@
                     mOemServiceConnectionTimeoutMs);
             writer.printf("OEM_CAR_SERVICE_READY_TIMEOUT_MS: %s\n", mOemServiceReadyTimeoutMs);
             writer.printf("mComponentName: %s\n", mComponentName);
+            // Dump OEM service stack
+            if (mIsOemServiceReady) {
+                writer.printf("OEM callstack\n");
+                int timeoutMs = 2000;
+                try {
+                    writer.printf(mHelper.doBinderTimedCallWithTimeout(CALL_TAG,
+                            () -> getOemService().getAllStackTraces(), timeoutMs));
+                } catch (TimeoutException e) {
+                    writer.printf("Didn't received OEM stack within %d milliseconds.\n", timeoutMs);
+                }
+            }
             // Dump helper
             mHelper.dump(writer);
         }
@@ -364,7 +421,7 @@
         if (!mIsOemServiceConnected) {
             Slogf.e(TAG, "OEM Service is not connected within: %dms, calling to crash CarService",
                     mOemServiceConnectionTimeoutMs);
-            mHelper.crashCarService("Timeout Exception");
+            mHelper.crashCarService("OEM Service not connected");
         }
     }
 
@@ -391,7 +448,7 @@
             if (!mIsOemServiceReady) {
                 Slogf.e(TAG, "OEM Service is not ready within: " + mOemServiceReadyTimeoutMs
                         + "ms, calling to crash CarService");
-                mHelper.crashCarService("Service not ready");
+                mHelper.crashCarService("OEM Service not ready");
             }
         }
         Slogf.i(TAG, "OEM Service is ready.");
@@ -399,7 +456,19 @@
 
     // Initialize all OEM related components.
     private void initOemServiceComponents() {
+        // Initialize all Oem Service components
         getCarOemAudioFocusService();
+
+        // Callback registered Car Service components for OEM service.
+        callCarServiceComponents();
+    }
+
+    private void callCarServiceComponents() {
+        synchronized (mLock) {
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                mCallbacks.get(i).onOemServiceReady();
+            }
+        }
     }
 
     /**
@@ -440,6 +509,7 @@
             Slogf.i(TAG, "OEM Car service is ready and running. Process ID of OEM Car Service is:"
                     + " %d", pid);
             mHelper.updateOemPid(pid);
+            mHelper.updateOemStackCall(() -> getOemService().getAllStackTraces());
             // Initialize other components on handler thread so that main thread is not
             // blocked
             mHandler.post(() -> initOemServiceComponents());
diff --git a/service/src/com/android/car/oem/CarOemProxyServiceCallback.java b/service/src/com/android/car/oem/CarOemProxyServiceCallback.java
new file mode 100644
index 0000000..277f64d
--- /dev/null
+++ b/service/src/com/android/car/oem/CarOemProxyServiceCallback.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 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 com.android.car.oem;
+
+/**
+ * Callback for other CarService components when OEM service is ready.
+ *
+ * <p>Other CarService components are not expected to call OEM Service during init process. If they
+ * need to make call to OEM service as soon as OEM service is ready, then can register this
+ * callback to {link CarOemProxyService}. This callback will be called for all callback registered
+ * during init calls. The callback will be made only once after OEM service is connected.
+ */
+public interface CarOemProxyServiceCallback {
+    /**
+     * Called when OEM service is ready.
+     */
+    void onOemServiceReady();
+
+}
diff --git a/service/src/com/android/car/oem/CarOemProxyServiceHelper.java b/service/src/com/android/car/oem/CarOemProxyServiceHelper.java
index 0a617f2..1360435 100644
--- a/service/src/com/android/car/oem/CarOemProxyServiceHelper.java
+++ b/service/src/com/android/car/oem/CarOemProxyServiceHelper.java
@@ -63,15 +63,22 @@
 
     private static final int MAX_CIRCULAR_CALLS_PER_CALLER = 5;
     private static final int MAX_CIRCULAR_CALL_TOTAL = 10;
+    private static final int MAX_THREAD_POOL_SIZE = 16;
+    private static final int MIN_THREAD_POOL_SIZE = 18;
 
     private final Object mLock = new Object();
 
-    // TODO(b/239607518):Resize threadpool using system property or dynamically if too many calls
-    // are getting timed out.
-    private static final int THREAD_POOL_SIZE = 5;
-
     private final int mRegularCallTimeoutMs;
     private final int mCrashCallTimeoutMs;
+    // Kept for dumping
+    private final int mThreadPoolSizeFromRRO;
+
+    // Thread pool size will be read from resource overlay. The default value is 8. The maximum
+    // and minimum thread pool size can be MAX_THREAD_POOL_SIZE and MIN_THREAD_POOL_SIZE
+    // respectively. If resource overlay value is more than MAX_THREAD_POOL_SIZE, then thread
+    // pool size will be MAX_THREAD_POOL_SIZE. If resource overlay value is less than
+    // MIN_THREAD_POOL_SIZE, then thread pool size will be MIN_THREAD_POOL_SIZE.
+    private final int mBinderDispatchThreadPoolSize;
 
     /**
      * This map would keep track of possible circular calls
@@ -95,18 +102,33 @@
 
     private final ExecutorService mThreadPool;
     @GuardedBy("mLock")
+    private Callable<String> mOemStackTracer;
+    @GuardedBy("mLock")
     private int mTotalCircularCallsInProcess;
     @GuardedBy("mLock")
     private int mOemCarServicePid;
 
     public CarOemProxyServiceHelper(Context context) {
-        Slogf.i(TAG, "Creating thread pool of size %d", THREAD_POOL_SIZE);
-        mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
         Resources res = context.getResources();
         mRegularCallTimeoutMs = res
                 .getInteger(R.integer.config_oemCarService_regularCall_timeout_ms);
         mCrashCallTimeoutMs = res
                 .getInteger(R.integer.config_oemCarService_crashCall_timeout_ms);
+        mThreadPoolSizeFromRRO = res
+                .getInteger(R.integer.config_oemCarService_thread_pool_size);
+        if (mThreadPoolSizeFromRRO > MAX_THREAD_POOL_SIZE) {
+            mBinderDispatchThreadPoolSize = MAX_THREAD_POOL_SIZE;
+        } else if (mThreadPoolSizeFromRRO < MIN_THREAD_POOL_SIZE) {
+            mBinderDispatchThreadPoolSize = MIN_THREAD_POOL_SIZE;
+        } else {
+            mBinderDispatchThreadPoolSize = mThreadPoolSizeFromRRO;
+        }
+
+        mThreadPool = Executors.newFixedThreadPool(mBinderDispatchThreadPoolSize);
+
+        Slogf.i(TAG, "RegularCallTimeoutMs: %d, CrashCallTimeoutMs: %d, ThreadPoolSizeFromRRO: %d,"
+                + " ThreadPoolSize: %d.", mRegularCallTimeoutMs,
+                mCrashCallTimeoutMs, mThreadPoolSizeFromRRO, mBinderDispatchThreadPoolSize);
     }
 
     /**
@@ -242,8 +264,6 @@
             Slogf.e(TAG, "Current Circular Calls for %s is %d which is more than the limit %d."
                     + " Calling to crash CarService", callerTag, (currentCircularCallForTag + 1),
                     MAX_CIRCULAR_CALLS_PER_CALLER);
-            // TODO(b/239607309): Research how to dump stack on OEM service for debugging if
-            // possible. One way is to get the OEM service stack as string from OEM service.
             crashCarService("Max Circular call for " + callerTag);
         }
 
@@ -355,12 +375,38 @@
      * Crashes CarService and OEM Service.
      */
     public void crashCarService(String reason) {
-        // TODO(b/239607309):Dump call stack and crash OEM service first. To crash OEM service
-        // get OEM Service PID and crash the service. Follow similar dump and crash in
-        // CarServiceHelperService for the requests received from CarWatchDog
-        int processId = Process.myPid();
-        Slogf.e(TAG, "****Crashing CarService because %s. PID: %s****", reason, processId);
-        Process.killProcess(processId);
+        Slogf.e(TAG, "****Crashing CarService and OEM service because %s****", reason);
+        Slogf.e(TAG, "Car Service stack-");
+        Slogf.e(TAG, Log.getStackTraceString(new Exception()));
+
+        Callable<String> oemStackTracer = null;
+        synchronized (mLock) {
+            oemStackTracer = mOemStackTracer;
+        }
+
+        if (oemStackTracer != null) {
+            Slogf.e(TAG, "OEM Service stack-");
+            int timeoutMs = 2000;
+            try {
+                String stack = doBinderTimedCallWithTimeout(TAG, oemStackTracer, timeoutMs);
+                Slogf.e(TAG, stack);
+            } catch (TimeoutException e) {
+                Slogf.e(TAG, "Didn't received OEM stack within %d milliseconds.\n", timeoutMs);
+            }
+        }
+
+        int carServicePid = Process.myPid();
+        int oemCarServicePid;
+        synchronized (mLock) {
+            oemCarServicePid = mOemCarServicePid;
+        }
+
+        if (oemCarServicePid != 0) {
+            Slogf.e(TAG, "Killing OEM service process with PID %d.", oemCarServicePid);
+            Process.killProcess(oemCarServicePid);
+        }
+        Slogf.e(TAG, "Killing Car service process with PID %d.", carServicePid);
+        Process.killProcess(carServicePid);
         System.exit(EXIT_FLAG);
     }
 
@@ -390,7 +436,20 @@
                 }
                 writer.decreaseIndent();
             }
+            writer.printf("mRegularCallTimeoutMs: %d\n", mRegularCallTimeoutMs);
+            writer.printf("mCrashCallTimeoutMs: %d\n", mCrashCallTimeoutMs);
+            writer.printf("mBinderDispatchThreadPoolSize: %d\n", mBinderDispatchThreadPoolSize);
+            writer.printf("ThreadPoolSizeFromRRO: %d\n", mThreadPoolSizeFromRRO);
         }
         writer.decreaseIndent();
     }
+
+    /**
+     * Updates call for getting OEM stack trace.
+     */
+    public void updateOemStackCall(Callable<String> oemStackTracer) {
+        synchronized (mLock) {
+            mOemStackTracer = oemStackTracer;
+        }
+    }
 }
diff --git a/service/src/com/android/car/telemetry/publisher/StatsPublisher.java b/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
index 4832782..31eb95c 100644
--- a/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
+++ b/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
@@ -21,6 +21,7 @@
 import static com.android.car.telemetry.AtomsProto.Atom.APP_CRASH_OCCURRED_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.Atom.APP_START_MEMORY_STATE_CAPTURED_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.Atom.PROCESS_CPU_TIME_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.Atom.PROCESS_MEMORY_SNAPSHOT_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.Atom.PROCESS_MEMORY_STATE_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.Atom.WTF_OCCURRED_FIELD_NUMBER;
 import static com.android.car.telemetry.CarTelemetryService.DEBUG;
@@ -41,6 +42,7 @@
 
 import com.android.car.CarLog;
 import com.android.car.telemetry.AtomsProto.ProcessCpuTime;
+import com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot;
 import com.android.car.telemetry.AtomsProto.ProcessMemoryState;
 import com.android.car.telemetry.ResultStore;
 import com.android.car.telemetry.StatsLogProto;
@@ -98,6 +100,10 @@
     static final long WTF_OCCURRED_ATOM_MATCHER_ID = 13;
     @VisibleForTesting
     static final long WTF_OCCURRED_EVENT_METRIC_ID = 14;
+    @VisibleForTesting
+    static final long PROCESS_MEMORY_SNAPSHOT_ATOM_MATCHER_ID = 15;
+    @VisibleForTesting
+    static final long PROCESS_MEMORY_SNAPSHOT_GAUGE_METRIC_ID = 16;
 
     // TODO(b/202115033): Flatten the load spike by pulling reports for each MetricsConfigs
     //                    using separate periodical timers.
@@ -135,6 +141,30 @@
                             .setField(ProcessCpuTime.SYSTEM_TIME_MILLIS_FIELD_NUMBER))
                     .build();
 
+    @VisibleForTesting
+    static final StatsdConfigProto.FieldMatcher PROCESS_MEMORY_SNAPSHOT_FIELDS_MATCHER =
+            StatsdConfigProto.FieldMatcher.newBuilder()
+                    .setField(
+                            PROCESS_MEMORY_SNAPSHOT_FIELD_NUMBER)
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot.PID_FIELD_NUMBER))
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot.OOM_SCORE_ADJ_FIELD_NUMBER))
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot.RSS_IN_KILOBYTES_FIELD_NUMBER))
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot.ANON_RSS_IN_KILOBYTES_FIELD_NUMBER))
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot.SWAP_IN_KILOBYTES_FIELD_NUMBER))
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot
+                                    .ANON_RSS_AND_SWAP_IN_KILOBYTES_FIELD_NUMBER))
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot.GPU_MEMORY_KB_FIELD_NUMBER))
+                    .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                            .setField(ProcessMemorySnapshot.HAS_FOREGROUND_SERVICES_FIELD_NUMBER))
+                    .build();
+
     private final StatsManagerProxy mStatsManager;
     private final ResultStore mResultStore;
     private final Handler mTelemetryHandler;
@@ -192,12 +222,10 @@
 
         if (!mIsPullingReports) {
             if (DEBUG) {
-                Slogf.d(CarLog.TAG_TELEMETRY, "Stats report will be pulled in "
-                        + PULL_REPORTS_PERIOD.toMinutes() + " minutes.");
+                Slogf.d(CarLog.TAG_TELEMETRY, "Triggering pull stats reports");
             }
             mIsPullingReports = true;
-            mTelemetryHandler.postDelayed(
-                    mPullReportsPeriodically, PULL_REPORTS_PERIOD.toMillis());
+            mTelemetryHandler.post(mPullReportsPeriodically);
         }
     }
 
@@ -247,12 +275,17 @@
             case WTF_OCCURRED:
                 metricId = WTF_OCCURRED_EVENT_METRIC_ID;
                 break;
+            case PROCESS_MEMORY_SNAPSHOT:
+                metricId = PROCESS_MEMORY_SNAPSHOT_GAUGE_METRIC_ID;
+                break;
             default:
                 return;
         }
         if (!metricBundles.containsKey(metricId)) {
             Slogf.w(CarLog.TAG_TELEMETRY,
-                    "No reports for metric id " + metricId + " for config " + configKey);
+                    "No reports for metric id " + metricId + " ("
+                            + subscriber.getPublisherParam().getStats().getSystemMetric()
+                            + ") for config " + configKey);
             return;
         }
         PersistableBundle bundle = metricBundles.get(metricId);
@@ -549,6 +582,8 @@
                 return buildAnrOccurredStatsdConfig(builder);
             case WTF_OCCURRED:
                 return buildWtfOccurredStatsdConfig(builder);
+            case PROCESS_MEMORY_SNAPSHOT:
+                return buildProcessMemorySnapshotStatsdConfig(builder);
             default:
                 throw new IllegalArgumentException("Unsupported metric " + metric.name());
         }
@@ -700,6 +735,39 @@
                 .build();
     }
 
+    @NonNull
+    private static StatsdConfig buildProcessMemorySnapshotStatsdConfig(
+            @NonNull StatsdConfig.Builder builder) {
+        return builder
+                .addAtomMatcher(StatsdConfigProto.AtomMatcher.newBuilder()
+                        // The id must be unique within StatsdConfig/matchers
+                        .setId(PROCESS_MEMORY_SNAPSHOT_ATOM_MATCHER_ID)
+                        .setSimpleAtomMatcher(StatsdConfigProto.SimpleAtomMatcher.newBuilder()
+                                .setAtomId(PROCESS_MEMORY_SNAPSHOT_FIELD_NUMBER)))
+                .addGaugeMetric(StatsdConfigProto.GaugeMetric.newBuilder()
+                        // The id must be unique within StatsdConfig/metrics
+                        .setId(PROCESS_MEMORY_SNAPSHOT_GAUGE_METRIC_ID)
+                        .setWhat(PROCESS_MEMORY_SNAPSHOT_ATOM_MATCHER_ID)
+                        .setDimensionsInWhat(StatsdConfigProto.FieldMatcher.newBuilder()
+                                .setField(PROCESS_MEMORY_SNAPSHOT_FIELD_NUMBER)
+                                .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                                        .setField(ProcessMemorySnapshot.UID_FIELD_NUMBER))
+                                .addChild(StatsdConfigProto.FieldMatcher.newBuilder()
+                                        .setField(ProcessMemorySnapshot.PROCESS_NAME_FIELD_NUMBER))
+                        )
+                        .setGaugeFieldsFilter(StatsdConfigProto.FieldFilter.newBuilder()
+                                .setFields(PROCESS_MEMORY_SNAPSHOT_FIELDS_MATCHER)
+                        )  // setGaugeFieldsFilter
+                        .setSamplingType(
+                                StatsdConfigProto.GaugeMetric.SamplingType.RANDOM_ONE_SAMPLE)
+                        .setBucket(StatsdConfigProto.TimeUnit.FIVE_MINUTES)
+                )
+                .addPullAtomPackages(StatsdConfigProto.PullAtomPackages.newBuilder()
+                        .setAtomId(PROCESS_MEMORY_SNAPSHOT_FIELD_NUMBER)
+                        .addPackages("AID_SYSTEM"))
+                .build();
+    }
+
     @Override
     protected void handleSessionStateChange(SessionAnnotation annotation) {}
 }
diff --git a/service/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverter.java b/service/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverter.java
index c9227f5..85e0eae 100644
--- a/service/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverter.java
+++ b/service/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverter.java
@@ -44,7 +44,8 @@
     // Map of pulled atom cases to corresponding atom converter.
     private static Map<Atom.PulledCase, AbstractAtomConverter<?>> sPulledCaseConverters = Map.of(
             Atom.PulledCase.PROCESS_MEMORY_STATE, new ProcessMemoryStateConverter(),
-            Atom.PulledCase.PROCESS_CPU_TIME, new ProcessCpuTimeConverter());
+            Atom.PulledCase.PROCESS_CPU_TIME, new ProcessCpuTimeConverter(),
+            Atom.PulledCase.PROCESS_MEMORY_SNAPSHOT, new ProcessMemorySnapshotConverter());
 
     /**
      * Converts a list of atoms to separate the atoms fields values into arrays to be put into the
diff --git a/service/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverter.java b/service/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverter.java
index 6728581..05f2d01 100644
--- a/service/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverter.java
+++ b/service/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverter.java
@@ -88,6 +88,10 @@
             stringsSet.addAll(report.getStringsList());
             // Each statsReport is for a different metric in the report.
             for (StatsLogProto.StatsLogReport statsReport : report.getMetricsList()) {
+                if (statsReport.getDataCase()
+                        == StatsLogProto.StatsLogReport.DataCase.DATA_NOT_SET) {
+                    continue;
+                }
                 Long metricId = statsReport.getMetricId();
                 if (!metricsStatsReportMap.containsKey(metricId)) {
                     metricsStatsReportMap.put(
@@ -102,7 +106,6 @@
         for (Map.Entry<Long, List<StatsLogProto.StatsLogReport>>
                     entry : metricsStatsReportMap.entrySet()) {
             PersistableBundle statsReportBundle = null;
-            Long metricId = entry.getKey();
             List<StatsLogProto.StatsLogReport> statsReportList = entry.getValue();
             switch (statsReportList.get(0).getDataCase()) {
                 case EVENT_METRICS:
@@ -128,7 +131,7 @@
                     break;
             }
             if (statsReportBundle != null) {
-                metricIdBundleMap.put(metricId, statsReportBundle);
+                metricIdBundleMap.put(entry.getKey(), statsReportBundle);
             }
         }
         return metricIdBundleMap;
diff --git a/service/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemorySnapshotConverter.java b/service/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemorySnapshotConverter.java
new file mode 100644
index 0000000..42845e8
--- /dev/null
+++ b/service/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemorySnapshotConverter.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2022 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 com.android.car.telemetry.publisher.statsconverters;
+
+import android.annotation.NonNull;
+import android.util.SparseArray;
+
+import com.android.car.telemetry.AtomsProto.Atom;
+import com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot;
+import com.android.internal.util.Preconditions;
+
+/**
+ * Atom data converter for atoms of type {@link ProcessMemorySnapshot}.
+ */
+public class ProcessMemorySnapshotConverter extends AbstractAtomConverter<ProcessMemorySnapshot> {
+
+    private static final SparseArray<AtomFieldAccessor<ProcessMemorySnapshot, ?>>
+            sAtomFieldAccessorMap = new SparseArray<>();
+    static {
+        sAtomFieldAccessorMap.append(1, new AtomFieldAccessor<>(
+                "uid",
+                a -> a.hasUid(),
+                a -> a.getUid()
+        ));
+        sAtomFieldAccessorMap.append(2, new AtomFieldAccessor<>(
+                "process_name",
+                a -> a.hasProcessName(),
+                a -> a.getProcessName()
+        ));
+        sAtomFieldAccessorMap.append(3, new AtomFieldAccessor<>(
+                "pid",
+                a -> a.hasPid(),
+                a -> a.getPid()
+        ));
+        sAtomFieldAccessorMap.append(4, new AtomFieldAccessor<>(
+                "oom_score_adj",
+                a -> a.hasOomScoreAdj(),
+                a -> a.getOomScoreAdj()
+        ));
+        sAtomFieldAccessorMap.append(5, new AtomFieldAccessor<>(
+                "rss_in_kilobytes",
+                a -> a.hasRssInKilobytes(),
+                a -> a.getRssInKilobytes()
+        ));
+        sAtomFieldAccessorMap.append(6, new AtomFieldAccessor<>(
+                "anon_rss_in_kilobytes",
+                a -> a.hasAnonRssInKilobytes(),
+                a -> a.getAnonRssInKilobytes()
+        ));
+        sAtomFieldAccessorMap.append(7, new AtomFieldAccessor<>(
+                "swap_in_kilobytes",
+                a -> a.hasSwapInKilobytes(),
+                a -> a.getSwapInKilobytes()
+        ));
+        sAtomFieldAccessorMap.append(8, new AtomFieldAccessor<>(
+                "anon_rss_and_swap_in_kilobytes",
+                a -> a.hasAnonRssAndSwapInKilobytes(),
+                a -> a.getAnonRssAndSwapInKilobytes()
+        ));
+        sAtomFieldAccessorMap.append(9, new AtomFieldAccessor<>(
+                "gpu_memory_kb",
+                a -> a.hasGpuMemoryKb(),
+                a -> a.getGpuMemoryKb()
+        ));
+        sAtomFieldAccessorMap.append(10, new AtomFieldAccessor<>(
+                "has_foreground_services",
+                a -> a.hasHasForegroundServices(),
+                a -> a.getHasForegroundServices()
+        ));
+    }
+
+    ProcessMemorySnapshotConverter() {
+        super();
+    }
+
+    @NonNull
+    @Override
+    SparseArray<AtomFieldAccessor<ProcessMemorySnapshot, ?>> getAtomFieldAccessorMap() {
+        return sAtomFieldAccessorMap;
+    }
+
+    @NonNull
+    @Override
+    ProcessMemorySnapshot getAtomData(@NonNull Atom atom) {
+        Preconditions.checkArgument(
+                atom.hasProcessMemorySnapshot(), "Atom doesn't contain ProcessMemorySnapshot");
+        return atom.getProcessMemorySnapshot();
+    }
+
+    @NonNull
+    @Override
+    String getAtomDataClassName() {
+        return ProcessMemorySnapshot.class.getSimpleName();
+    }
+}
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index 4526f3d..b07de01 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -41,6 +41,7 @@
 import android.car.ICarResultReceiver;
 import android.car.ICarUserService;
 import android.car.PlatformVersion;
+import android.car.VehicleAreaSeat;
 import android.car.builtin.app.ActivityManagerHelper;
 import android.car.builtin.content.pm.PackageManagerHelper;
 import android.car.builtin.os.BuildHelper;
@@ -432,14 +433,28 @@
                             Slogf.d(TAG, "onOccupantZoneConfigChanged: display zone change flag=%s",
                                     flagString);
                         }
+                        // TODO(b/254335743): Refactor startOtherUsers and call startOtherUsers
+                        // instead. Then we can respect the user=>zone mapping based on CarSettings.
                         CarOccupantZoneService zoneService = CarLocalServices.getService(
                                 CarOccupantZoneService.class);
+                        int driverZoneId = OccupantZoneInfo.INVALID_ZONE_ID;
+                        boolean hasDriverZone = zoneService.hasDriverZone();
+                        if (hasDriverZone) {
+                            driverZoneId = zoneService.getOccupantZone(
+                                    CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER,
+                                    VehicleAreaSeat.SEAT_UNKNOWN).zoneId;
+                        }
                         // Start user picker on displays without user allocation.
                         List<OccupantZoneInfo> occupantZoneInfos =
                                 zoneService.getAllOccupantZones();
                         for (int i = 0; i < occupantZoneInfos.size(); i++) {
                             OccupantZoneInfo occupantZoneInfo = occupantZoneInfos.get(i);
                             int zoneId = occupantZoneInfo.zoneId;
+                            // Skip driver zone.
+                            if (hasDriverZone && zoneId == driverZoneId) {
+                                continue;
+                            }
+
                             int userId = zoneService.getUserForOccupant(zoneId);
                             if (userId != CarOccupantZoneManager.INVALID_USER_ID) {
                                 // If there is already a user allocated to the zone, skip.
@@ -2460,7 +2475,8 @@
         boolean hasDriverZone = zoneService.hasDriverZone();
         if (hasDriverZone) {
             driverZoneId = zoneService.getOccupantZone(
-                    CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER, /* seat= */ 0).zoneId;
+                    CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER,
+                    VehicleAreaSeat.SEAT_UNKNOWN).zoneId;
         }
         // After this, mapping only keep the valid zone - user pair
         for (int i = mapping.size() - 1; i >= 0; i--) {
@@ -2508,6 +2524,13 @@
             int userId = mapping.valueAt(i);
             int displayId = zoneService.getDisplayForOccupant(zoneId,
                     CarOccupantZoneManager.DISPLAY_TYPE_MAIN);
+            if (displayId == Display.INVALID_DISPLAY) {
+                // TODO(b/254335743): Attempt this zone assignment once the display becomes
+                // available.
+                Slogf.i(TAG, "startOtherUsers(): cannot start user %d on the display in zone %d"
+                        + " because display is not available yet", userId, zoneId);
+                continue;
+            }
             boolean userStarted = false;
             Slogf.i(TAG, "startOtherUsers(): start user %d for display %d", userId,
                     displayId);
diff --git a/tests/BugReportApp/res/values-en-rCA/strings.xml b/tests/BugReportApp/res/values-en-rCA/strings.xml
index d8e579d..02e32cd 100644
--- a/tests/BugReportApp/res/values-en-rCA/strings.xml
+++ b/tests/BugReportApp/res/values-en-rCA/strings.xml
@@ -17,24 +17,24 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="2596316479611335185">"Bug Report"</string>
+    <string name="app_name" msgid="2596316479611335185">"Bug report"</string>
     <string name="bugreport_info_quit" msgid="5590138890181142473">"Close"</string>
-    <string name="bugreport_info_start" msgid="667324824650830832">"Start Bug Report"</string>
+    <string name="bugreport_info_start" msgid="667324824650830832">"Start bug report"</string>
     <string name="bugreport_info_status" msgid="7211044508792815451">"Status:"</string>
     <string name="bugreport_info_expires_soon_notice" msgid="927139313070992675">"This bug report will expire soon"</string>
     <string name="bugreport_dialog_submit" msgid="2789636252713280633">"Submit"</string>
     <string name="bugreport_dialog_cancel" msgid="4741928791364757040">"Cancel"</string>
     <string name="bugreport_dialog_upload" msgid="2517386929450370781">"Upload"</string>
     <string name="bugreport_dialog_save" msgid="3291363266190644226">"Save"</string>
-    <string name="bugreport_dialog_show_bugreports" msgid="6964385141627170297">"Show Bug Reports"</string>
+    <string name="bugreport_dialog_show_bugreports" msgid="6964385141627170297">"Show bug reports"</string>
     <string name="bugreport_dialog_close" msgid="289925437277364266">"Close"</string>
-    <string name="bugreport_dialog_title" msgid="3315160684205929910">"Speak &amp; Describe The Issue"</string>
+    <string name="bugreport_dialog_title" msgid="3315160684205929910">"Speak and describe the issue"</string>
     <string name="bugreport_dialog_add_audio_to_existing" msgid="4958460267276935700">"Audio message for bug report at %s"</string>
     <string name="bugreport_dialog_recording_finished" msgid="3982335902169398758">"Recording finished"</string>
     <string name="bugreport_dialog_in_progress_title" msgid="1663500052146177338">"Bug report is in progress"</string>
     <string name="bugreport_dialog_in_progress_title_finished" msgid="1610236990020413471">"A bug report has been collected"</string>
-    <string name="bugreport_add_audio_button_text" msgid="8606400151705699144">"Add Audio"</string>
-    <string name="bugreport_add_audio_upload_button_text" msgid="3830917832551764694">"Add Audio &amp; Upload"</string>
+    <string name="bugreport_add_audio_button_text" msgid="8606400151705699144">"Add audio"</string>
+    <string name="bugreport_add_audio_upload_button_text" msgid="3830917832551764694">"Add audio and upload"</string>
     <string name="bugreport_move_button_text" msgid="1245698439228323880">"Move to USB"</string>
     <string name="bugreport_upload_button_text" msgid="4136749466634820848">"Upload"</string>
     <string name="bugreport_upload_gcs_button_text" msgid="5844929656507607424">"Upload to GCS"</string>
diff --git a/tests/CarSecurityPermissionTest/src/com/android/car/CarPropertyManagerPublicPermissionTest.java b/tests/CarSecurityPermissionTest/src/com/android/car/CarPropertyManagerPublicPermissionTest.java
deleted file mode 100644
index e21905b..0000000
--- a/tests/CarSecurityPermissionTest/src/com/android/car/CarPropertyManagerPublicPermissionTest.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * 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 com.android.car;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.car.Car;
-import android.car.VehicleAreaType;
-import android.car.VehiclePropertyIds;
-import android.car.VehiclePropertyType;
-import android.car.hardware.property.CarPropertyManager;
-import android.os.Handler;
-import android.util.Log;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.HashSet;
-
-/**
- * This class contains security permission tests for the {@link CarPropertyManager}'s public APIs.
- */
-@RunWith(AndroidJUnit4.class)
-public class CarPropertyManagerPublicPermissionTest {
-    private Car mCar = null;
-    private CarPropertyManager mPropertyManager;
-    private HashSet<Integer> mProps = new HashSet<>();
-    private static final String TAG = CarPropertyManagerPublicPermissionTest.class.getSimpleName();
-    private static final Integer PLACEHOLDER_AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
-    // Fake values for setter test.
-    private static final int PLACEHOLDER_PROPERTY_VALUE_INTEGER = 1;
-    private static final Integer[] PLACEHOLDER_PROPERTY_VALUE_INTEGER_ARRAY = new Integer[]{1};
-    private static final float PLACEHOLDER_PROPERTY_VALUE_FLOAT = 1.0f;
-    private static final Float[] PLACEHOLDER_PROPERTY_VALUE_FLOAT_ARRAY = new Float[]{1.0f};
-    private static final Long PLACEHOLDER_PROPERTY_VALUE_LONG = 1L;
-    private static final Long[] PLACEHOLDER_PROPERTY_VALUE_LONG_ARRAY = new Long[]{1L};
-    private static final boolean PLACEHOLDER_PROPERTY_VALUE_BOOLEAN = true;
-    private static final String PLACEHOLDER_PROPERTY_VALUE_STRING = "test";
-    private static final byte[] PLACEHOLDER_PROPERTY_VALUE_BYTE_ARRAY = "test".getBytes();
-    private static final Object[] PLACEHOLDER_PROPERTY_VALUE_OBJECT_ARRAY = new Object[]{1, "test"};
-
-    @Before
-    public void setUp() throws Exception  {
-        initAllPropertyIds();
-        mCar = Car.createCar(
-                InstrumentationRegistry.getInstrumentation().getTargetContext(), (Handler) null);
-        mPropertyManager = (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE);
-        assertThat(mPropertyManager).isNotNull();
-    }
-
-    private void initAllPropertyIds() {
-        mProps.add(VehiclePropertyIds.DOOR_POS);
-        mProps.add(VehiclePropertyIds.DOOR_MOVE);
-        mProps.add(VehiclePropertyIds.DOOR_LOCK);
-        mProps.add(VehiclePropertyIds.MIRROR_Z_POS);
-        mProps.add(VehiclePropertyIds.MIRROR_Z_MOVE);
-        mProps.add(VehiclePropertyIds.MIRROR_Y_POS);
-        mProps.add(VehiclePropertyIds.MIRROR_Y_MOVE);
-        mProps.add(VehiclePropertyIds.MIRROR_LOCK);
-        mProps.add(VehiclePropertyIds.MIRROR_FOLD);
-        mProps.add(VehiclePropertyIds.SEAT_MEMORY_SELECT);
-        mProps.add(VehiclePropertyIds.SEAT_MEMORY_SET);
-        mProps.add(VehiclePropertyIds.SEAT_BELT_BUCKLED);
-        mProps.add(VehiclePropertyIds.SEAT_BELT_HEIGHT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_BELT_HEIGHT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_FORE_AFT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_FORE_AFT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_1_POS);
-        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_1_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_2_POS);
-        mProps.add(VehiclePropertyIds.SEAT_BACKREST_ANGLE_2_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_HEIGHT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_HEIGHT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_DEPTH_POS);
-        mProps.add(VehiclePropertyIds.SEAT_DEPTH_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_TILT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_TILT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_FORE_AFT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_FORE_AFT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_SIDE_SUPPORT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_LUMBAR_SIDE_SUPPORT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_HEADREST_HEIGHT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_HEADREST_HEIGHT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_HEADREST_ANGLE_POS);
-        mProps.add(VehiclePropertyIds.SEAT_HEADREST_ANGLE_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_HEADREST_FORE_AFT_POS);
-        mProps.add(VehiclePropertyIds.SEAT_HEADREST_FORE_AFT_MOVE);
-        mProps.add(VehiclePropertyIds.SEAT_OCCUPANCY);
-        mProps.add(VehiclePropertyIds.WINDOW_POS);
-        mProps.add(VehiclePropertyIds.WINDOW_MOVE);
-        mProps.add(VehiclePropertyIds.WINDOW_LOCK);
-
-        // HVAC properties
-        mProps.add(VehiclePropertyIds.HVAC_FAN_SPEED);
-        mProps.add(VehiclePropertyIds.HVAC_FAN_DIRECTION);
-        mProps.add(VehiclePropertyIds.HVAC_TEMPERATURE_CURRENT);
-        mProps.add(VehiclePropertyIds.HVAC_TEMPERATURE_SET);
-        mProps.add(VehiclePropertyIds.HVAC_DEFROSTER);
-        mProps.add(VehiclePropertyIds.HVAC_ELECTRIC_DEFROSTER_ON);
-        mProps.add(VehiclePropertyIds.HVAC_AC_ON);
-        mProps.add(VehiclePropertyIds.HVAC_MAX_AC_ON);
-        mProps.add(VehiclePropertyIds.HVAC_MAX_DEFROST_ON);
-        mProps.add(VehiclePropertyIds.HVAC_RECIRC_ON);
-        mProps.add(VehiclePropertyIds.HVAC_DUAL_ON);
-        mProps.add(VehiclePropertyIds.HVAC_AUTO_ON);
-        mProps.add(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE);
-        mProps.add(VehiclePropertyIds.HVAC_SIDE_MIRROR_HEAT);
-        mProps.add(VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT);
-        mProps.add(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS);
-        mProps.add(VehiclePropertyIds.HVAC_ACTUAL_FAN_SPEED_RPM);
-        mProps.add(VehiclePropertyIds.HVAC_POWER_ON);
-        mProps.add(VehiclePropertyIds.HVAC_FAN_DIRECTION_AVAILABLE);
-        mProps.add(VehiclePropertyIds.HVAC_AUTO_RECIRC_ON);
-        mProps.add(VehiclePropertyIds.HVAC_SEAT_VENTILATION);
-
-        // Info properties
-        mProps.add(VehiclePropertyIds.INFO_VIN);
-        mProps.add(VehiclePropertyIds.INFO_MAKE);
-        mProps.add(VehiclePropertyIds.INFO_MODEL);
-        mProps.add(VehiclePropertyIds.INFO_MODEL_YEAR);
-        mProps.add(VehiclePropertyIds.INFO_FUEL_CAPACITY);
-        mProps.add(VehiclePropertyIds.INFO_FUEL_TYPE);
-        mProps.add(VehiclePropertyIds.INFO_EV_BATTERY_CAPACITY);
-        mProps.add(VehiclePropertyIds.INFO_EV_CONNECTOR_TYPE);
-        mProps.add(VehiclePropertyIds.INFO_FUEL_DOOR_LOCATION);
-        mProps.add(VehiclePropertyIds.INFO_MULTI_EV_PORT_LOCATIONS);
-        mProps.add(VehiclePropertyIds.INFO_EV_PORT_LOCATION);
-        mProps.add(VehiclePropertyIds.INFO_DRIVER_SEAT);
-        mProps.add(VehiclePropertyIds.INFO_EXTERIOR_DIMENSIONS);
-
-        // Sensor properties
-        mProps.add(VehiclePropertyIds.PERF_ODOMETER);
-        mProps.add(VehiclePropertyIds.PERF_VEHICLE_SPEED);
-        mProps.add(VehiclePropertyIds.PERF_VEHICLE_SPEED_DISPLAY);
-        mProps.add(VehiclePropertyIds.ENGINE_COOLANT_TEMP);
-        mProps.add(VehiclePropertyIds.ENGINE_OIL_LEVEL);
-        mProps.add(VehiclePropertyIds.ENGINE_OIL_TEMP);
-        mProps.add(VehiclePropertyIds.ENGINE_RPM);
-        mProps.add(VehiclePropertyIds.WHEEL_TICK);
-        mProps.add(VehiclePropertyIds.FUEL_LEVEL);
-        mProps.add(VehiclePropertyIds.FUEL_DOOR_OPEN);
-        mProps.add(VehiclePropertyIds.EV_BATTERY_LEVEL);
-        mProps.add(VehiclePropertyIds.EV_CHARGE_PORT_OPEN);
-        mProps.add(VehiclePropertyIds.EV_CHARGE_PORT_CONNECTED);
-        mProps.add(VehiclePropertyIds.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE);
-        mProps.add(VehiclePropertyIds.RANGE_REMAINING);
-        mProps.add(VehiclePropertyIds.TIRE_PRESSURE);
-        mProps.add(VehiclePropertyIds.PERF_STEERING_ANGLE);
-        mProps.add(VehiclePropertyIds.PERF_REAR_STEERING_ANGLE);
-        mProps.add(VehiclePropertyIds.GEAR_SELECTION);
-        mProps.add(VehiclePropertyIds.CURRENT_GEAR);
-        mProps.add(VehiclePropertyIds.PARKING_BRAKE_ON);
-        mProps.add(VehiclePropertyIds.PARKING_BRAKE_AUTO_APPLY);
-        mProps.add(VehiclePropertyIds.FUEL_LEVEL_LOW);
-        mProps.add(VehiclePropertyIds.NIGHT_MODE);
-        mProps.add(VehiclePropertyIds.TURN_SIGNAL_STATE);
-        mProps.add(VehiclePropertyIds.IGNITION_STATE);
-        mProps.add(VehiclePropertyIds.ABS_ACTIVE);
-        mProps.add(VehiclePropertyIds.TRACTION_CONTROL_ACTIVE);
-        mProps.add(VehiclePropertyIds.ENV_OUTSIDE_TEMPERATURE);
-        mProps.add(VehiclePropertyIds.HEADLIGHTS_STATE);
-        mProps.add(VehiclePropertyIds.HIGH_BEAM_LIGHTS_STATE);
-        mProps.add(VehiclePropertyIds.FOG_LIGHTS_STATE);
-        mProps.add(VehiclePropertyIds.HAZARD_LIGHTS_STATE);
-        mProps.add(VehiclePropertyIds.HEADLIGHTS_SWITCH);
-        mProps.add(VehiclePropertyIds.HIGH_BEAM_LIGHTS_SWITCH);
-        mProps.add(VehiclePropertyIds.FOG_LIGHTS_SWITCH);
-        mProps.add(VehiclePropertyIds.HAZARD_LIGHTS_SWITCH);
-        mProps.add(VehiclePropertyIds.READING_LIGHTS_STATE);
-        mProps.add(VehiclePropertyIds.CABIN_LIGHTS_STATE);
-        mProps.add(VehiclePropertyIds.READING_LIGHTS_SWITCH);
-        mProps.add(VehiclePropertyIds.CABIN_LIGHTS_SWITCH);
-        // Display_Units
-        mProps.add(VehiclePropertyIds.DISTANCE_DISPLAY_UNITS);
-        mProps.add(VehiclePropertyIds.FUEL_VOLUME_DISPLAY_UNITS);
-        mProps.add(VehiclePropertyIds.TIRE_PRESSURE_DISPLAY_UNITS);
-        mProps.add(VehiclePropertyIds.EV_BATTERY_DISPLAY_UNITS);
-        mProps.add(VehiclePropertyIds.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME);
-        mProps.add(VehiclePropertyIds.VEHICLE_SPEED_DISPLAY_UNITS);
-        // Properties in S
-        mProps.add(VehiclePropertyIds.EPOCH_TIME);
-        mProps.add(VehiclePropertyIds.STORAGE_ENCRYPTION_BINDING_SEED);
-    }
-
-    @After
-    public void tearDown() {
-        if (mCar != null) {
-            mCar.disconnect();
-        }
-    }
-
-    @Test
-    public void testCarPropertyManagerGetter() {
-        for (int propertyId : mProps) {
-            try {
-                switch (propertyId & VehiclePropertyType.MASK) {
-                    case VehiclePropertyType.BOOLEAN:
-                        // The areaId may not match with it in propertyConfig. CarService
-                        // check the permission before checking valid areaId.
-                        mPropertyManager.getBooleanProperty(propertyId, PLACEHOLDER_AREA_ID);
-                        break;
-                    case VehiclePropertyType.FLOAT:
-                        mPropertyManager.getFloatProperty(propertyId, PLACEHOLDER_AREA_ID);
-                        break;
-                    case VehiclePropertyType.INT32_VEC:
-                        mPropertyManager.getIntArrayProperty(propertyId, PLACEHOLDER_AREA_ID);
-                        break;
-                    case VehiclePropertyType.INT32:
-                        mPropertyManager.getIntProperty(propertyId, PLACEHOLDER_AREA_ID);
-                        break;
-                    default:
-                        mPropertyManager.getProperty(propertyId, PLACEHOLDER_AREA_ID);
-                }
-            } catch (Exception e) {
-                assertWithMessage("Get property: 0x" + Integer.toHexString(propertyId)
-                        + " cause an unexpected exception: " + e)
-                        .that(e).isInstanceOf(SecurityException.class);
-                continue;
-            }
-            assertPropertyNotImplementedInVhal(propertyId);
-        }
-    }
-
-    private void assertPropertyNotImplementedInVhal(int propertyId) {
-        assertWithMessage("Get property : 0x " + Integer.toHexString(propertyId)
-                + " without permission.")
-                .that(mPropertyManager.getProperty(propertyId, PLACEHOLDER_AREA_ID)).isNull();
-        Log.w(TAG, "Property id: 0x" + Integer.toHexString(propertyId)
-                + " does not exist in the VHAL implementation.");
-    }
-
-    @Test
-    public void testCarPropertyManagerSetter() {
-        for (int propertyId : mProps) {
-            try {
-                // Fake value may not in the valid range. CarService checks permission
-                // and sends request to VHAL. VHAL checks specific property range.
-                switch (propertyId & VehiclePropertyType.MASK) {
-                    case VehiclePropertyType.BOOLEAN:
-                        mPropertyManager.setBooleanProperty(propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_BOOLEAN);
-                        break;
-                    case VehiclePropertyType.FLOAT:
-                        mPropertyManager.setFloatProperty(propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_FLOAT);
-                        break;
-                    case VehiclePropertyType.FLOAT_VEC:
-                        mPropertyManager.setProperty(Float[].class, propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_FLOAT_ARRAY);
-                        break;
-                    case VehiclePropertyType.INT32:
-                        mPropertyManager.setIntProperty(propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_INTEGER);
-                        break;
-                    case VehiclePropertyType.INT32_VEC:
-                        mPropertyManager.setProperty(Integer[].class, propertyId,
-                                PLACEHOLDER_AREA_ID, PLACEHOLDER_PROPERTY_VALUE_INTEGER_ARRAY);
-                        break;
-                    case VehiclePropertyType.INT64:
-                        mPropertyManager.setProperty(Long.class, propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_LONG);
-                        break;
-                    case VehiclePropertyType.INT64_VEC:
-                        mPropertyManager.setProperty(Long[].class, propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_LONG_ARRAY);
-                        break;
-                    case VehiclePropertyType.BYTES:
-                        mPropertyManager.setProperty(byte[].class, propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_BYTE_ARRAY);
-                        break;
-                    case VehiclePropertyType.MIXED:
-                        mPropertyManager.setProperty(Object[].class, propertyId,
-                                PLACEHOLDER_AREA_ID, PLACEHOLDER_PROPERTY_VALUE_OBJECT_ARRAY);
-                        break;
-                    case VehiclePropertyType.STRING:
-                        mPropertyManager.setProperty(String.class, propertyId, PLACEHOLDER_AREA_ID,
-                                PLACEHOLDER_PROPERTY_VALUE_STRING);
-                        break;
-                    default:
-                        throw new IllegalArgumentException("Invalid value type for property: 0x"
-                                + Integer.toHexString(propertyId));
-                }
-            } catch (IllegalArgumentException e) {
-                assertWithMessage("Set property: 0x" + Integer.toHexString(propertyId)
-                        + " cause an unexpected exception: " + e)
-                        .that(e.getMessage()).contains("does not exist in the vehicle");
-            } catch (Exception e) {
-                assertWithMessage("Get property: 0x" + Integer.toHexString(propertyId)
-                        + " cause an unexpected exception: " + e)
-                        .that(e).isInstanceOf(SecurityException.class);
-            }
-        }
-    }
-}
diff --git a/tests/DiagnosticTools/res/values-en-rCA/strings.xml b/tests/DiagnosticTools/res/values-en-rCA/strings.xml
index 4833f5f..bd4ccb9 100644
--- a/tests/DiagnosticTools/res/values-en-rCA/strings.xml
+++ b/tests/DiagnosticTools/res/values-en-rCA/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_freeze_frame_info" msgid="1425573367248263107">"Display Freeze Frame Info"</string>
+    <string name="display_freeze_frame_info" msgid="1425573367248263107">"Display freeze frame Info"</string>
 </resources>
diff --git a/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCDetailActivity.java b/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCDetailActivity.java
index e532b3d..022067f 100644
--- a/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCDetailActivity.java
+++ b/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCDetailActivity.java
@@ -212,12 +212,12 @@
                                 mDTC.getCode()))
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setPositiveButton(
-                        android.R.string.yes,
+                        android.R.string.ok,
                         (dialog, whichButton) -> {
                             mCarDiagnosticManager.clearFreezeFrames(mDTC.getTimestamp());
                             hideFreezeFrameFields();
                         })
-                .setNegativeButton(android.R.string.no, null)
+                .setNegativeButton(android.R.string.cancel, null)
                 .show();
     }
 }
diff --git a/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCListActivity.java b/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCListActivity.java
index 4d7220b..be4d81d 100644
--- a/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCListActivity.java
+++ b/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/DTCListActivity.java
@@ -82,8 +82,8 @@
                                 "Do you really want to clear %d mDtcs?", mAdapter.numSelected()))
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setPositiveButton(
-                        android.R.string.yes, (dialog, whichButton) -> mAdapter.deleteSelected())
-                .setNegativeButton(android.R.string.no, null)
+                        android.R.string.ok, (dialog, whichButton) -> mAdapter.deleteSelected())
+                .setNegativeButton(android.R.string.cancel, null)
                 .show();
     }
 }
diff --git a/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/ECUListActivity.java b/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/ECUListActivity.java
index a2ee70b..6ab2664 100644
--- a/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/ECUListActivity.java
+++ b/tests/DiagnosticTools/src/com/google/android/car/diagnostictools/ECUListActivity.java
@@ -87,8 +87,8 @@
                                 "Do you really want to clear %d mDtcs?", mAdapter.numSelected()))
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setPositiveButton(
-                        android.R.string.yes, (dialog, whichButton) -> mAdapter.deleteSelected())
-                .setNegativeButton(android.R.string.no, null)
+                        android.R.string.ok, (dialog, whichButton) -> mAdapter.deleteSelected())
+                .setNegativeButton(android.R.string.cancel, null)
                 .show();
     }
 }
diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
index 5119c72..e59f902 100644
--- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
+++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
@@ -72,6 +72,7 @@
     <uses-permission android:name="android.car.permission.CAR_IDENTIFICATION" />
     <uses-permission android:name="android.car.permission.PERMISSION_ADJUST_RANGE_REMAINING" />
     <uses-permission android:name="android.car.permission.PERMISSION_CAR_ENGINE_DETAILED" />
+    <uses-permission android:name="android.car.permission.CONTROL_STEERING_WHEEL" />
     <!-- use for CarServiceTest -->
     <uses-permission android:name="android.car.permission.VMS_PUBLISHER"/>
     <!-- use for CarServiceTest -->
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml b/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml
index 2a5d05f..8340a55 100644
--- a/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml
@@ -364,6 +364,31 @@
                     android:layout_height="wrap_content"
                     android:text="@string/get_report"/>
             </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/process_memory_snapshot_config"/>
+                <Button
+                    android:id="@+id/send_on_process_memory_snapshot_config"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/add_metrics_config"/>
+                <Button
+                    android:id="@+id/remove_on_process_memory_snapshot_config"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/remove_metrics_config"/>
+                <Button
+                    android:id="@+id/get_on_process_memory_snapshot_report"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/get_report"/>
+            </LinearLayout>
         </LinearLayout> <!-- @+id/metrics_config_buttons -->
 
         <TextView
diff --git a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
index b984b49..14152ea 100644
--- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
@@ -396,7 +396,7 @@
 
     <!-- CarTelemetryService Test -->
     <string name="gear_change_config" translatable="false">on_gear_change:</string>
-    <string name="process_memory_config" translatable="false">process_memory:</string>
+    <string name="process_memory_config" translatable="false">process_memory_state:</string>
     <string name="app_start_memory_state_captured_config" translatable="false">app_start_memory_state_captured:</string>
     <string name="activity_foreground_state_changed_config" translatable="false">activity_foreground_state_changed:</string>
     <string name="process_cpu_time_config" translatable="false">process_cpu_time:</string>
@@ -406,6 +406,7 @@
     <string name="wifi_netstats_config" translatable="false">wifi_netstats_top_consumers:</string>
     <string name="stats_and_connectivity_config" translatable="false">stats and connectivity:</string>
     <string name="memory_config" translatable="false">memory:</string>
+    <string name="process_memory_snapshot_config" translatable="false">process_memory_snapshot:</string>
     <string name="add_metrics_config" translatable="false">Add MetricsConfig</string>
     <string name="remove_metrics_config" translatable="false">Remove MetricsConfig</string>
     <string name="download_data" translatable="false">Download Data</string>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/alertdialog/AlertDialogTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/alertdialog/AlertDialogTestFragment.java
index 324df02..d473f05 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/alertdialog/AlertDialogTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/alertdialog/AlertDialogTestFragment.java
@@ -58,13 +58,13 @@
                 builder.setTitle("Alert Title")
                         .setMessage("Message for Alert dialog window, this part is text only")
                         .setPositiveButton(
-                                android.R.string.yes, new DialogInterface.OnClickListener() {
+                                android.R.string.ok, new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int which) {
                                 // do nothing
                             }
                         })
                         .setNegativeButton(
-                                android.R.string.no, new DialogInterface.OnClickListener() {
+                                android.R.string.cancel, new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int which) {
                                 // do nothing
                             }
@@ -82,13 +82,13 @@
                 builder.setTitle("Alert Title")
                         .setView(R.layout.alert_dialog_bluetooth_pin_entry)
                         .setPositiveButton(
-                                android.R.string.yes, new DialogInterface.OnClickListener() {
+                                android.R.string.ok, new DialogInterface.OnClickListener() {
                                     public void onClick(DialogInterface dialog, int which) {
                                         // do nothing
                                     }
                                 })
                         .setNegativeButton(
-                                android.R.string.no, new DialogInterface.OnClickListener() {
+                                android.R.string.cancel, new DialogInterface.OnClickListener() {
                                     public void onClick(DialogInterface dialog, int which) {
                                         // do nothing
                                     }
@@ -106,13 +106,13 @@
                 builder.setTitle("Alert Title")
                         .setView(R.layout.alert_dialog_bluetooth_pin_confirm)
                         .setPositiveButton(
-                                android.R.string.yes, new DialogInterface.OnClickListener() {
+                                android.R.string.ok, new DialogInterface.OnClickListener() {
                                     public void onClick(DialogInterface dialog, int which) {
                                         // do nothing
                                     }
                                 })
                         .setNegativeButton(
-                                android.R.string.no, new DialogInterface.OnClickListener() {
+                                android.R.string.cancel, new DialogInterface.OnClickListener() {
                                     public void onClick(DialogInterface dialog, int which) {
                                         // do nothing
                                     }
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java
index 10fb082..f442850 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java
@@ -21,6 +21,7 @@
 import static android.car.telemetry.TelemetryProto.StatsPublisher.SystemMetric.APP_CRASH_OCCURRED;
 import static android.car.telemetry.TelemetryProto.StatsPublisher.SystemMetric.APP_START_MEMORY_STATE_CAPTURED;
 import static android.car.telemetry.TelemetryProto.StatsPublisher.SystemMetric.PROCESS_CPU_TIME;
+import static android.car.telemetry.TelemetryProto.StatsPublisher.SystemMetric.PROCESS_MEMORY_SNAPSHOT;
 import static android.car.telemetry.TelemetryProto.StatsPublisher.SystemMetric.PROCESS_MEMORY_STATE;
 import static android.car.telemetry.TelemetryProto.StatsPublisher.SystemMetric.WTF_OCCURRED;
 
@@ -465,6 +466,32 @@
     private static final String MEMORY_CONFIG_NAME =
             METRICS_CONFIG_MEMORY_V1.getName();
 
+    /** ProcessMemorySnapshot section. */
+    private static final String LUA_SCRIPT_ON_PROCESS_MEMORY_SNAPSHOT = new StringBuilder()
+            .append("function onProcessMemorySnapshot(published_data, state)\n")
+            .append("    on_script_finished(published_data)\n")
+            .append("end\n")
+            .toString();
+    private static final TelemetryProto.Publisher PROCESS_MEMORY_SNAPSHOT_PUBLISHER =
+            TelemetryProto.Publisher.newBuilder()
+                    .setStats(
+                            TelemetryProto.StatsPublisher.newBuilder()
+                                    .setSystemMetric(PROCESS_MEMORY_SNAPSHOT))
+                    .build();
+    private static final TelemetryProto.MetricsConfig METRICS_CONFIG_PROCESS_MEMORY_SNAPSHOT_V1 =
+            TelemetryProto.MetricsConfig.newBuilder()
+                    .setName("process_memory_snapshot_metrics_config")
+                    .setVersion(1)
+                    .setScript(LUA_SCRIPT_ON_PROCESS_MEMORY_SNAPSHOT)
+                    .addSubscribers(
+                            TelemetryProto.Subscriber.newBuilder()
+                                    .setHandler("onProcessMemorySnapshot")
+                                    .setPublisher(PROCESS_MEMORY_SNAPSHOT_PUBLISHER)
+                                    .setPriority(SCRIPT_EXECUTION_PRIORITY_HIGH))
+                    .build();
+    private static final String PROCESS_MEMORY_SNAPSHOT_CONFIG_NAME =
+            METRICS_CONFIG_PROCESS_MEMORY_SNAPSHOT_V1.getName();
+
     private final Executor mExecutor = Executors.newSingleThreadExecutor();
 
     private boolean mReceiveReportNotification = false;
@@ -592,6 +619,13 @@
                 .setOnClickListener(this::onRemoveMemoryConfigBtnClick);
         view.findViewById(R.id.get_memory_report)
                 .setOnClickListener(this::onGetMemoryReportBtnClick);
+        /** StatsPublisher process_memory_snapshot */
+        view.findViewById(R.id.send_on_process_memory_snapshot_config)
+                .setOnClickListener(this::onSendProcessMemorySnapshotConfigBtnClick);
+        view.findViewById(R.id.remove_on_process_memory_snapshot_config)
+                .setOnClickListener(this::onRemoveProcessMemorySnapshotConfigBtnClick);
+        view.findViewById(R.id.get_on_process_memory_snapshot_report)
+                .setOnClickListener(this::onGetProcessMemorySnapshotReportBtnClick);
         /** Print mem info button */
         view.findViewById(R.id.print_mem_info_btn).setOnClickListener(this::onPrintMemInfoBtnClick);
         return view;
@@ -983,6 +1017,24 @@
         mCarTelemetryManager.getFinishedReport(MEMORY_CONFIG_NAME, mExecutor, mListener);
     }
 
+    private void onSendProcessMemorySnapshotConfigBtnClick(View view) {
+        mCarTelemetryManager.addMetricsConfig(
+                PROCESS_MEMORY_SNAPSHOT_CONFIG_NAME,
+                METRICS_CONFIG_PROCESS_MEMORY_SNAPSHOT_V1.toByteArray(),
+                mExecutor,
+                mAddMetricsConfigCallback);
+    }
+
+    private void onRemoveProcessMemorySnapshotConfigBtnClick(View view) {
+        showOutput("Removing MetricsConfig that listens for PROCESS_MEMORY_SNAPSHOT...");
+        mCarTelemetryManager.removeMetricsConfig(PROCESS_MEMORY_SNAPSHOT_CONFIG_NAME);
+    }
+
+    private void onGetProcessMemorySnapshotReportBtnClick(View view) {
+        mCarTelemetryManager.getFinishedReport(
+                PROCESS_MEMORY_SNAPSHOT_CONFIG_NAME, mExecutor, mListener);
+    }
+
     /** Gets a MemoryInfo object for the device's current memory status. */
     private ActivityManager.MemoryInfo getAvailableMemory() {
         ActivityManager activityManager = getActivity().getSystemService(ActivityManager.class);
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/SimpleUserPickerFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/SimpleUserPickerFragment.java
index 06e438b..9c7091b 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/SimpleUserPickerFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/SimpleUserPickerFragment.java
@@ -53,7 +53,9 @@
 import com.google.android.car.kitchensink.UserPickerActivity;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 public final class SimpleUserPickerFragment extends Fragment {
@@ -449,7 +451,7 @@
     private ArrayList<String> getUnassignedUsers() {
         ArrayList<String> users = new ArrayList<>();
         List<UserInfo> aliveUsers = mUserManager.getAliveUsers();
-        List<UserHandle> visibleUsers = mUserManager.getVisibleUsers();
+        Set<UserHandle> visibleUsers = mUserManager.getVisibleUsers();
         // Exclude visible users and only show unassigned users.
         for (int i = 0; i < aliveUsers.size(); ++i) {
             UserInfo u = aliveUsers.get(i);
@@ -487,13 +489,8 @@
         return displays;
     }
 
-    private static boolean isIncluded(int userId, List<UserHandle> visibleUsers) {
-        for (int i = 0; i < visibleUsers.size(); ++i) {
-            if (userId == visibleUsers.get(i).getIdentifier()) {
-                return true;
-            }
-        }
-        return false;
+    private static boolean isIncluded(int userId, Collection<UserHandle> users) {
+        return users.stream().anyMatch(u -> u.getIdentifier() == userId);
     }
 
     private static final class SpinnerWrapper {
diff --git a/tests/MultiDisplaySecondaryHomeTestLauncher/res/values-en-rCA/strings.xml b/tests/MultiDisplaySecondaryHomeTestLauncher/res/values-en-rCA/strings.xml
index 40d3c39..5eb136e 100644
--- a/tests/MultiDisplaySecondaryHomeTestLauncher/res/values-en-rCA/strings.xml
+++ b/tests/MultiDisplaySecondaryHomeTestLauncher/res/values-en-rCA/strings.xml
@@ -17,13 +17,13 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="3477029631237519798">"MultiDisplay"</string>
+    <string name="app_name" msgid="3477029631237519798">"Multi Display"</string>
     <string name="md_launcher" msgid="327845696688732506">"MD Launcher"</string>
     <string name="couldnt_launch" msgid="7815676424138012351">"Couldn\'t launch the activity"</string>
     <string name="select_display" msgid="1682700853391296117">"Select a display"</string>
     <string name="add_app_shortcut" msgid="8873512136913188432">"Add app shortcut"</string>
     <string name="set_wallpaper" msgid="3650915172749345197">"Set wallpaper"</string>
     <string name="new_instance" msgid="1924479866055190730">"Request launch in new instance"</string>
-    <string name="wallpaper_description" msgid="5885164573334720996">"Sample multidisplay wallpaper"</string>
+    <string name="wallpaper_description" msgid="5885164573334720996">"Sample multi-display wallpaper"</string>
     <string name="exit" msgid="3648703694102318310">"Exit"</string>
 </resources>
diff --git a/tests/MultiDisplayTestHelloActivity/res/values-en-rCA/strings.xml b/tests/MultiDisplayTestHelloActivity/res/values-en-rCA/strings.xml
index da391de..aff1d57 100644
--- a/tests/MultiDisplayTestHelloActivity/res/values-en-rCA/strings.xml
+++ b/tests/MultiDisplayTestHelloActivity/res/values-en-rCA/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="hello_activity_text_text" msgid="8189259382863353832">"Hello, World!"</string>
+    <string name="hello_activity_text_text" msgid="8189259382863353832">"Hello, world!"</string>
     <string name="app_name_default" msgid="110846623663619763">"MDTHelloDefault"</string>
     <string name="app_name_always" msgid="6684579479829101738">"MDTHelloAlways"</string>
 </resources>
diff --git a/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarAudioFocusServiceImpl.java b/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarAudioFocusServiceImpl.java
index d990119..e78554f 100644
--- a/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarAudioFocusServiceImpl.java
+++ b/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarAudioFocusServiceImpl.java
@@ -58,7 +58,7 @@
     }
 
     @Override
-    public void audioFocusChanged(List<AudioFocusInfo> currentFocusHolders,
+    public void notifyAudioFocusChange(List<AudioFocusInfo> currentFocusHolders,
             List<AudioFocusInfo> currentFocusLosers, int zoneId) {
         Log.d(TAG, "OemCarAudioFocusServiceImpl audioFocusChanged called");
     }
diff --git a/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarServiceImpl.java b/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarServiceImpl.java
index 23e27ae..b201ea4 100644
--- a/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarServiceImpl.java
+++ b/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarServiceImpl.java
@@ -75,16 +75,8 @@
         }
     }
 
-
-    @Override
-    public boolean isOemServiceReady() {
-        Log.d(TAG, "isOemServiceReady");
-        return true;
-    }
-
     @Override
     public void onCarServiceReady() {
-        super.onCarServiceReady();
         Log.d(TAG, "onCarServiceReady");
     }
 
diff --git a/tests/android_car_api_test/src/android/car/apitest/VehiclePropertyIdsTest.java b/tests/android_car_api_test/src/android/car/apitest/VehiclePropertyIdsTest.java
index e6ce2ca..b55bd19 100644
--- a/tests/android_car_api_test/src/android/car/apitest/VehiclePropertyIdsTest.java
+++ b/tests/android_car_api_test/src/android/car/apitest/VehiclePropertyIdsTest.java
@@ -48,7 +48,8 @@
                     "HW_CUSTOM_INPUT",
                     "HW_ROTARY_INPUT",
                     "SUPPORT_CUSTOMIZE_VENDOR_PERMISSION",
-                    "SUPPORTED_PROPERTY_IDS");
+                    "SUPPORTED_PROPERTY_IDS",
+                    "STORAGE_ENCRYPTION_BINDING_SEED");
 
     // TODO(b/242350638): add missing annotations, remove (on child bug of 242350638)
     @Override
@@ -307,8 +308,6 @@
         propsToString.put(VehiclePropertyIds.CLUSTER_REQUEST_DISPLAY, "CLUSTER_REQUEST_DISPLAY");
         propsToString.put(VehiclePropertyIds.CLUSTER_NAVIGATION_STATE, "CLUSTER_NAVIGATION_STATE");
         propsToString.put(VehiclePropertyIds.EPOCH_TIME, "EPOCH_TIME");
-        propsToString.put(VehiclePropertyIds.STORAGE_ENCRYPTION_BINDING_SEED,
-                "STORAGE_ENCRYPTION_BINDING_SEED");
         propsToString.put(VehiclePropertyIds.ELECTRONIC_TOLL_COLLECTION_CARD_STATUS,
                 "ELECTRONIC_TOLL_COLLECTION_CARD_STATUS");
         propsToString.put(VehiclePropertyIds.ELECTRONIC_TOLL_COLLECTION_CARD_TYPE,
diff --git a/tests/android_car_api_test/src/com/android/internal/car/CarServiceHelperServiceSystemTest.java b/tests/android_car_api_test/src/com/android/internal/car/CarServiceHelperServiceSystemTest.java
index aa15143..5264d6d 100644
--- a/tests/android_car_api_test/src/com/android/internal/car/CarServiceHelperServiceSystemTest.java
+++ b/tests/android_car_api_test/src/com/android/internal/car/CarServiceHelperServiceSystemTest.java
@@ -70,6 +70,10 @@
                     .contains("Safe to run device policy operations: false"));
         } finally {
             executeShellCommand("cmd car_service emulate-driving-state park");
+            // Assert that state is changed back
+            eventually(()-> assertWithMessage("CarServiceHelperService dump")
+                    .that(dumpCarServiceHelper())
+                    .contains("Safe to run device policy operations: true"));
         }
     }
 
@@ -105,6 +109,10 @@
                     .contains("Operation REBOOT is UNSAFE. Reason: DRIVING_DISTRACTION"));
         } finally {
             executeShellCommand("cmd car_service emulate-driving-state park");
+            // Assert that state is changed back
+            eventually(()-> assertWithMessage("CarServiceHelperService dump")
+                    .that(dumpCarServiceHelper("--is-operation-safe", "7"))
+                    .contains("Operation REBOOT is SAFE. Reason: NONE"));
         }
     }
 
diff --git a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
index d4f9940..d4c1588 100644
--- a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
@@ -867,7 +867,7 @@
 
         @Override
         public synchronized void onPropertySet(VehiclePropValue value) {
-            // Simulate HalClient.set() behavior.
+            // Simulate VehicleHal.set() behavior.
             int statusCode = mapPropertyToVhalStatusCode(value.prop);
             if (statusCode != VehicleHalStatusCode.STATUS_OK) {
                 // The ServiceSpecificException here would pass the statusCode back to caller.
@@ -879,7 +879,7 @@
 
         @Override
         public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
-            // Simulate HalClient.get() behavior.
+            // Simulate VehicleHal.get() behavior.
             int vhalStatusCode = mapPropertyToVhalStatusCode(value.prop);
             if (vhalStatusCode != VehicleHalStatusCode.STATUS_OK) {
                 // The ServiceSpecificException here would pass the statusCode back to caller.
diff --git a/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java b/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
index 5d5c5af..eb81015 100644
--- a/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
+++ b/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
@@ -101,46 +101,46 @@
             mIntegerOverrides.forEach(resources::overrideResource);
             mStringOverrides.forEach(resources::overrideResource);
         }
+
+        static ResourceOverrides of(int id, int value) {
+            ResourceOverrides result = new ResourceOverrides();
+            result.override(id, value);
+            return result;
+        }
+
+        static ResourceOverrides of(
+                int id1, int value1,
+                int id2, int value2,
+                int id3, int value3,
+                int id4, int value4) {
+            ResourceOverrides result = new ResourceOverrides();
+            result.override(id1, value1);
+            result.override(id2, value2);
+            result.override(id3, value3);
+            result.override(id4, value4);
+            return result;
+        }
     }
 
-    private final Map<String, ResourceOverrides> PER_TEST_RESOURCES =
-            new HashMap<String, ResourceOverrides>() {
-                {
-                    put("testAggregateIoStats",
-                            new ResourceOverrides() {{
-                                override(R.integer.ioStatsNumSamplesToStore, 5);
-                            }});
-                    put("testIoStatsDeltas",
-                            new ResourceOverrides() {{
-                                override(R.integer.ioStatsNumSamplesToStore, 5);
-                            }});
-                    put("testEventDelivery",
-                        new ResourceOverrides() {{
-                            override(R.integer.ioStatsNumSamplesToStore, 5);
-                        }});
-                    put("testIntentOnExcessiveWrite",
-                            new ResourceOverrides() {{
-                                override(R.integer.ioStatsNumSamplesToStore, 5);
-                                override(R.integer.maxExcessiveIoSamplesInWindow, 0);
-                                override(R.integer.acceptableWrittenKBytesPerSample, 10);
-                                override(R.integer.acceptableFsyncCallsPerSample, 1000);
-                            }});
-
-                    put("testIntentOnExcessiveFsync",
-                            new ResourceOverrides() {{
-                                override(R.integer.ioStatsNumSamplesToStore, 5);
-                                override(R.integer.maxExcessiveIoSamplesInWindow, 0);
-                                override(R.integer.acceptableWrittenKBytesPerSample, 1000);
-                                override(R.integer.acceptableFsyncCallsPerSample, 2);
-                            }});
-
-                    put("testZeroWindowDisablesCollection",
-                            new ResourceOverrides() {{
-                                override(R.integer.ioStatsNumSamplesToStore, 0);
-                            }});
-
-                }
-            };
+    private static final Map<String, ResourceOverrides> PER_TEST_RESOURCES = Map.of(
+            "testAggregateIoStats", ResourceOverrides.of(
+                    R.integer.ioStatsNumSamplesToStore, 5),
+            "testIoStatsDeltas", ResourceOverrides.of(
+                    R.integer.ioStatsNumSamplesToStore, 5),
+            "testEventDelivery", ResourceOverrides.of(
+                    R.integer.ioStatsNumSamplesToStore, 5),
+            "testIntentOnExcessiveWrite", ResourceOverrides.of(
+                    R.integer.ioStatsNumSamplesToStore, 5,
+                    R.integer.maxExcessiveIoSamplesInWindow, 0,
+                    R.integer.acceptableWrittenKBytesPerSample, 10,
+                    R.integer.acceptableFsyncCallsPerSample, 1000),
+            "testIntentOnExcessiveFsync", ResourceOverrides.of(
+                    R.integer.ioStatsNumSamplesToStore, 5,
+                    R.integer.maxExcessiveIoSamplesInWindow, 0,
+                    R.integer.acceptableWrittenKBytesPerSample, 1000,
+                    R.integer.acceptableFsyncCallsPerSample, 2),
+            "testZeroWindowDisablesCollection", ResourceOverrides.of(
+                    R.integer.ioStatsNumSamplesToStore, 0));
 
     private static final class TestData {
         static final TestData DEFAULT = new TestData(0, DEFAULT_WEAR_INFORMATION, null, null);
@@ -187,120 +187,117 @@
         }
     }
 
-    private static final Map<String, TestData> PER_TEST_DATA =
-            new HashMap<String, TestData>() {
-                {
-                    put("testReadWearHistory",
-                        new TestData(6500, DEFAULT_WEAR_INFORMATION,
-                            WearHistory.fromRecords(
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE)
-                                    .toWearEstimate(new WearEstimate(10, 0))
-                                    .atUptime(1000)
-                                    .atTimestamp(Instant.ofEpochMilli(5000)).build(),
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(new WearEstimate(10, 0))
-                                    .toWearEstimate(new WearEstimate(20, 0))
-                                    .atUptime(4000)
-                                    .atTimestamp(Instant.ofEpochMilli(12000)).build(),
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(new WearEstimate(20, 0))
-                                    .toWearEstimate(new WearEstimate(30, 0))
-                                    .atUptime(6500)
-                                    .atTimestamp(Instant.ofEpochMilli(17000)).build()), null));
+    private static final Map<String, TestData> PER_TEST_DATA = Map.of(
+            "testReadWearHistory",
+                new TestData(6500, DEFAULT_WEAR_INFORMATION,
+                    WearHistory.fromRecords(
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE)
+                            .toWearEstimate(new WearEstimate(10, 0))
+                            .atUptime(1000)
+                            .atTimestamp(Instant.ofEpochMilli(5000)).build(),
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(new WearEstimate(10, 0))
+                            .toWearEstimate(new WearEstimate(20, 0))
+                            .atUptime(4000)
+                            .atTimestamp(Instant.ofEpochMilli(12000)).build(),
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(new WearEstimate(20, 0))
+                            .toWearEstimate(new WearEstimate(30, 0))
+                            .atUptime(6500)
+                            .atTimestamp(Instant.ofEpochMilli(17000)).build()), null),
 
-                    put("testNotAcceptableWearEvent",
-                        new TestData(2520006499L,
-                            new WearInformation(40, 0, WearInformation.PRE_EOL_INFO_NORMAL),
-                            WearHistory.fromRecords(
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE)
-                                    .toWearEstimate(new WearEstimate(10, 0))
-                                    .atUptime(1000)
-                                    .atTimestamp(Instant.ofEpochMilli(5000)).build(),
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(new WearEstimate(10, 0))
-                                    .toWearEstimate(new WearEstimate(20, 0))
-                                    .atUptime(4000)
-                                    .atTimestamp(Instant.ofEpochMilli(12000)).build(),
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(new WearEstimate(20, 0))
-                                    .toWearEstimate(new WearEstimate(30, 0))
-                                    .atUptime(6500)
-                                    .atTimestamp(Instant.ofEpochMilli(17000)).build()), null));
+            "testNotAcceptableWearEvent",
+                new TestData(2520006499L,
+                    new WearInformation(40, 0, WearInformation.PRE_EOL_INFO_NORMAL),
+                    WearHistory.fromRecords(
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE)
+                            .toWearEstimate(new WearEstimate(10, 0))
+                            .atUptime(1000)
+                            .atTimestamp(Instant.ofEpochMilli(5000)).build(),
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(new WearEstimate(10, 0))
+                            .toWearEstimate(new WearEstimate(20, 0))
+                            .atUptime(4000)
+                            .atTimestamp(Instant.ofEpochMilli(12000)).build(),
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(new WearEstimate(20, 0))
+                            .toWearEstimate(new WearEstimate(30, 0))
+                            .atUptime(6500)
+                            .atTimestamp(Instant.ofEpochMilli(17000)).build()), null),
 
-                    put("testAcceptableWearEvent",
-                        new TestData(2520006501L,
-                            new WearInformation(40, 0, WearInformation.PRE_EOL_INFO_NORMAL),
-                            WearHistory.fromRecords(
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE)
-                                    .toWearEstimate(new WearEstimate(10, 0))
-                                    .atUptime(1000)
-                                    .atTimestamp(Instant.ofEpochMilli(5000)).build(),
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(new WearEstimate(10, 0))
-                                    .toWearEstimate(new WearEstimate(20, 0))
-                                    .atUptime(4000)
-                                    .atTimestamp(Instant.ofEpochMilli(12000)).build(),
-                                WearEstimateRecord.Builder.newBuilder()
-                                    .fromWearEstimate(new WearEstimate(20, 0))
-                                    .toWearEstimate(new WearEstimate(30, 0))
-                                    .atUptime(6500)
-                                    .atTimestamp(Instant.ofEpochMilli(17000)).build()), null));
+            "testAcceptableWearEvent",
+                new TestData(2520006501L,
+                    new WearInformation(40, 0, WearInformation.PRE_EOL_INFO_NORMAL),
+                    WearHistory.fromRecords(
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE)
+                            .toWearEstimate(new WearEstimate(10, 0))
+                            .atUptime(1000)
+                            .atTimestamp(Instant.ofEpochMilli(5000)).build(),
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(new WearEstimate(10, 0))
+                            .toWearEstimate(new WearEstimate(20, 0))
+                            .atUptime(4000)
+                            .atTimestamp(Instant.ofEpochMilli(12000)).build(),
+                        WearEstimateRecord.Builder.newBuilder()
+                            .fromWearEstimate(new WearEstimate(20, 0))
+                            .toWearEstimate(new WearEstimate(30, 0))
+                            .atUptime(6500)
+                            .atTimestamp(Instant.ofEpochMilli(17000)).build()), null),
 
-                    put("testBootIoStats",
-                        new TestData(1000L,
-                            new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
-                            null,
-                            new UidIoRecord[]{
-                                new UidIoRecord(0, 5000, 6000, 3000, 1000, 1,
-                                    0, 0, 0, 0, 0),
-                                new UidIoRecord(1000, 200, 5000, 0, 4000, 0,
-                                    1000, 0, 500, 0, 0)}));
+            "testBootIoStats",
+                new TestData(1000L,
+                    new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
+                    null,
+                    new UidIoRecord[]{
+                        new UidIoRecord(0, 5000, 6000, 3000, 1000, 1,
+                            0, 0, 0, 0, 0),
+                        new UidIoRecord(1000, 200, 5000, 0, 4000, 0,
+                            1000, 0, 500, 0, 0)}),
 
-                    put("testAggregateIoStats",
-                        new TestData(1000L,
-                            new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
-                            null,
-                            new UidIoRecord[]{
-                                new UidIoRecord(0, 5000, 6000, 3000, 1000, 1,
-                                    0, 0, 0, 0, 0),
-                                new UidIoRecord(1000, 200, 5000, 0, 4000, 0,
-                                    1000, 0, 500, 0, 0)}));
+            "testAggregateIoStats",
+                new TestData(1000L,
+                    new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
+                    null,
+                    new UidIoRecord[]{
+                        new UidIoRecord(0, 5000, 6000, 3000, 1000, 1,
+                            0, 0, 0, 0, 0),
+                        new UidIoRecord(1000, 200, 5000, 0, 4000, 0,
+                            1000, 0, 500, 0, 0)}),
 
-                    put("testIoStatsDeltas",
-                        new TestData(1000L,
-                            new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
-                            null,
-                            new UidIoRecord[]{
-                                new UidIoRecord(0, 5000, 6000, 3000, 1000, 1,
-                                    0, 0, 0, 0, 0)}));
+            "testIoStatsDeltas",
+                new TestData(1000L,
+                    new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
+                    null,
+                    new UidIoRecord[]{
+                        new UidIoRecord(0, 5000, 6000, 3000, 1000, 1,
+                            0, 0, 0, 0, 0)}),
 
-                    put("testComputeShutdownCost",
-                        new TestData(1000L,
-                            new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
-                            null,
-                            null,
-                            new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 120),
-                                                      new LifetimeWriteInfo("p2", "ext4", 100),
-                                                      new LifetimeWriteInfo("p3", "f2fs", 100)},
-                            new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 200),
-                                                      new LifetimeWriteInfo("p2", "ext4", 300),
-                                                      new LifetimeWriteInfo("p3", "f2fs", 100)}));
+            "testComputeShutdownCost",
+                new TestData(1000L,
+                    new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
+                    null,
+                    null,
+                    new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 120),
+                                              new LifetimeWriteInfo("p2", "ext4", 100),
+                                              new LifetimeWriteInfo("p3", "f2fs", 100)},
+                    new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 200),
+                                              new LifetimeWriteInfo("p2", "ext4", 300),
+                                              new LifetimeWriteInfo("p3", "f2fs", 100)}),
 
-                    put("testNegativeShutdownCost",
-                        new TestData(1000L,
-                            new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
-                            null,
-                            null,
-                            new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 120),
-                                new LifetimeWriteInfo("p2", "ext4", 100),
-                                new LifetimeWriteInfo("p3", "f2fs", 200)},
-                            new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 200),
-                                new LifetimeWriteInfo("p2", "ext4", 300),
-                                new LifetimeWriteInfo("p3", "f2fs", 100)}));
-                }};
+            "testNegativeShutdownCost",
+                new TestData(1000L,
+                    new WearInformation(0, 0, WearInformation.PRE_EOL_INFO_NORMAL),
+                    null,
+                    null,
+                    new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 120),
+                        new LifetimeWriteInfo("p2", "ext4", 100),
+                        new LifetimeWriteInfo("p3", "f2fs", 200)},
+                    new LifetimeWriteInfo[] { new LifetimeWriteInfo("p1", "ext4", 200),
+                        new LifetimeWriteInfo("p2", "ext4", 300),
+                        new LifetimeWriteInfo("p3", "f2fs", 100)}));
 
     private final MockSystemStateInterface mMockSystemStateInterface =
             new MockSystemStateInterface();
diff --git a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusConcurrentTest.java b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusConcurrentTest.java
index 13e6041..e59881c 100644
--- a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusConcurrentTest.java
+++ b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusConcurrentTest.java
@@ -28,6 +28,7 @@
 import android.media.AudioFocusInfo;
 import android.media.AudioManager;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -157,13 +158,19 @@
 
     @Before
     public void setUp() {
-        mCarAudioZones = generateAudioZones();
+        super.setUp();
         when(mCarAudioService.getZoneIdForUid(mExcludedAudioClientInfo.getClientUid()))
                 .thenReturn(PRIMARY_ZONE_ID);
         when(mCarAudioService.getZoneIdForUid(mAcceptedAudioClientInfo.getClientUid()))
                 .thenReturn(PRIMARY_ZONE_ID);
     }
 
+    @After
+    @Override
+    public void tearDown() {
+        super.tearDown();
+    }
+
     @Test
     public void concurrentInteractionsForFocusGainNoPause_requestGrantedAndFocusLossSent() {
         CarZonesAudioFocus carZonesAudioFocus = getCarZonesAudioFocus();
diff --git a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusExclusiveTest.java b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusExclusiveTest.java
index f12d726..032ab55 100644
--- a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusExclusiveTest.java
+++ b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusExclusiveTest.java
@@ -26,6 +26,7 @@
 import android.media.AudioFocusInfo;
 import android.media.AudioManager;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -104,14 +105,21 @@
     }
 
     @Before
+    @Override
     public void setUp() {
-        mCarAudioZones = generateAudioZones();
+        super.setUp();
         when(mCarAudioService.getZoneIdForUid(mExcludedAudioClientInfo.getClientUid()))
                 .thenReturn(PRIMARY_ZONE_ID);
         when(mCarAudioService.getZoneIdForUid(mAcceptedAudioClientInfo.getClientUid()))
                 .thenReturn(PRIMARY_ZONE_ID);
     }
 
+    @After
+    @Override
+    public void tearDown() {
+        super.tearDown();
+    }
+
     @Test
     public void exclusiveInteractionsForFocusGainNoPause_requestGrantedAndFocusLossSent() {
         testExclusiveNonTransientInteractions(/* pauseForDucking= */ false);
diff --git a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusRejectedTest.java b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusRejectedTest.java
index 657bc4a..ff2572b 100644
--- a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusRejectedTest.java
+++ b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusRejectedTest.java
@@ -25,6 +25,7 @@
 
 import android.media.AudioFocusInfo;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -115,14 +116,21 @@
     }
 
     @Before
+    @Override
     public void setUp() {
-        mCarAudioZones = generateAudioZones();
+        super.setUp();
         when(mCarAudioService.getZoneIdForUid(mAcceptedAudioClientInfo.getClientUid()))
                 .thenReturn(PRIMARY_ZONE_ID);
         when(mCarAudioService.getZoneIdForUid(mRejectedAudioClientInfo.getClientUid()))
                 .thenReturn(PRIMARY_ZONE_ID);
     }
 
+    @After
+    @Override
+    public void tearDown() {
+        super.tearDown();
+    }
+
     @Test
     public void rejectedInteractionsFocusTest() {
         CarZonesAudioFocus carZonesAudioFocus = getCarZonesAudioFocus();
diff --git a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTest.java b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTest.java
index 4cac67f..a889cc7 100644
--- a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTest.java
+++ b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTest.java
@@ -38,11 +38,9 @@
 import android.os.Bundle;
 import android.util.SparseArray;
 
-import com.android.car.CarLocalServices;
-import com.android.car.oem.CarOemProxyService;
-
 import com.google.common.truth.Expect;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -59,11 +57,16 @@
     public final Expect expect = Expect.create();
 
     @Before
+    @Override
     public void setUp() {
-        mCarAudioZones = generateAudioZones();
+        super.setUp();
         when(mCarAudioService.getZoneIdForUid(MEDIA_CLIENT_UID_1)).thenReturn(PRIMARY_ZONE_ID);
-        CarLocalServices.removeServiceForTest(CarOemProxyService.class);
-        CarLocalServices.addService(CarOemProxyService.class, mMockCarOemProxyService);
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        super.tearDown();
     }
 
     @Test
@@ -431,7 +434,7 @@
 
         carZonesAudioFocus.onAudioFocusRequest(audioFocusInfo, AUDIOFOCUS_REQUEST_GRANTED);
 
-        verify(mMockCarOemAudioFocusProxyService).audioFocusChanged(
+        verify(mMockCarOemAudioFocusProxyService).notifyAudioFocusChange(
                 focusHoldersCaptor.capture(), focusLosersCaptor.capture(), eq(PRIMARY_ZONE_ID));
         expect.withMessage("Audio focus request with null callback OEM service focus holders").that(
                 focusHoldersCaptor.getValue()).containsExactly(audioFocusInfo);
@@ -453,7 +456,7 @@
 
         carZonesAudioFocus.onAudioFocusRequest(audioFocusInfo, AUDIOFOCUS_REQUEST_GRANTED);
 
-        verify(mMockCarOemAudioFocusProxyService).audioFocusChanged(
+        verify(mMockCarOemAudioFocusProxyService).notifyAudioFocusChange(
                 focusHoldersCaptor.capture(), focusLosersCaptor.capture(), eq(PRIMARY_ZONE_ID));
         expect.withMessage("Audio focus request OEM service focus holders").that(
                 focusHoldersCaptor.getValue()).containsExactly(audioFocusInfo);
@@ -476,7 +479,7 @@
 
         carZonesAudioFocus.onAudioFocusAbandon(audioFocusInfo);
 
-        verify(mMockCarOemAudioFocusProxyService, times(2)).audioFocusChanged(
+        verify(mMockCarOemAudioFocusProxyService, times(2)).notifyAudioFocusChange(
                 focusHoldersCaptor.capture(), focusLosersCaptor.capture(), eq(PRIMARY_ZONE_ID));
         expect.withMessage("Audio focus abandon OEM service focus holders").that(
                 focusHoldersCaptor.getValue()).isEmpty();
@@ -500,7 +503,7 @@
 
         carZonesAudioFocus.onAudioFocusRequest(callAudioFocusInfo, AUDIOFOCUS_REQUEST_GRANTED);
 
-        verify(mMockCarOemAudioFocusProxyService, times(2)).audioFocusChanged(
+        verify(mMockCarOemAudioFocusProxyService, times(2)).notifyAudioFocusChange(
                 focusHoldersCaptor.capture(), focusLosersCaptor.capture(), eq(PRIMARY_ZONE_ID));
         expect.withMessage("Call audio focus request OEM service focus holders").that(
                 focusHoldersCaptor.getValue()).containsExactly(callAudioFocusInfo);
diff --git a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTestBase.java b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTestBase.java
index 13e3ee8..ba4b077 100644
--- a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTestBase.java
+++ b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusTestBase.java
@@ -47,6 +47,7 @@
 import android.media.audiopolicy.AudioPolicy;
 import android.util.SparseArray;
 
+import com.android.car.CarLocalServices;
 import com.android.car.oem.CarOemAudioFocusProxyService;
 import com.android.car.oem.CarOemProxyService;
 
@@ -184,6 +185,18 @@
 
     protected SparseArray<CarAudioZone> mCarAudioZones;
 
+    public void setUp() {
+        mCarAudioZones = generateAudioZones();
+        CarLocalServices.removeServiceForTest(CarOemProxyService.class);
+        CarLocalServices.addService(CarOemProxyService.class, mMockCarOemProxyService);
+        when(mMockCarOemProxyService.isOemServiceReady()).thenReturn(true);
+        when(mMockCarOemProxyService.isOemServiceEnabled()).thenReturn(true);
+    }
+
+    public void tearDown() {
+        CarLocalServices.removeServiceForTest(CarOemProxyService.class);
+    }
+
     protected AudioFocusInfo generateCallRequestForPrimaryZone() {
         return new AudioFocusInfoBuilder().setUsage(USAGE_VOICE_COMMUNICATION)
                 .setGainRequest(AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)
diff --git a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusUsageTest.java b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusUsageTest.java
index cc0b47b..4ba0e0f 100644
--- a/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusUsageTest.java
+++ b/tests/carservice_test/src/com/android/car/audio/CarZonesAudioFocusUsageTest.java
@@ -27,6 +27,7 @@
 
 import android.media.AudioFocusInfo;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -70,12 +71,19 @@
     }
 
     @Before
+    @Override
     public void setUp() {
-        mCarAudioZones = generateAudioZones();
+        super.setUp();
         when(mCarAudioService.getZoneIdForUid(mAudioClientInfo.getClientUid()))
                 .thenReturn(PRIMARY_ZONE_ID);
     }
 
+    @After
+    @Override
+    public void tearDown() {
+        super.tearDown();
+    }
+
     @Test
     public void requestFocus_forEveryUsage_requestGranted() {
         CarZonesAudioFocus carZonesAudioFocus = getCarZonesAudioFocus();
diff --git a/tests/carservice_unit_test/res/raw/car_api_classes.txt b/tests/carservice_unit_test/res/raw/car_api_classes.txt
index a77d57a..8c4a259 100644
--- a/tests/carservice_unit_test/res/raw/car_api_classes.txt
+++ b/tests/carservice_unit_test/res/raw/car_api_classes.txt
@@ -40,7 +40,6 @@
 android.car.VehicleHvacFanDirection
 android.car.VehicleIgnitionState
 android.car.VehicleLightState
-android.car.hardware.property.VehicleLightSwitch
 android.car.VehicleOilLevel
 android.car.VehiclePropertyAccess
 android.car.VehiclePropertyIds
diff --git a/tests/carservice_unit_test/src/android/car/oem/OemCarServiceTest.java b/tests/carservice_unit_test/src/android/car/oem/OemCarServiceTest.java
index e9ee6f6..973b3ba 100644
--- a/tests/carservice_unit_test/src/android/car/oem/OemCarServiceTest.java
+++ b/tests/carservice_unit_test/src/android/car/oem/OemCarServiceTest.java
@@ -52,8 +52,6 @@
                 () -> mOemCarService.getOemAudioFocusService());
         assertThrows(SecurityException.class,
                 () -> mOemCarService.onCarServiceReady(mIOemCarServiceCallback));
-        assertThrows(SecurityException.class,
-                () -> mOemCarService.isOemServiceReady());
     }
 
     @Test
@@ -64,13 +62,6 @@
     }
 
     @Test
-    public void testIsOemServiceReady() throws Exception {
-        mockCallerPemission();
-
-        assertThat(mOemCarService.isOemServiceReady()).isTrue();
-    }
-
-    @Test
     public void testGetOemAudioFocusService_notNull() throws Exception {
         TestOemCarService testOemCarService = new TestOemCarService();
         testOemCarService.mockCheckCallingPermission();
@@ -108,11 +99,6 @@
         }
 
         @Override
-        public boolean isOemServiceReady() {
-            return true;
-        }
-
-        @Override
         public OemCarAudioFocusService getOemAudioFocusService() {
             synchronized (mLock) {
                 if (mMockAudioFocusService) {
@@ -141,5 +127,9 @@
                 mMockAudioFocusService = true;
             }
         }
+
+        @Override
+        public void onCarServiceReady() {
+        }
     }
 }
diff --git a/tests/carservice_unit_test/src/android/car/test/mocks/AndroidMockitoHelperTest.java b/tests/carservice_unit_test/src/android/car/test/mocks/AndroidMockitoHelperTest.java
index 9d89c0a..e09bac2 100644
--- a/tests/carservice_unit_test/src/android/car/test/mocks/AndroidMockitoHelperTest.java
+++ b/tests/carservice_unit_test/src/android/car/test/mocks/AndroidMockitoHelperTest.java
@@ -32,6 +32,7 @@
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetSystemUser;
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetUserHandles;
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetUserInfo;
+import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetVisibleUsers;
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmHasUserRestrictionForUser;
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmIsHeadlessSystemUserMode;
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmIsUserRunning;
@@ -202,6 +203,16 @@
     }
 
     @Test
+    public void testMockUmGetVisibleUsers() {
+        UserHandle user1 = UserHandle.of(100);
+        UserHandle user2 = UserHandle.of(200);
+
+        mockUmGetVisibleUsers(mMockedUserManager, 100, 200);
+
+        assertThat(mMockedUserManager.getVisibleUsers()).containsExactly(user1, user2);
+    }
+
+    @Test
     public void testMockDpmLogoutUser() {
         mockDpmLogoutUser(mMockedDevicePolicyManager, 42);
 
diff --git a/tests/carservice_unit_test/src/com/android/car/AbstractICarServiceHelperStub.java b/tests/carservice_unit_test/src/com/android/car/AbstractICarServiceHelperStub.java
index 8455d53..27de5f7 100644
--- a/tests/carservice_unit_test/src/com/android/car/AbstractICarServiceHelperStub.java
+++ b/tests/carservice_unit_test/src/com/android/car/AbstractICarServiceHelperStub.java
@@ -17,6 +17,7 @@
 
 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE;
 
+import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.car.app.CarActivityManager;
 import android.content.ComponentName;
@@ -119,4 +120,11 @@
 
         return false;
     }
+
+    @Override
+    public void setProcessProfile(int pid, int uid, @NonNull String profile) {
+        Log.d(TAG, "setProcessProfile(" + pid + "," + uid + "," + profile + ")");
+
+        return;
+    }
 }
diff --git a/tests/carservice_unit_test/src/com/android/car/AidlVehicleStubUnitTest.java b/tests/carservice_unit_test/src/com/android/car/AidlVehicleStubUnitTest.java
index ed1ac13..65a5e06 100644
--- a/tests/carservice_unit_test/src/com/android/car/AidlVehicleStubUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/AidlVehicleStubUnitTest.java
@@ -62,10 +62,10 @@
 import android.os.ServiceSpecificException;
 
 import com.android.car.VehicleStub.AsyncGetSetRequest;
-import com.android.car.hal.HalClientCallback;
 import com.android.car.hal.HalPropConfig;
 import com.android.car.hal.HalPropValue;
 import com.android.car.hal.HalPropValueBuilder;
+import com.android.car.hal.VehicleHalCallback;
 import com.android.car.internal.LargeParcelable;
 import com.android.compatibility.common.util.PollingCheck;
 
@@ -243,7 +243,7 @@
         option.sampleRate = TEST_SAMPLE_RATE;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
 
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mAidlVehicleStub.newSubscriptionClient(callback);
 
         client.subscribe(options);
@@ -254,7 +254,7 @@
 
     @Test
     public void testUnsubscribeAidl() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mAidlVehicleStub.newSubscriptionClient(callback);
 
         client.unsubscribe(TEST_PROP);
@@ -1075,7 +1075,7 @@
 
     @Test
     public void testAidlVehicleCallbackOnPropertyEventSmallData() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mAidlVehicleStub.newSubscriptionClient(callback);
         IVehicleCallback aidlCallback = (IVehicleCallback) client;
         VehiclePropValues propValues = new VehiclePropValues();
@@ -1093,7 +1093,7 @@
 
     @Test
     public void testAidlVehicleCallbackOnPropertyEventLargeData() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mAidlVehicleStub.newSubscriptionClient(callback);
         IVehicleCallback aidlCallback = (IVehicleCallback) client;
         VehiclePropValues propValues = new VehiclePropValues();
@@ -1121,7 +1121,7 @@
 
     @Test
     public void testAidlVehicleCallbackOnPropertySetErrorSmallData() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mAidlVehicleStub.newSubscriptionClient(callback);
         IVehicleCallback aidlCallback = (IVehicleCallback) client;
         VehiclePropErrors errors = new VehiclePropErrors();
@@ -1138,7 +1138,7 @@
 
     @Test
     public void testAidlVehicleCallbackOnPropertySetErrorLargeData() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mAidlVehicleStub.newSubscriptionClient(callback);
         IVehicleCallback aidlCallback = (IVehicleCallback) client;
         VehiclePropErrors errors = new VehiclePropErrors();
diff --git a/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java
index 55cd10e..8e06e85 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarOccupantZoneServiceTest.java
@@ -668,7 +668,7 @@
                 assertThrows(IllegalArgumentException.class,
                         () -> mService.setAudioZoneIdsForOccupantZoneIds(
                                 audioZoneIdToOccupantZoneMapping));
-        thrown.getMessage().contains("does not exist");
+        assertThat(thrown).hasMessageThat().contains("does not exist");
     }
 
     @Test
diff --git a/tests/carservice_unit_test/src/com/android/car/CarTestServiceUnitTest.java b/tests/carservice_unit_test/src/com/android/car/CarTestServiceUnitTest.java
index 4360f9a..a945d9c 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarTestServiceUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarTestServiceUnitTest.java
@@ -88,10 +88,13 @@
 
     @Test
     public void testDumpVhal_VhalNotClosingFd() throws Exception {
+        // A holder for ParcelFileDescriptor to keep it alive.
+        ParcelFileDescriptor[] fdHolder = new ParcelFileDescriptor[1];
         doAnswer(invocation -> {
             ParcelFileDescriptor fd = (ParcelFileDescriptor) invocation.getArgument(0);
-            // Duplicate the fd and never close it.
-            fd.dup();
+            // Duplicate the fd and never close it. Make sure the copied fd is not closed until
+            // the end of the test by storing it.
+            fdHolder[0] = fd.dup();
             return null;
         }).when(mCarImpl).dumpVhal(any(), any());
 
diff --git a/tests/carservice_unit_test/src/com/android/car/HidlVehicleStubUnitTest.java b/tests/carservice_unit_test/src/com/android/car/HidlVehicleStubUnitTest.java
index 2432140..b976245 100644
--- a/tests/carservice_unit_test/src/com/android/car/HidlVehicleStubUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/HidlVehicleStubUnitTest.java
@@ -46,11 +46,11 @@
 import android.util.SparseArray;
 
 import com.android.car.VehicleStub.AsyncGetSetRequest;
-import com.android.car.hal.HalClientCallback;
 import com.android.car.hal.HalPropConfig;
 import com.android.car.hal.HalPropValue;
 import com.android.car.hal.HalPropValueBuilder;
 import com.android.car.hal.HidlHalPropConfig;
+import com.android.car.hal.VehicleHalCallback;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -360,7 +360,7 @@
         hidlOptions.sampleRate = TEST_SAMPLE_RATE;
         hidlOptions.flags = android.hardware.automotive.vehicle.V2_0.SubscribeFlags.EVENTS_FROM_CAR;
 
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mHidlVehicleStub.newSubscriptionClient(callback);
 
         client.subscribe(new SubscribeOptions[]{aidlOptions});
@@ -373,7 +373,7 @@
 
     @Test
     public void testUnsubscribeHidl() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mHidlVehicleStub.newSubscriptionClient(callback);
 
         client.unsubscribe(TEST_PROP);
@@ -632,7 +632,7 @@
 
     @Test
     public void testHidlVehicleCallbackOnPropertyEvent() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mHidlVehicleStub.newSubscriptionClient(callback);
         IVehicleCallback.Stub hidlCallback = (IVehicleCallback.Stub) client;
 
@@ -645,7 +645,7 @@
 
     @Test
     public void testHidlVehicleCallbackOnPropertySetError() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         VehicleStub.SubscriptionClient client = mHidlVehicleStub.newSubscriptionClient(callback);
         IVehicleCallback.Stub hidlCallback = (IVehicleCallback.Stub) client;
         VehiclePropError error = new VehiclePropError();
diff --git a/tests/carservice_unit_test/src/com/android/car/audio/CarAudioGainConfigInfoTest.java b/tests/carservice_unit_test/src/com/android/car/audio/CarAudioGainConfigInfoTest.java
index 2ce2769..326809f 100644
--- a/tests/carservice_unit_test/src/com/android/car/audio/CarAudioGainConfigInfoTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/audio/CarAudioGainConfigInfoTest.java
@@ -25,6 +25,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Objects;
+
 @RunWith(AndroidJUnit4.class)
 public final class CarAudioGainConfigInfoTest {
     private static final int PRIMARY_ZONE_ID = 0;
@@ -56,6 +58,45 @@
     }
 
     @Test
+    public void hash_forTheSameAudioGainConfigs_equals() {
+        AudioGainConfigInfo gainInfo = new AudioGainConfigInfo();
+        gainInfo.zoneId = PRIMARY_ZONE_ID;
+        gainInfo.devicePortAddress = PRIMARY_MUSIC_ADDRESS;
+        gainInfo.volumeIndex = 666;
+        CarAudioGainConfigInfo carGainInfo1 = new CarAudioGainConfigInfo(gainInfo);
+
+        assertWithMessage("Audio Gain Configs")
+                .that(Objects.hash(PRIMARY_ZONE_ID, PRIMARY_MUSIC_ADDRESS, 666))
+                .isEqualTo(carGainInfo1.hashCode());
+    }
+
+    @Test
+    public void hash_withDifferentZoneIds_notEquals() {
+        AudioGainConfigInfo gainInfo = new AudioGainConfigInfo();
+        gainInfo.zoneId = PRIMARY_ZONE_ID;
+        gainInfo.devicePortAddress = PRIMARY_MUSIC_ADDRESS;
+        gainInfo.volumeIndex = 666;
+        CarAudioGainConfigInfo carGainInfo1 = new CarAudioGainConfigInfo(gainInfo);
+
+        assertWithMessage("Audio Gain Configs")
+                .that(Objects.hash(PRIMARY_ZONE_ID, PRIMARY_MUSIC_ADDRESS, 665))
+                .isNotEqualTo(carGainInfo1.hashCode());
+    }
+
+    @Test
+    public void hash_forTheSameObject_succeeds() {
+        AudioGainConfigInfo gainInfo = new AudioGainConfigInfo();
+        gainInfo.zoneId = PRIMARY_ZONE_ID;
+        gainInfo.devicePortAddress = PRIMARY_MUSIC_ADDRESS;
+        gainInfo.volumeIndex = 666;
+        CarAudioGainConfigInfo carGainInfo1 = new CarAudioGainConfigInfo(gainInfo);
+        CarAudioGainConfigInfo carGainInfo2 = new CarAudioGainConfigInfo(gainInfo);
+
+        assertWithMessage("Audio Gain Configs").that(carGainInfo1.hashCode())
+                .isEqualTo(carGainInfo2.hashCode());
+    }
+
+    @Test
     public void equals_succeeds() {
         AudioGainConfigInfo gainInfo = new AudioGainConfigInfo();
         gainInfo.zoneId = PRIMARY_ZONE_ID;
diff --git a/tests/carservice_unit_test/src/com/android/car/audio/CarAudioServiceUnitTest.java b/tests/carservice_unit_test/src/com/android/car/audio/CarAudioServiceUnitTest.java
index 69597a1..c290c3d 100644
--- a/tests/carservice_unit_test/src/com/android/car/audio/CarAudioServiceUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/audio/CarAudioServiceUnitTest.java
@@ -74,6 +74,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.when;
 
@@ -116,6 +117,7 @@
 import com.android.car.audio.hal.AudioControlWrapper;
 import com.android.car.audio.hal.AudioControlWrapper.AudioControlDeathRecipient;
 import com.android.car.audio.hal.AudioControlWrapperAidl;
+import com.android.car.oem.CarOemProxyService;
 import com.android.car.test.utils.TemporaryFile;
 
 import org.junit.After;
@@ -198,17 +200,23 @@
     @Mock
     IBinder mBinder;
     @Mock
+    IBinder mVolumeCallbackBinder;
+    @Mock
     IAudioControl mAudioControl;
     @Mock
     private PackageManager mMockPackageManager;
     @Mock
     private CarOccupantZoneService mMockOccupantZoneService;
     @Mock
+    private CarOemProxyService mMockCarOemProxyService;
+    @Mock
     private IAudioService mMockAudioService;
     @Mock
     private Uri mNavSettingUri;
     @Mock
     private AudioControlWrapperAidl mAudioControlWrapperAidl;
+    @Mock
+    private CarVolumeCallbackHandler mCarVolumeCallbackHandler;
 
     private boolean mPersistMasterMute = true;
     private boolean mUseDynamicRouting = true;
@@ -229,7 +237,6 @@
         session
                 .spyStatic(AudioManagerHelper.class)
                 .spyStatic(AudioControlWrapperAidl.class)
-                .spyStatic(CarLocalServices.class)
                 .spyStatic(AudioControlFactory.class)
                 .spyStatic(SystemProperties.class)
                 .spyStatic(ServiceManager.class);
@@ -270,6 +277,8 @@
     public void tearDown() throws Exception {
         mTemporaryAudioConfigurationFile.close();
         mTemporaryAudioConfigurationWithoutZoneMappingFile.close();
+        CarLocalServices.removeServiceForTest(CarOemProxyService.class);
+        CarLocalServices.removeServiceForTest(CarOccupantZoneService.class);
     }
 
     private void setupAudioControlHAL() {
@@ -294,18 +303,23 @@
         doReturn(true)
                 .when(() -> AudioManagerHelper
                         .setAudioDeviceGain(any(), any(), anyInt(), anyBoolean()));
-        doReturn(mMockOccupantZoneService)
-                .when(() ->  CarLocalServices.getService(CarOccupantZoneService.class));
         doReturn(true)
                 .when(() -> SystemProperties.getBoolean(PROPERTY_RO_ENABLE_AUDIO_PATCH, false));
 
+        CarLocalServices.removeServiceForTest(CarOccupantZoneService.class);
+        CarLocalServices.addService(CarOccupantZoneService.class, mMockOccupantZoneService);
+
+        CarLocalServices.removeServiceForTest(CarOemProxyService.class);
+        CarLocalServices.addService(CarOemProxyService.class, mMockCarOemProxyService);
+
         setupAudioManager();
 
         setupResources();
 
         mCarAudioService =
                 new CarAudioService(mMockContext,
-                        mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                        mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                        mCarVolumeCallbackHandler);
     }
 
     private void setupAudioManager() throws Exception {
@@ -356,7 +370,9 @@
     public void constructor_withNullContextAndNullPath_fails() {
         NullPointerException thrown =
                 assertThrows(NullPointerException.class,
-                        () -> new CarAudioService(null, null));
+                        () -> new CarAudioService(/* context= */null,
+                                /* audioConfigurationPath= */ null,
+                                /* carVolumeCallbackHandler= */ null));
 
         assertWithMessage("Car Audio Service Construction")
                 .that(thrown).hasMessageThat().contains("Context");
@@ -398,7 +414,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         assertWithMessage("Non dynamic routing primary zone car volume group count")
@@ -420,7 +437,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         assertWithMessage("Non dynamic routing primary zone's media car volume group id")
@@ -443,7 +461,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         assertWithMessage("Non dynamic routing primary zone's navigation car volume group id")
@@ -467,7 +486,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         assertWithMessage("Non dynamic routing primary zone's invalid car volume group id")
@@ -674,7 +694,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         IllegalStateException thrown = assertThrows(IllegalStateException.class,
@@ -726,7 +747,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         boolean results = noZoneMappingAudioService
@@ -740,7 +762,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         noZoneMappingAudioService
@@ -758,7 +781,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
         AudioFocusInfo audioFocusInfo = createAudioFocusInfoForMedia();
 
@@ -780,7 +804,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         int zoneId = noZoneMappingAudioService
@@ -795,7 +820,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         noZoneMappingAudioService
@@ -813,7 +839,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         noZoneMappingAudioService
@@ -848,7 +875,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         IllegalStateException thrown = assertThrows(IllegalStateException.class,
@@ -874,7 +902,8 @@
     @Test
     public void clearZoneIdForUid_forNonMappedUid_succeeds() throws Exception {
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         boolean status = noZoneMappingAudioService
@@ -889,7 +918,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         noZoneMappingAudioService
@@ -906,7 +936,8 @@
         when(mMockAudioService.setUidDeviceAffinity(any(), anyInt(), any(), any()))
                 .thenReturn(SUCCESS);
         CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         noZoneMappingAudioService.init();
 
         noZoneMappingAudioService
@@ -936,6 +967,24 @@
     }
 
     @Test
+    public void setGroupVolume_withDynamicRoutingDisabled() {
+        when(mMockResources.getBoolean(audioUseDynamicRouting))
+                .thenReturn(/* useDynamicRouting= */ false);
+        CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        nonDynamicAudioService.init();
+
+        nonDynamicAudioService.setGroupVolume(
+                PRIMARY_AUDIO_ZONE, TEST_PRIMARY_GROUP, TEST_PRIMARY_GROUP_INDEX, TEST_FLAGS);
+
+        verify(mAudioManager).setStreamVolume(
+                CarAudioDynamicRouting.STREAM_TYPES[TEST_PRIMARY_GROUP],
+                TEST_PRIMARY_GROUP_INDEX,
+                TEST_FLAGS);
+    }
+
+    @Test
     public void getOutputDeviceAddressForUsage_forMusicUsage() {
         mCarAudioService.init();
 
@@ -951,7 +1000,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         IllegalStateException thrown = assertThrows(IllegalStateException.class,
@@ -1056,6 +1106,21 @@
     }
 
     @Test
+    public void isVolumeGroupMuted_withVolumeGroupMutingDisabled() {
+        when(mMockResources.getBoolean(audioUseCarVolumeGroupMuting))
+                .thenReturn(false);
+        CarAudioService nonVolumeGroupMutingAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        nonVolumeGroupMutingAudioService.init();
+
+        assertWithMessage("Volume group for disabled volume group muting")
+                .that(nonVolumeGroupMutingAudioService.isVolumeGroupMuted(
+                        PRIMARY_AUDIO_ZONE, TEST_PRIMARY_GROUP))
+                .isFalse();
+    }
+
+    @Test
     public void getGroupMaxVolume_forPrimaryZone() {
         mCarAudioService.init();
 
@@ -1083,6 +1148,51 @@
     }
 
     @Test
+    public void getGroupMaxVolume_withNoDynamicRouting() {
+        when(mMockResources.getBoolean(audioUseDynamicRouting))
+                .thenReturn(/* useDynamicRouting= */ false);
+        CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        nonDynamicAudioService.init();
+
+        nonDynamicAudioService.getGroupMaxVolume(PRIMARY_AUDIO_ZONE, TEST_PRIMARY_GROUP);
+
+        verify(mAudioManager).getStreamMaxVolume(
+                CarAudioDynamicRouting.STREAM_TYPES[TEST_PRIMARY_GROUP]);
+    }
+
+    @Test
+    public void getGroupMinVolume_withNoDynamicRouting() {
+        when(mMockResources.getBoolean(audioUseDynamicRouting))
+                .thenReturn(/* useDynamicRouting= */ false);
+        CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        nonDynamicAudioService.init();
+
+        nonDynamicAudioService.getGroupMinVolume(PRIMARY_AUDIO_ZONE, TEST_PRIMARY_GROUP);
+
+        verify(mAudioManager).getStreamMinVolume(
+                CarAudioDynamicRouting.STREAM_TYPES[TEST_PRIMARY_GROUP]);
+    }
+
+    @Test
+    public void getGroupCurrentVolume_withNoDynamicRouting() {
+        when(mMockResources.getBoolean(audioUseDynamicRouting))
+                .thenReturn(/* useDynamicRouting= */ false);
+        CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        nonDynamicAudioService.init();
+
+        nonDynamicAudioService.getGroupVolume(PRIMARY_AUDIO_ZONE, TEST_PRIMARY_GROUP);
+
+        verify(mAudioManager).getStreamVolume(
+                CarAudioDynamicRouting.STREAM_TYPES[TEST_PRIMARY_GROUP]);
+    }
+
+    @Test
     public void setBalanceTowardRight_nonNullValue() {
         mCarAudioService.init();
 
@@ -1138,7 +1248,8 @@
         when(mMockResources.getBoolean(audioUseDynamicRouting))
                 .thenReturn(/* useDynamicRouting= */ false);
         CarAudioService nonDynamicAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonDynamicAudioService.init();
 
         assertWithMessage("Disabled dynamic routing audio feature")
@@ -1160,7 +1271,8 @@
         when(mMockResources.getBoolean(audioUseCarVolumeGroupMuting))
                 .thenReturn(false);
         CarAudioService nonVolumeGroupMutingAudioService = new CarAudioService(mMockContext,
-                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath());
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
         nonVolumeGroupMutingAudioService.init();
 
         assertWithMessage("Disabled group muting audio feature")
@@ -1231,6 +1343,38 @@
     }
 
     @Test
+    public void onOccupantZoneConfigChanged_noOccupantZoneMapping() throws Exception {
+        CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        noZoneMappingAudioService.init();
+        ICarOccupantZoneCallback callback = getOccupantZoneCallback();
+
+        callback.onOccupantZoneConfigChanged(CarOccupantZoneManager.ZONE_CONFIG_CHANGE_FLAG_USER);
+
+        verify(mMockOccupantZoneService, never()).getUserForOccupant(anyInt());
+    }
+
+    @Test
+    public void onOccupantZoneConfigChanged_noOccupantZoneMapping_alreadyAssigned()
+            throws Exception {
+        CarAudioService noZoneMappingAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationWithoutZoneMappingFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        when(mMockOccupantZoneService.getDriverUserId()).thenReturn(TEST_DRIVER_USER_ID);
+        noZoneMappingAudioService.init();
+        ICarOccupantZoneCallback callback = getOccupantZoneCallback();
+
+        callback.onOccupantZoneConfigChanged(CarOccupantZoneManager.ZONE_CONFIG_CHANGE_FLAG_USER);
+        callback.onOccupantZoneConfigChanged(CarOccupantZoneManager.ZONE_CONFIG_CHANGE_FLAG_USER);
+
+        verify(mMockOccupantZoneService, never()).getUserForOccupant(anyInt());
+        assertWithMessage("Occupant Zone for primary zone")
+                .that(noZoneMappingAudioService.getUserIdForZone(PRIMARY_AUDIO_ZONE))
+                .isEqualTo(TEST_DRIVER_USER_ID);
+    }
+
+    @Test
     public void onOccupantZoneConfigChanged_multipleZones() throws Exception {
         mCarAudioService.init();
         when(mMockOccupantZoneService.getDriverUserId()).thenReturn(TEST_DRIVER_USER_ID);
@@ -1302,6 +1446,57 @@
                 .containsExactly(new AudioDeviceAttributes(MICROPHONE_TEST_DEVICE));
     }
 
+    @Test
+    public void getExternalSources_forSingleDevice() {
+        mCarAudioService.init();
+        AudioDeviceInfo[] inputDevices = generateInputDeviceInfos();
+
+        assertWithMessage("External input device addresses")
+                .that(mCarAudioService.getExternalSources())
+                .asList().containsExactly(inputDevices[1].getAddress());
+    }
+
+    @Test
+    public void setAudioEnabled_forEnabledVolumeGroupMuting() {
+        mCarAudioService.init();
+
+        mCarAudioService.setAudioEnabled(/* enabled= */ true);
+
+        verify(mAudioControlWrapperAidl).onDevicesToMuteChange(any());
+    }
+
+    @Test
+    public void setAudioEnabled_forDisabledVolumeGroupMuting() {
+        when(mMockResources.getBoolean(audioUseCarVolumeGroupMuting))
+                .thenReturn(false);
+        CarAudioService nonVolumeGroupMutingAudioService = new CarAudioService(mMockContext,
+                mTemporaryAudioConfigurationFile.getFile().getAbsolutePath(),
+                mCarVolumeCallbackHandler);
+        nonVolumeGroupMutingAudioService.init();
+
+        nonVolumeGroupMutingAudioService.setAudioEnabled(/* enabled= */ true);
+
+        verify(mAudioControlWrapperAidl, never()).onDevicesToMuteChange(any());
+    }
+
+    @Test
+    public void registerVolumeCallback_verifyCallbackHandler() {
+        mCarAudioService.init();
+
+        mCarAudioService.registerVolumeCallback(mVolumeCallbackBinder);
+
+        verify(mCarVolumeCallbackHandler).registerCallback(mVolumeCallbackBinder);
+    }
+
+    @Test
+    public void test() {
+        mCarAudioService.init();
+
+        mCarAudioService.unregisterVolumeCallback(mVolumeCallbackBinder);
+
+        verify(mCarVolumeCallbackHandler).unregisterCallback(mVolumeCallbackBinder);
+    }
+
     private void mockGrantCarControlAudioSettingsPermission() {
         mockContextCheckCallingOrSelfPermission(mMockContext,
                 PERMISSION_CAR_CONTROL_AUDIO_SETTINGS, PERMISSION_GRANTED);
diff --git a/tests/carservice_unit_test/src/com/android/car/audio/CarZonesAudioFocusUnitTest.java b/tests/carservice_unit_test/src/com/android/car/audio/CarZonesAudioFocusUnitTest.java
index 21424d9..74b9e87 100644
--- a/tests/carservice_unit_test/src/com/android/car/audio/CarZonesAudioFocusUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/audio/CarZonesAudioFocusUnitTest.java
@@ -39,6 +39,10 @@
 import android.os.Bundle;
 import android.util.SparseArray;
 
+import com.android.car.CarLocalServices;
+import com.android.car.oem.CarOemProxyService;
+
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -72,12 +76,21 @@
     private CarZonesAudioFocus.CarFocusCallback mMockCarFocusCallback;
     @Mock
     private PackageManager mMockPackageManager;
+    @Mock
+    private CarOemProxyService mMockCarOemProxyService;
 
     private CarZonesAudioFocus mCarZonesAudioFocus;
 
     @Before
     public void setUp() {
         mCarZonesAudioFocus = getCarZonesAudioFocus();
+        CarLocalServices.removeServiceForTest(CarOemProxyService.class);
+        CarLocalServices.addService(CarOemProxyService.class, mMockCarOemProxyService);
+    }
+
+    @After
+    public void tearDown() {
+        CarLocalServices.removeServiceForTest(CarOemProxyService.class);
     }
 
     @Test
diff --git a/tests/carservice_unit_test/src/com/android/car/audio/TestCarAudioZoneBuilder.java b/tests/carservice_unit_test/src/com/android/car/audio/TestCarAudioZoneBuilder.java
index 39439ca..0a2db84 100644
--- a/tests/carservice_unit_test/src/com/android/car/audio/TestCarAudioZoneBuilder.java
+++ b/tests/carservice_unit_test/src/com/android/car/audio/TestCarAudioZoneBuilder.java
@@ -16,6 +16,10 @@
 
 package com.android.car.audio;
 
+import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DEBUGGING_CODE;
+
+import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -27,21 +31,25 @@
     private CarAudioContext mCarAudioContext =
             new CarAudioContext(CarAudioContext.getAllContextsInfo());
 
+    @ExcludeFromCodeCoverageGeneratedReport(reason = DEBUGGING_CODE)
     public TestCarAudioZoneBuilder(String audioZoneName, int audioZoneId) {
         mAudioZoneId = audioZoneId;
         mAudioZoneName = audioZoneName;
     }
 
+    @ExcludeFromCodeCoverageGeneratedReport(reason = DEBUGGING_CODE)
     TestCarAudioZoneBuilder addVolumeGroup(CarVolumeGroup group) {
         mCarVolumeGroups.add(group);
         return this;
     }
 
+    @ExcludeFromCodeCoverageGeneratedReport(reason = DEBUGGING_CODE)
     TestCarAudioZoneBuilder setCarAudioContexts(CarAudioContext carAudioContext) {
         mCarAudioContext = carAudioContext;
         return this;
     }
 
+    @ExcludeFromCodeCoverageGeneratedReport(reason = DEBUGGING_CODE)
     CarAudioZone build() {
         return mCarVolumeGroups.stream().collect(
                 ()->new CarAudioZone(mCarAudioContext, mAudioZoneName, mAudioZoneId),
diff --git a/tests/carservice_unit_test/src/com/android/car/hal/HalClientUnitTest.java b/tests/carservice_unit_test/src/com/android/car/hal/HalClientUnitTest.java
deleted file mode 100644
index ebfc8e4..0000000
--- a/tests/carservice_unit_test/src/com/android/car/hal/HalClientUnitTest.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * 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 com.android.car.hal;
-
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET;
-
-import static com.android.car.hal.HalPropValueMatcher.isProperty;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.car.test.mocks.AbstractExtendedMockitoTestCase;
-import android.hardware.automotive.vehicle.StatusCode;
-import android.hardware.automotive.vehicle.SubscribeOptions;
-import android.hardware.automotive.vehicle.VehiclePropError;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.os.test.TestLooper;
-
-import com.android.car.VehicleStub;
-import com.android.car.VehicleStub.SubscriptionClient;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public final class HalClientUnitTest extends AbstractExtendedMockitoTestCase {
-
-    private static final int WAIT_CAP_FOR_RETRIABLE_RESULT_MS = 100;
-    private static final int SLEEP_BETWEEN_RETRIABLE_INVOKES_MS = 50;
-
-    private static final int PROP = 42;
-    private static final int AREA_ID = 108;
-
-    private final HalPropValueBuilder mPropValueBuilder = new HalPropValueBuilder(/*isAidl=*/true);
-    private final HalPropValue mProp = mPropValueBuilder.build(PROP, AREA_ID);
-
-    @Mock VehicleStub mIVehicle;
-    @Mock HalClientCallback mHalClientCallback;
-    @Mock SubscriptionClient mSubscriptionClient;
-    @Mock
-    VehicleStub.VehicleStubCallbackInterface mGetVehicleStubAsyncCallback;
-
-    private HalClient mClient;
-    private TestLooper mLooper = new TestLooper();
-
-    public HalClientUnitTest() {
-        super(HalClient.TAG);
-    }
-
-    @Before
-    public void setFixtures() {
-        when(mIVehicle.newSubscriptionClient(any())).thenReturn(mSubscriptionClient);
-        mClient = new HalClient(mIVehicle, mLooper.getLooper(), mHalClientCallback,
-                WAIT_CAP_FOR_RETRIABLE_RESULT_MS, SLEEP_BETWEEN_RETRIABLE_INVOKES_MS);
-    }
-
-    @Test
-    public void testGetValuesAsync() {
-        HalPropValue halPropValue = mPropValueBuilder.build(HVAC_TEMPERATURE_SET, /* areaId= */ 0);
-        int serviceRequestId = 1;
-
-        VehicleStub.AsyncGetSetRequest getVehicleStubAsyncRequest =
-                new VehicleStub.AsyncGetSetRequest(serviceRequestId, halPropValue,
-                        /* timeoutInMs= */ 0);
-
-        mClient.getValuesAsync(List.of(getVehicleStubAsyncRequest), mGetVehicleStubAsyncCallback);
-
-        ArgumentCaptor<List<VehicleStub.AsyncGetSetRequest>> captor =
-                ArgumentCaptor.forClass(List.class);
-        HalPropValue testHalPropValue = mPropValueBuilder.build(HVAC_TEMPERATURE_SET, /* areaId= */
-                0);
-
-        verify(mIVehicle).getAsync(captor.capture(),
-                any(VehicleStub.VehicleStubCallbackInterface.class));
-        assertThat(captor.getValue().get(0).getServiceRequestId()).isEqualTo(serviceRequestId);
-        assertThat(captor.getValue().get(0).getHalPropValue()).isEqualTo(testHalPropValue);
-    }
-
-    @Test
-    public void testCancelRequests() {
-        List<Integer> requestIds = mock(List.class);
-
-        mClient.cancelRequests(requestIds);
-
-        verify(mIVehicle).cancelRequests(requestIds);
-    }
-
-    @Test
-    public void testSet_remoteExceptionThenFail() throws Exception {
-        doThrow(new RemoteException("Never give up, never surrender!"))
-            .doThrow(new RemoteException("D'OH!"))
-            .when(mIVehicle).set(isProperty(PROP));
-
-        Exception actualException = assertThrows(ServiceSpecificException.class,
-                () -> mClient.setValue(mProp));
-
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(PROP));
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(AREA_ID));
-    }
-
-    @Test
-    public void testSet_remoteExceptionThenOk() throws Exception {
-        doThrow(new RemoteException("Never give up, never surrender!"))
-            .doNothing()
-            .when(mIVehicle).set(isProperty(PROP));
-
-
-        mClient.setValue(mProp);
-    }
-
-    @Test
-    public void testSet_invalidArgument() throws Exception {
-        doThrow(new ServiceSpecificException(StatusCode.INVALID_ARG))
-                .when(mIVehicle).set(isProperty(PROP));
-
-        Exception actualException = assertThrows(IllegalArgumentException.class,
-                () -> mClient.setValue(mProp));
-
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(PROP));
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(AREA_ID));
-    }
-
-    @Test
-    public void testSet_otherError() throws Exception {
-        doThrow(new ServiceSpecificException(StatusCode.INTERNAL_ERROR))
-            .when(mIVehicle).set(isProperty(PROP));
-
-        Exception actualException = assertThrows(ServiceSpecificException.class,
-                () -> mClient.setValue(mProp));
-
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(PROP));
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(AREA_ID));
-    }
-
-    @Test
-    public void testSet_ok() throws Exception {
-        doNothing().when(mIVehicle).set(isProperty(PROP));
-
-        mClient.setValue(mProp);
-    }
-
-    @Test
-    public void testGet_remoteExceptionThenFail() throws Exception {
-        when(mIVehicle.get(isProperty(PROP)))
-            .thenThrow(new RemoteException("Never give up, never surrender!"))
-            .thenThrow(new RemoteException("D'OH!"));
-
-        Exception actualException = assertThrows(ServiceSpecificException.class,
-                () -> mClient.getValue(mProp));
-
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(PROP));
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(AREA_ID));
-    }
-
-    @Test
-    public void testGet_remoteExceptionThenOk() throws Exception {
-        HalPropValue propValue = mock(HalPropValue.class);
-        when(mIVehicle.get(isProperty(PROP)))
-            .thenThrow(new RemoteException("Never give up, never surrender!"))
-            .thenReturn(propValue);
-
-        HalPropValue gotValue = mClient.getValue(mProp);
-
-        assertThat(gotValue).isEqualTo(propValue);
-    }
-
-    @Test
-    public void testGet_invalidArgument() throws Exception {
-        when(mIVehicle.get(isProperty(PROP))).thenThrow(new ServiceSpecificException(
-                StatusCode.INVALID_ARG));
-
-        Exception actualException = assertThrows(IllegalArgumentException.class,
-                () -> mClient.getValue(mProp));
-
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(PROP));
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(AREA_ID));
-    }
-
-    @Test
-    public void testGet_otherError() throws Exception {
-        when(mIVehicle.get(isProperty(PROP))).thenThrow(new ServiceSpecificException(
-                StatusCode.INTERNAL_ERROR));
-
-        Exception actualException = assertThrows(ServiceSpecificException.class,
-                () -> mClient.getValue(mProp));
-
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(PROP));
-        assertThat(actualException).hasMessageThat().contains(Integer.toHexString(AREA_ID));
-    }
-
-    @Test
-    public void testGet_returnNull() throws Exception {
-        when(mIVehicle.get(isProperty(PROP))).thenReturn(null);
-
-        ServiceSpecificException actualException = assertThrows(ServiceSpecificException.class,
-                () -> mClient.getValue(mProp));
-
-        assertThat(actualException.errorCode).isEqualTo(StatusCode.NOT_AVAILABLE);
-    }
-
-    @Test
-    public void testGet_ok() throws Exception {
-        HalPropValue propValue = mock(HalPropValue.class);
-        when(mIVehicle.get(isProperty(PROP))).thenReturn(propValue);
-
-        HalPropValue gotValue = mClient.getValue(mProp);
-
-        assertThat(gotValue).isEqualTo(propValue);
-    }
-
-    @Test
-    public void testGetAllPropConfigs() throws Exception {
-        HalPropConfig config = mock(HalPropConfig.class);
-        HalPropConfig[] configs = new HalPropConfig[]{config};
-        when(mIVehicle.getAllPropConfigs()).thenReturn(configs);
-
-        assertThat(mClient.getAllPropConfigs()).isEqualTo(configs);
-    }
-
-    @Test
-    public void testSubscribe() throws Exception {
-        SubscribeOptions option = mock(SubscribeOptions.class);
-
-        mClient.subscribe(option);
-
-        verify(mSubscriptionClient).subscribe(new SubscribeOptions[]{option});
-    }
-
-    @Test
-    public void testUnsubscribe() throws Exception {
-        mClient.unsubscribe(1);
-
-        verify(mSubscriptionClient).unsubscribe(1);
-    }
-
-    @Test
-    public void testInternalCallbackOnPropertyEvent() throws Exception {
-        HalClientCallback callback = mClient.getInternalCallback();
-
-        HalPropValue propValue1 = mock(HalPropValue.class);
-        HalPropValue propValue2 = mock(HalPropValue.class);
-        ArrayList<HalPropValue> values = new ArrayList<HalPropValue>(
-                Arrays.asList(propValue1, propValue2));
-
-        callback.onPropertyEvent(values);
-
-        mLooper.dispatchAll();
-
-        verify(mHalClientCallback).onPropertyEvent(values);
-    }
-
-    @Test
-    public void testInternalCallbackOnPropertySetError() throws Exception {
-        HalClientCallback callback = mClient.getInternalCallback();
-
-        VehiclePropError error1 = mock(VehiclePropError.class);
-        VehiclePropError error2 = mock(VehiclePropError.class);
-        ArrayList<VehiclePropError> errors = new ArrayList<VehiclePropError>(
-                Arrays.asList(error1, error2));
-
-        callback.onPropertySetError(errors);
-
-        mLooper.dispatchAll();
-
-        verify(mHalClientCallback).onPropertySetError(errors);
-    }
-}
diff --git a/tests/carservice_unit_test/src/com/android/car/hal/MockedPowerHalService.java b/tests/carservice_unit_test/src/com/android/car/hal/MockedPowerHalService.java
index 353c5e6..d9dfee2 100644
--- a/tests/carservice_unit_test/src/com/android/car/hal/MockedPowerHalService.java
+++ b/tests/carservice_unit_test/src/com/android/car/hal/MockedPowerHalService.java
@@ -69,7 +69,6 @@
                 mock(DiagnosticHalService.class),
                 mock(ClusterHalService.class),
                 mock(TimeHalService.class),
-                mock(HalClient.class),
                 CarServiceUtils.getHandlerThread(VehicleHal.class.getSimpleName()),
                 vehicleStub);
 
diff --git a/tests/carservice_unit_test/src/com/android/car/hal/VehicleHalTest.java b/tests/carservice_unit_test/src/com/android/car/hal/VehicleHalTest.java
index 53b2493..21c1f38 100644
--- a/tests/carservice_unit_test/src/com/android/car/hal/VehicleHalTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/hal/VehicleHalTest.java
@@ -22,6 +22,7 @@
 
 import static org.junit.Assert.assertThrows;
 import static org.mockito.AdditionalMatchers.not;
+import static org.mockito.Mockito.after;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
@@ -29,12 +30,14 @@
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.car.hardware.property.CarPropertyManager;
 import android.content.Context;
+import android.hardware.automotive.vehicle.StatusCode;
 import android.hardware.automotive.vehicle.SubscribeOptions;
 import android.hardware.automotive.vehicle.VehicleAreaConfig;
 import android.hardware.automotive.vehicle.VehiclePropConfig;
@@ -75,6 +78,8 @@
 @RunWith(MockitoJUnitRunner.class)
 public class VehicleHalTest {
 
+    private static final int WAIT_TIMEOUT_MS = 1000;
+
     private static final int SOME_READ_ON_CHANGE_PROPERTY = 0x01;
     private static final int SOME_READ_WRITE_STATIC_PROPERTY = 0x02;
     private static final int SOME_BOOL_PROPERTY = VehiclePropertyType.BOOLEAN | 0x03;
@@ -97,9 +102,9 @@
     @Mock private DiagnosticHalService mDiagnosticHalService;
     @Mock private ClusterHalService mClusterHalService;
     @Mock private TimeHalService mTimeHalService;
-    @Mock private HalClient mHalClient;
     @Mock private VehicleStub mVehicle;
     @Mock private VehicleStub.VehicleStubCallbackInterface mGetVehicleStubAsyncCallback;
+    @Mock private VehicleStub.SubscriptionClient mSubscriptionClient;
 
     private final HandlerThread mHandlerThread = CarServiceUtils.getHandlerThread(
             VehicleHal.class.getSimpleName());
@@ -120,13 +125,61 @@
     /** Hal services configurations */
     private final ArrayList<VehiclePropConfig> mConfigs = new ArrayList<>();
 
+    private void init(VehiclePropConfig powerHalConfig, VehiclePropConfig propertyHalConfig)
+            throws Exception {
+        // Initialize PowerHAL service with a READ_WRITE and ON_CHANGE property
+        when(mPowerHalService.getAllSupportedProperties()).thenReturn(
+                new int[]{SOME_READ_ON_CHANGE_PROPERTY});
+        mConfigs.add(powerHalConfig);
+
+        // Initialize PropertyHAL service with a READ_WRITE and STATIC property
+        when(mPropertyHalService.getAllSupportedProperties()).thenReturn(
+                new int[]{SOME_READ_WRITE_STATIC_PROPERTY});
+        mConfigs.add(propertyHalConfig);
+
+        // Initialize the remaining services with empty properties
+        when(mInputHalService.getAllSupportedProperties()).thenReturn(new int[0]);
+        when(mVmsHalService.getAllSupportedProperties()).thenReturn(new int[0]);
+        when(mUserHalService.getAllSupportedProperties()).thenReturn(new int[0]);
+        when(mDiagnosticHalService.getAllSupportedProperties()).thenReturn(new int[0]);
+        when(mTimeHalService.getAllSupportedProperties()).thenReturn(new int[0]);
+        when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
+
+        when(mVehicle.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
+        mVehicleHal.init();
+    }
+
+    private static Answer<Void> checkConfigs(ArrayList<VehiclePropConfig> configs) {
+        return new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) {
+                ArrayList<HalPropConfig> halConfigs =
+                        (ArrayList<HalPropConfig>) invocation.getArguments()[0];
+                ArrayList<VehiclePropConfig> aidlConfigs = new ArrayList<VehiclePropConfig>();
+                for (HalPropConfig halConfig : halConfigs) {
+                    aidlConfigs.add((VehiclePropConfig) (halConfig.toVehiclePropConfig()));
+                }
+                assertThat(configs).isEqualTo(aidlConfigs);
+                return null;
+            }
+        };
+    }
+
+    private static HalPropConfig[] toHalPropConfigs(List<VehiclePropConfig> configs) {
+        HalPropConfig[] halConfigs = new HalPropConfig[configs.size()];
+        for (int i = 0; i < configs.size(); i++) {
+            halConfigs[i] = new AidlHalPropConfig(configs.get(i));
+        }
+        return halConfigs;
+    }
+
     @Before
     public void setUp() throws Exception {
         when(mVehicle.getHalPropValueBuilder()).thenReturn(mPropValueBuilder);
+        when(mVehicle.newSubscriptionClient(any())).thenReturn(mSubscriptionClient);
 
         mVehicleHal = new VehicleHal(mContext, mPowerHalService,
                 mPropertyHalService, mInputHalService, mVmsHalService, mUserHalService,
-                mDiagnosticHalService, mClusterHalService, mTimeHalService, mHalClient,
+                mDiagnosticHalService, mClusterHalService, mTimeHalService,
                 mHandlerThread, mVehicle);
 
         mConfigs.clear();
@@ -158,7 +211,7 @@
 
         ArgumentCaptor<List<AsyncGetSetRequest>> captor =
                 ArgumentCaptor.forClass(List.class);
-        verify(mHalClient).getValuesAsync(captor.capture(),
+        verify(mVehicle).getAsync(captor.capture(),
                 any(VehicleStub.VehicleStubCallbackInterface.class));
         assertThat(captor.getValue().get(0).getServiceRequestId()).isEqualTo(REQUEST_ID_1);
         assertThat(captor.getValue().get(0).getHalPropValue()).isEqualTo(mHalPropValue);
@@ -174,7 +227,7 @@
 
         ArgumentCaptor<List<AsyncGetSetRequest>> captor =
                 ArgumentCaptor.forClass(List.class);
-        verify(mHalClient).getValuesAsync(captor.capture(),
+        verify(mVehicle).getAsync(captor.capture(),
                 any(VehicleStub.VehicleStubCallbackInterface.class));
         assertThat(captor.getValue().get(0).getServiceRequestId()).isEqualTo(REQUEST_ID_1);
         assertThat(captor.getValue().get(0).getHalPropValue()).isEqualTo(mHalPropValue);
@@ -182,53 +235,6 @@
         assertThat(captor.getValue().get(1).getHalPropValue()).isEqualTo(mHalPropValue);
     }
 
-    private void init(VehiclePropConfig powerHalConfig, VehiclePropConfig propertyHalConfig)
-            throws Exception {
-        // Initialize PowerHAL service with a READ_WRITE and ON_CHANGE property
-        when(mPowerHalService.getAllSupportedProperties()).thenReturn(
-                new int[]{SOME_READ_ON_CHANGE_PROPERTY});
-        mConfigs.add(powerHalConfig);
-
-        // Initialize PropertyHAL service with a READ_WRITE and STATIC property
-        when(mPropertyHalService.getAllSupportedProperties()).thenReturn(
-                new int[]{SOME_READ_WRITE_STATIC_PROPERTY});
-        mConfigs.add(propertyHalConfig);
-
-        // Initialize the remaining services with empty properties
-        when(mInputHalService.getAllSupportedProperties()).thenReturn(new int[0]);
-        when(mVmsHalService.getAllSupportedProperties()).thenReturn(new int[0]);
-        when(mUserHalService.getAllSupportedProperties()).thenReturn(new int[0]);
-        when(mDiagnosticHalService.getAllSupportedProperties()).thenReturn(new int[0]);
-        when(mTimeHalService.getAllSupportedProperties()).thenReturn(new int[0]);
-        when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
-
-        when(mHalClient.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
-        mVehicleHal.init();
-    }
-
-    private static Answer<Void> checkConfigs(ArrayList<VehiclePropConfig> configs) {
-        return new Answer<Void>() {
-            public Void answer(InvocationOnMock invocation) {
-                ArrayList<HalPropConfig> halConfigs =
-                        (ArrayList<HalPropConfig>) invocation.getArguments()[0];
-                ArrayList<VehiclePropConfig> aidlConfigs = new ArrayList<VehiclePropConfig>();
-                for (HalPropConfig halConfig : halConfigs) {
-                    aidlConfigs.add((VehiclePropConfig) (halConfig.toVehiclePropConfig()));
-                }
-                assertThat(configs).isEqualTo(aidlConfigs);
-                return null;
-            }
-        };
-    }
-
-    private static HalPropConfig[] toHalPropConfigs(List<VehiclePropConfig> configs) {
-        HalPropConfig[] halConfigs = new HalPropConfig[configs.size()];
-        for (int i = 0; i < configs.size(); i++) {
-            halConfigs[i] = new AidlHalPropConfig(configs.get(i));
-        }
-        return halConfigs;
-    }
-
     @Test
     public void testInit_skipSetupInit() throws Exception {
         VehiclePropConfig powerHalConfig = new VehiclePropConfig();
@@ -305,7 +311,7 @@
         when(mTimeHalService.getAllSupportedProperties()).thenReturn(new int[0]);
         when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
 
-        when(mHalClient.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
+        when(mVehicle.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
 
         mVehicleHal.init();
     }
@@ -326,7 +332,7 @@
         mVehicleHal.init();
 
         // getAllPropConfigs should only be called once.
-        verify(mHalClient, times(1)).getAllPropConfigs();
+        verify(mVehicle, times(1)).getAllPropConfigs();
     }
 
     @Test
@@ -348,7 +354,7 @@
         when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
 
         // Return empty prop configs.
-        when(mHalClient.getAllPropConfigs()).thenReturn(new HalPropConfig[0]);
+        when(mVehicle.getAllPropConfigs()).thenReturn(new HalPropConfig[0]);
 
         doAnswer(checkConfigs(new ArrayList<VehiclePropConfig>()))
                 .when(mPowerHalService).takeProperties(any());
@@ -392,7 +398,7 @@
         when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
 
         // Return empty prop configs.
-        when(mHalClient.getAllPropConfigs()).thenReturn(null);
+        when(mVehicle.getAllPropConfigs()).thenReturn(null);
 
         doAnswer(checkConfigs(new ArrayList<VehiclePropConfig>()))
                 .when(mPowerHalService).takeProperties(any());
@@ -436,7 +442,7 @@
         when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
 
         // Throw exception.
-        when(mHalClient.getAllPropConfigs()).thenThrow(new RemoteException());
+        when(mVehicle.getAllPropConfigs()).thenThrow(new RemoteException());
 
         assertThrows(RuntimeException.class, () -> mVehicleHal.init());
     }
@@ -454,7 +460,7 @@
         verify(mVmsHalService).release();
         verify(mUserHalService).release();
         verify(mDiagnosticHalService).release();
-        verify(mHalClient).unsubscribe(SOME_READ_ON_CHANGE_PROPERTY);
+        verify(mSubscriptionClient).unsubscribe(SOME_READ_ON_CHANGE_PROPERTY);
     }
 
     @Test
@@ -462,7 +468,8 @@
         mVehicleHal.subscribeProperty(
                 mPowerHalService, SOME_READ_ON_CHANGE_PROPERTY, ANY_SAMPLING_RATE);
         // This exception should be captured into a warning.
-        doThrow(new RemoteException()).when(mHalClient).unsubscribe(SOME_READ_ON_CHANGE_PROPERTY);
+        doThrow(new RemoteException()).when(mSubscriptionClient).unsubscribe(
+                SOME_READ_ON_CHANGE_PROPERTY);
 
         mVehicleHal.release();
 
@@ -472,7 +479,7 @@
         verify(mVmsHalService).release();
         verify(mUserHalService).release();
         verify(mDiagnosticHalService).release();
-        verify(mHalClient).unsubscribe(SOME_READ_ON_CHANGE_PROPERTY);
+        verify(mSubscriptionClient).unsubscribe(SOME_READ_ON_CHANGE_PROPERTY);
     }
 
     @Test
@@ -499,7 +506,7 @@
         expectedOptions.sampleRate = ANY_SAMPLING_RATE;
         expectedOptions.areaIds = new int[0];
 
-        verify(mHalClient).subscribe(eq(expectedOptions));
+        verify(mSubscriptionClient).subscribe(eq(new SubscribeOptions[]{expectedOptions}));
     }
 
     @Test
@@ -512,7 +519,7 @@
         expectedOptions.sampleRate = 0f;
         expectedOptions.areaIds = new int[0];
 
-        verify(mHalClient).subscribe(eq(expectedOptions));
+        verify(mSubscriptionClient).subscribe(eq(new SubscribeOptions[]{expectedOptions}));
     }
 
     @Test
@@ -526,7 +533,7 @@
         expectedOptions.sampleRate = ANY_SAMPLING_RATE;
         expectedOptions.areaIds = new int[0];
 
-        verify(mHalClient).subscribe(eq(expectedOptions));
+        verify(mSubscriptionClient).subscribe(eq(new SubscribeOptions[]{expectedOptions}));
     }
 
     @Test
@@ -553,7 +560,7 @@
 
     @Test
     public void testSubscribeProperty_remoteException() throws Exception {
-        doThrow(new RemoteException()).when(mHalClient).subscribe(any());
+        doThrow(new RemoteException()).when(mSubscriptionClient).subscribe(any());
 
         mVehicleHal.subscribeProperty(mPowerHalService, SOME_READ_ON_CHANGE_PROPERTY,
                 ANY_SAMPLING_RATE);
@@ -564,7 +571,7 @@
         expectedOptions.areaIds = new int[0];
 
         // RemoteException is handled in subscribeProperty.
-        verify(mHalClient).subscribe(eq(expectedOptions));
+        verify(mSubscriptionClient).subscribe(eq(new SubscribeOptions[]{expectedOptions}));
     }
 
     @Test
@@ -574,7 +581,7 @@
                 mPowerHalService, SOME_READ_WRITE_STATIC_PROPERTY, ANY_SAMPLING_RATE);
 
         // Assert
-        verify(mHalClient, never()).subscribe(any(SubscribeOptions.class));
+        verify(mSubscriptionClient, never()).subscribe(any());
     }
 
     @Test
@@ -586,7 +593,7 @@
         mVehicleHal.unsubscribeProperty(mPowerHalService, SOME_READ_ON_CHANGE_PROPERTY);
 
         // Assert
-        verify(mHalClient).unsubscribe(eq(SOME_READ_ON_CHANGE_PROPERTY));
+        verify(mSubscriptionClient).unsubscribe(eq(SOME_READ_ON_CHANGE_PROPERTY));
     }
 
     @Test
@@ -595,7 +602,7 @@
         mVehicleHal.unsubscribeProperty(mPowerHalService, UNSUPPORTED_PROPERTY);
 
         // Assert
-        verify(mHalClient, never()).unsubscribe(anyInt());
+        verify(mSubscriptionClient, never()).unsubscribe(anyInt());
     }
 
     @Test
@@ -604,7 +611,7 @@
         mVehicleHal.unsubscribeProperty(mPowerHalService, SOME_READ_WRITE_STATIC_PROPERTY);
 
         // Assert
-        verify(mHalClient, never()).unsubscribe(anyInt());
+        verify(mSubscriptionClient, never()).unsubscribe(anyInt());
     }
 
     @Test
@@ -617,14 +624,14 @@
     public void testUnsubscribeProperty_remoteException() throws Exception {
         // Arrange
         mVehicleHal.subscribeProperty(mPowerHalService, SOME_READ_ON_CHANGE_PROPERTY);
-        doThrow(new RemoteException()).when(mHalClient).unsubscribe(anyInt());
+        doThrow(new RemoteException()).when(mSubscriptionClient).unsubscribe(anyInt());
 
         //Act
         mVehicleHal.unsubscribeProperty(mPowerHalService, SOME_READ_ON_CHANGE_PROPERTY);
 
         // Assert
         // RemoteException is handled in subscribeProperty.
-        verify(mHalClient).unsubscribe(eq(SOME_READ_ON_CHANGE_PROPERTY));
+        verify(mSubscriptionClient).unsubscribe(eq(SOME_READ_ON_CHANGE_PROPERTY));
     }
 
     @Test
@@ -653,9 +660,9 @@
         mVehicleHal.onPropertyEvent(propValues);
 
         // Assert
-        verify(dispatchList).add(propValue);
-        verify(mPowerHalService).onHalEvents(dispatchList);
-        verify(dispatchList).clear();
+        verify(dispatchList, timeout(WAIT_TIMEOUT_MS)).add(propValue);
+        verify(mPowerHalService, timeout(WAIT_TIMEOUT_MS)).onHalEvents(dispatchList);
+        verify(dispatchList, timeout(WAIT_TIMEOUT_MS)).clear();
     }
 
     @Test
@@ -672,6 +679,8 @@
         // Act
         mVehicleHal.onPropertyEvent(propValues);
         mVehicleHal.onPropertyEvent(propValues);
+        // Wait for event to be handled.
+        verify(dispatchList, timeout(WAIT_TIMEOUT_MS).times(2)).clear();
 
         // Assert
         StringWriter writer = new StringWriter();
@@ -695,7 +704,7 @@
 
         mVehicleHal.onPropertyEvent(propValues);
 
-        verify(mPowerHalService, never()).onHalEvents(any());
+        verify(mPowerHalService, after(100).never()).onHalEvents(any());
     }
 
     @Test
@@ -722,10 +731,10 @@
         mVehicleHal.onPropertySetError(errors);
 
         // Assert
-        verify(mPowerHalService).onPropertySetError(new ArrayList<VehiclePropError>(Arrays.asList(
-                error1, error2)));
-        verify(mPropertyHalService).onPropertySetError(new ArrayList<VehiclePropError>(
-                Arrays.asList(error3)));
+        verify(mPowerHalService, timeout(WAIT_TIMEOUT_MS)).onPropertySetError(
+                new ArrayList<VehiclePropError>(Arrays.asList(error1, error2)));
+        verify(mPropertyHalService, timeout(WAIT_TIMEOUT_MS)).onPropertySetError(
+                new ArrayList<VehiclePropError>(Arrays.asList(error3)));
     }
 
     @Test
@@ -742,7 +751,7 @@
         mVehicleHal.onPropertySetError(errors);
 
         // Assert
-        verify(mPowerHalService, never()).onPropertySetError(errors);
+        verify(mPowerHalService, after(100).never()).onPropertySetError(errors);
     }
 
     @Test
@@ -759,7 +768,7 @@
         mVehicleHal.onPropertySetError(errors);
 
         // Assert
-        verify(mPowerHalService, never()).onPropertySetError(errors);
+        verify(mPowerHalService, after(100).never()).onPropertySetError(errors);
     }
 
     @Test
@@ -777,18 +786,18 @@
         CarServiceUtils.runOnLooperSync(mHandlerThread.getLooper(), () -> {});
 
         // Assert
-        verify(mPowerHalService).onPropertySetError(errors);
+        verify(mPowerHalService, timeout(WAIT_TIMEOUT_MS)).onPropertySetError(errors);
     }
 
     @Test
-    public void testGetIfAvailableOrFail() {
+    public void testGetIfSupportedOrFail() throws Exception {
         // Arrange
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA);
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         // Act
-        HalPropValue actual = mVehicleHal.getIfAvailableOrFail(SOME_READ_ON_CHANGE_PROPERTY,
+        HalPropValue actual = mVehicleHal.getIfSupportedOrFail(SOME_READ_ON_CHANGE_PROPERTY,
                 /* numberOfRetries= */ 1);
 
         // Assert
@@ -796,39 +805,49 @@
     }
 
     @Test
-    public void testGetIfAvailableOrFail_unsupportedProperty() {
-        HalPropValue actual = mVehicleHal.getIfAvailableOrFail(UNSUPPORTED_PROPERTY,
+    public void testGetIfSupportedOrFail_unsupportedProperty() {
+        HalPropValue actual = mVehicleHal.getIfSupportedOrFail(UNSUPPORTED_PROPERTY,
                 /* numberOfRetries= */ 1);
 
         assertThat(actual).isNull();
     }
 
     @Test
-    public void testGetIfAvailableOrFail_serviceSpecificException() {
-        when(mHalClient.getValue(any(HalPropValue.class))).thenThrow(
-                new ServiceSpecificException(0));
+    public void testGetIfSupportedOrFail_serviceSpecificException() throws Exception {
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(
+                new ServiceSpecificException(StatusCode.INTERNAL_ERROR));
 
-        assertThrows(IllegalStateException.class, () -> mVehicleHal.getIfAvailableOrFail(
+        assertThrows(IllegalStateException.class, () -> mVehicleHal.getIfSupportedOrFail(
                 SOME_READ_ON_CHANGE_PROPERTY, /* numberOfRetries= */ 1));
     }
 
     @Test
-    public void testGetIfAvailableOrFail_serviceSpecificExceptionRetrySucceed() {
+    public void testGetIfSupportedOrFail_serviceSpecificExceptionRetrySucceed() throws Exception {
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA);
-        when(mHalClient.getValue(any(HalPropValue.class))).thenThrow(
-                new ServiceSpecificException(0)).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(
+                new ServiceSpecificException(StatusCode.TRY_AGAIN)).thenReturn(propValue);
 
         // Retry once.
-        HalPropValue actual = mVehicleHal.getIfAvailableOrFail(SOME_READ_ON_CHANGE_PROPERTY,
+        HalPropValue actual = mVehicleHal.getIfSupportedOrFail(SOME_READ_ON_CHANGE_PROPERTY,
                 /* numberOfRetries= */ 2);
 
         assertThat(actual).isEqualTo(propValue);
-        verify(mHalClient, times(2)).getValue(eq(propValue));
+        verify(mVehicle, times(2)).get(propValue);
     }
 
     @Test
-    public void testGetIfAvailableOrFailForEarlyStage_skipSetupInit() throws Exception {
+    public void testGetIfSupportedOrFail_serviceSpecificExceptionRetryFailed() throws Exception {
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(
+                new ServiceSpecificException(StatusCode.TRY_AGAIN)).thenThrow(
+                new ServiceSpecificException(StatusCode.TRY_AGAIN));
+
+        assertThrows(IllegalStateException.class, () -> mVehicleHal.getIfSupportedOrFail(
+                SOME_READ_ON_CHANGE_PROPERTY, /* numberOfRetries= */ 2));
+    }
+
+    @Test
+    public void testGetIfSupportedOrFailForEarlyStage_skipSetupInit() throws Exception {
         // Skip setup init() because this function would be called before init() is called.
         VehiclePropConfig powerHalConfig = new VehiclePropConfig();
         powerHalConfig.prop = SOME_READ_ON_CHANGE_PROPERTY;
@@ -854,14 +873,14 @@
         when(mTimeHalService.getAllSupportedProperties()).thenReturn(new int[0]);
         when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
 
-        when(mHalClient.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
+        when(mVehicle.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
 
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA);
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         // Act
-        HalPropValue actual = mVehicleHal.getIfAvailableOrFailForEarlyStage(
+        HalPropValue actual = mVehicleHal.getIfSupportedOrFailForEarlyStage(
                 SOME_READ_ON_CHANGE_PROPERTY, /* numberOfRetries= */ 1);
 
         // Assert
@@ -873,7 +892,7 @@
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA, 0, 0, new int[]{1, 2}, new float[]{1.1f, 1.2f},
                 new long[0], "test", new byte[]{0x00, 0x01});
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         assertThat(mVehicleHal.<Integer>get(Integer.class, propValue)).isEqualTo(1);
         assertThat(mVehicleHal.<Integer>get(int.class, propValue)).isEqualTo(1);
@@ -899,7 +918,7 @@
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA, "test");
 
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         assertThrows(IllegalArgumentException.class, () -> mVehicleHal
                 .<android.hardware.automotive.vehicle.V2_0.VehiclePropValue>get(
@@ -910,14 +929,104 @@
     public void testGetClazz_defaultArea() throws Exception {
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA, 1);
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         Integer actual = mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
 
         assertThat(actual).isEqualTo(1);
         HalPropValue requestProp = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA);
-        verify(mHalClient).getValue(eq(requestProp));
+        verify(mVehicle).get(requestProp);
+    }
+
+    @Test
+    public void testGetWithRetry_retrySucceed() throws Exception {
+        HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA, 1);
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(new ServiceSpecificException(
+                StatusCode.TRY_AGAIN)).thenReturn(propValue);
+
+        Integer actual = mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
+
+        assertThat(actual).isEqualTo(1);
+        HalPropValue requestProp = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA);
+        verify(mVehicle, times(2)).get(requestProp);
+    }
+
+    @Test
+    public void testGetWithRetry_retryFailed() throws Exception {
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(new ServiceSpecificException(
+                StatusCode.TRY_AGAIN)).thenThrow(new ServiceSpecificException(
+                StatusCode.TRY_AGAIN)).thenThrow(new ServiceSpecificException(
+                StatusCode.TRY_AGAIN));
+        mVehicleHal.setMaxDurationForRetryMs(200);
+        mVehicleHal.setSleepBetweenRetryMs(100);
+
+        ServiceSpecificException e = assertThrows(ServiceSpecificException.class, () -> {
+            mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
+        });
+        assertThat(e.errorCode).isEqualTo(StatusCode.TRY_AGAIN);
+    }
+
+    @Test
+    public void testGetWithRetry_nonRetriableError() throws Exception {
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(new ServiceSpecificException(
+                StatusCode.TRY_AGAIN)).thenThrow(new ServiceSpecificException(
+                StatusCode.NOT_AVAILABLE));
+        mVehicleHal.setMaxDurationForRetryMs(1000);
+        mVehicleHal.setSleepBetweenRetryMs(100);
+
+        ServiceSpecificException e = assertThrows(ServiceSpecificException.class, () -> {
+            mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
+        });
+        assertThat(e.errorCode).isEqualTo(StatusCode.NOT_AVAILABLE);
+        verify(mVehicle, times(2)).get(any());
+    }
+
+    @Test
+    public void testGetWithRetry_IllegalArgumentException() throws Exception {
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(new ServiceSpecificException(
+                StatusCode.INVALID_ARG));
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
+        });
+    }
+
+    @Test
+    public void testGetWithRetry_vhalReturnsNull() throws Exception {
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(null);
+
+        ServiceSpecificException e = assertThrows(ServiceSpecificException.class, () -> {
+            mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
+        });
+        assertThat(e.errorCode).isEqualTo(StatusCode.NOT_AVAILABLE);
+    }
+
+    @Test
+    public void testGetWithRetry_RemoteExceptionFromVhal() throws Exception {
+        // RemoteException is retriable.
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(new RemoteException())
+                .thenThrow(new RemoteException())
+                .thenThrow(new RemoteException());
+        mVehicleHal.setMaxDurationForRetryMs(200);
+        mVehicleHal.setSleepBetweenRetryMs(100);
+
+        ServiceSpecificException e = assertThrows(ServiceSpecificException.class, () -> {
+            mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
+        });
+        assertThat(e.errorCode).isEqualTo(StatusCode.TRY_AGAIN);
+    }
+
+    @Test
+    public void testGetWithRetry_IllegalArgumentExceptionFromVhal() throws Exception {
+        // IllegalArgumentException is not a retriable exception.
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(new IllegalArgumentException());
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            mVehicleHal.get(Integer.class, SOME_READ_ON_CHANGE_PROPERTY);
+        });
     }
 
     // A test class to class protected method of VehicleHal.
@@ -931,11 +1040,10 @@
                 DiagnosticHalService diagnosticHal,
                 ClusterHalService clusterHalService,
                 TimeHalService timeHalService,
-                HalClient halClient,
                 HandlerThread handlerThread,
                 VehicleStub vehicleStub) {
             super(context, powerHal, propertyHal, inputHal, vmsHal, userHal, diagnosticHal,
-                    clusterHalService, timeHalService, halClient, handlerThread, vehicleStub);
+                    clusterHalService, timeHalService, handlerThread, vehicleStub);
         }
     }
 
@@ -944,14 +1052,129 @@
         VehicleHalTestClass t = new VehicleHalTestClass(mContext, mPowerHalService,
                 mPropertyHalService, mInputHalService, mVmsHalService, mUserHalService,
                 mDiagnosticHalService, mClusterHalService, mTimeHalService,
-                mHalClient, mHandlerThread, mVehicle);
+                mHandlerThread, mVehicle);
         t.init();
 
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA);
         t.set(propValue);
 
-        verify(mHalClient).setValue(propValue);
+        verify(mVehicle).set(propValue);
+    }
+
+    @Test
+    public void testSetWithRetry_retrySucceed() throws Exception {
+        VehicleHalTestClass t = new VehicleHalTestClass(mContext, mPowerHalService,
+                mPropertyHalService, mInputHalService, mVmsHalService, mUserHalService,
+                mDiagnosticHalService, mClusterHalService, mTimeHalService,
+                mHandlerThread, mVehicle);
+        t.init();
+        doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .doNothing().when(mVehicle).set(any());
+
+        HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA);
+        t.setMaxDurationForRetryMs(1000);
+        t.setSleepBetweenRetryMs(100);
+        t.set(propValue);
+
+        verify(mVehicle, times(2)).set(propValue);
+    }
+
+    @Test
+    public void testSetWithRetry_retryFailed() throws Exception {
+        VehicleHalTestClass t = new VehicleHalTestClass(mContext, mPowerHalService,
+                mPropertyHalService, mInputHalService, mVmsHalService, mUserHalService,
+                mDiagnosticHalService, mClusterHalService, mTimeHalService,
+                mHandlerThread, mVehicle);
+        t.init();
+        doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .when(mVehicle).set(any());
+
+        HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA);
+        t.setMaxDurationForRetryMs(200);
+        t.setSleepBetweenRetryMs(100);
+
+        ServiceSpecificException e = assertThrows(ServiceSpecificException.class, () -> {
+            t.set(propValue);
+        });
+        assertThat(e.errorCode).isEqualTo(StatusCode.TRY_AGAIN);
+    }
+
+    @Test
+    public void testSetWithRetry_nonRetriableError() throws Exception {
+        VehicleHalTestClass t = new VehicleHalTestClass(mContext, mPowerHalService,
+                mPropertyHalService, mInputHalService, mVmsHalService, mUserHalService,
+                mDiagnosticHalService, mClusterHalService, mTimeHalService,
+                mHandlerThread, mVehicle);
+        t.init();
+        doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .doThrow(new ServiceSpecificException(StatusCode.INTERNAL_ERROR))
+                .when(mVehicle).set(any());
+
+        HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA);
+        t.setMaxDurationForRetryMs(1000);
+        t.setSleepBetweenRetryMs(100);
+
+        ServiceSpecificException e = assertThrows(ServiceSpecificException.class, () -> {
+            t.set(propValue);
+        });
+        assertThat(e.errorCode).isEqualTo(StatusCode.INTERNAL_ERROR);
+    }
+
+    @Test
+    public void testSetWithRetry_IllegalArgumentException() throws Exception {
+        VehicleHalTestClass t = new VehicleHalTestClass(mContext, mPowerHalService,
+                mPropertyHalService, mInputHalService, mVmsHalService, mUserHalService,
+                mDiagnosticHalService, mClusterHalService, mTimeHalService,
+                mHandlerThread, mVehicle);
+        t.init();
+        doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .doThrow(new ServiceSpecificException(StatusCode.TRY_AGAIN))
+                .doThrow(new ServiceSpecificException(StatusCode.INVALID_ARG))
+                .when(mVehicle).set(any());
+
+        HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA);
+        t.setMaxDurationForRetryMs(1000);
+        t.setSleepBetweenRetryMs(100);
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            t.set(propValue);
+        });
+    }
+
+    @Test
+    public void testSetWithRetry_RemoteExceptionFromVhal() throws Exception {
+        // RemoteException is retriable.
+        doThrow(new RemoteException()).doThrow(new RemoteException()).doThrow(new RemoteException())
+                .when(mVehicle).set(any());
+        HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA);
+        mVehicleHal.setMaxDurationForRetryMs(200);
+        mVehicleHal.setSleepBetweenRetryMs(100);
+
+        ServiceSpecificException e = assertThrows(ServiceSpecificException.class, () -> {
+            mVehicleHal.set(propValue);
+        });
+        assertThat(e.errorCode).isEqualTo(StatusCode.TRY_AGAIN);
+    }
+
+    @Test
+    public void testSetWithRetry_IllegalArgumentExceptionFromVhal() throws Exception {
+        // IllegalArgumentException is not a retriable exception.
+        doThrow(new IllegalArgumentException()).when(mVehicle).set(any());
+        HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
+                VehicleHal.NO_AREA);
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            mVehicleHal.set(propValue);
+        });
     }
 
     @Test
@@ -959,7 +1182,7 @@
         mVehicleHal.set(SOME_READ_ON_CHANGE_PROPERTY).to(true);
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA, new int[]{1});
-        verify(mHalClient).setValue(propValue);
+        verify(mVehicle).set(propValue);
     }
 
     @Test
@@ -968,7 +1191,7 @@
 
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA, new int[]{2});
-        verify(mHalClient).setValue(propValue);
+        verify(mVehicle).set(propValue);
     }
 
     @Test
@@ -977,7 +1200,7 @@
 
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA, new int[]{1, 2});
-        verify(mHalClient).setValue(propValue);
+        verify(mVehicle).set(propValue);
     }
 
     @Test
@@ -986,7 +1209,7 @@
 
         HalPropValue propValue = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA, new int[]{1, 2});
-        verify(mHalClient).setValue(propValue);
+        verify(mVehicle).set(propValue);
     }
 
     // Testing dump methods
@@ -1046,13 +1269,13 @@
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_all() {
+    public void testDumpPropertyValueByCommand_all() throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
         HalPropValue propValue = mPropValueBuilder.build(/*propId=*/0, /*areaId=*/0, "some_value");
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         // Act
         mVehicleHal.dumpPropertyValueByCommand(printWriter, /* propId= */ -1, /* areaId= */-1);
@@ -1062,13 +1285,13 @@
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_allAreaIdsNoAreaConfig() {
+    public void testDumpPropertyValueByCommand_allAreaIdsNoAreaConfig() throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
         HalPropValue propValue = mPropValueBuilder.build(/*propId=*/0, /*areaId=*/0, "some_value");
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         // Act
         mVehicleHal.dumpPropertyValueByCommand(printWriter, SOME_READ_ON_CHANGE_PROPERTY,
@@ -1079,17 +1302,17 @@
 
         HalPropValue requestProp = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY,
                 VehicleHal.NO_AREA);
-        verify(mHalClient).getValue(requestProp);
+        verify(mVehicle).get(requestProp);
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_allAreaIdsWithAreaConfig() {
+    public void testDumpPropertyValueByCommand_allAreaIdsWithAreaConfig() throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
         HalPropValue propValue = mPropValueBuilder.build(/*propId=*/0, /*areaId=*/0, "some_value");
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         VehicleAreaConfig areaConfig = new VehicleAreaConfig();
         areaConfig.areaId = 123;
@@ -1105,17 +1328,17 @@
         assertThat(writer.toString()).contains("string: some_value");
 
         HalPropValue requestProp = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY, 123);
-        verify(mHalClient).getValue(requestProp);
+        verify(mVehicle).get(requestProp);
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_propArea() {
+    public void testDumpPropertyValueByCommand_propArea() throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
         HalPropValue propValue = mPropValueBuilder.build(/*propId=*/0, /*areaId=*/0, "some_value");
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         VehicleAreaConfig areaConfig = new VehicleAreaConfig();
         areaConfig.areaId = 123;
@@ -1130,17 +1353,18 @@
         assertThat(writer.toString()).contains("string: some_value");
 
         HalPropValue requestProp = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY, 123);
-        verify(mHalClient).getValue(requestProp);
+        verify(mVehicle).get(requestProp);
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_byConfigNoAreaConfigsGetValueException() {
+    public void testDumpPropertyValueByCommand_byConfigNoAreaConfigsGetValueException()
+            throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
-        when(mHalClient.getValue(any(HalPropValue.class))).thenThrow(
-                new ServiceSpecificException(0));
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(
+                new ServiceSpecificException(StatusCode.INTERNAL_ERROR));
 
         // Act
         mVehicleHal.dumpPropertyValueByCommand(printWriter, SOME_READ_ON_CHANGE_PROPERTY,
@@ -1151,13 +1375,14 @@
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_byConfigWithAreaConfigsGetValueException() {
+    public void testDumpPropertyValueByCommand_byConfigWithAreaConfigsGetValueException()
+             throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
-        when(mHalClient.getValue(any(HalPropValue.class))).thenThrow(
-                new ServiceSpecificException(0));
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(
+                new ServiceSpecificException(StatusCode.INTERNAL_ERROR));
 
         VehicleAreaConfig areaConfig = new VehicleAreaConfig();
         areaConfig.areaId = 123;
@@ -1172,17 +1397,17 @@
         // Assert
         assertThat(writer.toString()).contains("Can not get property value");
         HalPropValue requestProp = mPropValueBuilder.build(SOME_READ_ON_CHANGE_PROPERTY, 123);
-        verify(mHalClient).getValue(requestProp);
+        verify(mVehicle).get(requestProp);
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_GetValueException() {
+    public void testDumpPropertyValueByCommand_GetValueException() throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
-        when(mHalClient.getValue(any(HalPropValue.class))).thenThrow(
-                new ServiceSpecificException(0));
+        when(mVehicle.get(any(HalPropValue.class))).thenThrow(
+                new ServiceSpecificException(StatusCode.INTERNAL_ERROR));
 
         // Act
         mVehicleHal.dumpPropertyValueByCommand(printWriter, SOME_READ_ON_CHANGE_PROPERTY,
@@ -1193,13 +1418,13 @@
     }
 
     @Test
-    public void testDumpPropertyValueByCommand_unsupportedProp() {
+    public void testDumpPropertyValueByCommand_unsupportedProp() throws Exception {
         // Arrange
         StringWriter writer = new StringWriter();
         PrintWriter printWriter = new PrintWriter(writer);
 
         HalPropValue propValue = mPropValueBuilder.build(/*propId=*/0, /*areaId=*/0, "some_value");
-        when(mHalClient.getValue(any(HalPropValue.class))).thenReturn(propValue);
+        when(mVehicle.get(any(HalPropValue.class))).thenReturn(propValue);
 
         // Act
         // Note here we cannot use UNSUPPORTED_PROPERTY because its value -1 has special meaning
@@ -1223,29 +1448,34 @@
     // Testing vehicle hal property getters
 
     @Test
-    public void testGetForPropertyIdAndAreaId() {
+    public void testGetForPropertyIdAndAreaId() throws Exception {
         // Arrange
         int propertyId = 123;  // Any property id
         int areaId = 456;  // Any area id
+        HalPropValue expectResultValue = mPropValueBuilder.build(0, 0);
+        when(mVehicle.get(any())).thenReturn(expectResultValue);
 
         // Act
-        mVehicleHal.get(propertyId, areaId);
+        HalPropValue gotResultValue = mVehicleHal.get(propertyId, areaId);
 
         // Assert
         HalPropValue expectedPropValue = mPropValueBuilder.build(propertyId, areaId);
-        verify(mHalClient).getValue(eq(expectedPropValue));
+        verify(mVehicle).get(expectedPropValue);
+        assertThat(gotResultValue).isEqualTo(expectResultValue);
     }
 
     @Test
-    public void testGet_HalPropValue() {
+    public void testGet_HalPropValue() throws Exception {
         // Arrange
         HalPropValue propValue = mPropValueBuilder.build(0, 0);
+        when(mVehicle.get(any())).thenReturn(propValue);
 
         // Act
-        mVehicleHal.get(propValue);
+        HalPropValue result = mVehicleHal.get(propValue);
 
         // Assert
-        verify(mHalClient).getValue(propValue);
+        verify(mVehicle).get(propValue);
+        assertThat(result).isEqualTo(propValue);
     }
 
     // Make a copy of the prop value reference so that we could check them later.
@@ -1274,7 +1504,7 @@
         when(mTimeHalService.getAllSupportedProperties()).thenReturn(new int[0]);
         when(mClusterHalService.getAllSupportedProperties()).thenReturn(new int[0]);
 
-        when(mHalClient.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
+        when(mVehicle.getAllPropConfigs()).thenReturn(toHalPropConfigs(mConfigs));
 
         List<HalPropValue> dispatchList = new ArrayList<HalPropValue>();
         when(mPowerHalService.getDispatchList()).thenReturn(dispatchList);
@@ -1495,6 +1725,6 @@
 
         mVehicleHal.cancelRequests(requestIds);
 
-        verify(mHalClient).cancelRequests(requestIds);
+        verify(mVehicle).cancelRequests(requestIds);
     }
 }
diff --git a/tests/carservice_unit_test/src/com/android/car/hal/fakevhal/FakeVehicleStubUnitTest.java b/tests/carservice_unit_test/src/com/android/car/hal/fakevhal/FakeVehicleStubUnitTest.java
index 3a9b7ab..f728baa 100644
--- a/tests/carservice_unit_test/src/com/android/car/hal/fakevhal/FakeVehicleStubUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/hal/fakevhal/FakeVehicleStubUnitTest.java
@@ -51,10 +51,10 @@
 import com.android.car.VehicleStub;
 import com.android.car.VehicleStub.SubscriptionClient;
 import com.android.car.hal.AidlHalPropConfig;
-import com.android.car.hal.HalClientCallback;
 import com.android.car.hal.HalPropConfig;
 import com.android.car.hal.HalPropValue;
 import com.android.car.hal.HalPropValueBuilder;
+import com.android.car.hal.VehicleHalCallback;
 
 import com.google.common.truth.Expect;
 
@@ -853,7 +853,7 @@
         HalPropValue requestPropValue = buildHalPropValue(
                 /* propId= */ VehicleProperty.ENGINE_OIL_LEVEL, /* areaId= */ 0,
                 SystemClock.elapsedRealtimeNanos(), rawPropValues);
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -898,7 +898,7 @@
         HalPropValue requestPropValue2 = buildHalPropValue(
                 /* propId= */ VehicleProperty.NIGHT_MODE, /* areaId= */ 0,
                 SystemClock.elapsedRealtimeNanos(), rawPropValues2);
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -941,7 +941,7 @@
         HalPropValue requestPropValue2 = buildHalPropValue(
                 /* propId= */ VehicleProperty.SEAT_HEADREST_ANGLE_POS, SEAT_1_RIGHT,
                 SystemClock.elapsedRealtimeNanos(), rawPropValues);
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -969,8 +969,8 @@
         HalPropValue requestPropValue = buildHalPropValue(
                 /* propId= */ VehicleProperty.ENGINE_OIL_LEVEL, /* areaId= */ 0,
                 SystemClock.elapsedRealtimeNanos(), rawPropValues);
-        HalClientCallback callback1 = mock(HalClientCallback.class);
-        HalClientCallback callback2 = mock(HalClientCallback.class);
+        VehicleHalCallback callback1 = mock(VehicleHalCallback.class);
+        VehicleHalCallback callback2 = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -999,7 +999,7 @@
         option.propId = VehicleProperty.FUEL_LEVEL;
         option.sampleRate = 100f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1027,7 +1027,7 @@
         option2.propId = VehicleProperty.FUEL_LEVEL;
         option2.sampleRate = 50f;
         SubscribeOptions[] options2 = new SubscribeOptions[]{option2};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1057,7 +1057,7 @@
         option.sampleRate = 200f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
 
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub = new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
         VehicleStub.SubscriptionClient client = fakeVehicleStub.newSubscriptionClient(callback);
@@ -1080,7 +1080,7 @@
         option.propId = VehicleProperty.FUEL_LEVEL;
         option.sampleRate = -50f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1101,7 +1101,7 @@
         option.propId = 123;
         option.sampleRate = 0f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), new ArrayList<>());
 
@@ -1126,7 +1126,7 @@
         option.areaIds = new int[]{SEAT_1_LEFT};
         option.sampleRate = 1f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1153,7 +1153,7 @@
         option.propId = VehicleProperty.INFO_FUEL_CAPACITY;
         option.sampleRate = 0f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1167,7 +1167,7 @@
 
     @Test
     public void testUnsubscribePropIdNotSupport() throws Exception {
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), new ArrayList<>());
 
@@ -1184,7 +1184,7 @@
         // Create a custom config file.
         String jsonString = "{\"properties\": [" + PROPERTY_CONFIG_STRING_STATIC + "]}";
         List<File> customFileList = createFilenameList(jsonString);
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1212,7 +1212,7 @@
         HalPropValue requestPropValue = buildHalPropValue(
                 /* propId= */ VehicleProperty.ENGINE_OIL_LEVEL, /* areaId= */ 0,
                 SystemClock.elapsedRealtimeNanos(), rawPropValues);
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
         VehicleStub.SubscriptionClient client = fakeVehicleStub.newSubscriptionClient(callback);
@@ -1240,7 +1240,7 @@
         option.propId = VehicleProperty.FUEL_LEVEL;
         option.sampleRate = 100f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1265,8 +1265,8 @@
         option.propId = VehicleProperty.FUEL_LEVEL;
         option.sampleRate = 100f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback1 = mock(HalClientCallback.class);
-        HalClientCallback callback2 = mock(HalClientCallback.class);
+        VehicleHalCallback callback1 = mock(VehicleHalCallback.class);
+        VehicleHalCallback callback2 = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1304,7 +1304,7 @@
         option2.propId = VehicleProperty.EV_BATTERY_LEVEL;
         option2.sampleRate = 100f;
         SubscribeOptions[] options = new SubscribeOptions[]{option1, option2};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub = new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), customFileList);
 
@@ -1355,7 +1355,7 @@
         option.propId = VehicleProperty.VHAL_HEARTBEAT;
         option.sampleRate = 100f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), new ArrayList<>());
         SubscriptionClient realClient = mock(SubscriptionClient.class);
@@ -1375,7 +1375,7 @@
         option.propId = VehicleProperty.VHAL_HEARTBEAT;
         option.sampleRate = 100f;
         SubscribeOptions[] options = new SubscribeOptions[]{option};
-        HalClientCallback callback = mock(HalClientCallback.class);
+        VehicleHalCallback callback = mock(VehicleHalCallback.class);
         FakeVehicleStub fakeVehicleStub =  new FakeVehicleStub(mMockRealVehicleStub,
                 new FakeVhalConfigParser(), new ArrayList<>());
         SubscriptionClient realClient = mock(SubscriptionClient.class);
diff --git a/tests/carservice_unit_test/src/com/android/car/internal/util/ConcurrentUtilsTest.java b/tests/carservice_unit_test/src/com/android/car/internal/util/ConcurrentUtilsTest.java
index d8e752d..a6a09bf 100644
--- a/tests/carservice_unit_test/src/com/android/car/internal/util/ConcurrentUtilsTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/internal/util/ConcurrentUtilsTest.java
@@ -19,6 +19,8 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import org.junit.Test;
 
@@ -40,22 +42,14 @@
     }
 
     @Test
-    public void testWaitForFutureNoInterruptInterrupted() {
+    public void testWaitForFutureNoInterruptInterrupted() throws Exception {
         ExecutorService service = ConcurrentUtils.newFixedThreadPool(1, "test pool",
                 /* linuxThreadPriority= */ 0);
-        Future<Boolean> future = service.submit(() -> {
-            // Sleep to make sure the future does not complete before we interrupt the current
-            // thread.
-            Thread.sleep(1000);
-            return true;
-        });
-        // This would set the interrupt flag on the current thread and cause future.get() to
-        // throw InterruptedException.
-        Thread.currentThread().interrupt();
+        Future<Boolean> mockFuture = mock(Future.class);
+        when(mockFuture.get()).thenThrow(new InterruptedException());
+
         assertThrows(IllegalStateException.class,
-                () -> ConcurrentUtils.waitForFutureNoInterrupt(future, "wait for result"));
-        future.cancel(/* mayInterruptIfRunning= */ true);
-        assertThat(future.isCancelled()).isTrue();
+                () -> ConcurrentUtils.waitForFutureNoInterrupt(mockFuture, "wait for result"));
     }
 
     @Test
diff --git a/tests/carservice_unit_test/src/com/android/car/oem/CarOemProxyServiceTest.java b/tests/carservice_unit_test/src/com/android/car/oem/CarOemProxyServiceTest.java
new file mode 100644
index 0000000..5a352a6
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/oem/CarOemProxyServiceTest.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2022 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 com.android.car.oem;
+
+import static com.android.compatibility.common.util.SystemUtil.eventually;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.car.CarVersion;
+import android.car.builtin.content.pm.PackageManagerHelper;
+import android.car.oem.IOemCarAudioFocusService;
+import android.car.oem.IOemCarService;
+import android.car.oem.IOemCarServiceCallback;
+import android.car.test.mocks.AbstractExtendedMockitoTestCase;
+import android.car.test.mocks.JavaMockitoHelper;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+
+import com.android.car.R;
+import com.android.internal.annotations.GuardedBy;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.concurrent.CountDownLatch;
+
+public final class CarOemProxyServiceTest extends AbstractExtendedMockitoTestCase {
+
+    private static final String COMPONENT_NAME = "android.car.test/unittest";
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private Resources mResources;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private CarOemProxyServiceHelper mCarOemProxyServiceHelper;
+    @Captor
+    ArgumentCaptor<String> mReasonCapture;
+    @Captor
+    ArgumentCaptor<ServiceConnection> mConnectionCapture;
+
+    private final TestOemCarService mTestOemCarService = new TestOemCarService();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    @Override
+    protected void onSessionBuilder(CustomMockitoSessionBuilder session) {
+        session.spyStatic(PackageManagerHelper.class);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        mockCallTimeout(/* timeoutMs= */ 5000);
+    }
+
+    @Test
+    public void testFeatureDisabled() throws Exception {
+        CarOemProxyService carOemProxyService = new CarOemProxyService(mContext);
+
+        assertThat(carOemProxyService.isOemServiceEnabled()).isFalse();
+    }
+
+    @Test
+    public void testFeatureEnabled() throws Exception {
+        mockOemCarServiceComponent();
+        CarOemProxyService carOemProxyService = new CarOemProxyService(mContext);
+
+        assertThat(carOemProxyService.isOemServiceEnabled()).isTrue();
+        assertThat(carOemProxyService.getOemServiceName()).isEqualTo(COMPONENT_NAME);
+    }
+
+    @Test
+    public void testOemServiceCalledPriorToInit() throws Exception {
+        mockOemCarServiceComponent();
+        CarOemProxyService carOemProxyService = new CarOemProxyService(mContext);
+        mockServiceConnection();
+
+        assertThrows(IllegalStateException.class,
+                () -> carOemProxyService.getCarOemAudioFocusService());
+    }
+
+    @Test
+    public void testCarServiceCrash_oemNotConnected() throws Exception {
+        mockCallTimeout(/* timeoutMs= */ 100);
+        mockOemCarServiceComponent();
+        CarOemProxyService carOemProxyService = new CarOemProxyService(mContext,
+                mCarOemProxyServiceHelper, mHandler);
+
+        //call will wait for OEM service connected
+        carOemProxyService.onInitComplete();
+        waitForHandlerThreadToFinish();
+
+        // First it will call crash with "OEM Service not connected", as it is mocked, it would
+        // continue with other calls.
+        verify(mCarOemProxyServiceHelper, times(2)).crashCarService(mReasonCapture.capture());
+        assertThat(mReasonCapture.getAllValues()).containsExactly("OEM Service not connected",
+                "OEM Service not ready");
+    }
+
+    @Test
+    public void testCarServiceCrash_oemNotReady() throws Exception {
+        mockCallTimeout(/* timeoutMs= */ 100);
+        mockOemCarServiceComponent();
+        CarOemProxyService carOemProxyService = new CarOemProxyService(mContext,
+                mCarOemProxyServiceHelper, mHandler);
+        mockServiceConnection();
+
+        //call will wait for OEM service ready
+        carOemProxyService.onInitComplete();
+        waitForHandlerThreadToFinish();
+
+        verify(mCarOemProxyServiceHelper).crashCarService("OEM Service not ready");
+    }
+
+    @Test
+    public void testOemServiceIsReady() throws Exception {
+        mockOemCarServiceComponent();
+        CarOemProxyService carOemProxyService = new CarOemProxyService(mContext);
+        mockServiceConnection();
+        mockServiceReady();
+        carOemProxyService.onInitComplete();
+
+        eventually(() -> assertWithMessage("Oem Service not ready.")
+                .that(carOemProxyService.isOemServiceReady()).isTrue());
+
+        assertThat(carOemProxyService.getCarOemAudioFocusService()).isNull();
+    }
+
+    @Test
+    public void testCallbackWhenOemServiceIsReady() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        mockOemCarServiceComponent();
+        CarOemProxyService carOemProxyService = new CarOemProxyService(mContext);
+        mockServiceConnection();
+        mockServiceReady();
+
+        carOemProxyService.registerCallback(() -> latch.countDown());
+        carOemProxyService.onInitComplete();
+
+        JavaMockitoHelper.await(latch, 5000);
+    }
+
+    private void waitForHandlerThreadToFinish() {
+        int timeoutMs = 2000;
+        assertWithMessage("handler not idle in %sms", timeoutMs)
+                .that(mHandler.runWithScissors(() -> {}, timeoutMs)).isTrue();
+    }
+
+    private void mockServiceConnection() {
+        verify(mContext).bindServiceAsUser(any(), mConnectionCapture.capture(), anyInt(), any());
+        ServiceConnection connection = mConnectionCapture.getValue();
+        connection.onServiceConnected(ComponentName.unflattenFromString(COMPONENT_NAME),
+                mTestOemCarService);
+    }
+
+    private void mockOemCarServiceComponent() throws Exception {
+        when(mResources.getString(R.string.config_oemCarService)).thenReturn(COMPONENT_NAME);
+        // make it a valid component.
+        String packageName = ComponentName.unflattenFromString(COMPONENT_NAME).getPackageName();
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        when(mPackageManager.getPackageInfo(packageName, 0)).thenReturn(packageInfo);
+        doReturn(true).when(() -> PackageManagerHelper.isSystemApp(any()));
+        when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true);
+    }
+
+    private void mockCallTimeout(int timeoutMs) {
+        when(mResources.getInteger(R.integer.config_oemCarService_connection_timeout_ms))
+                .thenReturn(timeoutMs);
+        when(mResources.getInteger(R.integer.config_oemCarService_serviceReady_timeout_ms))
+                .thenReturn(timeoutMs);
+    }
+
+    private void mockServiceReady() throws Exception {
+        mTestOemCarService.mockServiceReady();
+    }
+
+    private final class TestOemCarService extends IOemCarService.Stub {
+
+        private final Object mLock = new Object();
+
+        @GuardedBy("mLock")
+        private boolean mMockedServiceReady;
+
+        public void mockServiceReady() {
+            synchronized (mLock) {
+                mMockedServiceReady = true;
+            }
+        }
+
+        @Override
+        public IOemCarAudioFocusService getOemAudioFocusService() {
+            return null;
+        }
+
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        }
+
+        @Override
+        public CarVersion getSupportedCarVersion() {
+            return CarVersion.VERSION_CODES.TIRAMISU_2;
+        }
+
+        @Override
+        public void onCarServiceReady(IOemCarServiceCallback callback) throws RemoteException {
+            boolean mockedServiceReady;
+            synchronized (mLock) {
+                mockedServiceReady = mMockedServiceReady;
+            }
+            if (mockedServiceReady) {
+                callback.sendOemCarServiceReady();
+            }
+        }
+
+        @Override
+        public String getAllStackTraces() {
+            return "";
+        }
+    }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/storagemonitoring/CarStorageMonitoringTest.java b/tests/carservice_unit_test/src/com/android/car/storagemonitoring/CarStorageMonitoringTest.java
index e006f25..7ddea92 100644
--- a/tests/carservice_unit_test/src/com/android/car/storagemonitoring/CarStorageMonitoringTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/storagemonitoring/CarStorageMonitoringTest.java
@@ -576,15 +576,8 @@
             new IoStatsEntry.Metrics(50, 100, 100, 30, 40),
             new IoStatsEntry.Metrics(30, 0, 0, 0, 0));
 
-        ArrayList<IoStatsEntry> statsEntries1 = new ArrayList<IoStatsEntry>() {{
-            add(entry10);
-            add(entry20);
-        }};
-
-        ArrayList<IoStatsEntry> statsEntries2 = new ArrayList<IoStatsEntry>() {{
-            add(entry20);
-            add(entry30);
-        }};
+        List<IoStatsEntry> statsEntries1 = List.of(entry10, entry20);
+        List<IoStatsEntry> statsEntries2 = List.of(entry20, entry30);
 
         IoStats delta1 = new IoStats(statsEntries1, 5000);
         IoStats delta2 = new IoStats(statsEntries1, 5000);
@@ -607,10 +600,7 @@
             new IoStatsEntry.Metrics(100, 200, 50, 200, 1),
             new IoStatsEntry.Metrics(0, 30, 10, 0, 1));
 
-        ArrayList<IoStatsEntry> statsEntries = new ArrayList<IoStatsEntry>() {{
-            add(entry10);
-            add(entry20);
-        }};
+        List<IoStatsEntry> statsEntries = List.of(entry10, entry20);
 
         IoStats delta = new IoStats(statsEntries, 5000);
 
@@ -648,10 +638,7 @@
             new IoStatsEntry.Metrics(200, 60, 100, 30, 40),
             new IoStatsEntry.Metrics(20, 10, 20, 0, 0));
 
-        ArrayList<IoStatsEntry> statsEntries = new ArrayList<IoStatsEntry>() {{
-            add(entry10);
-            add(entry20);
-        }};
+        List<IoStatsEntry> statsEntries = List.of(entry10, entry20);
 
         IoStats statsDelta = new IoStats(statsEntries, 5000);
 
@@ -679,10 +666,7 @@
                 new IoStatsEntry.Metrics(200, 60, 100, 30, 40),
                 new IoStatsEntry.Metrics(20, 10, 20, 0, 0));
 
-            ArrayList<IoStatsEntry> statsEntries = new ArrayList<IoStatsEntry>() {{
-                add(entry10);
-                add(entry20);
-            }};
+            List<IoStatsEntry> statsEntries = List.of(entry10, entry20);
 
             IoStats statsDelta = new IoStats(statsEntries, 5000);
             try (JsonWriter jsonWriter = new JsonWriter(new FileWriter(temporaryFile.getFile()))) {
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java
index 59e27e0..d3858e4 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java
@@ -387,8 +387,7 @@
 
         assertThat(mFakeHandlerWrapper.getQueuedMessages()).hasSize(1);
         Message msg = mFakeHandlerWrapper.getQueuedMessages().get(0);
-        long expectedPullPeriodMillis = 10 * 60 * 1000;  // 10 minutes
-        assertThatMessageIsScheduledWithGivenDelay(msg, expectedPullPeriodMillis);
+        assertThatMessageIsScheduledWithGivenDelay(msg, 0);
     }
 
     @Test
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverterTest.java
index cd7da4b..b669d73 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ConfigMetricsReportListConverterTest.java
@@ -74,14 +74,25 @@
                         .setValueStrHash(hash))
                 .build();
 
+        // This report list contains 2 metrics, an event and a gauge metric. There are empty
+        // reports, these should be skipped.
         ConfigMetricsReportList reportList = ConfigMetricsReportList.newBuilder()
-                .addReports(ConfigMetricsReport.newBuilder()
+                .addReports(ConfigMetricsReport.newBuilder()  // Empty event metric report
+                        .addMetrics(StatsLogReport.newBuilder()
+                                .setMetricId(12345L)))
+                .addReports(ConfigMetricsReport.newBuilder()  // Event metric report
                         .addMetrics(StatsLogReport.newBuilder()
                                 .setMetricId(12345L)
                                 .setEventMetrics(
                                         StatsLogReport.EventMetricDataWrapper.newBuilder()
                                                 .addData(eventData))))
-                .addReports(ConfigMetricsReport.newBuilder()
+                .addReports(ConfigMetricsReport.newBuilder()  // Empty event metric report
+                        .addMetrics(StatsLogReport.newBuilder()
+                                .setMetricId(12345L)))
+                .addReports(ConfigMetricsReport.newBuilder()  // Empty gauge metric report
+                        .addMetrics(StatsLogReport.newBuilder()
+                                .setMetricId(23456L)))
+                .addReports(ConfigMetricsReport.newBuilder()  // Gauge metric report
                         .addMetrics(StatsLogReport.newBuilder()
                                 .setMetricId(23456L)
                                 .setGaugeMetrics(
@@ -94,6 +105,9 @@
                                                 .addDimensionsValue(DimensionsValue.newBuilder()
                                                         .setField(2)))))
                         .addStrings(testGaugeMetricProcessName))
+                .addReports(ConfigMetricsReport.newBuilder()  // Empty gauge metric report
+                        .addMetrics(StatsLogReport.newBuilder()
+                                .setMetricId(23456L)))
                 .build();
         SparseArray<AtomFieldAccessor<AppStartMemoryStateCaptured, ?>> appMemAccessorMap =
                 new AppStartMemoryStateCapturedConverter().getAtomFieldAccessorMap();
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemorySnapshotConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemorySnapshotConverterTest.java
new file mode 100644
index 0000000..715830e
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemorySnapshotConverterTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2022 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 com.android.car.telemetry.publisher.statsconverters;
+
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.ANON_RSS_AND_SWAP_IN_KILOBYTES_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.ANON_RSS_IN_KILOBYTES_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.GPU_MEMORY_KB_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.HAS_FOREGROUND_SERVICES_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.OOM_SCORE_ADJ_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.PID_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.PROCESS_NAME_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.RSS_IN_KILOBYTES_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.SWAP_IN_KILOBYTES_FIELD_NUMBER;
+import static com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot.UID_FIELD_NUMBER;
+import static com.android.car.telemetry.publisher.Constants.STATS_BUNDLE_KEY_PREFIX;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.PersistableBundle;
+import android.util.SparseArray;
+
+import com.android.car.telemetry.AtomsProto.Atom;
+import com.android.car.telemetry.AtomsProto.ProcessMemorySnapshot;
+import com.android.car.telemetry.StatsLogProto.DimensionsValue;
+import com.android.car.telemetry.publisher.HashUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(JUnit4.class)
+public class ProcessMemorySnapshotConverterTest {
+    private static final Atom ATOM_A =
+            Atom.newBuilder()
+                    .setProcessMemorySnapshot(ProcessMemorySnapshot.newBuilder()
+                            .setPid(88)
+                            .setOomScoreAdj(100)
+                            .setRssInKilobytes(1234)
+                            .setAnonRssInKilobytes(99)
+                            .setSwapInKilobytes(101)
+                            .setAnonRssAndSwapInKilobytes(200)
+                            .setGpuMemoryKb(0)
+                            .setHasForegroundServices(true))
+                    .build();
+
+    private static final Atom ATOM_B =
+            Atom.newBuilder()
+                    .setProcessMemorySnapshot(ProcessMemorySnapshot.newBuilder()
+                            .setPid(99)
+                            .setOomScoreAdj(200)
+                            .setRssInKilobytes(6666)
+                            .setAnonRssInKilobytes(100)
+                            .setSwapInKilobytes(100)
+                            .setAnonRssAndSwapInKilobytes(200)
+                            .setGpuMemoryKb(1)
+                            .setHasForegroundServices(false))
+                    .build();
+
+    private static final Atom ATOM_MISMATCH =
+            Atom.newBuilder()
+                    .setProcessMemorySnapshot(ProcessMemorySnapshot.newBuilder()
+                            // Some fields are not set, creating mismatch with above atoms
+                            .setSwapInKilobytes(333))
+                    .build();
+
+    private static final List<Integer> DIM_FIELDS_IDS = Arrays.asList(1, 2);
+    private static final Long HASH_1 = HashUtils.murmur2Hash64("process.name.1");
+    private static final Long HASH_2 = HashUtils.murmur2Hash64("process.name.2");
+    private static final Map<Long, String> HASH_STR_MAP = Map.of(
+            HASH_1, "process.name.1",
+            HASH_2, "process.name.2");
+
+    private static final List<DimensionsValue> DV_PAIR_A =
+            Arrays.asList(
+                    DimensionsValue.newBuilder().setValueInt(1000).build(),
+                    DimensionsValue.newBuilder().setValueStrHash(HASH_1).build());
+
+    private static final List<DimensionsValue> DV_PAIR_B =
+            Arrays.asList(
+                    DimensionsValue.newBuilder().setValueInt(2000).build(),
+                    DimensionsValue.newBuilder().setValueStrHash(HASH_2).build());
+
+    private static final List<DimensionsValue> DV_PAIR_MALFORMED =
+            Arrays.asList(
+                    DimensionsValue.newBuilder().setValueInt(3000).build(),
+                    // Wrong format since leaf level dimension value should set value, not field
+                    DimensionsValue.newBuilder().setField(3).build());
+
+    // Subject of the test.
+    private ProcessMemorySnapshotConverter mConverter = new ProcessMemorySnapshotConverter();
+
+    @Test
+    public void testConvertAtomsListWithDimensionValues_putsCorrectDataToPersistableBundle()
+            throws StatsConversionException {
+        List<Atom> atomsList = Arrays.asList(ATOM_A, ATOM_B);
+        List<List<DimensionsValue>> dimensionsValuesList = Arrays.asList(DV_PAIR_A, DV_PAIR_B);
+        SparseArray<AtomFieldAccessor<ProcessMemorySnapshot, ?>> accessorMap =
+                mConverter.getAtomFieldAccessorMap();
+
+        PersistableBundle bundle = mConverter.convert(atomsList, DIM_FIELDS_IDS,
+                dimensionsValuesList, HASH_STR_MAP);
+
+        assertThat(bundle.size()).isEqualTo(10);
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(UID_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(1000, 2000).inOrder();
+        assertThat(Arrays.asList(bundle.getStringArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        PROCESS_NAME_FIELD_NUMBER).getFieldName())))
+                .containsExactly("process.name.1", "process.name.2").inOrder();
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(PID_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(88, 99);
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        OOM_SCORE_ADJ_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(100, 200).inOrder();
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        RSS_IN_KILOBYTES_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(1234, 6666).inOrder();
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        ANON_RSS_IN_KILOBYTES_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(99, 100).inOrder();
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        SWAP_IN_KILOBYTES_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(101, 100).inOrder();
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        ANON_RSS_AND_SWAP_IN_KILOBYTES_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(200, 200).inOrder();
+        assertThat(bundle.getIntArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        GPU_MEMORY_KB_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(0, 1).inOrder();
+        assertThat(bundle.getBooleanArray(
+                STATS_BUNDLE_KEY_PREFIX + accessorMap.get(
+                        HAS_FOREGROUND_SERVICES_FIELD_NUMBER).getFieldName()))
+                .asList().containsExactly(true, false).inOrder();
+    }
+
+    @Test
+    public void testAtomSetFieldInconsistency_throwsException() {
+        List<Atom> atomsList = Arrays.asList(ATOM_A, ATOM_MISMATCH);
+        List<List<DimensionsValue>> dimensionsValuesList = Arrays.asList(DV_PAIR_A, DV_PAIR_B);
+
+        assertThrows(
+                StatsConversionException.class,
+                () -> mConverter.convert(
+                        atomsList,
+                        DIM_FIELDS_IDS,
+                        dimensionsValuesList,
+                        HASH_STR_MAP));
+    }
+
+    @Test
+    public void testMalformedDimensionValue_throwsException() {
+        List<Atom> atomsList = Arrays.asList(ATOM_A, ATOM_B);
+        List<List<DimensionsValue>> dimensionsValuesList =
+                Arrays.asList(DV_PAIR_A, DV_PAIR_MALFORMED);
+
+        assertThrows(
+                StatsConversionException.class,
+                () -> mConverter.convert(
+                        atomsList,
+                        DIM_FIELDS_IDS,
+                        dimensionsValuesList,
+                        HASH_STR_MAP));
+    }
+}
diff --git a/tools/keventreader/common/com/android/car/keventreader/KeypressEvent.java b/tools/keventreader/common/com/android/car/keventreader/KeypressEvent.java
index 8270690..7aa864e 100644
--- a/tools/keventreader/common/com/android/car/keventreader/KeypressEvent.java
+++ b/tools/keventreader/common/com/android/car/keventreader/KeypressEvent.java
@@ -23,561 +23,562 @@
 import java.util.Objects;
 
 public final class KeypressEvent implements Parcelable {
-    private static final Map<Integer, String> KEYCODE_NAME_MAP = new HashMap<Integer, String>() {{
-        put(0,"RESERVED");
-        put(1,"ESC");
-        put(2,"1");
-        put(3,"2");
-        put(4,"3");
-        put(5,"4");
-        put(6,"5");
-        put(7,"6");
-        put(8,"7");
-        put(9,"8");
-        put(10,"9");
-        put(11,"0");
-        put(12,"MINUS");
-        put(13,"EQUAL");
-        put(14,"BACKSPACE");
-        put(15,"TAB");
-        put(16,"Q");
-        put(17,"W");
-        put(18,"E");
-        put(19,"R");
-        put(20,"T");
-        put(21,"Y");
-        put(22,"U");
-        put(23,"I");
-        put(24,"O");
-        put(25,"P");
-        put(26,"LEFTBRACE");
-        put(27,"RIGHTBRACE");
-        put(28,"ENTER");
-        put(29,"LEFTCTRL");
-        put(30,"A");
-        put(31,"S");
-        put(32,"D");
-        put(33,"F");
-        put(34,"G");
-        put(35,"H");
-        put(36,"J");
-        put(37,"K");
-        put(38,"L");
-        put(39,"SEMICOLON");
-        put(40,"APOSTROPHE");
-        put(41,"GRAVE");
-        put(42,"LEFTSHIFT");
-        put(43,"BACKSLASH");
-        put(44,"Z");
-        put(45,"X");
-        put(46,"C");
-        put(47,"V");
-        put(48,"B");
-        put(49,"N");
-        put(50,"M");
-        put(51,"COMMA");
-        put(52,"DOT");
-        put(53,"SLASH");
-        put(54,"RIGHTSHIFT");
-        put(55,"KPASTERISK");
-        put(56,"LEFTALT");
-        put(57,"SPACE");
-        put(58,"CAPSLOCK");
-        put(59,"F1");
-        put(60,"F2");
-        put(61,"F3");
-        put(62,"F4");
-        put(63,"F5");
-        put(64,"F6");
-        put(65,"F7");
-        put(66,"F8");
-        put(67,"F9");
-        put(68,"F10");
-        put(69,"NUMLOCK");
-        put(70,"SCROLLLOCK");
-        put(71,"KP7");
-        put(72,"KP8");
-        put(73,"KP9");
-        put(74,"KPMINUS");
-        put(75,"KP4");
-        put(76,"KP5");
-        put(77,"KP6");
-        put(78,"KPPLUS");
-        put(79,"KP1");
-        put(80,"KP2");
-        put(81,"KP3");
-        put(82,"KP0");
-        put(83,"KPDOT");
-        put(85,"ZENKAKUHANKAKU");
-        put(86,"102ND");
-        put(87,"F11");
-        put(88,"F12");
-        put(89,"RO");
-        put(90,"KATAKANA");
-        put(91,"HIRAGANA");
-        put(92,"HENKAN");
-        put(93,"KATAKANAHIRAGANA");
-        put(94,"MUHENKAN");
-        put(95,"KPJPCOMMA");
-        put(96,"KPENTER");
-        put(97,"RIGHTCTRL");
-        put(98,"KPSLASH");
-        put(99,"SYSRQ");
-        put(100,"RIGHTALT");
-        put(101,"LINEFEED");
-        put(102,"HOME");
-        put(103,"UP");
-        put(104,"PAGEUP");
-        put(105,"LEFT");
-        put(106,"RIGHT");
-        put(107,"END");
-        put(108,"DOWN");
-        put(109,"PAGEDOWN");
-        put(110,"INSERT");
-        put(111,"DELETE");
-        put(112,"MACRO");
-        put(113,"MUTE");
-        put(114,"VOLUMEDOWN");
-        put(115,"VOLUMEUP");
-        put(116,"POWER");
-        put(117,"KPEQUAL");
-        put(118,"KPPLUSMINUS");
-        put(119,"PAUSE");
-        put(120,"SCALE");
-        put(121,"KPCOMMA");
-        put(122,"HANGEUL");
-        put(123,"HANJA");
-        put(124,"YEN");
-        put(125,"LEFTMETA");
-        put(126,"RIGHTMETA");
-        put(127,"COMPOSE");
-        put(128,"STOP");
-        put(129,"AGAIN");
-        put(130,"PROPS");
-        put(131,"UNDO");
-        put(132,"FRONT");
-        put(133,"COPY");
-        put(134,"OPEN");
-        put(135,"PASTE");
-        put(136,"FIND");
-        put(137,"CUT");
-        put(138,"HELP");
-        put(139,"MENU");
-        put(140,"CALC");
-        put(141,"SETUP");
-        put(142,"SLEEP");
-        put(143,"WAKEUP");
-        put(144,"FILE");
-        put(145,"SENDFILE");
-        put(146,"DELETEFILE");
-        put(147,"XFER");
-        put(148,"PROG1");
-        put(149,"PROG2");
-        put(150,"WWW");
-        put(151,"MSDOS");
-        put(152,"SCREENLOCK");
-        put(153,"ROTATE_DISPLAY");
-        put(154,"CYCLEWINDOWS");
-        put(155,"MAIL");
-        put(156,"BOOKMARKS");
-        put(157,"COMPUTER");
-        put(158,"BACK");
-        put(159,"FORWARD");
-        put(160,"CLOSECD");
-        put(161,"EJECTCD");
-        put(162,"EJECTCLOSECD");
-        put(163,"NEXTSONG");
-        put(164,"PLAYPAUSE");
-        put(165,"PREVIOUSSONG");
-        put(166,"STOPCD");
-        put(167,"RECORD");
-        put(168,"REWIND");
-        put(169,"PHONE");
-        put(170,"ISO");
-        put(171,"CONFIG");
-        put(172,"HOMEPAGE");
-        put(173,"REFRESH");
-        put(174,"EXIT");
-        put(175,"MOVE");
-        put(176,"EDIT");
-        put(177,"SCROLLUP");
-        put(178,"SCROLLDOWN");
-        put(179,"KPLEFTPAREN");
-        put(180,"KPRIGHTPAREN");
-        put(181,"NEW");
-        put(182,"REDO");
-        put(183,"F13");
-        put(184,"F14");
-        put(185,"F15");
-        put(186,"F16");
-        put(187,"F17");
-        put(188,"F18");
-        put(189,"F19");
-        put(190,"F20");
-        put(191,"F21");
-        put(192,"F22");
-        put(193,"F23");
-        put(194,"F24");
-        put(200,"PLAYCD");
-        put(201,"PAUSECD");
-        put(202,"PROG3");
-        put(203,"PROG4");
-        put(204,"DASHBOARD");
-        put(205,"SUSPEND");
-        put(206,"CLOSE");
-        put(207,"PLAY");
-        put(208,"FASTFORWARD");
-        put(209,"BASSBOOST");
-        put(210,"PRINT");
-        put(211,"HP");
-        put(212,"CAMERA");
-        put(213,"SOUND");
-        put(214,"QUESTION");
-        put(215,"EMAIL");
-        put(216,"CHAT");
-        put(217,"SEARCH");
-        put(218,"CONNECT");
-        put(219,"FINANCE");
-        put(220,"SPORT");
-        put(221,"SHOP");
-        put(222,"ALTERASE");
-        put(223,"CANCEL");
-        put(224,"BRIGHTNESSDOWN");
-        put(225,"BRIGHTNESSUP");
-        put(226,"MEDIA");
-        put(227,"SWITCHVIDEOMODE");
-        put(228,"KBDILLUMTOGGLE");
-        put(229,"KBDILLUMDOWN");
-        put(230,"KBDILLUMUP");
-        put(231,"SEND");
-        put(232,"REPLY");
-        put(233,"FORWARDMAIL");
-        put(234,"SAVE");
-        put(235,"DOCUMENTS");
-        put(236,"BATTERY");
-        put(237,"BLUETOOTH");
-        put(238,"WLAN");
-        put(239,"UWB");
-        put(240,"UNKNOWN");
-        put(241,"VIDEO_NEXT");
-        put(242,"VIDEO_PREV");
-        put(243,"BRIGHTNESS_CYCLE");
-        put(244,"BRIGHTNESS_AUTO");
-        put(245,"DISPLAY_OFF");
-        put(246,"WWAN");
-        put(247,"RFKILL");
-        put(248,"MICMUTE");
-        put(0x160,"OK");
-        put(0x161,"SELECT");
-        put(0x162,"GOTO");
-        put(0x163,"CLEAR");
-        put(0x164,"POWER2");
-        put(0x165,"OPTION");
-        put(0x166,"INFO");
-        put(0x167,"TIME");
-        put(0x168,"VENDOR");
-        put(0x169,"ARCHIVE");
-        put(0x16a,"PROGRAM");
-        put(0x16b,"CHANNEL");
-        put(0x16c,"FAVORITES");
-        put(0x16d,"EPG");
-        put(0x16e,"PVR");
-        put(0x16f,"MHP");
-        put(0x170,"LANGUAGE");
-        put(0x171,"TITLE");
-        put(0x172,"SUBTITLE");
-        put(0x173,"ANGLE");
-        put(0x174,"ZOOM");
-        put(0x175,"MODE");
-        put(0x176,"KEYBOARD");
-        put(0x177,"SCREEN");
-        put(0x178,"PC");
-        put(0x179,"TV");
-        put(0x17a,"TV2");
-        put(0x17b,"VCR");
-        put(0x17c,"VCR2");
-        put(0x17d,"SAT");
-        put(0x17e,"SAT2");
-        put(0x17f,"CD");
-        put(0x180,"TAPE");
-        put(0x181,"RADIO");
-        put(0x182,"TUNER");
-        put(0x183,"PLAYER");
-        put(0x184,"TEXT");
-        put(0x185,"DVD");
-        put(0x186,"AUX");
-        put(0x187,"MP3");
-        put(0x188,"AUDIO");
-        put(0x189,"VIDEO");
-        put(0x18a,"DIRECTORY");
-        put(0x18b,"LIST");
-        put(0x18c,"MEMO");
-        put(0x18d,"CALENDAR");
-        put(0x18e,"RED");
-        put(0x18f,"GREEN");
-        put(0x190,"YELLOW");
-        put(0x191,"BLUE");
-        put(0x192,"CHANNELUP");
-        put(0x193,"CHANNELDOWN");
-        put(0x194,"FIRST");
-        put(0x195,"LAST");
-        put(0x196,"AB");
-        put(0x197,"NEXT");
-        put(0x198,"RESTART");
-        put(0x199,"SLOW");
-        put(0x19a,"SHUFFLE");
-        put(0x19b,"BREAK");
-        put(0x19c,"PREVIOUS");
-        put(0x19d,"DIGITS");
-        put(0x19e,"TEEN");
-        put(0x19f,"TWEN");
-        put(0x1a0,"VIDEOPHONE");
-        put(0x1a1,"GAMES");
-        put(0x1a2,"ZOOMIN");
-        put(0x1a3,"ZOOMOUT");
-        put(0x1a4,"ZOOMRESET");
-        put(0x1a5,"WORDPROCESSOR");
-        put(0x1a6,"EDITOR");
-        put(0x1a7,"SPREADSHEET");
-        put(0x1a8,"GRAPHICSEDITOR");
-        put(0x1a9,"PRESENTATION");
-        put(0x1aa,"DATABASE");
-        put(0x1ab,"NEWS");
-        put(0x1ac,"VOICEMAIL");
-        put(0x1ad,"ADDRESSBOOK");
-        put(0x1ae,"MESSENGER");
-        put(0x1af,"DISPLAYTOGGLE");
-        put(0x1b0,"SPELLCHECK");
-        put(0x1b1,"LOGOFF");
-        put(0x1b2,"DOLLAR");
-        put(0x1b3,"EURO");
-        put(0x1b4,"FRAMEBACK");
-        put(0x1b5,"FRAMEFORWARD");
-        put(0x1b6,"CONTEXT_MENU");
-        put(0x1b7,"MEDIA_REPEAT");
-        put(0x1b8,"10CHANNELSUP");
-        put(0x1b9,"10CHANNELSDOWN");
-        put(0x1ba,"IMAGES");
-        put(0x1c0,"DEL_EOL");
-        put(0x1c1,"DEL_EOS");
-        put(0x1c2,"INS_LINE");
-        put(0x1c3,"DEL_LINE");
-        put(0x1d0,"FN");
-        put(0x1d1,"FN_ESC");
-        put(0x1d2,"FN_F1");
-        put(0x1d3,"FN_F2");
-        put(0x1d4,"FN_F3");
-        put(0x1d5,"FN_F4");
-        put(0x1d6,"FN_F5");
-        put(0x1d7,"FN_F6");
-        put(0x1d8,"FN_F7");
-        put(0x1d9,"FN_F8");
-        put(0x1da,"FN_F9");
-        put(0x1db,"FN_F10");
-        put(0x1dc,"FN_F11");
-        put(0x1dd,"FN_F12");
-        put(0x1de,"FN_1");
-        put(0x1df,"FN_2");
-        put(0x1e0,"FN_D");
-        put(0x1e1,"FN_E");
-        put(0x1e2,"FN_F");
-        put(0x1e3,"FN_S");
-        put(0x1e4,"FN_B");
-        put(0x1f1,"BRL_DOT1");
-        put(0x1f2,"BRL_DOT2");
-        put(0x1f3,"BRL_DOT3");
-        put(0x1f4,"BRL_DOT4");
-        put(0x1f5,"BRL_DOT5");
-        put(0x1f6,"BRL_DOT6");
-        put(0x1f7,"BRL_DOT7");
-        put(0x1f8,"BRL_DOT8");
-        put(0x1f9,"BRL_DOT9");
-        put(0x1fa,"BRL_DOT10");
-        put(0x200,"NUMERIC_0");
-        put(0x201,"NUMERIC_1");
-        put(0x202,"NUMERIC_2");
-        put(0x203,"NUMERIC_3");
-        put(0x204,"NUMERIC_4");
-        put(0x205,"NUMERIC_5");
-        put(0x206,"NUMERIC_6");
-        put(0x207,"NUMERIC_7");
-        put(0x208,"NUMERIC_8");
-        put(0x209,"NUMERIC_9");
-        put(0x20a,"NUMERIC_STAR");
-        put(0x20b,"NUMERIC_POUND");
-        put(0x20c,"NUMERIC_A");
-        put(0x20d,"NUMERIC_B");
-        put(0x20e,"NUMERIC_C");
-        put(0x20f,"NUMERIC_D");
-        put(0x210,"CAMERA_FOCUS");
-        put(0x211,"WPS_BUTTON");
-        put(0x212,"TOUCHPAD_TOGGLE");
-        put(0x213,"TOUCHPAD_ON");
-        put(0x214,"TOUCHPAD_OFF");
-        put(0x215,"CAMERA_ZOOMIN");
-        put(0x216,"CAMERA_ZOOMOUT");
-        put(0x217,"CAMERA_UP");
-        put(0x218,"CAMERA_DOWN");
-        put(0x219,"CAMERA_LEFT");
-        put(0x21a,"CAMERA_RIGHT");
-        put(0x21b,"ATTENDANT_ON");
-        put(0x21c,"ATTENDANT_OFF");
-        put(0x21d,"ATTENDANT_TOGGLE");
-        put(0x21e,"LIGHTS_TOGGLE");
-        put(0x230,"ALS_TOGGLE");
-        put(0x240,"BUTTONCONFIG");
-        put(0x241,"TASKMANAGER");
-        put(0x242,"JOURNAL");
-        put(0x243,"CONTROLPANEL");
-        put(0x244,"APPSELECT");
-        put(0x245,"SCREENSAVER");
-        put(0x246,"VOICECOMMAND");
-        put(0x247,"ASSISTANT");
-        put(0x250,"BRIGHTNESS_MIN");
-        put(0x251,"BRIGHTNESS_MAX");
-        put(0x260,"KBDINPUTASSIST_PREV");
-        put(0x261,"KBDINPUTASSIST_NEXT");
-        put(0x262,"KBDINPUTASSIST_PREVGROUP");
-        put(0x263,"KBDINPUTASSIST_NEXTGROUP");
-        put(0x264,"KBDINPUTASSIST_ACCEPT");
-        put(0x265,"KBDINPUTASSIST_CANCEL");
-        put(0x266,"RIGHT_UP");
-        put(0x267,"RIGHT_DOWN");
-        put(0x268,"LEFT_UP");
-        put(0x269,"LEFT_DOWN");
-        put(0x26a,"ROOT_MENU");
-        put(0x26b,"MEDIA_TOP_MENU");
-        put(0x26c,"NUMERIC_11");
-        put(0x26d,"NUMERIC_12");
-        put(0x26e,"AUDIO_DESC");
-        put(0x26f,"3D_MODE");
-        put(0x270,"NEXT_FAVORITE");
-        put(0x271,"STOP_RECORD");
-        put(0x272,"PAUSE_RECORD");
-        put(0x273,"VOD");
-        put(0x274,"UNMUTE");
-        put(0x275,"FASTREVERSE");
-        put(0x276,"SLOWREVERSE");
-        put(0x277,"DATA");
-        put(0x278,"ONSCREEN_KEYBOARD");
-        put(113,"MIN_INTERESTING");
-        put(0x2ff,"MAX");
-        put(0x100,"MISC");
-        put(0x100,"0");
-        put(0x101,"1");
-        put(0x102,"2");
-        put(0x103,"3");
-        put(0x104,"4");
-        put(0x105,"5");
-        put(0x106,"6");
-        put(0x107,"7");
-        put(0x108,"8");
-        put(0x109,"9");
-        put(0x110,"MOUSE");
-        put(0x110,"LEFT");
-        put(0x111,"RIGHT");
-        put(0x112,"MIDDLE");
-        put(0x113,"SIDE");
-        put(0x114,"EXTRA");
-        put(0x115,"FORWARD");
-        put(0x116,"BACK");
-        put(0x117,"TASK");
-        put(0x120,"JOYSTICK");
-        put(0x120,"TRIGGER");
-        put(0x121,"THUMB");
-        put(0x122,"THUMB2");
-        put(0x123,"TOP");
-        put(0x124,"TOP2");
-        put(0x125,"PINKIE");
-        put(0x126,"BASE");
-        put(0x127,"BASE2");
-        put(0x128,"BASE3");
-        put(0x129,"BASE4");
-        put(0x12a,"BASE5");
-        put(0x12b,"BASE6");
-        put(0x12f,"DEAD");
-        put(0x130,"GAMEPAD");
-        put(0x130,"SOUTH");
-        put(0x131,"EAST");
-        put(0x132,"C");
-        put(0x133,"NORTH");
-        put(0x134,"WEST");
-        put(0x135,"Z");
-        put(0x136,"TL");
-        put(0x137,"TR");
-        put(0x138,"TL2");
-        put(0x139,"TR2");
-        put(0x13a,"SELECT");
-        put(0x13b,"START");
-        put(0x13c,"MODE");
-        put(0x13d,"THUMBL");
-        put(0x13e,"THUMBR");
-        put(0x140,"DIGI");
-        put(0x140,"TOOL_PEN");
-        put(0x141,"TOOL_RUBBER");
-        put(0x142,"TOOL_BRUSH");
-        put(0x143,"TOOL_PENCIL");
-        put(0x144,"TOOL_AIRBRUSH");
-        put(0x145,"TOOL_FINGER");
-        put(0x146,"TOOL_MOUSE");
-        put(0x147,"TOOL_LENS");
-        put(0x148,"TOOL_QUINTTAP");
-        put(0x149,"STYLUS3");
-        put(0x14a,"TOUCH");
-        put(0x14b,"STYLUS");
-        put(0x14c,"STYLUS2");
-        put(0x14d,"TOOL_DOUBLETAP");
-        put(0x14e,"TOOL_TRIPLETAP");
-        put(0x14f,"TOOL_QUADTAP");
-        put(0x150,"WHEEL");
-        put(0x150,"GEAR_DOWN");
-        put(0x151,"GEAR_UP");
-        put(0x220,"DPAD_UP");
-        put(0x221,"DPAD_DOWN");
-        put(0x222,"DPAD_LEFT");
-        put(0x223,"DPAD_RIGHT");
-        put(0x2c0,"TRIGGER_HAPPY");
-        put(0x2c0,"TRIGGER_HAPPY1");
-        put(0x2c1,"TRIGGER_HAPPY2");
-        put(0x2c2,"TRIGGER_HAPPY3");
-        put(0x2c3,"TRIGGER_HAPPY4");
-        put(0x2c4,"TRIGGER_HAPPY5");
-        put(0x2c5,"TRIGGER_HAPPY6");
-        put(0x2c6,"TRIGGER_HAPPY7");
-        put(0x2c7,"TRIGGER_HAPPY8");
-        put(0x2c8,"TRIGGER_HAPPY9");
-        put(0x2c9,"TRIGGER_HAPPY10");
-        put(0x2ca,"TRIGGER_HAPPY11");
-        put(0x2cb,"TRIGGER_HAPPY12");
-        put(0x2cc,"TRIGGER_HAPPY13");
-        put(0x2cd,"TRIGGER_HAPPY14");
-        put(0x2ce,"TRIGGER_HAPPY15");
-        put(0x2cf,"TRIGGER_HAPPY16");
-        put(0x2d0,"TRIGGER_HAPPY17");
-        put(0x2d1,"TRIGGER_HAPPY18");
-        put(0x2d2,"TRIGGER_HAPPY19");
-        put(0x2d3,"TRIGGER_HAPPY20");
-        put(0x2d4,"TRIGGER_HAPPY21");
-        put(0x2d5,"TRIGGER_HAPPY22");
-        put(0x2d6,"TRIGGER_HAPPY23");
-        put(0x2d7,"TRIGGER_HAPPY24");
-        put(0x2d8,"TRIGGER_HAPPY25");
-        put(0x2d9,"TRIGGER_HAPPY26");
-        put(0x2da,"TRIGGER_HAPPY27");
-        put(0x2db,"TRIGGER_HAPPY28");
-        put(0x2dc,"TRIGGER_HAPPY29");
-        put(0x2dd,"TRIGGER_HAPPY30");
-        put(0x2de,"TRIGGER_HAPPY31");
-        put(0x2df,"TRIGGER_HAPPY32");
-        put(0x2e0,"TRIGGER_HAPPY33");
-        put(0x2e1,"TRIGGER_HAPPY34");
-        put(0x2e2,"TRIGGER_HAPPY35");
-        put(0x2e3,"TRIGGER_HAPPY36");
-        put(0x2e4,"TRIGGER_HAPPY37");
-        put(0x2e5,"TRIGGER_HAPPY38");
-        put(0x2e6,"TRIGGER_HAPPY39");
-        put(0x2e7,"TRIGGER_HAPPY40");
-    }};
+    private static final Map<Integer, String> KEYCODE_NAME_MAP = new HashMap<Integer, String>();
+    static {
+        KEYCODE_NAME_MAP.put(0, "RESERVED");
+        KEYCODE_NAME_MAP.put(1, "ESC");
+        KEYCODE_NAME_MAP.put(2, "1");
+        KEYCODE_NAME_MAP.put(3, "2");
+        KEYCODE_NAME_MAP.put(4, "3");
+        KEYCODE_NAME_MAP.put(5, "4");
+        KEYCODE_NAME_MAP.put(6, "5");
+        KEYCODE_NAME_MAP.put(7, "6");
+        KEYCODE_NAME_MAP.put(8, "7");
+        KEYCODE_NAME_MAP.put(9, "8");
+        KEYCODE_NAME_MAP.put(10, "9");
+        KEYCODE_NAME_MAP.put(11, "0");
+        KEYCODE_NAME_MAP.put(12, "MINUS");
+        KEYCODE_NAME_MAP.put(13, "EQUAL");
+        KEYCODE_NAME_MAP.put(14, "BACKSPACE");
+        KEYCODE_NAME_MAP.put(15, "TAB");
+        KEYCODE_NAME_MAP.put(16, "Q");
+        KEYCODE_NAME_MAP.put(17, "W");
+        KEYCODE_NAME_MAP.put(18, "E");
+        KEYCODE_NAME_MAP.put(19, "R");
+        KEYCODE_NAME_MAP.put(20, "T");
+        KEYCODE_NAME_MAP.put(21, "Y");
+        KEYCODE_NAME_MAP.put(22, "U");
+        KEYCODE_NAME_MAP.put(23, "I");
+        KEYCODE_NAME_MAP.put(24, "O");
+        KEYCODE_NAME_MAP.put(25, "P");
+        KEYCODE_NAME_MAP.put(26, "LEFTBRACE");
+        KEYCODE_NAME_MAP.put(27, "RIGHTBRACE");
+        KEYCODE_NAME_MAP.put(28, "ENTER");
+        KEYCODE_NAME_MAP.put(29, "LEFTCTRL");
+        KEYCODE_NAME_MAP.put(30, "A");
+        KEYCODE_NAME_MAP.put(31, "S");
+        KEYCODE_NAME_MAP.put(32, "D");
+        KEYCODE_NAME_MAP.put(33, "F");
+        KEYCODE_NAME_MAP.put(34, "G");
+        KEYCODE_NAME_MAP.put(35, "H");
+        KEYCODE_NAME_MAP.put(36, "J");
+        KEYCODE_NAME_MAP.put(37, "K");
+        KEYCODE_NAME_MAP.put(38, "L");
+        KEYCODE_NAME_MAP.put(39, "SEMICOLON");
+        KEYCODE_NAME_MAP.put(40, "APOSTROPHE");
+        KEYCODE_NAME_MAP.put(41, "GRAVE");
+        KEYCODE_NAME_MAP.put(42, "LEFTSHIFT");
+        KEYCODE_NAME_MAP.put(43, "BACKSLASH");
+        KEYCODE_NAME_MAP.put(44, "Z");
+        KEYCODE_NAME_MAP.put(45, "X");
+        KEYCODE_NAME_MAP.put(46, "C");
+        KEYCODE_NAME_MAP.put(47, "V");
+        KEYCODE_NAME_MAP.put(48, "B");
+        KEYCODE_NAME_MAP.put(49, "N");
+        KEYCODE_NAME_MAP.put(50, "M");
+        KEYCODE_NAME_MAP.put(51, "COMMA");
+        KEYCODE_NAME_MAP.put(52, "DOT");
+        KEYCODE_NAME_MAP.put(53, "SLASH");
+        KEYCODE_NAME_MAP.put(54, "RIGHTSHIFT");
+        KEYCODE_NAME_MAP.put(55, "KPASTERISK");
+        KEYCODE_NAME_MAP.put(56, "LEFTALT");
+        KEYCODE_NAME_MAP.put(57, "SPACE");
+        KEYCODE_NAME_MAP.put(58, "CAPSLOCK");
+        KEYCODE_NAME_MAP.put(59, "F1");
+        KEYCODE_NAME_MAP.put(60, "F2");
+        KEYCODE_NAME_MAP.put(61, "F3");
+        KEYCODE_NAME_MAP.put(62, "F4");
+        KEYCODE_NAME_MAP.put(63, "F5");
+        KEYCODE_NAME_MAP.put(64, "F6");
+        KEYCODE_NAME_MAP.put(65, "F7");
+        KEYCODE_NAME_MAP.put(66, "F8");
+        KEYCODE_NAME_MAP.put(67, "F9");
+        KEYCODE_NAME_MAP.put(68, "F10");
+        KEYCODE_NAME_MAP.put(69, "NUMLOCK");
+        KEYCODE_NAME_MAP.put(70, "SCROLLLOCK");
+        KEYCODE_NAME_MAP.put(71, "KP7");
+        KEYCODE_NAME_MAP.put(72, "KP8");
+        KEYCODE_NAME_MAP.put(73, "KP9");
+        KEYCODE_NAME_MAP.put(74, "KPMINUS");
+        KEYCODE_NAME_MAP.put(75, "KP4");
+        KEYCODE_NAME_MAP.put(76, "KP5");
+        KEYCODE_NAME_MAP.put(77, "KP6");
+        KEYCODE_NAME_MAP.put(78, "KPPLUS");
+        KEYCODE_NAME_MAP.put(79, "KP1");
+        KEYCODE_NAME_MAP.put(80, "KP2");
+        KEYCODE_NAME_MAP.put(81, "KP3");
+        KEYCODE_NAME_MAP.put(82, "KP0");
+        KEYCODE_NAME_MAP.put(83, "KPDOT");
+        KEYCODE_NAME_MAP.put(85, "ZENKAKUHANKAKU");
+        KEYCODE_NAME_MAP.put(86, "102ND");
+        KEYCODE_NAME_MAP.put(87, "F11");
+        KEYCODE_NAME_MAP.put(88, "F12");
+        KEYCODE_NAME_MAP.put(89, "RO");
+        KEYCODE_NAME_MAP.put(90, "KATAKANA");
+        KEYCODE_NAME_MAP.put(91, "HIRAGANA");
+        KEYCODE_NAME_MAP.put(92, "HENKAN");
+        KEYCODE_NAME_MAP.put(93, "KATAKANAHIRAGANA");
+        KEYCODE_NAME_MAP.put(94, "MUHENKAN");
+        KEYCODE_NAME_MAP.put(95, "KPJPCOMMA");
+        KEYCODE_NAME_MAP.put(96, "KPENTER");
+        KEYCODE_NAME_MAP.put(97, "RIGHTCTRL");
+        KEYCODE_NAME_MAP.put(98, "KPSLASH");
+        KEYCODE_NAME_MAP.put(99, "SYSRQ");
+        KEYCODE_NAME_MAP.put(100, "RIGHTALT");
+        KEYCODE_NAME_MAP.put(101, "LINEFEED");
+        KEYCODE_NAME_MAP.put(102, "HOME");
+        KEYCODE_NAME_MAP.put(103, "UP");
+        KEYCODE_NAME_MAP.put(104, "PAGEUP");
+        KEYCODE_NAME_MAP.put(105, "LEFT");
+        KEYCODE_NAME_MAP.put(106, "RIGHT");
+        KEYCODE_NAME_MAP.put(107, "END");
+        KEYCODE_NAME_MAP.put(108, "DOWN");
+        KEYCODE_NAME_MAP.put(109, "PAGEDOWN");
+        KEYCODE_NAME_MAP.put(110, "INSERT");
+        KEYCODE_NAME_MAP.put(111, "DELETE");
+        KEYCODE_NAME_MAP.put(112, "MACRO");
+        KEYCODE_NAME_MAP.put(113, "MUTE");
+        KEYCODE_NAME_MAP.put(114, "VOLUMEDOWN");
+        KEYCODE_NAME_MAP.put(115, "VOLUMEUP");
+        KEYCODE_NAME_MAP.put(116, "POWER");
+        KEYCODE_NAME_MAP.put(117, "KPEQUAL");
+        KEYCODE_NAME_MAP.put(118, "KPPLUSMINUS");
+        KEYCODE_NAME_MAP.put(119, "PAUSE");
+        KEYCODE_NAME_MAP.put(120, "SCALE");
+        KEYCODE_NAME_MAP.put(121, "KPCOMMA");
+        KEYCODE_NAME_MAP.put(122, "HANGEUL");
+        KEYCODE_NAME_MAP.put(123, "HANJA");
+        KEYCODE_NAME_MAP.put(124, "YEN");
+        KEYCODE_NAME_MAP.put(125, "LEFTMETA");
+        KEYCODE_NAME_MAP.put(126, "RIGHTMETA");
+        KEYCODE_NAME_MAP.put(127, "COMPOSE");
+        KEYCODE_NAME_MAP.put(128, "STOP");
+        KEYCODE_NAME_MAP.put(129, "AGAIN");
+        KEYCODE_NAME_MAP.put(130, "PROPS");
+        KEYCODE_NAME_MAP.put(131, "UNDO");
+        KEYCODE_NAME_MAP.put(132, "FRONT");
+        KEYCODE_NAME_MAP.put(133, "COPY");
+        KEYCODE_NAME_MAP.put(134, "OPEN");
+        KEYCODE_NAME_MAP.put(135, "PASTE");
+        KEYCODE_NAME_MAP.put(136, "FIND");
+        KEYCODE_NAME_MAP.put(137, "CUT");
+        KEYCODE_NAME_MAP.put(138, "HELP");
+        KEYCODE_NAME_MAP.put(139, "MENU");
+        KEYCODE_NAME_MAP.put(140, "CALC");
+        KEYCODE_NAME_MAP.put(141, "SETUP");
+        KEYCODE_NAME_MAP.put(142, "SLEEP");
+        KEYCODE_NAME_MAP.put(143, "WAKEUP");
+        KEYCODE_NAME_MAP.put(144, "FILE");
+        KEYCODE_NAME_MAP.put(145, "SENDFILE");
+        KEYCODE_NAME_MAP.put(146, "DELETEFILE");
+        KEYCODE_NAME_MAP.put(147, "XFER");
+        KEYCODE_NAME_MAP.put(148, "PROG1");
+        KEYCODE_NAME_MAP.put(149, "PROG2");
+        KEYCODE_NAME_MAP.put(150, "WWW");
+        KEYCODE_NAME_MAP.put(151, "MSDOS");
+        KEYCODE_NAME_MAP.put(152, "SCREENLOCK");
+        KEYCODE_NAME_MAP.put(153, "ROTATE_DISPLAY");
+        KEYCODE_NAME_MAP.put(154, "CYCLEWINDOWS");
+        KEYCODE_NAME_MAP.put(155, "MAIL");
+        KEYCODE_NAME_MAP.put(156, "BOOKMARKS");
+        KEYCODE_NAME_MAP.put(157, "COMPUTER");
+        KEYCODE_NAME_MAP.put(158, "BACK");
+        KEYCODE_NAME_MAP.put(159, "FORWARD");
+        KEYCODE_NAME_MAP.put(160, "CLOSECD");
+        KEYCODE_NAME_MAP.put(161, "EJECTCD");
+        KEYCODE_NAME_MAP.put(162, "EJECTCLOSECD");
+        KEYCODE_NAME_MAP.put(163, "NEXTSONG");
+        KEYCODE_NAME_MAP.put(164, "PLAYPAUSE");
+        KEYCODE_NAME_MAP.put(165, "PREVIOUSSONG");
+        KEYCODE_NAME_MAP.put(166, "STOPCD");
+        KEYCODE_NAME_MAP.put(167, "RECORD");
+        KEYCODE_NAME_MAP.put(168, "REWIND");
+        KEYCODE_NAME_MAP.put(169, "PHONE");
+        KEYCODE_NAME_MAP.put(170, "ISO");
+        KEYCODE_NAME_MAP.put(171, "CONFIG");
+        KEYCODE_NAME_MAP.put(172, "HOMEPAGE");
+        KEYCODE_NAME_MAP.put(173, "REFRESH");
+        KEYCODE_NAME_MAP.put(174, "EXIT");
+        KEYCODE_NAME_MAP.put(175, "MOVE");
+        KEYCODE_NAME_MAP.put(176, "EDIT");
+        KEYCODE_NAME_MAP.put(177, "SCROLLUP");
+        KEYCODE_NAME_MAP.put(178, "SCROLLDOWN");
+        KEYCODE_NAME_MAP.put(179, "KPLEFTPAREN");
+        KEYCODE_NAME_MAP.put(180, "KPRIGHTPAREN");
+        KEYCODE_NAME_MAP.put(181, "NEW");
+        KEYCODE_NAME_MAP.put(182, "REDO");
+        KEYCODE_NAME_MAP.put(183, "F13");
+        KEYCODE_NAME_MAP.put(184, "F14");
+        KEYCODE_NAME_MAP.put(185, "F15");
+        KEYCODE_NAME_MAP.put(186, "F16");
+        KEYCODE_NAME_MAP.put(187, "F17");
+        KEYCODE_NAME_MAP.put(188, "F18");
+        KEYCODE_NAME_MAP.put(189, "F19");
+        KEYCODE_NAME_MAP.put(190, "F20");
+        KEYCODE_NAME_MAP.put(191, "F21");
+        KEYCODE_NAME_MAP.put(192, "F22");
+        KEYCODE_NAME_MAP.put(193, "F23");
+        KEYCODE_NAME_MAP.put(194, "F24");
+        KEYCODE_NAME_MAP.put(200, "PLAYCD");
+        KEYCODE_NAME_MAP.put(201, "PAUSECD");
+        KEYCODE_NAME_MAP.put(202, "PROG3");
+        KEYCODE_NAME_MAP.put(203, "PROG4");
+        KEYCODE_NAME_MAP.put(204, "DASHBOARD");
+        KEYCODE_NAME_MAP.put(205, "SUSPEND");
+        KEYCODE_NAME_MAP.put(206, "CLOSE");
+        KEYCODE_NAME_MAP.put(207, "PLAY");
+        KEYCODE_NAME_MAP.put(208, "FASTFORWARD");
+        KEYCODE_NAME_MAP.put(209, "BASSBOOST");
+        KEYCODE_NAME_MAP.put(210, "PRINT");
+        KEYCODE_NAME_MAP.put(211, "HP");
+        KEYCODE_NAME_MAP.put(212, "CAMERA");
+        KEYCODE_NAME_MAP.put(213, "SOUND");
+        KEYCODE_NAME_MAP.put(214, "QUESTION");
+        KEYCODE_NAME_MAP.put(215, "EMAIL");
+        KEYCODE_NAME_MAP.put(216, "CHAT");
+        KEYCODE_NAME_MAP.put(217, "SEARCH");
+        KEYCODE_NAME_MAP.put(218, "CONNECT");
+        KEYCODE_NAME_MAP.put(219, "FINANCE");
+        KEYCODE_NAME_MAP.put(220, "SPORT");
+        KEYCODE_NAME_MAP.put(221, "SHOP");
+        KEYCODE_NAME_MAP.put(222, "ALTERASE");
+        KEYCODE_NAME_MAP.put(223, "CANCEL");
+        KEYCODE_NAME_MAP.put(224, "BRIGHTNESSDOWN");
+        KEYCODE_NAME_MAP.put(225, "BRIGHTNESSUP");
+        KEYCODE_NAME_MAP.put(226, "MEDIA");
+        KEYCODE_NAME_MAP.put(227, "SWITCHVIDEOMODE");
+        KEYCODE_NAME_MAP.put(228, "KBDILLUMTOGGLE");
+        KEYCODE_NAME_MAP.put(229, "KBDILLUMDOWN");
+        KEYCODE_NAME_MAP.put(230, "KBDILLUMUP");
+        KEYCODE_NAME_MAP.put(231, "SEND");
+        KEYCODE_NAME_MAP.put(232, "REPLY");
+        KEYCODE_NAME_MAP.put(233, "FORWARDMAIL");
+        KEYCODE_NAME_MAP.put(234, "SAVE");
+        KEYCODE_NAME_MAP.put(235, "DOCUMENTS");
+        KEYCODE_NAME_MAP.put(236, "BATTERY");
+        KEYCODE_NAME_MAP.put(237, "BLUETOOTH");
+        KEYCODE_NAME_MAP.put(238, "WLAN");
+        KEYCODE_NAME_MAP.put(239, "UWB");
+        KEYCODE_NAME_MAP.put(240, "UNKNOWN");
+        KEYCODE_NAME_MAP.put(241, "VIDEO_NEXT");
+        KEYCODE_NAME_MAP.put(242, "VIDEO_PREV");
+        KEYCODE_NAME_MAP.put(243, "BRIGHTNESS_CYCLE");
+        KEYCODE_NAME_MAP.put(244, "BRIGHTNESS_AUTO");
+        KEYCODE_NAME_MAP.put(245, "DISPLAY_OFF");
+        KEYCODE_NAME_MAP.put(246, "WWAN");
+        KEYCODE_NAME_MAP.put(247, "RFKILL");
+        KEYCODE_NAME_MAP.put(248, "MICMUTE");
+        KEYCODE_NAME_MAP.put(0x160, "OK");
+        KEYCODE_NAME_MAP.put(0x161, "SELECT");
+        KEYCODE_NAME_MAP.put(0x162, "GOTO");
+        KEYCODE_NAME_MAP.put(0x163, "CLEAR");
+        KEYCODE_NAME_MAP.put(0x164, "POWER2");
+        KEYCODE_NAME_MAP.put(0x165, "OPTION");
+        KEYCODE_NAME_MAP.put(0x166, "INFO");
+        KEYCODE_NAME_MAP.put(0x167, "TIME");
+        KEYCODE_NAME_MAP.put(0x168, "VENDOR");
+        KEYCODE_NAME_MAP.put(0x169, "ARCHIVE");
+        KEYCODE_NAME_MAP.put(0x16a, "PROGRAM");
+        KEYCODE_NAME_MAP.put(0x16b, "CHANNEL");
+        KEYCODE_NAME_MAP.put(0x16c, "FAVORITES");
+        KEYCODE_NAME_MAP.put(0x16d, "EPG");
+        KEYCODE_NAME_MAP.put(0x16e, "PVR");
+        KEYCODE_NAME_MAP.put(0x16f, "MHP");
+        KEYCODE_NAME_MAP.put(0x170, "LANGUAGE");
+        KEYCODE_NAME_MAP.put(0x171, "TITLE");
+        KEYCODE_NAME_MAP.put(0x172, "SUBTITLE");
+        KEYCODE_NAME_MAP.put(0x173, "ANGLE");
+        KEYCODE_NAME_MAP.put(0x174, "ZOOM");
+        KEYCODE_NAME_MAP.put(0x175, "MODE");
+        KEYCODE_NAME_MAP.put(0x176, "KEYBOARD");
+        KEYCODE_NAME_MAP.put(0x177, "SCREEN");
+        KEYCODE_NAME_MAP.put(0x178, "PC");
+        KEYCODE_NAME_MAP.put(0x179, "TV");
+        KEYCODE_NAME_MAP.put(0x17a, "TV2");
+        KEYCODE_NAME_MAP.put(0x17b, "VCR");
+        KEYCODE_NAME_MAP.put(0x17c, "VCR2");
+        KEYCODE_NAME_MAP.put(0x17d, "SAT");
+        KEYCODE_NAME_MAP.put(0x17e, "SAT2");
+        KEYCODE_NAME_MAP.put(0x17f, "CD");
+        KEYCODE_NAME_MAP.put(0x180, "TAPE");
+        KEYCODE_NAME_MAP.put(0x181, "RADIO");
+        KEYCODE_NAME_MAP.put(0x182, "TUNER");
+        KEYCODE_NAME_MAP.put(0x183, "PLAYER");
+        KEYCODE_NAME_MAP.put(0x184, "TEXT");
+        KEYCODE_NAME_MAP.put(0x185, "DVD");
+        KEYCODE_NAME_MAP.put(0x186, "AUX");
+        KEYCODE_NAME_MAP.put(0x187, "MP3");
+        KEYCODE_NAME_MAP.put(0x188, "AUDIO");
+        KEYCODE_NAME_MAP.put(0x189, "VIDEO");
+        KEYCODE_NAME_MAP.put(0x18a, "DIRECTORY");
+        KEYCODE_NAME_MAP.put(0x18b, "LIST");
+        KEYCODE_NAME_MAP.put(0x18c, "MEMO");
+        KEYCODE_NAME_MAP.put(0x18d, "CALENDAR");
+        KEYCODE_NAME_MAP.put(0x18e, "RED");
+        KEYCODE_NAME_MAP.put(0x18f, "GREEN");
+        KEYCODE_NAME_MAP.put(0x190, "YELLOW");
+        KEYCODE_NAME_MAP.put(0x191, "BLUE");
+        KEYCODE_NAME_MAP.put(0x192, "CHANNELUP");
+        KEYCODE_NAME_MAP.put(0x193, "CHANNELDOWN");
+        KEYCODE_NAME_MAP.put(0x194, "FIRST");
+        KEYCODE_NAME_MAP.put(0x195, "LAST");
+        KEYCODE_NAME_MAP.put(0x196, "AB");
+        KEYCODE_NAME_MAP.put(0x197, "NEXT");
+        KEYCODE_NAME_MAP.put(0x198, "RESTART");
+        KEYCODE_NAME_MAP.put(0x199, "SLOW");
+        KEYCODE_NAME_MAP.put(0x19a, "SHUFFLE");
+        KEYCODE_NAME_MAP.put(0x19b, "BREAK");
+        KEYCODE_NAME_MAP.put(0x19c, "PREVIOUS");
+        KEYCODE_NAME_MAP.put(0x19d, "DIGITS");
+        KEYCODE_NAME_MAP.put(0x19e, "TEEN");
+        KEYCODE_NAME_MAP.put(0x19f, "TWEN");
+        KEYCODE_NAME_MAP.put(0x1a0, "VIDEOPHONE");
+        KEYCODE_NAME_MAP.put(0x1a1, "GAMES");
+        KEYCODE_NAME_MAP.put(0x1a2, "ZOOMIN");
+        KEYCODE_NAME_MAP.put(0x1a3, "ZOOMOUT");
+        KEYCODE_NAME_MAP.put(0x1a4, "ZOOMRESET");
+        KEYCODE_NAME_MAP.put(0x1a5, "WORDPROCESSOR");
+        KEYCODE_NAME_MAP.put(0x1a6, "EDITOR");
+        KEYCODE_NAME_MAP.put(0x1a7, "SPREADSHEET");
+        KEYCODE_NAME_MAP.put(0x1a8, "GRAPHICSEDITOR");
+        KEYCODE_NAME_MAP.put(0x1a9, "PRESENTATION");
+        KEYCODE_NAME_MAP.put(0x1aa, "DATABASE");
+        KEYCODE_NAME_MAP.put(0x1ab, "NEWS");
+        KEYCODE_NAME_MAP.put(0x1ac, "VOICEMAIL");
+        KEYCODE_NAME_MAP.put(0x1ad, "ADDRESSBOOK");
+        KEYCODE_NAME_MAP.put(0x1ae, "MESSENGER");
+        KEYCODE_NAME_MAP.put(0x1af, "DISPLAYTOGGLE");
+        KEYCODE_NAME_MAP.put(0x1b0, "SPELLCHECK");
+        KEYCODE_NAME_MAP.put(0x1b1, "LOGOFF");
+        KEYCODE_NAME_MAP.put(0x1b2, "DOLLAR");
+        KEYCODE_NAME_MAP.put(0x1b3, "EURO");
+        KEYCODE_NAME_MAP.put(0x1b4, "FRAMEBACK");
+        KEYCODE_NAME_MAP.put(0x1b5, "FRAMEFORWARD");
+        KEYCODE_NAME_MAP.put(0x1b6, "CONTEXT_MENU");
+        KEYCODE_NAME_MAP.put(0x1b7, "MEDIA_REPEAT");
+        KEYCODE_NAME_MAP.put(0x1b8, "10CHANNELSUP");
+        KEYCODE_NAME_MAP.put(0x1b9, "10CHANNELSDOWN");
+        KEYCODE_NAME_MAP.put(0x1ba, "IMAGES");
+        KEYCODE_NAME_MAP.put(0x1c0, "DEL_EOL");
+        KEYCODE_NAME_MAP.put(0x1c1, "DEL_EOS");
+        KEYCODE_NAME_MAP.put(0x1c2, "INS_LINE");
+        KEYCODE_NAME_MAP.put(0x1c3, "DEL_LINE");
+        KEYCODE_NAME_MAP.put(0x1d0, "FN");
+        KEYCODE_NAME_MAP.put(0x1d1, "FN_ESC");
+        KEYCODE_NAME_MAP.put(0x1d2, "FN_F1");
+        KEYCODE_NAME_MAP.put(0x1d3, "FN_F2");
+        KEYCODE_NAME_MAP.put(0x1d4, "FN_F3");
+        KEYCODE_NAME_MAP.put(0x1d5, "FN_F4");
+        KEYCODE_NAME_MAP.put(0x1d6, "FN_F5");
+        KEYCODE_NAME_MAP.put(0x1d7, "FN_F6");
+        KEYCODE_NAME_MAP.put(0x1d8, "FN_F7");
+        KEYCODE_NAME_MAP.put(0x1d9, "FN_F8");
+        KEYCODE_NAME_MAP.put(0x1da, "FN_F9");
+        KEYCODE_NAME_MAP.put(0x1db, "FN_F10");
+        KEYCODE_NAME_MAP.put(0x1dc, "FN_F11");
+        KEYCODE_NAME_MAP.put(0x1dd, "FN_F12");
+        KEYCODE_NAME_MAP.put(0x1de, "FN_1");
+        KEYCODE_NAME_MAP.put(0x1df, "FN_2");
+        KEYCODE_NAME_MAP.put(0x1e0, "FN_D");
+        KEYCODE_NAME_MAP.put(0x1e1, "FN_E");
+        KEYCODE_NAME_MAP.put(0x1e2, "FN_F");
+        KEYCODE_NAME_MAP.put(0x1e3, "FN_S");
+        KEYCODE_NAME_MAP.put(0x1e4, "FN_B");
+        KEYCODE_NAME_MAP.put(0x1f1, "BRL_DOT1");
+        KEYCODE_NAME_MAP.put(0x1f2, "BRL_DOT2");
+        KEYCODE_NAME_MAP.put(0x1f3, "BRL_DOT3");
+        KEYCODE_NAME_MAP.put(0x1f4, "BRL_DOT4");
+        KEYCODE_NAME_MAP.put(0x1f5, "BRL_DOT5");
+        KEYCODE_NAME_MAP.put(0x1f6, "BRL_DOT6");
+        KEYCODE_NAME_MAP.put(0x1f7, "BRL_DOT7");
+        KEYCODE_NAME_MAP.put(0x1f8, "BRL_DOT8");
+        KEYCODE_NAME_MAP.put(0x1f9, "BRL_DOT9");
+        KEYCODE_NAME_MAP.put(0x1fa, "BRL_DOT10");
+        KEYCODE_NAME_MAP.put(0x200, "NUMERIC_0");
+        KEYCODE_NAME_MAP.put(0x201, "NUMERIC_1");
+        KEYCODE_NAME_MAP.put(0x202, "NUMERIC_2");
+        KEYCODE_NAME_MAP.put(0x203, "NUMERIC_3");
+        KEYCODE_NAME_MAP.put(0x204, "NUMERIC_4");
+        KEYCODE_NAME_MAP.put(0x205, "NUMERIC_5");
+        KEYCODE_NAME_MAP.put(0x206, "NUMERIC_6");
+        KEYCODE_NAME_MAP.put(0x207, "NUMERIC_7");
+        KEYCODE_NAME_MAP.put(0x208, "NUMERIC_8");
+        KEYCODE_NAME_MAP.put(0x209, "NUMERIC_9");
+        KEYCODE_NAME_MAP.put(0x20a, "NUMERIC_STAR");
+        KEYCODE_NAME_MAP.put(0x20b, "NUMERIC_POUND");
+        KEYCODE_NAME_MAP.put(0x20c, "NUMERIC_A");
+        KEYCODE_NAME_MAP.put(0x20d, "NUMERIC_B");
+        KEYCODE_NAME_MAP.put(0x20e, "NUMERIC_C");
+        KEYCODE_NAME_MAP.put(0x20f, "NUMERIC_D");
+        KEYCODE_NAME_MAP.put(0x210, "CAMERA_FOCUS");
+        KEYCODE_NAME_MAP.put(0x211, "WPS_BUTTON");
+        KEYCODE_NAME_MAP.put(0x212, "TOUCHPAD_TOGGLE");
+        KEYCODE_NAME_MAP.put(0x213, "TOUCHPAD_ON");
+        KEYCODE_NAME_MAP.put(0x214, "TOUCHPAD_OFF");
+        KEYCODE_NAME_MAP.put(0x215, "CAMERA_ZOOMIN");
+        KEYCODE_NAME_MAP.put(0x216, "CAMERA_ZOOMOUT");
+        KEYCODE_NAME_MAP.put(0x217, "CAMERA_UP");
+        KEYCODE_NAME_MAP.put(0x218, "CAMERA_DOWN");
+        KEYCODE_NAME_MAP.put(0x219, "CAMERA_LEFT");
+        KEYCODE_NAME_MAP.put(0x21a, "CAMERA_RIGHT");
+        KEYCODE_NAME_MAP.put(0x21b, "ATTENDANT_ON");
+        KEYCODE_NAME_MAP.put(0x21c, "ATTENDANT_OFF");
+        KEYCODE_NAME_MAP.put(0x21d, "ATTENDANT_TOGGLE");
+        KEYCODE_NAME_MAP.put(0x21e, "LIGHTS_TOGGLE");
+        KEYCODE_NAME_MAP.put(0x230, "ALS_TOGGLE");
+        KEYCODE_NAME_MAP.put(0x240, "BUTTONCONFIG");
+        KEYCODE_NAME_MAP.put(0x241, "TASKMANAGER");
+        KEYCODE_NAME_MAP.put(0x242, "JOURNAL");
+        KEYCODE_NAME_MAP.put(0x243, "CONTROLPANEL");
+        KEYCODE_NAME_MAP.put(0x244, "APPSELECT");
+        KEYCODE_NAME_MAP.put(0x245, "SCREENSAVER");
+        KEYCODE_NAME_MAP.put(0x246, "VOICECOMMAND");
+        KEYCODE_NAME_MAP.put(0x247, "ASSISTANT");
+        KEYCODE_NAME_MAP.put(0x250, "BRIGHTNESS_MIN");
+        KEYCODE_NAME_MAP.put(0x251, "BRIGHTNESS_MAX");
+        KEYCODE_NAME_MAP.put(0x260, "KBDINPUTASSIST_PREV");
+        KEYCODE_NAME_MAP.put(0x261, "KBDINPUTASSIST_NEXT");
+        KEYCODE_NAME_MAP.put(0x262, "KBDINPUTASSIST_PREVGROUP");
+        KEYCODE_NAME_MAP.put(0x263, "KBDINPUTASSIST_NEXTGROUP");
+        KEYCODE_NAME_MAP.put(0x264, "KBDINPUTASSIST_ACCEPT");
+        KEYCODE_NAME_MAP.put(0x265, "KBDINPUTASSIST_CANCEL");
+        KEYCODE_NAME_MAP.put(0x266, "RIGHT_UP");
+        KEYCODE_NAME_MAP.put(0x267, "RIGHT_DOWN");
+        KEYCODE_NAME_MAP.put(0x268, "LEFT_UP");
+        KEYCODE_NAME_MAP.put(0x269, "LEFT_DOWN");
+        KEYCODE_NAME_MAP.put(0x26a, "ROOT_MENU");
+        KEYCODE_NAME_MAP.put(0x26b, "MEDIA_TOP_MENU");
+        KEYCODE_NAME_MAP.put(0x26c, "NUMERIC_11");
+        KEYCODE_NAME_MAP.put(0x26d, "NUMERIC_12");
+        KEYCODE_NAME_MAP.put(0x26e, "AUDIO_DESC");
+        KEYCODE_NAME_MAP.put(0x26f, "3D_MODE");
+        KEYCODE_NAME_MAP.put(0x270, "NEXT_FAVORITE");
+        KEYCODE_NAME_MAP.put(0x271, "STOP_RECORD");
+        KEYCODE_NAME_MAP.put(0x272, "PAUSE_RECORD");
+        KEYCODE_NAME_MAP.put(0x273, "VOD");
+        KEYCODE_NAME_MAP.put(0x274, "UNMUTE");
+        KEYCODE_NAME_MAP.put(0x275, "FASTREVERSE");
+        KEYCODE_NAME_MAP.put(0x276, "SLOWREVERSE");
+        KEYCODE_NAME_MAP.put(0x277, "DATA");
+        KEYCODE_NAME_MAP.put(0x278, "ONSCREEN_KEYBOARD");
+        KEYCODE_NAME_MAP.put(113, "MIN_INTERESTING");
+        KEYCODE_NAME_MAP.put(0x2ff, "MAX");
+        KEYCODE_NAME_MAP.put(0x100, "MISC");
+        KEYCODE_NAME_MAP.put(0x100, "0");
+        KEYCODE_NAME_MAP.put(0x101, "1");
+        KEYCODE_NAME_MAP.put(0x102, "2");
+        KEYCODE_NAME_MAP.put(0x103, "3");
+        KEYCODE_NAME_MAP.put(0x104, "4");
+        KEYCODE_NAME_MAP.put(0x105, "5");
+        KEYCODE_NAME_MAP.put(0x106, "6");
+        KEYCODE_NAME_MAP.put(0x107, "7");
+        KEYCODE_NAME_MAP.put(0x108, "8");
+        KEYCODE_NAME_MAP.put(0x109, "9");
+        KEYCODE_NAME_MAP.put(0x110, "MOUSE");
+        KEYCODE_NAME_MAP.put(0x110, "LEFT");
+        KEYCODE_NAME_MAP.put(0x111, "RIGHT");
+        KEYCODE_NAME_MAP.put(0x112, "MIDDLE");
+        KEYCODE_NAME_MAP.put(0x113, "SIDE");
+        KEYCODE_NAME_MAP.put(0x114, "EXTRA");
+        KEYCODE_NAME_MAP.put(0x115, "FORWARD");
+        KEYCODE_NAME_MAP.put(0x116, "BACK");
+        KEYCODE_NAME_MAP.put(0x117, "TASK");
+        KEYCODE_NAME_MAP.put(0x120, "JOYSTICK");
+        KEYCODE_NAME_MAP.put(0x120, "TRIGGER");
+        KEYCODE_NAME_MAP.put(0x121, "THUMB");
+        KEYCODE_NAME_MAP.put(0x122, "THUMB2");
+        KEYCODE_NAME_MAP.put(0x123, "TOP");
+        KEYCODE_NAME_MAP.put(0x124, "TOP2");
+        KEYCODE_NAME_MAP.put(0x125, "PINKIE");
+        KEYCODE_NAME_MAP.put(0x126, "BASE");
+        KEYCODE_NAME_MAP.put(0x127, "BASE2");
+        KEYCODE_NAME_MAP.put(0x128, "BASE3");
+        KEYCODE_NAME_MAP.put(0x129, "BASE4");
+        KEYCODE_NAME_MAP.put(0x12a, "BASE5");
+        KEYCODE_NAME_MAP.put(0x12b, "BASE6");
+        KEYCODE_NAME_MAP.put(0x12f, "DEAD");
+        KEYCODE_NAME_MAP.put(0x130, "GAMEPAD");
+        KEYCODE_NAME_MAP.put(0x130, "SOUTH");
+        KEYCODE_NAME_MAP.put(0x131, "EAST");
+        KEYCODE_NAME_MAP.put(0x132, "C");
+        KEYCODE_NAME_MAP.put(0x133, "NORTH");
+        KEYCODE_NAME_MAP.put(0x134, "WEST");
+        KEYCODE_NAME_MAP.put(0x135, "Z");
+        KEYCODE_NAME_MAP.put(0x136, "TL");
+        KEYCODE_NAME_MAP.put(0x137, "TR");
+        KEYCODE_NAME_MAP.put(0x138, "TL2");
+        KEYCODE_NAME_MAP.put(0x139, "TR2");
+        KEYCODE_NAME_MAP.put(0x13a, "SELECT");
+        KEYCODE_NAME_MAP.put(0x13b, "START");
+        KEYCODE_NAME_MAP.put(0x13c, "MODE");
+        KEYCODE_NAME_MAP.put(0x13d, "THUMBL");
+        KEYCODE_NAME_MAP.put(0x13e, "THUMBR");
+        KEYCODE_NAME_MAP.put(0x140, "DIGI");
+        KEYCODE_NAME_MAP.put(0x140, "TOOL_PEN");
+        KEYCODE_NAME_MAP.put(0x141, "TOOL_RUBBER");
+        KEYCODE_NAME_MAP.put(0x142, "TOOL_BRUSH");
+        KEYCODE_NAME_MAP.put(0x143, "TOOL_PENCIL");
+        KEYCODE_NAME_MAP.put(0x144, "TOOL_AIRBRUSH");
+        KEYCODE_NAME_MAP.put(0x145, "TOOL_FINGER");
+        KEYCODE_NAME_MAP.put(0x146, "TOOL_MOUSE");
+        KEYCODE_NAME_MAP.put(0x147, "TOOL_LENS");
+        KEYCODE_NAME_MAP.put(0x148, "TOOL_QUINTTAP");
+        KEYCODE_NAME_MAP.put(0x149, "STYLUS3");
+        KEYCODE_NAME_MAP.put(0x14a, "TOUCH");
+        KEYCODE_NAME_MAP.put(0x14b, "STYLUS");
+        KEYCODE_NAME_MAP.put(0x14c, "STYLUS2");
+        KEYCODE_NAME_MAP.put(0x14d, "TOOL_DOUBLETAP");
+        KEYCODE_NAME_MAP.put(0x14e, "TOOL_TRIPLETAP");
+        KEYCODE_NAME_MAP.put(0x14f, "TOOL_QUADTAP");
+        KEYCODE_NAME_MAP.put(0x150, "WHEEL");
+        KEYCODE_NAME_MAP.put(0x150, "GEAR_DOWN");
+        KEYCODE_NAME_MAP.put(0x151, "GEAR_UP");
+        KEYCODE_NAME_MAP.put(0x220, "DPAD_UP");
+        KEYCODE_NAME_MAP.put(0x221, "DPAD_DOWN");
+        KEYCODE_NAME_MAP.put(0x222, "DPAD_LEFT");
+        KEYCODE_NAME_MAP.put(0x223, "DPAD_RIGHT");
+        KEYCODE_NAME_MAP.put(0x2c0, "TRIGGER_HAPPY");
+        KEYCODE_NAME_MAP.put(0x2c0, "TRIGGER_HAPPY1");
+        KEYCODE_NAME_MAP.put(0x2c1, "TRIGGER_HAPPY2");
+        KEYCODE_NAME_MAP.put(0x2c2, "TRIGGER_HAPPY3");
+        KEYCODE_NAME_MAP.put(0x2c3, "TRIGGER_HAPPY4");
+        KEYCODE_NAME_MAP.put(0x2c4, "TRIGGER_HAPPY5");
+        KEYCODE_NAME_MAP.put(0x2c5, "TRIGGER_HAPPY6");
+        KEYCODE_NAME_MAP.put(0x2c6, "TRIGGER_HAPPY7");
+        KEYCODE_NAME_MAP.put(0x2c7, "TRIGGER_HAPPY8");
+        KEYCODE_NAME_MAP.put(0x2c8, "TRIGGER_HAPPY9");
+        KEYCODE_NAME_MAP.put(0x2c9, "TRIGGER_HAPPY10");
+        KEYCODE_NAME_MAP.put(0x2ca, "TRIGGER_HAPPY11");
+        KEYCODE_NAME_MAP.put(0x2cb, "TRIGGER_HAPPY12");
+        KEYCODE_NAME_MAP.put(0x2cc, "TRIGGER_HAPPY13");
+        KEYCODE_NAME_MAP.put(0x2cd, "TRIGGER_HAPPY14");
+        KEYCODE_NAME_MAP.put(0x2ce, "TRIGGER_HAPPY15");
+        KEYCODE_NAME_MAP.put(0x2cf, "TRIGGER_HAPPY16");
+        KEYCODE_NAME_MAP.put(0x2d0, "TRIGGER_HAPPY17");
+        KEYCODE_NAME_MAP.put(0x2d1, "TRIGGER_HAPPY18");
+        KEYCODE_NAME_MAP.put(0x2d2, "TRIGGER_HAPPY19");
+        KEYCODE_NAME_MAP.put(0x2d3, "TRIGGER_HAPPY20");
+        KEYCODE_NAME_MAP.put(0x2d4, "TRIGGER_HAPPY21");
+        KEYCODE_NAME_MAP.put(0x2d5, "TRIGGER_HAPPY22");
+        KEYCODE_NAME_MAP.put(0x2d6, "TRIGGER_HAPPY23");
+        KEYCODE_NAME_MAP.put(0x2d7, "TRIGGER_HAPPY24");
+        KEYCODE_NAME_MAP.put(0x2d8, "TRIGGER_HAPPY25");
+        KEYCODE_NAME_MAP.put(0x2d9, "TRIGGER_HAPPY26");
+        KEYCODE_NAME_MAP.put(0x2da, "TRIGGER_HAPPY27");
+        KEYCODE_NAME_MAP.put(0x2db, "TRIGGER_HAPPY28");
+        KEYCODE_NAME_MAP.put(0x2dc, "TRIGGER_HAPPY29");
+        KEYCODE_NAME_MAP.put(0x2dd, "TRIGGER_HAPPY30");
+        KEYCODE_NAME_MAP.put(0x2de, "TRIGGER_HAPPY31");
+        KEYCODE_NAME_MAP.put(0x2df, "TRIGGER_HAPPY32");
+        KEYCODE_NAME_MAP.put(0x2e0, "TRIGGER_HAPPY33");
+        KEYCODE_NAME_MAP.put(0x2e1, "TRIGGER_HAPPY34");
+        KEYCODE_NAME_MAP.put(0x2e2, "TRIGGER_HAPPY35");
+        KEYCODE_NAME_MAP.put(0x2e3, "TRIGGER_HAPPY36");
+        KEYCODE_NAME_MAP.put(0x2e4, "TRIGGER_HAPPY37");
+        KEYCODE_NAME_MAP.put(0x2e5, "TRIGGER_HAPPY38");
+        KEYCODE_NAME_MAP.put(0x2e6, "TRIGGER_HAPPY39");
+        KEYCODE_NAME_MAP.put(0x2e7, "TRIGGER_HAPPY40");
+    }
 
     public final String source;
     public final int keycode;
diff --git a/tools/telemetry/lua-interpreter/data/anr_occurred.json b/tools/telemetry/lua-interpreter/data/anr_occurred.json
index f944256..66b7c10 100644
--- a/tools/telemetry/lua-interpreter/data/anr_occurred.json
+++ b/tools/telemetry/lua-interpreter/data/anr_occurred.json
@@ -58,5 +58,14 @@
     ],
     "stats.process_name": [
         "com.android.systemui"
+    ],
+    "stats.is_incremental": [
+        false
+    ],
+    "stats.read_logs_enabled": [
+        false
+    ],
+    "stats.loading_progress": [
+        1.0
     ]
 }
diff --git a/tools/telemetry/lua-interpreter/data/app_crash_occurred.json b/tools/telemetry/lua-interpreter/data/app_crash_occurred.json
index 2642bfa..83fda11 100644
--- a/tools/telemetry/lua-interpreter/data/app_crash_occurred.json
+++ b/tools/telemetry/lua-interpreter/data/app_crash_occurred.json
@@ -58,5 +58,14 @@
     ],
     "stats.process_name": [
         "com.android.calendar"
+    ],
+    "stats.is_incremental": [
+        false
+    ],
+    "stats.read_logs_enabled": [
+        false
+    ],
+    "stats.loading_progress": [
+        1.0
     ]
 }
diff --git a/tools/telemetry/lua-interpreter/data/process_memory_snapshot.json b/tools/telemetry/lua-interpreter/data/process_memory_snapshot.json
new file mode 100644
index 0000000..96698c1
--- /dev/null
+++ b/tools/telemetry/lua-interpreter/data/process_memory_snapshot.json
@@ -0,0 +1,5513 @@
+{
+    "stats.pid": [
+      1810,
+      421,
+      3668,
+      556,
+      1930,
+      1270,
+      505,
+      1275,
+      1030,
+      4438,
+      501,
+      1808,
+      1659,
+      4118,
+      457,
+      565,
+      1041,
+      10673,
+      966,
+      1346,
+      5382,
+      1077,
+      567,
+      3333,
+      2039,
+      1011,
+      2270,
+      1027,
+      975,
+      1327,
+      2036,
+      1,
+      455,
+      1363,
+      1260,
+      456,
+      499,
+      1345,
+      568,
+      1348,
+      487,
+      5443,
+      10775,
+      1258,
+      1026,
+      554,
+      1103,
+      10773,
+      1202,
+      2846,
+      2229,
+      484,
+      4277,
+      2573,
+      1259,
+      520,
+      485,
+      558,
+      504,
+      1310,
+      449,
+      1100,
+      557,
+      1019,
+      1022,
+      2766,
+      1055,
+      1014,
+      976,
+      1340,
+      965,
+      1012,
+      1025,
+      3249,
+      10712,
+      506,
+      1047,
+      517,
+      1220,
+      569,
+      1817,
+      2514,
+      1681,
+      1050,
+      1031,
+      516,
+      1056,
+      427,
+      1215,
+      1078,
+      1292,
+      964,
+      4145,
+      2216,
+      439,
+      2181,
+      1362,
+      519,
+      357,
+      631,
+      10648,
+      1015,
+      10724,
+      4830,
+      1738,
+      1342,
+      1424,
+      458,
+      1017,
+      1255,
+      1279,
+      1343,
+      1018,
+      2953,
+      3692,
+      482,
+      1829,
+      5311,
+      500,
+      518,
+      1324,
+      1338,
+      1219,
+      1013,
+      1267,
+      3158,
+      483,
+      2658,
+      10900,
+      1761,
+      536,
+      1024,
+      6801,
+      2782,
+      1097,
+      1218,
+      1086,
+      3976,
+      3446,
+      3756,
+      6780,
+      3373,
+      3824,
+      1058,
+      3038,
+      1036,
+      2473,
+      1928,
+      2161,
+      1028,
+      1029,
+      5118,
+      1040,
+      2260,
+      3116,
+      2428,
+      1079,
+      4463,
+      3212,
+      3416,
+      1023,
+      526,
+      5479,
+      1016,
+      2737,
+      20161,
+      20337,
+      420,
+      420,
+      3000,
+      3000,
+      1769,
+      1769,
+      1328,
+      1328,
+      503,
+      503,
+      19498,
+      1329,
+      1329,
+      1042,
+      1042,
+      500,
+      500,
+      1768,
+      1768,
+      1659,
+      1659,
+      4092,
+      4092,
+      456,
+      456,
+      562,
+      562,
+      1057,
+      1057,
+      9691,
+      9691,
+      973,
+      973,
+      553,
+      553,
+      1929,
+      1929,
+      563,
+      563,
+      3286,
+      3286,
+      2040,
+      2040,
+      1018,
+      1018,
+      2329,
+      2329,
+      1039,
+      1039,
+      983,
+      983,
+      1346,
+      1346,
+      2039,
+      2039,
+      11896,
+      1,
+      1,
+      454,
+      454,
+      1381,
+      1381,
+      1293,
+      1293,
+      455,
+      455,
+      498,
+      498,
+      1356,
+      1356,
+      564,
+      564,
+      19113,
+      19113,
+      1358,
+      1358,
+      485,
+      485,
+      18890,
+      18890,
+      1235,
+      1235,
+      1357,
+      1357,
+      1080,
+      1080,
+      19452,
+      1038,
+      1038,
+      552,
+      552,
+      1103,
+      1103,
+      18888,
+      18888,
+      1211,
+      1211,
+      2631,
+      2631,
+      2252,
+      2252,
+      483,
+      483,
+      3720,
+      3720,
+      2826,
+      2826,
+      1291,
+      1291,
+      521,
+      521,
+      484,
+      484,
+      555,
+      555,
+      502,
+      502,
+      1343,
+      1343,
+      453,
+      453,
+      1101,
+      1101,
+      554,
+      554,
+      1026,
+      1026,
+      1028,
+      1028,
+      2232,
+      2232,
+      1063,
+      1063,
+      1021,
+      1021,
+      984,
+      984,
+      20056,
+      1350,
+      1350,
+      11916,
+      11916,
+      972,
+      972,
+      1019,
+      1019,
+      1032,
+      1032,
+      3346,
+      3346,
+      18828,
+      18828,
+      505,
+      505,
+      1059,
+      1059,
+      516,
+      516,
+      1226,
+      1226,
+      565,
+      565,
+      1771,
+      1771,
+      2475,
+      2475,
+      1683,
+      1683,
+      1060,
+      1060,
+      1049,
+      1049,
+      515,
+      515,
+      1066,
+      1066,
+      438,
+      438,
+      1221,
+      1221,
+      1081,
+      1081,
+      1342,
+      1342,
+      971,
+      971,
+      15243,
+      15243,
+      2213,
+      2213,
+      1040,
+      1040,
+      1041,
+      1041,
+      452,
+      452,
+      2162,
+      2162,
+      1379,
+      1379,
+      1022,
+      1022,
+      518,
+      518,
+      357,
+      357,
+      631,
+      631,
+      18798,
+      18798,
+      1432,
+      1432,
+      457,
+      457,
+      1024,
+      1024,
+      1229,
+      1229,
+      1335,
+      1335,
+      1352,
+      1352,
+      1025,
+      1025,
+      2639,
+      2639,
+      3682,
+      3682,
+      481,
+      481,
+      19925,
+      1790,
+      1790,
+      4969,
+      4969,
+      499,
+      499,
+      517,
+      517,
+      1345,
+      1345,
+      1348,
+      1348,
+      1740,
+      1740,
+      4606,
+      4606,
+      18840,
+      18840,
+      1351,
+      1351,
+      1225,
+      1225,
+      1020,
+      1020,
+      1323,
+      1323,
+      20223,
+      19075,
+      19075,
+      482,
+      482,
+      3190,
+      3190,
+      19010,
+      20831,
+      1730,
+      1730,
+      529,
+      529,
+      1031,
+      1031,
+      6818,
+      6818,
+      19951,
+      2256,
+      2256,
+      1094,
+      1094,
+      1224,
+      1224,
+      1088,
+      1088,
+      3892,
+      3892,
+      14974,
+      14974,
+      3383,
+      3383,
+      3753,
+      3753,
+      1069,
+      1069,
+      4631,
+      4631,
+      1052,
+      1052,
+      2577,
+      2577,
+      1924,
+      1924,
+      2184,
+      2184,
+      1055,
+      1055,
+      2264,
+      2264,
+      2862,
+      2862,
+      2543,
+      2543,
+      1082,
+      1082,
+      2957,
+      2957,
+      3210,
+      3210,
+      19570,
+      3420,
+      3420,
+      1030,
+      1030,
+      524,
+      524,
+      15228,
+      15228,
+      3544,
+      3544,
+      1023,
+      1023,
+      2804,
+      2804
+    ],
+    "stats.uid": [
+      1001,
+      1000,
+      1010151,
+      1000,
+      10060,
+      0,
+      1000,
+      1040,
+      9999,
+      1010171,
+      1041,
+      1068,
+      1010,
+      10058,
+      1000,
+      0,
+      1000,
+      1010141,
+      0,
+      1000,
+      1010096,
+      1000,
+      1000,
+      1010145,
+      1000,
+      1041,
+      1010093,
+      0,
+      0,
+      1046,
+      9999,
+      0,
+      1000,
+      1021,
+      1047,
+      0,
+      1000,
+      0,
+      1054,
+      0,
+      1000,
+      10152,
+      0,
+      0,
+      1000,
+      1000,
+      2903,
+      0,
+      1000,
+      10187,
+      1010139,
+      1000,
+      1010103,
+      1010151,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      0,
+      1000,
+      1000,
+      1017,
+      1000,
+      1000,
+      0,
+      1000,
+      1002,
+      0,
+      1000,
+      0,
+      1000,
+      1000,
+      1010057,
+      0,
+      1000,
+      1000,
+      1000,
+      9999,
+      1000,
+      10165,
+      1010148,
+      1000,
+      1000,
+      1041,
+      1000,
+      1046,
+      1000,
+      1000,
+      1000,
+      1013,
+      1066,
+      1000,
+      1001000,
+      1013,
+      1001002,
+      1021,
+      1003,
+      0,
+      1058,
+      1010090,
+      1013,
+      1010070,
+      1010084,
+      1053,
+      1001,
+      1000,
+      1092,
+      1013,
+      0,
+      1013,
+      1021,
+      1021,
+      10151,
+      1001000,
+      1036,
+      10151,
+      1010058,
+      1041,
+      1062,
+      1010,
+      1046,
+      9999,
+      1054,
+      1067,
+      10176,
+      1069,
+      1010177,
+      1010147,
+      1073,
+      0,
+      1000,
+      10087,
+      10151,
+      1072,
+      1019,
+      1076,
+      10152,
+      1010063,
+      10171,
+      1010061,
+      1010138,
+      1010061,
+      2906,
+      1010152,
+      1000,
+      1010145,
+      10148,
+      1010151,
+      1010,
+      1041,
+      1010152,
+      1000,
+      1010165,
+      1010151,
+      1010102,
+      1041,
+      1010150,
+      1010187,
+      1010159,
+      1000,
+      1062,
+      1001000,
+      1013,
+      1010161,
+      10090,
+      1010081,
+      1000,
+      1000,
+      1010151,
+      1010151,
+      1001,
+      1001,
+      0,
+      0,
+      1000,
+      1000,
+      1010171,
+      1040,
+      1040,
+      9999,
+      9999,
+      1041,
+      1041,
+      1068,
+      1068,
+      1010,
+      1010,
+      10058,
+      10058,
+      1000,
+      1000,
+      0,
+      0,
+      1000,
+      1000,
+      1010141,
+      1010141,
+      0,
+      0,
+      1000,
+      1000,
+      10060,
+      10060,
+      1000,
+      1000,
+      1010145,
+      1010145,
+      1000,
+      1000,
+      1041,
+      1041,
+      1010093,
+      1010093,
+      0,
+      0,
+      0,
+      0,
+      1046,
+      1046,
+      9999,
+      9999,
+      10144,
+      0,
+      0,
+      1000,
+      1000,
+      1021,
+      1021,
+      1047,
+      1047,
+      0,
+      0,
+      1000,
+      1000,
+      0,
+      0,
+      1054,
+      1054,
+      0,
+      0,
+      0,
+      0,
+      1000,
+      1000,
+      0,
+      0,
+      0,
+      0,
+      1000,
+      1000,
+      1000,
+      1000,
+      1010151,
+      1000,
+      1000,
+      1000,
+      1000,
+      2903,
+      2903,
+      0,
+      0,
+      1000,
+      1000,
+      10187,
+      10187,
+      1010139,
+      1010139,
+      1000,
+      1000,
+      1010103,
+      1010103,
+      1010151,
+      1010151,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      0,
+      0,
+      1000,
+      1000,
+      1000,
+      1000,
+      1017,
+      1017,
+      1000,
+      1000,
+      1000,
+      1000,
+      0,
+      0,
+      1000,
+      1000,
+      1002,
+      1002,
+      0,
+      0,
+      1010089,
+      1000,
+      1000,
+      1010144,
+      1010144,
+      0,
+      0,
+      1000,
+      1000,
+      1000,
+      1000,
+      1010057,
+      1010057,
+      0,
+      0,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      9999,
+      9999,
+      1000,
+      1000,
+      10165,
+      10165,
+      1010148,
+      1010148,
+      1000,
+      1000,
+      1000,
+      1000,
+      1041,
+      1041,
+      1000,
+      1000,
+      1046,
+      1046,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1000,
+      1013,
+      1013,
+      1066,
+      1066,
+      1000,
+      1000,
+      1001000,
+      1001000,
+      1010,
+      1010,
+      1041,
+      1041,
+      1013,
+      1013,
+      1001002,
+      1001002,
+      1021,
+      1021,
+      1013,
+      1013,
+      1003,
+      1003,
+      0,
+      0,
+      1058,
+      1058,
+      1010090,
+      1010090,
+      1000,
+      1000,
+      1092,
+      1092,
+      1013,
+      1013,
+      0,
+      0,
+      1013,
+      1013,
+      1021,
+      1021,
+      1021,
+      1021,
+      10151,
+      10151,
+      1001000,
+      1001000,
+      1036,
+      1036,
+      1010108,
+      10151,
+      10151,
+      1010058,
+      1010058,
+      1041,
+      1041,
+      1062,
+      1062,
+      1010,
+      1010,
+      1046,
+      1046,
+      1053,
+      1053,
+      1010084,
+      1010084,
+      1010070,
+      1010070,
+      1001,
+      1001,
+      9999,
+      9999,
+      1054,
+      1054,
+      1067,
+      1067,
+      1010088,
+      10176,
+      10176,
+      1069,
+      1069,
+      1010177,
+      1010177,
+      1010147,
+      1010147,
+      1073,
+      1073,
+      0,
+      0,
+      1000,
+      1000,
+      10087,
+      10087,
+      1010095,
+      10151,
+      10151,
+      1072,
+      1072,
+      1019,
+      1019,
+      1076,
+      1076,
+      10152,
+      10152,
+      1010061,
+      1010061,
+      1010138,
+      1010138,
+      1010061,
+      1010061,
+      2906,
+      2906,
+      1010152,
+      1010152,
+      1000,
+      1000,
+      1010145,
+      1010145,
+      10148,
+      10148,
+      1010151,
+      1010151,
+      1000,
+      1000,
+      1010165,
+      1010165,
+      1010151,
+      1010151,
+      1010102,
+      1010102,
+      1041,
+      1041,
+      1010150,
+      1010150,
+      1010187,
+      1010187,
+      1010140,
+      1010159,
+      1010159,
+      1000,
+      1000,
+      1062,
+      1062,
+      1001000,
+      1001000,
+      1010063,
+      1010063,
+      1013,
+      1013,
+      1010161,
+      1010161
+    ],
+    "stats.gpu_memory_kb": [
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0
+    ],
+    "stats.swap_in_kilobytes": [
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0
+    ],
+    "stats.process_name": [
+      "com.android.phone",
+      "/system/vendor/bin/ais_server",
+      "com.google.process.gapps",
+      "/system/bin/carpowerpolicyd",
+      "com.android.car.cartelemetryapp",
+      "/system/bin/installd",
+      "/vendor/bin/hw/android.hardware.keymaster@4.1-service-qti",
+      "media.extractor",
+      "/vendor/bin/hw/android.hardware.memtrack-service.example",
+      "com.google.android.permissioncontroller",
+      "/vendor/bin/audioextplugind",
+      "com.android.se",
+      "/vendor/bin/hw/wpa_supplicant",
+      "com.android.car.messenger",
+      "/system/bin/android.automotive.telemetryd@1.0",
+      "/vendor/bin/hw/android.hardware.boot@1.2-service",
+      "/vendor/bin/hw/vendor.qti.hardware.capabilityconfigstore@1.0-service",
+      "com.google.android.car.setupwizard",
+      "zygote64",
+      "/system/bin/gatekeeperd",
+      "com.android.car.dialer",
+      "/vendor/bin/pd-mapper",
+      "/vendor/bin/hw/android.hardware.gatekeeper@1.0-service-qti",
+      "com.google.android.carassistant:search",
+      "com.android.experimentalcar",
+      "/vendor/bin/hw/android.hardware.audio.service",
+      "com.google.android.embedded.projection",
+      "/vendor/bin/hw/android.hardware.usb@1.2-service-qti",
+      "/system/bin/iptables-restore",
+      "media.codec",
+      "/system/bin/com.android.car.procfsinspector",
+      "/system/bin/init",
+      "/vendor/bin/timedaemon",
+      "xtra-daemon",
+      "/system/bin/cameraserver",
+      "/vendor/bin/ipcdaemon",
+      "/vendor/bin/audio_hal_plugin_service",
+      "/vendor/bin/update_agent",
+      "/vendor/bin/hw/android.hardware.automotive.vehicle@V1-pasa-service",
+      "/system/bin/update_engine",
+      "/vendor/bin/vndservicemanager",
+      "com.android.vending:background",
+      "app_process",
+      "/vendor/bin/thermal-engine",
+      "/vendor/bin/hw/android.hardware.thermal@2.0-service.mock",
+      "/system/bin/hw/android.system.suspend-service",
+      "/vendor/bin/tftp_server",
+      "/system/bin/sh",
+      "/vendor/bin/diag-router",
+      "com.google.android.providers.media.module",
+      ".qtidataservices",
+      "/system/bin/servicemanager",
+      "com.google.android.car.netdbug",
+      "com.google.android.gms",
+      "/vendor/bin/cdsprpcd",
+      "/vendor/bin/android.hardware.automotive.evs@1.1-pasa",
+      "/system/bin/hwservicemanager",
+      "/vendor/bin/hw/android.hardware.atrace@1.0-service",
+      "/system/bin/carwatchdogd",
+      "/system/bin/storaged",
+      "/vendor/bin/audiod",
+      "/system/bin/surfaceflinger",
+      "/system/bin/keystore2",
+      "/vendor/bin/hw/android.hardware.graphics.composer@2.4-service",
+      "/vendor/bin/hw/android.hardware.health@2.1-service",
+      "/vendor/bin/car_power_daemon",
+      "/vendor/bin/hw/vendor.qti.hardware.tui_comm@1.0-service-qti",
+      "/vendor/bin/hw/android.hardware.bluetooth@1.0-service-qti",
+      "/system/bin/ip6tables-restore",
+      "/system/vendor/bin/cnss-daemon",
+      "/system/bin/netd",
+      "/system/bin/hw/android.hidl.allocator@1.0-service",
+      "/vendor/bin/hw/android.hardware.sensors@1.0-service",
+      "com.android.car.media",
+      "/apex/com.android.adbd/bin/adbd",
+      "/vendor/bin/hw/android.hardware.security.keymint-service-qti",
+      "/vendor/bin/hw/vendor.qti.hardware.display.allocator-service",
+      "/vendor/bin/hw/vendor.qti.hardware.qseecom@1.0-service",
+      "/system/bin/traced",
+      "/vendor/bin/hw/vendor.qti.hardware.qteeconnector@1.0-service",
+      "com.android.systemui",
+      "com.google.android.companiondevicesupport",
+      "com.android.car",
+      "/vendor/bin/hw/vendor.qti.hardware.soter@1.0-service",
+      "/vendor/bin/panasonic.hardware.broadcastradio.pasa@2.0-service",
+      "/vendor/bin/qseecomd",
+      "media.hwcodec",
+      "/vendor/bin/adsprpcd",
+      "/vendor/bin/pm-proxy",
+      "/vendor/bin/pm-service",
+      "/system/bin/mediaserver",
+      "/apex/com.android.os.statsd/bin/statsd",
+      "com.android.car.developeroptions",
+      "com.android.car",
+      "/vendor/bin/adsprpcd",
+      "com.google.android.bluetooth",
+      "lowi-server",
+      "/system/bin/android.frameworks.automotive.display@1.0-service",
+      "/system/bin/ueventd",
+      "/system/bin/tombstoned",
+      "com.google.android.car.kitchensink",
+      "/vendor/bin/hw/android.hardware.cas@1.2-service",
+      "android.process.media",
+      "com.google.android.apps.automotive.sensing.sensorreplay.recordingapp",
+      "webview_zygote",
+      "/vendor/bin/ssgqmigd",
+      "system",
+      "/system/bin/prng_seeder",
+      "/vendor/bin/hw/android.hardware.drm@1.4-service.widevine",
+      "/vendor/bin/keyhandler",
+      "media.metrics",
+      "/system/vendor/bin/loc_launcher",
+      "/vendor/bin/hw/android.hardware.gnss@2.1-service-qti",
+      "com.google.process.gservices",
+      "com.qualcomm.qti.services.secureui:sui_service",
+      "/system/bin/logd",
+      "com.google.android.gms.persistent",
+      "com.android.car.messenger",
+      "/vendor/bin/I2CAbs_serverd",
+      "/system/bin/evsmanagerd",
+      "/system/bin/wificond",
+      "media.swcodec",
+      "/system/bin/traced_probes",
+      "/vendor/bin/hw/android.hardware.automotive.can@1.0-service",
+      "/system/bin/incidentd",
+      "com.android.car.scriptexecutor:com.android.car.scriptexecutor.ScriptExecutor",
+      "/system/bin/lmkd",
+      "com.google.android.ext.services",
+      "com.google.android.apps.maps",
+      "com.android.networkstack.process",
+      "/system/bin/vold",
+      "/vendor/bin/hw/android.hardware.power-service",
+      "android.car.cluster",
+      "com.google.android.gms",
+      "/system/bin/gpuservice",
+      "/system/bin/drmserver",
+      "/system/bin/credstore",
+      "com.android.vending",
+      "com.android.car.carlauncher",
+      "com.google.android.permissioncontroller",
+      "com.android.car.radio:appService",
+      "com.android.car.custominput.sample",
+      "com.android.car.radio",
+      "/vendor/bin/qrtr-ns",
+      "com.android.vending",
+      "/vendor/bin/hw/vendor.display.color@1.0-service",
+      "com.google.android.carassistant:interactor",
+      "com.google.android.companiondevicesupport",
+      "com.google.android.gms.persistent",
+      "/vendor/bin/hw/android.hardware.wifi@1.0-service",
+      "/vendor/bin/hw/android.hardware.automotive.audiocontrol-service.example",
+      "com.android.vending:background",
+      "/vendor/bin/hw/vendor.qti.automotive.qcarcam@1.0-service",
+      "com.android.systemui",
+      "com.google.process.gservices",
+      "com.android.car.rotary",
+      "/system/bin/audioserver",
+      "com.google.android.apps.automotive.templates.host:renderer_service",
+      "com.google.android.providers.media.module",
+      "com.google.android.tts",
+      "/vendor/bin/hw/android.hardware.neuralnetworks@1.3-service-qti",
+      "/vendor/bin/evs_pasa_app",
+      "com.android.car.developeroptions",
+      "/vendor/bin/hw/android.hardware.drm@1.4-service.clearkey",
+      "com.google.android.apps.automotive.inputmethod",
+      "com.google.android.car.kitchensink",
+      "com.google.android.gms.vehicle.testapp",
+      "/system/vendor/bin/ais_server",
+      "/system/vendor/bin/ais_server",
+      "com.google.process.gapps",
+      "com.google.process.gapps",
+      "com.android.phone",
+      "com.android.phone",
+      "/system/bin/installd",
+      "/system/bin/installd",
+      "/vendor/bin/hw/android.hardware.keymaster@4.1-service-qti",
+      "/vendor/bin/hw/android.hardware.keymaster@4.1-service-qti",
+      "com.google.android.permissioncontroller",
+      "media.extractor",
+      "media.extractor",
+      "/vendor/bin/hw/android.hardware.memtrack-service.example",
+      "/vendor/bin/hw/android.hardware.memtrack-service.example",
+      "/vendor/bin/audioextplugind",
+      "/vendor/bin/audioextplugind",
+      "com.android.se",
+      "com.android.se",
+      "/vendor/bin/hw/wpa_supplicant",
+      "/vendor/bin/hw/wpa_supplicant",
+      "com.android.car.messenger",
+      "com.android.car.messenger",
+      "/system/bin/android.automotive.telemetryd@1.0",
+      "/system/bin/android.automotive.telemetryd@1.0",
+      "/vendor/bin/hw/android.hardware.boot@1.2-service",
+      "/vendor/bin/hw/android.hardware.boot@1.2-service",
+      "/vendor/bin/hw/vendor.qti.hardware.capabilityconfigstore@1.0-service",
+      "/vendor/bin/hw/vendor.qti.hardware.capabilityconfigstore@1.0-service",
+      "com.google.android.car.setupwizard",
+      "com.google.android.car.setupwizard",
+      "zygote64",
+      "zygote64",
+      "/system/bin/carpowerpolicyd",
+      "/system/bin/carpowerpolicyd",
+      "com.android.car.cartelemetryapp",
+      "com.android.car.cartelemetryapp",
+      "/vendor/bin/hw/android.hardware.gatekeeper@1.0-service-qti",
+      "/vendor/bin/hw/android.hardware.gatekeeper@1.0-service-qti",
+      "com.google.android.carassistant:search",
+      "com.google.android.carassistant:search",
+      "com.android.experimentalcar",
+      "com.android.experimentalcar",
+      "/vendor/bin/hw/android.hardware.audio.service",
+      "/vendor/bin/hw/android.hardware.audio.service",
+      "com.google.android.embedded.projection",
+      "com.google.android.embedded.projection",
+      "/vendor/bin/hw/android.hardware.usb@1.2-service-qti",
+      "/vendor/bin/hw/android.hardware.usb@1.2-service-qti",
+      "/system/bin/iptables-restore",
+      "/system/bin/iptables-restore",
+      "media.codec",
+      "media.codec",
+      "/system/bin/com.android.car.procfsinspector",
+      "/system/bin/com.android.car.procfsinspector",
+      "com.google.android.configupdater",
+      "/system/bin/init",
+      "/system/bin/init",
+      "/vendor/bin/timedaemon",
+      "/vendor/bin/timedaemon",
+      "xtra-daemon",
+      "xtra-daemon",
+      "/system/bin/cameraserver",
+      "/system/bin/cameraserver",
+      "/vendor/bin/ipcdaemon",
+      "/vendor/bin/ipcdaemon",
+      "/vendor/bin/audio_hal_plugin_service",
+      "/vendor/bin/audio_hal_plugin_service",
+      "/vendor/bin/update_agent",
+      "/vendor/bin/update_agent",
+      "/vendor/bin/hw/android.hardware.automotive.vehicle@V1-pasa-service",
+      "/vendor/bin/hw/android.hardware.automotive.vehicle@V1-pasa-service",
+      "-/system/bin/sh",
+      "-/system/bin/sh",
+      "/system/bin/update_engine",
+      "/system/bin/update_engine",
+      "/vendor/bin/vndservicemanager",
+      "/vendor/bin/vndservicemanager",
+      "app_process",
+      "app_process",
+      "/vendor/bin/thermal-engine",
+      "/vendor/bin/thermal-engine",
+      "/system/bin/gatekeeperd",
+      "/system/bin/gatekeeperd",
+      "/vendor/bin/pd-mapper",
+      "/vendor/bin/pd-mapper",
+      "com.google.android.gms.unstable",
+      "/vendor/bin/hw/android.hardware.thermal@2.0-service.mock",
+      "/vendor/bin/hw/android.hardware.thermal@2.0-service.mock",
+      "/system/bin/hw/android.system.suspend-service",
+      "/system/bin/hw/android.system.suspend-service",
+      "/vendor/bin/tftp_server",
+      "/vendor/bin/tftp_server",
+      "/system/bin/sh",
+      "/system/bin/sh",
+      "/vendor/bin/diag-router",
+      "/vendor/bin/diag-router",
+      "com.google.android.providers.media.module",
+      "com.google.android.providers.media.module",
+      ".qtidataservices",
+      ".qtidataservices",
+      "/system/bin/servicemanager",
+      "/system/bin/servicemanager",
+      "com.google.android.car.netdbug",
+      "com.google.android.car.netdbug",
+      "com.google.android.gms",
+      "com.google.android.gms",
+      "/vendor/bin/cdsprpcd",
+      "/vendor/bin/cdsprpcd",
+      "/vendor/bin/android.hardware.automotive.evs@1.1-pasa",
+      "/vendor/bin/android.hardware.automotive.evs@1.1-pasa",
+      "/system/bin/hwservicemanager",
+      "/system/bin/hwservicemanager",
+      "/vendor/bin/hw/android.hardware.atrace@1.0-service",
+      "/vendor/bin/hw/android.hardware.atrace@1.0-service",
+      "/system/bin/carwatchdogd",
+      "/system/bin/carwatchdogd",
+      "/system/bin/storaged",
+      "/system/bin/storaged",
+      "/vendor/bin/audiod",
+      "/vendor/bin/audiod",
+      "/system/bin/surfaceflinger",
+      "/system/bin/surfaceflinger",
+      "/system/bin/keystore2",
+      "/system/bin/keystore2",
+      "/vendor/bin/hw/android.hardware.graphics.composer@2.4-service",
+      "/vendor/bin/hw/android.hardware.graphics.composer@2.4-service",
+      "/vendor/bin/hw/android.hardware.health@2.1-service",
+      "/vendor/bin/hw/android.hardware.health@2.1-service",
+      "/vendor/bin/car_power_daemon",
+      "/vendor/bin/car_power_daemon",
+      "/vendor/bin/hw/vendor.qti.hardware.tui_comm@1.0-service-qti",
+      "/vendor/bin/hw/vendor.qti.hardware.tui_comm@1.0-service-qti",
+      "/vendor/bin/hw/android.hardware.bluetooth@1.0-service-qti",
+      "/vendor/bin/hw/android.hardware.bluetooth@1.0-service-qti",
+      "/system/bin/ip6tables-restore",
+      "/system/bin/ip6tables-restore",
+      "com.android.car.ui.paintbooth",
+      "/system/vendor/bin/cnss-daemon",
+      "/system/vendor/bin/cnss-daemon",
+      "com.google.android.configupdater",
+      "com.google.android.configupdater",
+      "/system/bin/netd",
+      "/system/bin/netd",
+      "/system/bin/hw/android.hidl.allocator@1.0-service",
+      "/system/bin/hw/android.hidl.allocator@1.0-service",
+      "/vendor/bin/hw/android.hardware.sensors@1.0-service",
+      "/vendor/bin/hw/android.hardware.sensors@1.0-service",
+      "com.android.car.media",
+      "com.android.car.media",
+      "/apex/com.android.adbd/bin/adbd",
+      "/apex/com.android.adbd/bin/adbd",
+      "/vendor/bin/hw/android.hardware.security.keymint-service-qti",
+      "/vendor/bin/hw/android.hardware.security.keymint-service-qti",
+      "/vendor/bin/hw/vendor.qti.hardware.display.allocator-service",
+      "/vendor/bin/hw/vendor.qti.hardware.display.allocator-service",
+      "/vendor/bin/hw/vendor.qti.hardware.qseecom@1.0-service",
+      "/vendor/bin/hw/vendor.qti.hardware.qseecom@1.0-service",
+      "/system/bin/traced",
+      "/system/bin/traced",
+      "/vendor/bin/hw/vendor.qti.hardware.qteeconnector@1.0-service",
+      "/vendor/bin/hw/vendor.qti.hardware.qteeconnector@1.0-service",
+      "com.android.systemui",
+      "com.android.systemui",
+      "com.google.android.companiondevicesupport",
+      "com.google.android.companiondevicesupport",
+      "com.android.car",
+      "com.android.car",
+      "/vendor/bin/hw/vendor.qti.hardware.soter@1.0-service",
+      "/vendor/bin/hw/vendor.qti.hardware.soter@1.0-service",
+      "/vendor/bin/panasonic.hardware.broadcastradio.pasa@2.0-service",
+      "/vendor/bin/panasonic.hardware.broadcastradio.pasa@2.0-service",
+      "/vendor/bin/qseecomd",
+      "/vendor/bin/qseecomd",
+      "media.hwcodec",
+      "media.hwcodec",
+      "/vendor/bin/adsprpcd",
+      "/vendor/bin/adsprpcd",
+      "/vendor/bin/pm-proxy",
+      "/vendor/bin/pm-proxy",
+      "/vendor/bin/pm-service",
+      "/vendor/bin/pm-service",
+      "/system/bin/mediaserver",
+      "/system/bin/mediaserver",
+      "/apex/com.android.os.statsd/bin/statsd",
+      "/apex/com.android.os.statsd/bin/statsd",
+      "com.android.car.developeroptions",
+      "com.android.car.developeroptions",
+      "com.android.car",
+      "com.android.car",
+      "/vendor/bin/hw/android.hardware.wifi@1.0-service",
+      "/vendor/bin/hw/android.hardware.wifi@1.0-service",
+      "/vendor/bin/hw/android.hardware.automotive.audiocontrol-service.example",
+      "/vendor/bin/hw/android.hardware.automotive.audiocontrol-service.example",
+      "/vendor/bin/adsprpcd",
+      "/vendor/bin/adsprpcd",
+      "com.google.android.bluetooth",
+      "com.google.android.bluetooth",
+      "lowi-server",
+      "lowi-server",
+      "/vendor/bin/hw/android.hardware.cas@1.2-service",
+      "/vendor/bin/hw/android.hardware.cas@1.2-service",
+      "/system/bin/android.frameworks.automotive.display@1.0-service",
+      "/system/bin/android.frameworks.automotive.display@1.0-service",
+      "/system/bin/ueventd",
+      "/system/bin/ueventd",
+      "/system/bin/tombstoned",
+      "/system/bin/tombstoned",
+      "com.google.android.car.kitchensink",
+      "com.google.android.car.kitchensink",
+      "system",
+      "system",
+      "/system/bin/prng_seeder",
+      "/system/bin/prng_seeder",
+      "/vendor/bin/hw/android.hardware.drm@1.4-service.widevine",
+      "/vendor/bin/hw/android.hardware.drm@1.4-service.widevine",
+      "/vendor/bin/keyhandler",
+      "/vendor/bin/keyhandler",
+      "media.metrics",
+      "media.metrics",
+      "/system/vendor/bin/loc_launcher",
+      "/system/vendor/bin/loc_launcher",
+      "/vendor/bin/hw/android.hardware.gnss@2.1-service-qti",
+      "/vendor/bin/hw/android.hardware.gnss@2.1-service-qti",
+      "com.google.process.gservices",
+      "com.google.process.gservices",
+      "com.qualcomm.qti.services.secureui:sui_service",
+      "com.qualcomm.qti.services.secureui:sui_service",
+      "/system/bin/logd",
+      "/system/bin/logd",
+      "com.android.car.calendar",
+      "com.google.android.gms.persistent",
+      "com.google.android.gms.persistent",
+      "com.android.car.messenger",
+      "com.android.car.messenger",
+      "/vendor/bin/I2CAbs_serverd",
+      "/vendor/bin/I2CAbs_serverd",
+      "/system/bin/evsmanagerd",
+      "/system/bin/evsmanagerd",
+      "/system/bin/wificond",
+      "/system/bin/wificond",
+      "media.swcodec",
+      "media.swcodec",
+      "webview_zygote",
+      "webview_zygote",
+      "com.google.android.apps.automotive.sensing.sensorreplay.recordingapp",
+      "com.google.android.apps.automotive.sensing.sensorreplay.recordingapp",
+      "android.process.media",
+      "android.process.media",
+      "/vendor/bin/ssgqmigd",
+      "/vendor/bin/ssgqmigd",
+      "/system/bin/traced_probes",
+      "/system/bin/traced_probes",
+      "/vendor/bin/hw/android.hardware.automotive.can@1.0-service",
+      "/vendor/bin/hw/android.hardware.automotive.can@1.0-service",
+      "/system/bin/incidentd",
+      "/system/bin/incidentd",
+      "com.google.android.apps.geo.autograph.vms.client.console.car",
+      "com.android.car.scriptexecutor:com.android.car.scriptexecutor.ScriptExecutor",
+      "com.android.car.scriptexecutor:com.android.car.scriptexecutor.ScriptExecutor",
+      "/system/bin/lmkd",
+      "/system/bin/lmkd",
+      "com.google.android.ext.services",
+      "com.google.android.ext.services",
+      "com.google.android.apps.maps",
+      "com.google.android.apps.maps",
+      "com.android.networkstack.process",
+      "com.android.networkstack.process",
+      "/system/bin/vold",
+      "/system/bin/vold",
+      "/vendor/bin/hw/android.hardware.power-service",
+      "/vendor/bin/hw/android.hardware.power-service",
+      "android.car.cluster",
+      "android.car.cluster",
+      "com.android.providers.calendar",
+      "com.google.android.gms",
+      "com.google.android.gms",
+      "/system/bin/gpuservice",
+      "/system/bin/gpuservice",
+      "/system/bin/drmserver",
+      "/system/bin/drmserver",
+      "/system/bin/credstore",
+      "/system/bin/credstore",
+      "com.android.vending",
+      "com.android.vending",
+      "com.android.car.radio:appService",
+      "com.android.car.radio:appService",
+      "com.android.car.custominput.sample",
+      "com.android.car.custominput.sample",
+      "com.android.car.radio",
+      "com.android.car.radio",
+      "/vendor/bin/qrtr-ns",
+      "/vendor/bin/qrtr-ns",
+      "com.android.vending",
+      "com.android.vending",
+      "/vendor/bin/hw/vendor.display.color@1.0-service",
+      "/vendor/bin/hw/vendor.display.color@1.0-service",
+      "com.google.android.carassistant:interactor",
+      "com.google.android.carassistant:interactor",
+      "com.google.android.companiondevicesupport",
+      "com.google.android.companiondevicesupport",
+      "com.google.android.gms.persistent",
+      "com.google.android.gms.persistent",
+      "/vendor/bin/hw/vendor.qti.automotive.qcarcam@1.0-service",
+      "/vendor/bin/hw/vendor.qti.automotive.qcarcam@1.0-service",
+      "com.android.systemui",
+      "com.android.systemui",
+      "com.google.process.gservices",
+      "com.google.process.gservices",
+      "com.android.car.rotary",
+      "com.android.car.rotary",
+      "/system/bin/audioserver",
+      "/system/bin/audioserver",
+      "com.google.android.apps.automotive.templates.host:renderer_service",
+      "com.google.android.apps.automotive.templates.host:renderer_service",
+      "com.google.android.providers.media.module",
+      "com.google.android.providers.media.module",
+      "com.google.android.partnersetup",
+      "com.google.android.tts",
+      "com.google.android.tts",
+      "/vendor/bin/hw/android.hardware.neuralnetworks@1.3-service-qti",
+      "/vendor/bin/hw/android.hardware.neuralnetworks@1.3-service-qti",
+      "/vendor/bin/evs_pasa_app",
+      "/vendor/bin/evs_pasa_app",
+      "com.android.car.developeroptions",
+      "com.android.car.developeroptions",
+      "com.android.car.carlauncher",
+      "com.android.car.carlauncher",
+      "/vendor/bin/hw/android.hardware.drm@1.4-service.clearkey",
+      "/vendor/bin/hw/android.hardware.drm@1.4-service.clearkey",
+      "com.google.android.apps.automotive.inputmethod",
+      "com.google.android.apps.automotive.inputmethod"
+    ],
+    "stats.elapsed_timestamp_nanos": [
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      944668609012,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951,
+      2797710058984,
+      3020312433951
+    ],
+    "stats.rss_in_kilobytes": [
+      129580,
+      40648,
+      100748,
+      5120,
+      94216,
+      7328,
+      5696,
+      29332,
+      4704,
+      106680,
+      9592,
+      95560,
+      11104,
+      97588,
+      3892,
+      4580,
+      5008,
+      104292,
+      173916,
+      6268,
+      97464,
+      4068,
+      4988,
+      248216,
+      91948,
+      29060,
+      108020,
+      5292,
+      3444,
+      11180,
+      4088,
+      13868,
+      5412,
+      9688,
+      26596,
+      2076,
+      4036,
+      4884,
+      5508,
+      10240,
+      3664,
+      134704,
+      123708,
+      5356,
+      4932,
+      5172,
+      3060,
+      3136,
+      6852,
+      120140,
+      91772,
+      5348,
+      94224,
+      173616,
+      5376,
+      33984,
+      5956,
+      3700,
+      6796,
+      5756,
+      9300,
+      51664,
+      14464,
+      21796,
+      5024,
+      6736,
+      5108,
+      6724,
+      3372,
+      5248,
+      10560,
+      3968,
+      5824,
+      101612,
+      10508,
+      7628,
+      8644,
+      4560,
+      3940,
+      6104,
+      235072,
+      109868,
+      122004,
+      5880,
+      6636,
+      4956,
+      22364,
+      4428,
+      4416,
+      4660,
+      26080,
+      6424,
+      117576,
+      101860,
+      4468,
+      121616,
+      6648,
+      8260,
+      8984,
+      2192,
+      169308,
+      4988,
+      97980,
+      96160,
+      84204,
+      2412,
+      386552,
+      6032,
+      9864,
+      5036,
+      8112,
+      4524,
+      17768,
+      99124,
+      90332,
+      7292,
+      187564,
+      97992,
+      1988,
+      6632,
+      7044,
+      21660,
+      3848,
+      4848,
+      5428,
+      88420,
+      2632,
+      89836,
+      172968,
+      106336,
+      9424,
+      5232,
+      120584,
+      169900,
+      8440,
+      7892,
+      8140,
+      178348,
+      182868,
+      104920,
+      107640,
+      88720,
+      95832,
+      2944,
+      183184,
+      7448,
+      162236,
+      112912,
+      186168,
+      15588,
+      5688,
+      134844,
+      4988,
+      153224,
+      99776,
+      122064,
+      31104,
+      157180,
+      121484,
+      221260,
+      21608,
+      10772,
+      115964,
+      8484,
+      138928,
+      169288,
+      158284,
+      40156,
+      40156,
+      101708,
+      101708,
+      130920,
+      131192,
+      7236,
+      7236,
+      4648,
+      4648,
+      134988,
+      29188,
+      29188,
+      4680,
+      4680,
+      9524,
+      9524,
+      95808,
+      95808,
+      11012,
+      11012,
+      99476,
+      99476,
+      3908,
+      3908,
+      4336,
+      4336,
+      5004,
+      5004,
+      99832,
+      99832,
+      174704,
+      174868,
+      4700,
+      4700,
+      94208,
+      94208,
+      4968,
+      4968,
+      247452,
+      247452,
+      92516,
+      92516,
+      29188,
+      29188,
+      108864,
+      108864,
+      5088,
+      5088,
+      3464,
+      3464,
+      11192,
+      11192,
+      4172,
+      4172,
+      90128,
+      13908,
+      13908,
+      5288,
+      5288,
+      9768,
+      9768,
+      26832,
+      26832,
+      2000,
+      2000,
+      3776,
+      3776,
+      4924,
+      4924,
+      5328,
+      5328,
+      3204,
+      3204,
+      10300,
+      10300,
+      4160,
+      4160,
+      123376,
+      126028,
+      5368,
+      5368,
+      6224,
+      6224,
+      4100,
+      4100,
+      152960,
+      4776,
+      4776,
+      4860,
+      4860,
+      3016,
+      3016,
+      3328,
+      3328,
+      6992,
+      6992,
+      121204,
+      121204,
+      92120,
+      92120,
+      5444,
+      5444,
+      96352,
+      96352,
+      170884,
+      171608,
+      5312,
+      5312,
+      33556,
+      33556,
+      5924,
+      5924,
+      3608,
+      3608,
+      6712,
+      6736,
+      5700,
+      5700,
+      9008,
+      9008,
+      52932,
+      55384,
+      14036,
+      14248,
+      21500,
+      21864,
+      5100,
+      5100,
+      6680,
+      6680,
+      5224,
+      5224,
+      6816,
+      6816,
+      3280,
+      3280,
+      153084,
+      5300,
+      5300,
+      90076,
+      90076,
+      10260,
+      10288,
+      3556,
+      3556,
+      5724,
+      5724,
+      103384,
+      103384,
+      11440,
+      11552,
+      7416,
+      7416,
+      8524,
+      8632,
+      4432,
+      4432,
+      3708,
+      3844,
+      5796,
+      5796,
+      219540,
+      233712,
+      111600,
+      111600,
+      122440,
+      123540,
+      5860,
+      5860,
+      6856,
+      6856,
+      5064,
+      5064,
+      23044,
+      23888,
+      4328,
+      4328,
+      4620,
+      4620,
+      4712,
+      4712,
+      24636,
+      24636,
+      6620,
+      6656,
+      122316,
+      122316,
+      100868,
+      100868,
+      16480,
+      16560,
+      5584,
+      5584,
+      4380,
+      4380,
+      122516,
+      122516,
+      6524,
+      6520,
+      4928,
+      4928,
+      7876,
+      7876,
+      9040,
+      9040,
+      2232,
+      2232,
+      170328,
+      166160,
+      354656,
+      394084,
+      6076,
+      6076,
+      9672,
+      9672,
+      5116,
+      5116,
+      8492,
+      8492,
+      4932,
+      4932,
+      17688,
+      17664,
+      99456,
+      99456,
+      90772,
+      90772,
+      7260,
+      7288,
+      152436,
+      185168,
+      188556,
+      98056,
+      98056,
+      1836,
+      1836,
+      6492,
+      6492,
+      7264,
+      7264,
+      21976,
+      21976,
+      83920,
+      83920,
+      97720,
+      97720,
+      99616,
+      99616,
+      2384,
+      2384,
+      3736,
+      3736,
+      5016,
+      5016,
+      5588,
+      5588,
+      162932,
+      85828,
+      85828,
+      2604,
+      2604,
+      87400,
+      87400,
+      159516,
+      158640,
+      106936,
+      106892,
+      9508,
+      9520,
+      5160,
+      5160,
+      124104,
+      124588,
+      96940,
+      168880,
+      168904,
+      8336,
+      8336,
+      7852,
+      7852,
+      7412,
+      7412,
+      168528,
+      168528,
+      107964,
+      107964,
+      90296,
+      90296,
+      97900,
+      97900,
+      2960,
+      2960,
+      168864,
+      168864,
+      7420,
+      7420,
+      162908,
+      165912,
+      109752,
+      109752,
+      189336,
+      191356,
+      5112,
+      5112,
+      150656,
+      151264,
+      101168,
+      100232,
+      120372,
+      122668,
+      31384,
+      31448,
+      158128,
+      158128,
+      120152,
+      120152,
+      92484,
+      217308,
+      217308,
+      21480,
+      21480,
+      10544,
+      10544,
+      122240,
+      122240,
+      170428,
+      234808,
+      8392,
+      8392,
+      139568,
+      186048
+    ],
+    "stats.has_foreground_services": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false
+    ],
+    "stats.anon_rss_in_kilobytes": [
+      50728,
+      26464,
+      47488,
+      784,
+      46724,
+      1996,
+      920,
+      4796,
+      712,
+      47592,
+      1912,
+      48432,
+      1268,
+      46796,
+      636,
+      764,
+      776,
+      54092,
+      47536,
+      900,
+      46984,
+      696,
+      840,
+      125996,
+      46552,
+      17160,
+      49208,
+      732,
+      888,
+      2104,
+      636,
+      5316,
+      840,
+      1460,
+      3820,
+      460,
+      704,
+      776,
+      1280,
+      1364,
+      672,
+      50232,
+      30324,
+      1584,
+      704,
+      1072,
+      528,
+      668,
+      2348,
+      51004,
+      46676,
+      1300,
+      47152,
+      62336,
+      768,
+      5488,
+      1300,
+      668,
+      2232,
+      848,
+      3376,
+      13816,
+      2652,
+      4256,
+      776,
+      888,
+      756,
+      1460,
+      728,
+      980,
+      1824,
+      708,
+      884,
+      47312,
+      5280,
+      1152,
+      1248,
+      788,
+      768,
+      972,
+      79192,
+      48884,
+      50912,
+      848,
+      884,
+      1032,
+      4428,
+      752,
+      692,
+      736,
+      4496,
+      1548,
+      47220,
+      48100,
+      788,
+      49508,
+      1472,
+      1300,
+      2872,
+      412,
+      64952,
+      728,
+      46932,
+      46616,
+      46840,
+      416,
+      122764,
+      812,
+      1244,
+      784,
+      1984,
+      676,
+      2680,
+      45840,
+      46580,
+      3068,
+      70400,
+      47088,
+      512,
+      996,
+      1084,
+      3648,
+      720,
+      704,
+      880,
+      46880,
+      472,
+      46604,
+      68776,
+      49624,
+      2184,
+      760,
+      48376,
+      60572,
+      1356,
+      1200,
+      1144,
+      68356,
+      60268,
+      47448,
+      47688,
+      46776,
+      46628,
+      508,
+      74100,
+      996,
+      65360,
+      48936,
+      67588,
+      5728,
+      856,
+      50300,
+      792,
+      57472,
+      46316,
+      48344,
+      6432,
+      51404,
+      51856,
+      133636,
+      3532,
+      1632,
+      47204,
+      1096,
+      51624,
+      52880,
+      58800,
+      26472,
+      26472,
+      47904,
+      47904,
+      50840,
+      51112,
+      1884,
+      1884,
+      836,
+      836,
+      53184,
+      4512,
+      4512,
+      704,
+      704,
+      1888,
+      1888,
+      48448,
+      48420,
+      1344,
+      1344,
+      46996,
+      46996,
+      632,
+      632,
+      772,
+      772,
+      768,
+      768,
+      52204,
+      52204,
+      47636,
+      47800,
+      816,
+      816,
+      46856,
+      46856,
+      832,
+      832,
+      125400,
+      125400,
+      46604,
+      46604,
+      17168,
+      17168,
+      49752,
+      49752,
+      736,
+      736,
+      888,
+      888,
+      2104,
+      2104,
+      640,
+      640,
+      46768,
+      5284,
+      5284,
+      836,
+      836,
+      1456,
+      1456,
+      3836,
+      3836,
+      460,
+      460,
+      708,
+      708,
+      768,
+      768,
+      1280,
+      1280,
+      752,
+      752,
+      1356,
+      1356,
+      804,
+      804,
+      30344,
+      30944,
+      1596,
+      1596,
+      908,
+      908,
+      684,
+      684,
+      52792,
+      708,
+      708,
+      1048,
+      1048,
+      524,
+      524,
+      668,
+      668,
+      2392,
+      2392,
+      50992,
+      50992,
+      46828,
+      46828,
+      1304,
+      1304,
+      47380,
+      47380,
+      59676,
+      60972,
+      764,
+      764,
+      5472,
+      5472,
+      1292,
+      1292,
+      676,
+      676,
+      2316,
+      2340,
+      852,
+      852,
+      3368,
+      3368,
+      13900,
+      15476,
+      2712,
+      2920,
+      4296,
+      4660,
+      784,
+      784,
+      888,
+      888,
+      760,
+      760,
+      1456,
+      1456,
+      716,
+      716,
+      57176,
+      988,
+      988,
+      46780,
+      46780,
+      1896,
+      1924,
+      700,
+      700,
+      880,
+      880,
+      47284,
+      47284,
+      6196,
+      6308,
+      1132,
+      1132,
+      1256,
+      1364,
+      780,
+      780,
+      772,
+      908,
+      972,
+      972,
+      75992,
+      77580,
+      49128,
+      49128,
+      51964,
+      52972,
+      840,
+      840,
+      984,
+      984,
+      1036,
+      1036,
+      4444,
+      4460,
+      752,
+      752,
+      692,
+      692,
+      732,
+      732,
+      4012,
+      4012,
+      1712,
+      1740,
+      47380,
+      47380,
+      47772,
+      47772,
+      6548,
+      6628,
+      848,
+      848,
+      784,
+      784,
+      49716,
+      49716,
+      1392,
+      1388,
+      672,
+      672,
+      1296,
+      1296,
+      2836,
+      2836,
+      412,
+      412,
+      63952,
+      58536,
+      98360,
+      127632,
+      812,
+      812,
+      1252,
+      1252,
+      788,
+      788,
+      1776,
+      1776,
+      896,
+      896,
+      2688,
+      2664,
+      46216,
+      46216,
+      46708,
+      46708,
+      3128,
+      3156,
+      53500,
+      68276,
+      70644,
+      46952,
+      46952,
+      508,
+      508,
+      1012,
+      1012,
+      1312,
+      1312,
+      3808,
+      3808,
+      46956,
+      46956,
+      47796,
+      47796,
+      47180,
+      47180,
+      416,
+      416,
+      712,
+      712,
+      700,
+      700,
+      876,
+      876,
+      55600,
+      46816,
+      46816,
+      472,
+      472,
+      46708,
+      46708,
+      55908,
+      56324,
+      49896,
+      49824,
+      2188,
+      2200,
+      752,
+      752,
+      48512,
+      48932,
+      46960,
+      58460,
+      58484,
+      1356,
+      1356,
+      1200,
+      1200,
+      1148,
+      1148,
+      61100,
+      61100,
+      47848,
+      47848,
+      46964,
+      46964,
+      46824,
+      46824,
+      512,
+      512,
+      61532,
+      61532,
+      1000,
+      1000,
+      65224,
+      68200,
+      47352,
+      47352,
+      67644,
+      69380,
+      792,
+      792,
+      56360,
+      56524,
+      47812,
+      46876,
+      48852,
+      48888,
+      6436,
+      6460,
+      51752,
+      51752,
+      50952,
+      50952,
+      46880,
+      128616,
+      128616,
+      3536,
+      3536,
+      1628,
+      1628,
+      47392,
+      47392,
+      58640,
+      76924,
+      1096,
+      1096,
+      52024,
+      62968
+    ],
+    "stats.oom_score_adj": [
+      -800,
+      -1001,
+      925,
+      -1001,
+      100,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      975,
+      -1001,
+      -800,
+      -1001,
+      200,
+      -1001,
+      -1001,
+      -1001,
+      925,
+      -1001,
+      -1001,
+      945,
+      -1001,
+      -1001,
+      250,
+      100,
+      -1001,
+      100,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      965,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -700,
+      500,
+      -1001,
+      200,
+      905,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      200,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -800,
+      100,
+      -800,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      955,
+      100,
+      -1001,
+      -700,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      0,
+      -1001,
+      915,
+      200,
+      -1001,
+      -1001,
+      -900,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      945,
+      800,
+      -1001,
+      100,
+      200,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      100,
+      -1001,
+      100,
+      100,
+      -800,
+      -1001,
+      -1001,
+      -700,
+      905,
+      -1001,
+      -1001,
+      -1001,
+      935,
+      600,
+      955,
+      200,
+      100,
+      200,
+      -1001,
+      935,
+      -1001,
+      100,
+      100,
+      100,
+      -1001,
+      -1001,
+      975,
+      -1001,
+      500,
+      915,
+      100,
+      -1001,
+      200,
+      -700,
+      100,
+      -1001,
+      -1001,
+      965,
+      -1001,
+      200,
+      910,
+      200,
+      -1001,
+      -1001,
+      925,
+      945,
+      -800,
+      -800,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      905,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -800,
+      -800,
+      -1001,
+      -1001,
+      200,
+      200,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      945,
+      955,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      100,
+      100,
+      -1001,
+      -1001,
+      250,
+      0,
+      100,
+      100,
+      -1001,
+      -1001,
+      100,
+      100,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      999,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      935,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -700,
+      -700,
+      999,
+      985,
+      -1001,
+      -1001,
+      200,
+      200,
+      905,
+      200,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      930,
+      -1001,
+      -1001,
+      999,
+      975,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      200,
+      200,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -800,
+      -800,
+      100,
+      100,
+      -800,
+      -800,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      965,
+      955,
+      100,
+      100,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -700,
+      -700,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      0,
+      920,
+      -900,
+      -900,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      955,
+      915,
+      999,
+      985,
+      -1001,
+      -1001,
+      940,
+      100,
+      100,
+      200,
+      200,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      200,
+      200,
+      905,
+      945,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      900,
+      100,
+      100,
+      -1001,
+      -1001,
+      100,
+      100,
+      100,
+      100,
+      -800,
+      -800,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -700,
+      -700,
+      925,
+      905,
+      905,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      995,
+      975,
+      200,
+      100,
+      100,
+      100,
+      200,
+      100,
+      -1001,
+      -1001,
+      985,
+      965,
+      -1001,
+      -1001,
+      100,
+      100,
+      100,
+      100,
+      100,
+      100,
+      -1001,
+      -1001,
+      905,
+      905,
+      915,
+      925,
+      100,
+      100,
+      -1001,
+      -1001,
+      200,
+      200,
+      -700,
+      -700,
+      935,
+      100,
+      100,
+      -1001,
+      -1001,
+      -1001,
+      -1001,
+      975,
+      965,
+      600,
+      0,
+      -1001,
+      -1001,
+      200,
+      200
+    ],
+    "stats.anon_rss_and_swap_in_kilobytes": [
+      50728,
+      26464,
+      47488,
+      784,
+      46724,
+      1996,
+      920,
+      4796,
+      712,
+      47592,
+      1912,
+      48432,
+      1268,
+      46796,
+      636,
+      764,
+      776,
+      54092,
+      47536,
+      900,
+      46984,
+      696,
+      840,
+      125996,
+      46552,
+      17160,
+      49208,
+      732,
+      888,
+      2104,
+      636,
+      5316,
+      840,
+      1460,
+      3820,
+      460,
+      704,
+      776,
+      1280,
+      1364,
+      672,
+      50232,
+      30324,
+      1584,
+      704,
+      1072,
+      528,
+      668,
+      2348,
+      51004,
+      46676,
+      1300,
+      47152,
+      62336,
+      768,
+      5488,
+      1300,
+      668,
+      2232,
+      848,
+      3376,
+      13816,
+      2652,
+      4256,
+      776,
+      888,
+      756,
+      1460,
+      728,
+      980,
+      1824,
+      708,
+      884,
+      47312,
+      5280,
+      1152,
+      1248,
+      788,
+      768,
+      972,
+      79192,
+      48884,
+      50912,
+      848,
+      884,
+      1032,
+      4428,
+      752,
+      692,
+      736,
+      4496,
+      1548,
+      47220,
+      48100,
+      788,
+      49508,
+      1472,
+      1300,
+      2872,
+      412,
+      64952,
+      728,
+      46932,
+      46616,
+      46840,
+      416,
+      122764,
+      812,
+      1244,
+      784,
+      1984,
+      676,
+      2680,
+      45840,
+      46580,
+      3068,
+      70400,
+      47088,
+      512,
+      996,
+      1084,
+      3648,
+      720,
+      704,
+      880,
+      46880,
+      472,
+      46604,
+      68776,
+      49624,
+      2184,
+      760,
+      48376,
+      60572,
+      1356,
+      1200,
+      1144,
+      68356,
+      60268,
+      47448,
+      47688,
+      46776,
+      46628,
+      508,
+      74100,
+      996,
+      65360,
+      48936,
+      67588,
+      5728,
+      856,
+      50300,
+      792,
+      57472,
+      46316,
+      48344,
+      6432,
+      51404,
+      51856,
+      133636,
+      3532,
+      1632,
+      47204,
+      1096,
+      51624,
+      52880,
+      58800,
+      26472,
+      26472,
+      47904,
+      47904,
+      50840,
+      51112,
+      1884,
+      1884,
+      836,
+      836,
+      53184,
+      4512,
+      4512,
+      704,
+      704,
+      1888,
+      1888,
+      48448,
+      48420,
+      1344,
+      1344,
+      46996,
+      46996,
+      632,
+      632,
+      772,
+      772,
+      768,
+      768,
+      52204,
+      52204,
+      47636,
+      47800,
+      816,
+      816,
+      46856,
+      46856,
+      832,
+      832,
+      125400,
+      125400,
+      46604,
+      46604,
+      17168,
+      17168,
+      49752,
+      49752,
+      736,
+      736,
+      888,
+      888,
+      2104,
+      2104,
+      640,
+      640,
+      46768,
+      5284,
+      5284,
+      836,
+      836,
+      1456,
+      1456,
+      3836,
+      3836,
+      460,
+      460,
+      708,
+      708,
+      768,
+      768,
+      1280,
+      1280,
+      752,
+      752,
+      1356,
+      1356,
+      804,
+      804,
+      30344,
+      30944,
+      1596,
+      1596,
+      908,
+      908,
+      684,
+      684,
+      52792,
+      708,
+      708,
+      1048,
+      1048,
+      524,
+      524,
+      668,
+      668,
+      2392,
+      2392,
+      50992,
+      50992,
+      46828,
+      46828,
+      1304,
+      1304,
+      47380,
+      47380,
+      59676,
+      60972,
+      764,
+      764,
+      5472,
+      5472,
+      1292,
+      1292,
+      676,
+      676,
+      2316,
+      2340,
+      852,
+      852,
+      3368,
+      3368,
+      13900,
+      15476,
+      2712,
+      2920,
+      4296,
+      4660,
+      784,
+      784,
+      888,
+      888,
+      760,
+      760,
+      1456,
+      1456,
+      716,
+      716,
+      57176,
+      988,
+      988,
+      46780,
+      46780,
+      1896,
+      1924,
+      700,
+      700,
+      880,
+      880,
+      47284,
+      47284,
+      6196,
+      6308,
+      1132,
+      1132,
+      1256,
+      1364,
+      780,
+      780,
+      772,
+      908,
+      972,
+      972,
+      75992,
+      77580,
+      49128,
+      49128,
+      51964,
+      52972,
+      840,
+      840,
+      984,
+      984,
+      1036,
+      1036,
+      4444,
+      4460,
+      752,
+      752,
+      692,
+      692,
+      732,
+      732,
+      4012,
+      4012,
+      1712,
+      1740,
+      47380,
+      47380,
+      47772,
+      47772,
+      6548,
+      6628,
+      848,
+      848,
+      784,
+      784,
+      49716,
+      49716,
+      1392,
+      1388,
+      672,
+      672,
+      1296,
+      1296,
+      2836,
+      2836,
+      412,
+      412,
+      63952,
+      58536,
+      98360,
+      127632,
+      812,
+      812,
+      1252,
+      1252,
+      788,
+      788,
+      1776,
+      1776,
+      896,
+      896,
+      2688,
+      2664,
+      46216,
+      46216,
+      46708,
+      46708,
+      3128,
+      3156,
+      53500,
+      68276,
+      70644,
+      46952,
+      46952,
+      508,
+      508,
+      1012,
+      1012,
+      1312,
+      1312,
+      3808,
+      3808,
+      46956,
+      46956,
+      47796,
+      47796,
+      47180,
+      47180,
+      416,
+      416,
+      712,
+      712,
+      700,
+      700,
+      876,
+      876,
+      55600,
+      46816,
+      46816,
+      472,
+      472,
+      46708,
+      46708,
+      55908,
+      56324,
+      49896,
+      49824,
+      2188,
+      2200,
+      752,
+      752,
+      48512,
+      48932,
+      46960,
+      58460,
+      58484,
+      1356,
+      1356,
+      1200,
+      1200,
+      1148,
+      1148,
+      61100,
+      61100,
+      47848,
+      47848,
+      46964,
+      46964,
+      46824,
+      46824,
+      512,
+      512,
+      61532,
+      61532,
+      1000,
+      1000,
+      65224,
+      68200,
+      47352,
+      47352,
+      67644,
+      69380,
+      792,
+      792,
+      56360,
+      56524,
+      47812,
+      46876,
+      48852,
+      48888,
+      6436,
+      6460,
+      51752,
+      51752,
+      50952,
+      50952,
+      46880,
+      128616,
+      128616,
+      3536,
+      3536,
+      1628,
+      1628,
+      47392,
+      47392,
+      58640,
+      76924,
+      1096,
+      1096,
+      52024,
+      62968
+    ]
+  }
\ No newline at end of file
diff --git a/tools/watchdog/README.md b/tools/watchdog/README.md
new file mode 100644
index 0000000..7f1912a
--- /dev/null
+++ b/tools/watchdog/README.md
@@ -0,0 +1,34 @@
+# CarWatchdog's Performance Analysis Tools
+
+## Performance Stats Parser
+The `parser/` directory contains the scripts to parse CarWatchdog daemon's dumps
+and generate a protobuf binary with the performance stats. The proto format is
+available in `parser/performancestats.proto`.
+
+### Generate protobuf binary
+To generate the proto binary for the CarWatchdog performance stats, run:
+```bash
+export PARSER_PATH=$TOP/packages/services/Car/tools/watchdog/parser
+python $PARSER_PATH/perf_stats_parser.py -f <file-with-dump>.txt -o ~/perf_stats_out.pb
+```
+
+The proto binary will be saved to `~/perf_stats_out.pb`.
+
+### Read the protobuf binary
+To read the protobuf binary from a python file, one could use:
+
+```python
+from perf_stats_parser import read_pb
+```
+
+The `read_pb` method takes the protobuf binary filename and returns a
+`PerformanceStats` class instance with the same perf stats stored in the
+protobuf.
+
+### Generate `performancestats_pb2.py`
+If changes are made to `parser/performancestats.proto`, the
+`parser/performancestats_pb2.py` file needs to be regenerated. This can be done
+by running:
+```bash
+aprotoc --proto_path=$PARSER_PATH --python_out=$PARSER_PATH $PARSER_PATH/performancestats.proto
+```
\ No newline at end of file
diff --git a/tools/watchdog/parser/perf_stats_parser.py b/tools/watchdog/parser/perf_stats_parser.py
new file mode 100644
index 0000000..c914f72
--- /dev/null
+++ b/tools/watchdog/parser/perf_stats_parser.py
@@ -0,0 +1,392 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2022 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.
+#
+"""
+Tool to parse CarWatchdog's performance stats dump.
+"""
+import argparse
+import os
+import performancestats_pb2
+import re
+import sys
+
+from datetime import datetime
+
+BOOT_TIME_REPORT_HEADER = "Boot-time performance report:"
+TOP_N_CPU_TIME_HEADER = "Top N CPU Times:"
+
+DUMP_DATETIME_FORMAT = "%a %b %d %H:%M:%S %Y %Z"
+DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
+
+STATS_COLLECTION_PATTERN = "Collection (\d+): <(.+)>"
+PACKAGE_CPU_STATS_PATTERN = "(\d+), (.+), (\d+), (\d+).(\d+)%"
+PROCESS_CPU_STATS_PATTERN = "\s+(.+), (\d+), (\d+).(\d+)%"
+TOTAL_CPU_TIME_PATTERN = "Total CPU time \\(ms\\): (\d+)"
+TOTAL_IDLE_CPU_TIME_PATTERN = "Total idle CPU time \\(ms\\)/percent: (\d+) / .+"
+CPU_IO_WAIT_TIME_PATTERN = "CPU I/O wait time \\(ms\\)/percent: (\d+) / .+"
+CONTEXT_SWITCHES_PATTERN = "Number of context switches: (\d+)"
+IO_BLOCKED_PROCESSES_PATTERN = "Number of I/O blocked processes/percent: (\d+) / .+"
+
+class ProcessCpuStats:
+  def __init__(self, command, cpu_time_ms, package_cpu_time_percent):
+    self.command = command
+    self.cpu_time_ms = cpu_time_ms
+    self.package_cpu_time_percent = package_cpu_time_percent
+
+  def __repr__(self):
+    return "ProcessCpuStats (command={}, CPU time={}ms, percent of " \
+           "package's CPU time={}%)".format(self.command, self.cpu_time_ms,
+                                           self.package_cpu_time_percent)
+
+
+class PackageCpuStats:
+  def __init__(self, user_id, package_name, cpu_time_ms,
+      total_cpu_time_percent):
+    self.user_id = user_id
+    self.package_name = package_name
+    self.cpu_time_ms = cpu_time_ms
+    self.total_cpu_time_percent = total_cpu_time_percent
+    self.process_cpu_stats = []
+
+  def __repr__(self):
+    process_cpu_stats_str = "[])"
+    if len(self.process_cpu_stats) > 0:
+      process_list_str = "\n      ".join(list(map(repr, self.process_cpu_stats)))
+      process_cpu_stats_str = "\n      {}\n    )".format(process_list_str)
+    return "PackageCpuStats (user id={}, package name={}, CPU time={}ms, " \
+           "percent of total CPU time={}%, process CPU stats={}" \
+      .format(self.user_id, self.package_name, self.cpu_time_ms,
+              self.total_cpu_time_percent, process_cpu_stats_str)
+
+
+class StatsCollection:
+  def __init__(self):
+    self.id = -1
+    self.date = None
+    self.total_cpu_time_ms = 0
+    self.idle_cpu_time_ms = 0
+    self.io_wait_time_ms = 0
+    self.context_switches = 0
+    self.io_blocked_processes = 0
+    self.package_cpu_stats = []
+
+  def is_empty(self):
+    val = self.total_cpu_time_ms + self.idle_cpu_time_ms + self.io_wait_time_ms + \
+          self.context_switches + self.io_blocked_processes
+    return self.id == -1 and not self.date and val == 0 and len(self.package_cpu_stats) == 0
+
+  def __repr__(self):
+    date = self.date.strftime(DATETIME_FORMAT) if self.date else ""
+    pcs_str = "\n    ".join(list(map(repr, self.package_cpu_stats)))
+    return "StatsCollection (id={}, date={}, total CPU time={}ms, " \
+           "idle CPU time={}ms, I/O wait time={}ms, total context switches={}, " \
+           "total I/O blocked processes={}, package CPU stats=\n    {}\n  )" \
+      .format(self.id, date, self.total_cpu_time_ms, self.idle_cpu_time_ms,
+              self.io_wait_time_ms, self.context_switches,
+              self.io_blocked_processes, pcs_str)
+
+
+class SystemEventStats:
+  def __init__(self):
+    self.collections = []
+
+  def add(self, collection):
+    self.collections.append(collection)
+
+  def is_empty(self):
+    return not any(map(lambda c: not c.is_empty(), self.collections))
+
+  def __repr__(self):
+    collections_str = "\n  ".join(list(map(repr, self.collections)))
+    return "SystemEventStats (\n" \
+           "  {}".format(collections_str)
+
+
+class PerformanceStats:
+  def __init__(self):
+    self.boot_time_stats = None
+    self.user_switch_stats = []
+
+  def has_boot_time(self):
+    return self.boot_time_stats and not self.boot_time_stats.is_empty()
+
+  def is_empty(self):
+    return not self.has_boot_time() \
+           and not any(map(lambda u: not u.is_empty(), self.user_switch_stats))
+
+  def __repr__(self):
+    return "PerformanceStats (\n" \
+          "boot-time stats={}\n" \
+          "\nuser-switch stats={}\n)" \
+      .format(self.boot_time_stats, self.user_switch_stats)
+
+
+def parse_cpu_times(lines, idx):
+  package_cpu_stats = []
+  package_cpu_stat = None
+
+  while not (line := lines[idx].rstrip()).startswith("Top N") \
+      and not re.match(STATS_COLLECTION_PATTERN, line) \
+      and not line.startswith('-' * 50):
+    if match := re.match(PACKAGE_CPU_STATS_PATTERN, line):
+      user_id = int(match.group(1))
+      package_name = match.group(2)
+      cpu_time_ms = int(match.group(3))
+      total_cpu_time_percent = float("{}.{}".format(match.group(4),
+                                                    match.group(5)))
+
+      package_cpu_stat = PackageCpuStats(user_id, package_name,
+                                         cpu_time_ms,
+                                         total_cpu_time_percent)
+      package_cpu_stats.append(package_cpu_stat)
+    elif match := re.match(PROCESS_CPU_STATS_PATTERN, line):
+      command = match.group(1)
+      cpu_time_ms = int(match.group(2))
+      package_cpu_time_percent = float("{}.{}".format(match.group(3),
+                                                      match.group(4)))
+      if package_cpu_stat:
+        package_cpu_stat.process_cpu_stats.append(
+          ProcessCpuStats(command, cpu_time_ms, package_cpu_time_percent))
+      else:
+        print("No package CPU stats parsed for process:", command, file=sys.stderr)
+
+    idx += 1
+
+  return package_cpu_stats, idx
+
+
+def parse_collection(lines, idx, match):
+  collection = StatsCollection()
+  collection.id = int(match.group(1))
+  collection.date = datetime.strptime(match.group(2), DUMP_DATETIME_FORMAT)
+
+  while not re.match(STATS_COLLECTION_PATTERN,
+                     (line := lines[idx].strip())) and not line.startswith('-' * 50):
+    if match := re.match(TOTAL_CPU_TIME_PATTERN, line):
+      collection.total_cpu_time_ms = int(match.group(1))
+    elif match := re.match(TOTAL_IDLE_CPU_TIME_PATTERN, line):
+      collection.idle_cpu_time_ms = int(match.group(1))
+    elif match := re.match(CPU_IO_WAIT_TIME_PATTERN, line):
+      collection.io_wait_time_ms = int(match.group(1))
+    elif match := re.match(CONTEXT_SWITCHES_PATTERN, line):
+      collection.context_switches = int(match.group(1))
+    elif match := re.match(IO_BLOCKED_PROCESSES_PATTERN, line):
+      collection.io_blocked_processes = int(match.group(1))
+    elif line == TOP_N_CPU_TIME_HEADER:
+      idx += 1  # Skip subsection header
+      package_cpu_stats, idx = parse_cpu_times(lines, idx)
+      collection.package_cpu_stats = package_cpu_stats
+      continue
+
+    idx += 1
+
+  return collection, idx
+
+
+def parse_stats_collections(lines, idx):
+  system_event_stats = SystemEventStats()
+  while not (line := lines[idx].strip()).startswith('-' * 50):
+    if match := re.match(STATS_COLLECTION_PATTERN, line):
+      idx += 1  # Skip the collection header
+      collection, idx = parse_collection(lines, idx, match)
+      if not collection.is_empty():
+        system_event_stats.add(collection)
+    else:
+      idx += 1
+  return system_event_stats, idx
+
+
+def parse_dump(dump):
+  lines = dump.split("\n")
+  performance_stats = PerformanceStats()
+  idx = 0
+  while idx < len(lines):
+    line = lines[idx].strip()
+    if line == BOOT_TIME_REPORT_HEADER:
+      boot_time_stats, idx = parse_stats_collections(lines, idx)
+      if not boot_time_stats.is_empty():
+        performance_stats.boot_time_stats = boot_time_stats
+    else:
+      idx += 1
+
+  return performance_stats
+
+
+def create_date_pb(date):
+  date_pb = performancestats_pb2.Date()
+  date_pb.year = date.year
+  date_pb.month = date.month
+  date_pb.day = date.day
+  return date_pb
+
+
+def create_timeofday_pb(date):
+  timeofday_pb = performancestats_pb2.TimeOfDay()
+  timeofday_pb.hours = date.hour
+  timeofday_pb.minutes = date.minute
+  timeofday_pb.seconds = date.second
+  return timeofday_pb
+
+
+def add_system_event_pb(system_event_stats, system_event_pb):
+  for collection in system_event_stats.collections:
+    stats_collection_pb = system_event_pb.collections.add()
+    stats_collection_pb.id = collection.id
+    stats_collection_pb.date.CopyFrom(create_date_pb(collection.date))
+    stats_collection_pb.time.CopyFrom(create_timeofday_pb(collection.date))
+    stats_collection_pb.total_cpu_time_ms = collection.total_cpu_time_ms
+    stats_collection_pb.idle_cpu_time_ms = collection.idle_cpu_time_ms
+    stats_collection_pb.io_wait_time_ms = collection.io_wait_time_ms
+    stats_collection_pb.context_switches = collection.context_switches
+    stats_collection_pb.io_blocked_processes = collection.io_blocked_processes
+
+    for package_cpu_stats in collection.package_cpu_stats:
+      package_cpu_stats_pb = stats_collection_pb.package_cpu_stats.add()
+      package_cpu_stats_pb.user_id = package_cpu_stats.user_id
+      package_cpu_stats_pb.package_name = package_cpu_stats.package_name
+      package_cpu_stats_pb.cpu_time_ms = package_cpu_stats.cpu_time_ms
+      package_cpu_stats_pb.total_cpu_time_percent = package_cpu_stats.total_cpu_time_percent
+
+      for process_cpu_stats in package_cpu_stats.process_cpu_stats:
+        process_cpu_stats_pb = package_cpu_stats_pb.process_cpu_stats.add()
+        process_cpu_stats_pb.command = process_cpu_stats.command
+        process_cpu_stats_pb.cpu_time_ms = process_cpu_stats.cpu_time_ms
+        process_cpu_stats_pb.package_cpu_time_percent = process_cpu_stats.package_cpu_time_percent
+
+
+def get_system_event(system_event_pb):
+  system_event_stats = SystemEventStats()
+  for stats_collection_pb in system_event_pb.collections:
+    stats_collection = StatsCollection()
+    stats_collection.id = stats_collection_pb.id
+    date_pb = stats_collection_pb.date
+    time_pb = stats_collection_pb.time
+    stats_collection.date = datetime(date_pb.year, date_pb.month, date_pb.day,
+                                     time_pb.hours, time_pb.minutes, time_pb.seconds)
+    stats_collection.total_cpu_time_ms = stats_collection_pb.total_cpu_time_ms
+    stats_collection.idle_cpu_time_ms = stats_collection_pb.idle_cpu_time_ms
+    stats_collection.io_wait_time_ms = stats_collection_pb.io_wait_time_ms
+    stats_collection.context_switches = stats_collection_pb.context_switches
+    stats_collection.io_blocked_processes = stats_collection_pb.io_blocked_processes
+
+    for package_cpu_stats_pb in stats_collection_pb.package_cpu_stats:
+      package_cpu_stats = \
+        PackageCpuStats(package_cpu_stats_pb.user_id,
+                        package_cpu_stats_pb.package_name,
+                        package_cpu_stats_pb.cpu_time_ms,
+                        round(package_cpu_stats_pb.total_cpu_time_percent, 2))
+
+      for process_cpu_stats_pb in package_cpu_stats_pb.process_cpu_stats:
+        process_cpu_stats = \
+          ProcessCpuStats(process_cpu_stats_pb.command,
+                          process_cpu_stats_pb.cpu_time_ms,
+                          round(process_cpu_stats_pb.package_cpu_time_percent,
+                                2))
+
+        package_cpu_stats.process_cpu_stats.append(process_cpu_stats)
+      stats_collection.package_cpu_stats.append(package_cpu_stats)
+    system_event_stats.add(stats_collection)
+
+  return system_event_stats
+
+
+def write_pb(perf_stats, out_file):
+  if perf_stats.is_empty():
+    print("Cannot write proto since performance stats are empty")
+    return False
+
+  perf_stats_pb = performancestats_pb2.PerformanceStats()
+
+  # Boot time proto
+  if perf_stats.has_boot_time():
+    boot_time_stats_pb = performancestats_pb2.SystemEventStats()
+    add_system_event_pb(perf_stats.boot_time_stats, boot_time_stats_pb)
+    perf_stats_pb.boot_time_stats.CopyFrom(boot_time_stats_pb)
+
+  # TODO(b/256654082): Add user switch events to proto
+
+  # Write pb binary to disk
+  with open(out_file, "wb") as f:
+    f.write(perf_stats_pb.SerializeToString())
+
+  return True
+
+
+def read_pb(pb_file):
+  perf_stats_pb = performancestats_pb2.PerformanceStats()
+
+  with open(pb_file, "rb") as f:
+    perf_stats_pb.ParseFromString(f.read())
+    perf_stats_pb.DiscardUnknownFields()
+
+  if not perf_stats_pb:
+    raise IOError("Proto stored in", pb_file, "has incorrect format.")
+
+  perf_stats = PerformanceStats()
+  perf_stats.boot_time_stats = get_system_event(perf_stats_pb.boot_time_stats)
+
+  return perf_stats
+
+
+def init_arguments():
+  parser = argparse.ArgumentParser(description="Parses CarWatchdog's dump.")
+  parser.add_argument('-f', '--file', dest='file',
+                      default='dump.txt',
+                      help="File with the CarWatchdog dump", )
+  parser.add_argument('-o', '--out', dest='out',
+                      help='protobuf binary with parsed performance stats', )
+  parser.add_argument('-p', '--print', dest='print', action='store_true',
+                      help='prints the parsed performance data to the console '
+                           'when out proto defined')
+  parser.add_argument('-r', '--read', dest='read_proto',
+                      help='Protobuf binary to be printed in console. If this flag is set no other'
+                           'process is executed.')
+
+  return parser.parse_args()
+
+# TODO(b/256654082): Add a wrapper proto which includes the perf stats proto
+#  plus build information. The build information is optional to pass through
+#  arguments.
+if __name__ == "__main__":
+  args = init_arguments()
+
+  if args.read_proto:
+    if not os.path.isfile(args.read_proto):
+      print("Proto binary '%s' does not exist" % args.read_proto)
+      exit(1)
+    print("Reading performance stats proto:")
+    performance_stats = read_pb(args.read_proto)
+    print(performance_stats)
+    exit()
+
+  print("Parsing CarWatchdog performance stats")
+  if not os.path.isfile(args.file):
+    print("File '%s' does not exist" % args.file)
+    exit(1)
+
+  with open(args.file, 'r') as f:
+    performance_stats = parse_dump(f.read())
+
+    if performance_stats.is_empty():
+      print("No performance stats were parsed. Make sure dump file contains carwatchdog's dump "
+            "text.")
+      exit(1)
+
+    if args.out and write_pb(performance_stats, args.out):
+      print("Output protobuf binary in:", args.out)
+
+    if args.print or not args.out:
+      print(performance_stats)
diff --git a/tools/watchdog/parser/performancestats.proto b/tools/watchdog/parser/performancestats.proto
new file mode 100644
index 0000000..01f694f
--- /dev/null
+++ b/tools/watchdog/parser/performancestats.proto
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+syntax = "proto2";
+
+package carwatchdog;
+
+// Represents a whole or partial calendar date, such as a birthday. The time of
+// day and time zone are either specified elsewhere or are insignificant. The
+// date is relative to the Gregorian Calendar. This can represent one of the
+// following:
+//
+// * A full date, with non-zero year, month, and day values
+// * A month and day value, with a zero year, such as an anniversary
+// * A year on its own, with zero month and day values
+// * A year and month value, with a zero day, such as a credit card expiration
+// date
+//
+// Related types are [google.type.TimeOfDay][google.type.TimeOfDay] and
+// `google.protobuf.Timestamp`.
+//
+// Copied from:
+// https://github.com/googleapis/googleapis/blob/master/google/type/date.proto
+message Date {
+  // Year of the date. Must be from 1 to 9999, or 0 to specify a date without
+  // a year.
+  optional int32 year = 1;
+
+  // Month of a year. Must be from 1 to 12, or 0 to specify a year without a
+  // month and day.
+  optional int32 month = 2;
+
+  // Day of a month. Must be from 1 to 31 and valid for the year and month, or 0
+  // to specify a year by itself or a year and month where the day isn't
+  // significant.
+  optional int32 day = 3;
+}
+
+// Represents a time of day. The date and time zone are either not significant
+// or are specified elsewhere. An API may choose to allow leap seconds. Related
+// types are [google.type.Date][google.type.Date] and
+// `google.protobuf.Timestamp`.
+//
+// Copied from:
+// https://github.com/googleapis/googleapis/blob/master/google/type/timeofday.proto
+message TimeOfDay {
+  // Hours of day in 24 hour format. Should be from 0 to 23. An API may choose
+  // to allow the value "24:00:00" for scenarios like business closing time.
+  optional int32 hours = 1;
+
+  // Minutes of hour of day. Must be from 0 to 59.
+  optional int32 minutes = 2;
+
+  // Seconds of minutes of the time. Must normally be from 0 to 59. An API may
+  // allow the value 60 if it allows leap-seconds.
+  optional int32 seconds = 3;
+
+  // Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999.
+  optional int32 nanos = 4;
+}
+
+message ProcessCpuStats {
+  optional string command = 1;
+  optional int32 cpu_time_ms = 2;
+  optional float package_cpu_time_percent = 3;
+}
+
+message PackageCpuStats {
+  optional int32 user_id = 1;
+  optional string package_name = 2;
+  optional int32 cpu_time_ms = 3;
+  optional float total_cpu_time_percent = 4;
+  repeated ProcessCpuStats process_cpu_stats = 5;
+}
+
+message StatsCollection {
+  optional int32 id = 1;
+  optional Date date = 2;
+  optional TimeOfDay time = 3;
+  optional int32 total_cpu_time_ms = 4;
+  optional int32 idle_cpu_time_ms = 5;
+  optional int32 io_wait_time_ms = 6;
+  optional int64 context_switches = 7;
+  optional int32 io_blocked_processes = 8;
+  repeated PackageCpuStats package_cpu_stats = 9;
+}
+
+message SystemEventStats {
+  repeated StatsCollection collections = 1;
+}
+
+message PerformanceStats {
+  optional SystemEventStats boot_time_stats = 1;
+  repeated SystemEventStats user_switch_stats = 2;
+}
diff --git a/tools/watchdog/parser/performancestats_pb2.py b/tools/watchdog/parser/performancestats_pb2.py
new file mode 100644
index 0000000..1002f44
--- /dev/null
+++ b/tools/watchdog/parser/performancestats_pb2.py
@@ -0,0 +1,451 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: performancestats.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='performancestats.proto',
+  package='carwatchdog',
+  syntax='proto2',
+  serialized_options=None,
+  serialized_pb=_b('\n\x16performancestats.proto\x12\x0b\x63\x61rwatchdog\"0\n\x04\x44\x61te\x12\x0c\n\x04year\x18\x01 \x01(\x05\x12\r\n\x05month\x18\x02 \x01(\x05\x12\x0b\n\x03\x64\x61y\x18\x03 \x01(\x05\"K\n\tTimeOfDay\x12\r\n\x05hours\x18\x01 \x01(\x05\x12\x0f\n\x07minutes\x18\x02 \x01(\x05\x12\x0f\n\x07seconds\x18\x03 \x01(\x05\x12\r\n\x05nanos\x18\x04 \x01(\x05\"Y\n\x0fProcessCpuStats\x12\x0f\n\x07\x63ommand\x18\x01 \x01(\t\x12\x13\n\x0b\x63pu_time_ms\x18\x02 \x01(\x05\x12 \n\x18package_cpu_time_percent\x18\x03 \x01(\x02\"\xa6\x01\n\x0fPackageCpuStats\x12\x0f\n\x07user_id\x18\x01 \x01(\x05\x12\x14\n\x0cpackage_name\x18\x02 \x01(\t\x12\x13\n\x0b\x63pu_time_ms\x18\x03 \x01(\x05\x12\x1e\n\x16total_cpu_time_percent\x18\x04 \x01(\x02\x12\x37\n\x11process_cpu_stats\x18\x05 \x03(\x0b\x32\x1c.carwatchdog.ProcessCpuStats\"\xa3\x02\n\x0fStatsCollection\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x04\x64\x61te\x18\x02 \x01(\x0b\x32\x11.carwatchdog.Date\x12$\n\x04time\x18\x03 \x01(\x0b\x32\x16.carwatchdog.TimeOfDay\x12\x19\n\x11total_cpu_time_ms\x18\x04 \x01(\x05\x12\x18\n\x10idle_cpu_time_ms\x18\x05 \x01(\x05\x12\x17\n\x0fio_wait_time_ms\x18\x06 \x01(\x05\x12\x18\n\x10\x63ontext_switches\x18\x07 \x01(\x03\x12\x1c\n\x14io_blocked_processes\x18\x08 \x01(\x05\x12\x37\n\x11package_cpu_stats\x18\t \x03(\x0b\x32\x1c.carwatchdog.PackageCpuStats\"E\n\x10SystemEventStats\x12\x31\n\x0b\x63ollections\x18\x01 \x03(\x0b\x32\x1c.carwatchdog.StatsCollection\"\x84\x01\n\x10PerformanceStats\x12\x36\n\x0f\x62oot_time_stats\x18\x01 \x01(\x0b\x32\x1d.carwatchdog.SystemEventStats\x12\x38\n\x11user_switch_stats\x18\x02 \x03(\x0b\x32\x1d.carwatchdog.SystemEventStats')
+)
+
+
+
+
+_DATE = _descriptor.Descriptor(
+  name='Date',
+  full_name='carwatchdog.Date',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='year', full_name='carwatchdog.Date.year', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='month', full_name='carwatchdog.Date.month', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='day', full_name='carwatchdog.Date.day', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=39,
+  serialized_end=87,
+)
+
+
+_TIMEOFDAY = _descriptor.Descriptor(
+  name='TimeOfDay',
+  full_name='carwatchdog.TimeOfDay',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='hours', full_name='carwatchdog.TimeOfDay.hours', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='minutes', full_name='carwatchdog.TimeOfDay.minutes', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='seconds', full_name='carwatchdog.TimeOfDay.seconds', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='nanos', full_name='carwatchdog.TimeOfDay.nanos', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=89,
+  serialized_end=164,
+)
+
+
+_PROCESSCPUSTATS = _descriptor.Descriptor(
+  name='ProcessCpuStats',
+  full_name='carwatchdog.ProcessCpuStats',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='command', full_name='carwatchdog.ProcessCpuStats.command', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='cpu_time_ms', full_name='carwatchdog.ProcessCpuStats.cpu_time_ms', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='package_cpu_time_percent', full_name='carwatchdog.ProcessCpuStats.package_cpu_time_percent', index=2,
+      number=3, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=166,
+  serialized_end=255,
+)
+
+
+_PACKAGECPUSTATS = _descriptor.Descriptor(
+  name='PackageCpuStats',
+  full_name='carwatchdog.PackageCpuStats',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='user_id', full_name='carwatchdog.PackageCpuStats.user_id', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='package_name', full_name='carwatchdog.PackageCpuStats.package_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='cpu_time_ms', full_name='carwatchdog.PackageCpuStats.cpu_time_ms', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='total_cpu_time_percent', full_name='carwatchdog.PackageCpuStats.total_cpu_time_percent', index=3,
+      number=4, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='process_cpu_stats', full_name='carwatchdog.PackageCpuStats.process_cpu_stats', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=258,
+  serialized_end=424,
+)
+
+
+_STATSCOLLECTION = _descriptor.Descriptor(
+  name='StatsCollection',
+  full_name='carwatchdog.StatsCollection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='carwatchdog.StatsCollection.id', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='date', full_name='carwatchdog.StatsCollection.date', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='time', full_name='carwatchdog.StatsCollection.time', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='total_cpu_time_ms', full_name='carwatchdog.StatsCollection.total_cpu_time_ms', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='idle_cpu_time_ms', full_name='carwatchdog.StatsCollection.idle_cpu_time_ms', index=4,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='io_wait_time_ms', full_name='carwatchdog.StatsCollection.io_wait_time_ms', index=5,
+      number=6, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='context_switches', full_name='carwatchdog.StatsCollection.context_switches', index=6,
+      number=7, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='io_blocked_processes', full_name='carwatchdog.StatsCollection.io_blocked_processes', index=7,
+      number=8, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='package_cpu_stats', full_name='carwatchdog.StatsCollection.package_cpu_stats', index=8,
+      number=9, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=427,
+  serialized_end=718,
+)
+
+
+_SYSTEMEVENTSTATS = _descriptor.Descriptor(
+  name='SystemEventStats',
+  full_name='carwatchdog.SystemEventStats',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='collections', full_name='carwatchdog.SystemEventStats.collections', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=720,
+  serialized_end=789,
+)
+
+
+_PERFORMANCESTATS = _descriptor.Descriptor(
+  name='PerformanceStats',
+  full_name='carwatchdog.PerformanceStats',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='boot_time_stats', full_name='carwatchdog.PerformanceStats.boot_time_stats', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='user_switch_stats', full_name='carwatchdog.PerformanceStats.user_switch_stats', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=792,
+  serialized_end=924,
+)
+
+_PACKAGECPUSTATS.fields_by_name['process_cpu_stats'].message_type = _PROCESSCPUSTATS
+_STATSCOLLECTION.fields_by_name['date'].message_type = _DATE
+_STATSCOLLECTION.fields_by_name['time'].message_type = _TIMEOFDAY
+_STATSCOLLECTION.fields_by_name['package_cpu_stats'].message_type = _PACKAGECPUSTATS
+_SYSTEMEVENTSTATS.fields_by_name['collections'].message_type = _STATSCOLLECTION
+_PERFORMANCESTATS.fields_by_name['boot_time_stats'].message_type = _SYSTEMEVENTSTATS
+_PERFORMANCESTATS.fields_by_name['user_switch_stats'].message_type = _SYSTEMEVENTSTATS
+DESCRIPTOR.message_types_by_name['Date'] = _DATE
+DESCRIPTOR.message_types_by_name['TimeOfDay'] = _TIMEOFDAY
+DESCRIPTOR.message_types_by_name['ProcessCpuStats'] = _PROCESSCPUSTATS
+DESCRIPTOR.message_types_by_name['PackageCpuStats'] = _PACKAGECPUSTATS
+DESCRIPTOR.message_types_by_name['StatsCollection'] = _STATSCOLLECTION
+DESCRIPTOR.message_types_by_name['SystemEventStats'] = _SYSTEMEVENTSTATS
+DESCRIPTOR.message_types_by_name['PerformanceStats'] = _PERFORMANCESTATS
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Date = _reflection.GeneratedProtocolMessageType('Date', (_message.Message,), {
+  'DESCRIPTOR' : _DATE,
+  '__module__' : 'performancestats_pb2'
+  # @@protoc_insertion_point(class_scope:carwatchdog.Date)
+  })
+_sym_db.RegisterMessage(Date)
+
+TimeOfDay = _reflection.GeneratedProtocolMessageType('TimeOfDay', (_message.Message,), {
+  'DESCRIPTOR' : _TIMEOFDAY,
+  '__module__' : 'performancestats_pb2'
+  # @@protoc_insertion_point(class_scope:carwatchdog.TimeOfDay)
+  })
+_sym_db.RegisterMessage(TimeOfDay)
+
+ProcessCpuStats = _reflection.GeneratedProtocolMessageType('ProcessCpuStats', (_message.Message,), {
+  'DESCRIPTOR' : _PROCESSCPUSTATS,
+  '__module__' : 'performancestats_pb2'
+  # @@protoc_insertion_point(class_scope:carwatchdog.ProcessCpuStats)
+  })
+_sym_db.RegisterMessage(ProcessCpuStats)
+
+PackageCpuStats = _reflection.GeneratedProtocolMessageType('PackageCpuStats', (_message.Message,), {
+  'DESCRIPTOR' : _PACKAGECPUSTATS,
+  '__module__' : 'performancestats_pb2'
+  # @@protoc_insertion_point(class_scope:carwatchdog.PackageCpuStats)
+  })
+_sym_db.RegisterMessage(PackageCpuStats)
+
+StatsCollection = _reflection.GeneratedProtocolMessageType('StatsCollection', (_message.Message,), {
+  'DESCRIPTOR' : _STATSCOLLECTION,
+  '__module__' : 'performancestats_pb2'
+  # @@protoc_insertion_point(class_scope:carwatchdog.StatsCollection)
+  })
+_sym_db.RegisterMessage(StatsCollection)
+
+SystemEventStats = _reflection.GeneratedProtocolMessageType('SystemEventStats', (_message.Message,), {
+  'DESCRIPTOR' : _SYSTEMEVENTSTATS,
+  '__module__' : 'performancestats_pb2'
+  # @@protoc_insertion_point(class_scope:carwatchdog.SystemEventStats)
+  })
+_sym_db.RegisterMessage(SystemEventStats)
+
+PerformanceStats = _reflection.GeneratedProtocolMessageType('PerformanceStats', (_message.Message,), {
+  'DESCRIPTOR' : _PERFORMANCESTATS,
+  '__module__' : 'performancestats_pb2'
+  # @@protoc_insertion_point(class_scope:carwatchdog.PerformanceStats)
+  })
+_sym_db.RegisterMessage(PerformanceStats)
+
+
+# @@protoc_insertion_point(module_scope)