Merge changes from topic "Mute on audio disable" into sc-dev

* changes:
  Restricting muting on audio disable
  Swap to CarAudioService#setIsAudioEnabled
  Add CarVolumeGroup#hasCrticialAudioContexts
diff --git a/car-lib/src/android/car/admin/ICarDevicePolicyService.aidl b/car-lib/src/android/car/admin/ICarDevicePolicyService.aidl
index 3d9bec1..88b42b1 100644
--- a/car-lib/src/android/car/admin/ICarDevicePolicyService.aidl
+++ b/car-lib/src/android/car/admin/ICarDevicePolicyService.aidl
@@ -16,12 +16,16 @@
 
 package android.car.admin;
 
-import android.car.user.UserRemovalResult;
 import android.car.user.UserCreationResult;
+import android.car.user.UserRemovalResult;
+import android.car.user.UserStartResult;
+import android.car.user.UserStopResult;
 import com.android.internal.infra.AndroidFuture;
 
 /** @hide */
 interface ICarDevicePolicyService {
     void removeUser(int userId, in AndroidFuture<UserRemovalResult> receiver);
     void createUser(String name, int flags, in AndroidFuture<UserCreationResult> receiver);
+    void startUserInBackground(int userId, in AndroidFuture<UserStartResult> receiver);
+    void stopUser(int userId, in AndroidFuture<UserStopResult> receiver);
 }
diff --git a/car-lib/src/android/car/cluster/ClusterState.aidl b/car-lib/src/android/car/cluster/ClusterState.aidl
index 1a9e4f1..a41656c 100644
--- a/car-lib/src/android/car/cluster/ClusterState.aidl
+++ b/car-lib/src/android/car/cluster/ClusterState.aidl
@@ -17,12 +17,12 @@
 package android.car.cluster;
 
 import android.graphics.Insets;
+import android.graphics.Rect;
 
 /** @hide */
 parcelable ClusterState {
     boolean on;
-    int width;
-    int height;
+    Rect bounds;
     Insets insets;
     int uiType;
 }
diff --git a/car-lib/src/android/car/hardware/property/CarPropertyManager.java b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
index f73201e..bd47263 100644
--- a/car-lib/src/android/car/hardware/property/CarPropertyManager.java
+++ b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
@@ -496,17 +496,45 @@
 
     /**
      * Returns value of a bool property
+     *
      * <p> This method may take couple seconds to complete, so it needs to be called from an
      * non-main thread.
      *
+     * <p> Clients that declare a {@link android.content.pm.ApplicationInfo#targetSdkVersion} equal
+     * or later than {@link Build.VERSION_CODES#R} will receive the following exceptions when
+     * request is failed.
+     * <ul>
+     *     <li>{@link CarInternalErrorException}
+     *     <li>{@link PropertyAccessDeniedSecurityException}
+     *     <li>{@link PropertyNotAvailableAndRetryException}
+     *     <li>{@link PropertyNotAvailableException}
+     *     <li>{@link IllegalArgumentException}
+     * </ul>
+     * <p> Clients that declare a {@link android.content.pm.ApplicationInfo#targetSdkVersion}
+     * earlier than {@link Build.VERSION_CODES#R} will receive the following exceptions if the call
+     * fails.
+     * <ul>
+     *     <li>{@link IllegalStateException} when there is an error detected in cars.
+     *     <li>{@link IllegalArgumentException} when the property in the areaId is not supplied.
+     * </ul>
+     *
      * @param prop Property ID to get
      * @param area Area of the property to get
-     * @return value of a bool property.
+     *
+     * @throws {@link CarInternalErrorException} when there is an error detected in cars.
+     * @throws {@link PropertyAccessDeniedSecurityException} when cars denied the access of the
+     * property.
+     * @throws {@link PropertyNotAvailableAndRetryException} when the property is temporarily
+     * not available and likely that retrying will be successful.
+     * @throws {@link PropertyNotAvailableException} when the property is temporarily not available.
+     * @throws {@link IllegalArgumentException} when the property in the areaId is not supplied.
+     *
+     * @return value of a bool property, {@code false} if can not get value from cars.
      */
     public boolean getBooleanProperty(int prop, int area) {
         checkSupportedProperty(prop);
         CarPropertyValue<Boolean> carProp = getProperty(Boolean.class, prop, area);
-        return carProp != null ? carProp.getValue() : false;
+        return handleNullAndPropertyStatus(carProp, area, false);
     }
 
     /**
@@ -515,43 +543,82 @@
      * <p> This method may take couple seconds to complete, so it needs to be called from an
      * non-main thread.
      *
+     * <p> This method has the same exception behavior as {@link #getBooleanProperty(int, int)}.
+     *
      * @param prop Property ID to get
      * @param area Area of the property to get
+     *
+     * @throws {@link CarInternalErrorException} when there is an error detected in cars.
+     * @throws {@link PropertyAccessDeniedSecurityException} when cars denied the access of the
+     * property.
+     * @throws {@link PropertyNotAvailableAndRetryException} when the property is temporarily
+     * not available and likely that retrying will be successful.
+     * @throws {@link PropertyNotAvailableException} when the property is temporarily not available.
+     * @throws {@link IllegalArgumentException} when the property in the areaId is not supplied.
+     *
+     * @return value of a float property, 0 if can not get value from the cars.
      */
     public float getFloatProperty(int prop, int area) {
         checkSupportedProperty(prop);
         CarPropertyValue<Float> carProp = getProperty(Float.class, prop, area);
-        return carProp != null ? carProp.getValue() : 0f;
+        return handleNullAndPropertyStatus(carProp, area, 0f);
     }
 
     /**
-     * Returns value of a integer property
+     * Returns value of an integer property
      *
      * <p> This method may take couple seconds to complete, so it needs to be called form an
      * non-main thread.
+     *
+     * <p> This method has the same exception behavior as {@link #getBooleanProperty(int, int)}.
+     *
      * @param prop Property ID to get
      * @param area Zone of the property to get
+     *
+     * @throws {@link CarInternalErrorException} when there is an error detected in cars.
+     * @throws {@link PropertyAccessDeniedSecurityException} when cars denied the access of the
+     * property.
+     * @throws {@link PropertyNotAvailableAndRetryException} when the property is temporarily
+     * not available and likely that retrying will be successful.
+     * @throws {@link PropertyNotAvailableException} when the property is temporarily not available.
+     * @throws {@link IllegalArgumentException} when the property in the areaId is not supplied.
+     *
+     * @return value of an integer property, 0 if can not get the value from cars.
      */
     public int getIntProperty(int prop, int area) {
         checkSupportedProperty(prop);
         CarPropertyValue<Integer> carProp = getProperty(Integer.class, prop, area);
-        return carProp != null ? carProp.getValue() : 0;
+        return handleNullAndPropertyStatus(carProp, area, 0);
     }
 
     /**
-     * Returns value of a integer array property
+     * Returns value of an integer array property
      *
      * <p> This method may take couple seconds to complete, so it needs to be called from an
      * non-main thread.
      *
+     * <p> This method has the same exception behavior as {@link #getBooleanProperty(int, int)}.
+     *
      * @param prop Property ID to get
      * @param area Zone of the property to get
+     *
+     * @throws {@link CarInternalErrorException} when there is an error detected in cars.
+     * @throws {@link PropertyAccessDeniedSecurityException} when cars denied the access of the
+     * property.
+     * @throws {@link PropertyNotAvailableAndRetryException} when the property is temporarily
+     * not available and likely that retrying will be successful.
+     * @throws {@link PropertyNotAvailableException} when the property is temporarily not available.
+     * @throws {@link IllegalArgumentException} when the property in the areaId is not supplied.
+     *
+     * @return value of an integer array property, an empty integer array if can not get the value
+     * from cars.
      */
     @NonNull
     public int[] getIntArrayProperty(int prop, int area) {
         checkSupportedProperty(prop);
         CarPropertyValue<Integer[]> carProp = getProperty(Integer[].class, prop, area);
-        return carProp != null ? toIntArray(carProp.getValue()) : new int[0];
+        Integer[] res = handleNullAndPropertyStatus(carProp, area, new Integer[0]);
+        return toIntArray(res);
     }
 
     private static int[] toIntArray(Integer[] input) {
@@ -563,6 +630,30 @@
         return arr;
     }
 
+    private <T> T handleNullAndPropertyStatus(CarPropertyValue<T> propertyValue, int areaId,
+            T defaultValue) {
+
+        if (propertyValue == null) {
+            return defaultValue;
+        }
+
+        // Keeps the same behavior as android R.
+        if (mAppTargetSdk < Build.VERSION_CODES.S) {
+            return propertyValue.getStatus() == CarPropertyValue.STATUS_AVAILABLE
+                    ? propertyValue.getValue() : defaultValue;
+        }
+
+        // throws new exceptions in android S.
+        switch (propertyValue.getStatus()) {
+            case CarPropertyValue.STATUS_ERROR:
+                throw new CarInternalErrorException(propertyValue.getPropertyId(), areaId);
+            case CarPropertyValue.STATUS_UNAVAILABLE:
+                throw new PropertyNotAvailableException(propertyValue.getPropertyId(), areaId);
+            default:
+                return propertyValue.getValue();
+        }
+    }
+
     /**
      * Return CarPropertyValue
      *
diff --git a/car-lib/src/android/car/user/UserStartResult.aidl b/car-lib/src/android/car/user/UserStartResult.aidl
new file mode 100644
index 0000000..d5333ec
--- /dev/null
+++ b/car-lib/src/android/car/user/UserStartResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.car.user;
+
+parcelable UserStartResult;
diff --git a/car-lib/src/android/car/user/UserStartResult.java b/car-lib/src/android/car/user/UserStartResult.java
new file mode 100644
index 0000000..d1a5d32
--- /dev/null
+++ b/car-lib/src/android/car/user/UserStartResult.java
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+package android.car.user;
+
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * User start results.
+ *
+ * @hide
+ */
+@DataClass(
+        genToString = true,
+        genHiddenConstructor = true,
+        genHiddenConstDefs = true)
+public final class UserStartResult implements Parcelable, OperationResult {
+
+    /**
+    * When user start is successful.
+    *
+    * @hide
+    */
+    public static final int STATUS_SUCCESSFUL = CommonResults.STATUS_SUCCESSFUL;
+
+    /**
+    * When user start failed.
+    *
+    * @hide
+    */
+    public static final int STATUS_ANDROID_FAILURE = CommonResults.STATUS_ANDROID_FAILURE;
+
+     /**
+     * When user to start is same as current user.
+     *
+     * @hide
+     */
+    public static final int STATUS_SUCCESSFUL_USER_IS_CURRENT_USER =
+            CommonResults.LAST_COMMON_STATUS + 1;
+
+    /**
+     * When user to start does not exist.
+     *
+     * @hide
+     */
+    public static final int STATUS_USER_DOES_NOT_EXIST = CommonResults.LAST_COMMON_STATUS + 2;
+
+    /**
+    * Gets the user start result status.
+    *
+    * @return either {@link UserStartRsult#STATUS_SUCCESSFUL},
+    *         {@link UserStartResult#STATUS_SUCCESSFUL_USER_IS_CURRENT_USER},
+    *         {@link UserStartResult#STATUS_ANDROID_FAILURE},
+    *         {@link UserStartResult#STATUS_USER_DOES_NOT_EXIST}, or
+    */
+    private final @Status int mStatus;
+
+    @Override
+    public boolean isSuccess() {
+        return mStatus == STATUS_SUCCESSFUL || mStatus == STATUS_SUCCESSFUL_USER_IS_CURRENT_USER;
+    }
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/packages/services/Car/car-lib/src/android/car/user/UserStartResult.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /** @hide */
+    @android.annotation.IntDef(prefix = "STATUS_", value = {
+        STATUS_SUCCESSFUL,
+        STATUS_ANDROID_FAILURE,
+        STATUS_SUCCESSFUL_USER_IS_CURRENT_USER,
+        STATUS_USER_DOES_NOT_EXIST
+    })
+    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface Status {}
+
+    /** @hide */
+    @DataClass.Generated.Member
+    public static String statusToString(@Status int value) {
+        switch (value) {
+            case STATUS_SUCCESSFUL:
+                    return "STATUS_SUCCESSFUL";
+            case STATUS_ANDROID_FAILURE:
+                    return "STATUS_ANDROID_FAILURE";
+            case STATUS_SUCCESSFUL_USER_IS_CURRENT_USER:
+                    return "STATUS_SUCCESSFUL_USER_IS_CURRENT_USER";
+            case STATUS_USER_DOES_NOT_EXIST:
+                    return "STATUS_USER_DOES_NOT_EXIST";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    /**
+     * Creates a new UserStartResult.
+     *
+     * @param status
+     *   Gets the user start result status.
+     *
+     *   @return either {@link UserStartRsult#STATUS_SUCCESSFUL},
+     *           {@link UserStartResult#STATUS_ANDROID_FAILURE},
+     *           {@link UserStartResult#STATUS_SUCCESSFUL_USER_IS_CURRENT_USER},
+     *           {@link UserStartResult#STATUS_USER_DOES_NOT_EXIST}, or
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public UserStartResult(
+            @Status int status) {
+        this.mStatus = status;
+
+        if (!(mStatus == STATUS_SUCCESSFUL)
+                && !(mStatus == STATUS_ANDROID_FAILURE)
+                && !(mStatus == STATUS_SUCCESSFUL_USER_IS_CURRENT_USER)
+                && !(mStatus == STATUS_USER_DOES_NOT_EXIST)) {
+            throw new java.lang.IllegalArgumentException(
+                    "status was " + mStatus + " but must be one of: "
+                            + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+                            + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+                            + "STATUS_SUCCESSFUL_USER_IS_CURRENT_USER(" + STATUS_SUCCESSFUL_USER_IS_CURRENT_USER + "), "
+                            + "STATUS_USER_DOES_NOT_EXIST(" + STATUS_USER_DOES_NOT_EXIST + ")");
+        }
+
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * Gets the user start result status.
+     *
+     * @return either {@link UserStartRsult#STATUS_SUCCESSFUL},
+     *         {@link UserStartResult#STATUS_ANDROID_FAILURE},
+     *         {@link UserStartResult#STATUS_SUCCESSFUL_USER_IS_CURRENT_USER},
+     *         {@link UserStartResult#STATUS_USER_DOES_NOT_EXIST}, or
+     */
+    @DataClass.Generated.Member
+    public @Status int getStatus() {
+        return mStatus;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "UserStartResult { " +
+                "status = " + statusToString(mStatus) +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@android.annotation.NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeInt(mStatus);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ UserStartResult(@android.annotation.NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        int status = in.readInt();
+
+        this.mStatus = status;
+
+        if (!(mStatus == STATUS_SUCCESSFUL)
+                && !(mStatus == STATUS_ANDROID_FAILURE)
+                && !(mStatus == STATUS_SUCCESSFUL_USER_IS_CURRENT_USER)
+                && !(mStatus == STATUS_USER_DOES_NOT_EXIST)) {
+            throw new java.lang.IllegalArgumentException(
+                    "status was " + mStatus + " but must be one of: "
+                            + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+                            + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+                            + "STATUS_SUCCESSFUL_USER_IS_CURRENT_USER(" + STATUS_SUCCESSFUL_USER_IS_CURRENT_USER + "), "
+                            + "STATUS_USER_DOES_NOT_EXIST(" + STATUS_USER_DOES_NOT_EXIST + ")");
+        }
+
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @android.annotation.NonNull Parcelable.Creator<UserStartResult> CREATOR
+            = new Parcelable.Creator<UserStartResult>() {
+        @Override
+        public UserStartResult[] newArray(int size) {
+            return new UserStartResult[size];
+        }
+
+        @Override
+        public UserStartResult createFromParcel(@android.annotation.NonNull android.os.Parcel in) {
+            return new UserStartResult(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1618957103487L,
+            codegenVersion = "1.0.23",
+            sourceFile = "packages/services/Car/car-lib/src/android/car/user/UserStartResult.java",
+            inputSignatures = "public static final  int STATUS_SUCCESSFUL\npublic static final  int STATUS_ANDROID_FAILURE\npublic static final  int STATUS_SUCCESSFUL_USER_IS_CURRENT_USER\npublic static final  int STATUS_USER_DOES_NOT_EXIST\nprivate final @android.car.user.UserStartResult.Status int mStatus\npublic @java.lang.Override boolean isSuccess()\nclass UserStartResult extends java.lang.Object implements [android.os.Parcelable, android.car.user.OperationResult]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/car-lib/src/android/car/user/UserStopResult.aidl b/car-lib/src/android/car/user/UserStopResult.aidl
new file mode 100644
index 0000000..d90eb46
--- /dev/null
+++ b/car-lib/src/android/car/user/UserStopResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.car.user;
+
+parcelable UserStopResult;
\ No newline at end of file
diff --git a/car-lib/src/android/car/user/UserStopResult.java b/car-lib/src/android/car/user/UserStopResult.java
new file mode 100644
index 0000000..5f17220
--- /dev/null
+++ b/car-lib/src/android/car/user/UserStopResult.java
@@ -0,0 +1,262 @@
+/*
+ * 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.
+ */
+
+package android.car.user;
+
+import android.annotation.IntDef;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * User remove result.
+ *
+ * @hide
+ */
+@DataClass(
+        genToString = true,
+        genHiddenConstructor = true,
+        genHiddenConstDefs = true)
+public final class UserStopResult implements Parcelable, OperationResult {
+
+    /**
+     * When user stop is successful.
+     */
+    public static final int STATUS_SUCCESSFUL = CommonResults.STATUS_SUCCESSFUL;
+
+    /**
+     * When user stop fails.
+     */
+    public static final int STATUS_ANDROID_FAILURE = CommonResults.STATUS_ANDROID_FAILURE;
+
+     /**
+     * When user to stop doesn't exits.
+     */
+    public static final int STATUS_USER_DOES_NOT_EXIST = CommonResults.LAST_COMMON_STATUS + 1;
+
+    /**
+     * When user to stop is the system user.
+     */
+    public static final int STATUS_FAILURE_SYSTEM_USER = CommonResults.LAST_COMMON_STATUS + 2;
+
+    /**
+     * When user to stop is the current user.
+     */
+    public static final int STATUS_FAILURE_CURRENT_USER = CommonResults.LAST_COMMON_STATUS + 3;
+
+     /**
+     * Gets the user switch result status.
+     *
+     * @return either {@link UserStopResult#STATUS_SUCCESSFUL},
+     * {@link UserStopResult#STATUS_ANDROID_FAILURE},
+     * {@link UserStopResult#STATUS_USER_DOES_NOT_EXIST},
+     * {@link UserStopResult#STATUS_FAILURE_SYSTEM_USER}, or
+     * {@link UserStopResult#STATUS_FAILURE_CURRENT_USER}.
+     */
+    private final @Status int mStatus;
+
+    /**
+     * Checks if the {@code status} represents a success status.
+     *
+     * @param status to check
+     * @return true for a success status
+     */
+    public static boolean isSuccess(@Status int status) {
+        return status == STATUS_SUCCESSFUL;
+    }
+
+    @Override
+    public boolean isSuccess() {
+        return isSuccess(mStatus);
+    }
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/packages/services/Car/car-lib/src/android/car/user/UserStopResult.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /** @hide */
+    @IntDef(prefix = "STATUS_", value = {
+        STATUS_SUCCESSFUL,
+        STATUS_ANDROID_FAILURE,
+        STATUS_USER_DOES_NOT_EXIST,
+        STATUS_FAILURE_SYSTEM_USER,
+        STATUS_FAILURE_CURRENT_USER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface Status {}
+
+    /** @hide */
+    @DataClass.Generated.Member
+    public static String statusToString(@Status int value) {
+        switch (value) {
+            case STATUS_SUCCESSFUL:
+                    return "STATUS_SUCCESSFUL";
+            case STATUS_ANDROID_FAILURE:
+                    return "STATUS_ANDROID_FAILURE";
+            case STATUS_USER_DOES_NOT_EXIST:
+                    return "STATUS_USER_DOES_NOT_EXIST";
+            case STATUS_FAILURE_SYSTEM_USER:
+                    return "STATUS_FAILURE_SYSTEM_USER";
+            case STATUS_FAILURE_CURRENT_USER:
+                    return "STATUS_FAILURE_CURRENT_USER";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    /**
+     * Creates a new UserStopResult.
+     *
+     * @param status
+     *   Gets the user switch result status.
+     *
+     *   @return either {@link UserStopResult#STATUS_SUCCESSFUL},
+     *   {@link UserStopResult#STATUS_ANDROID_FAILURE},
+     *   {@link UserStopResult#STATUS_USER_DOES_NOT_EXIST},
+     *   {@link UserStopResult#STATUS_FAILURE_SYSTEM_USER}, or
+     *   {@link UserStopResult#STATUS_FAILURE_CURRENT_USER}.
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public UserStopResult(
+            @Status int status) {
+        this.mStatus = status;
+
+        if (!(mStatus == STATUS_SUCCESSFUL)
+                && !(mStatus == STATUS_ANDROID_FAILURE)
+                && !(mStatus == STATUS_USER_DOES_NOT_EXIST)
+                && !(mStatus == STATUS_FAILURE_SYSTEM_USER)
+                && !(mStatus == STATUS_FAILURE_CURRENT_USER)) {
+            throw new java.lang.IllegalArgumentException(
+                    "status was " + mStatus + " but must be one of: "
+                            + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+                            + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+                            + "STATUS_USER_DOES_NOT_EXIST(" + STATUS_USER_DOES_NOT_EXIST + "), "
+                            + "STATUS_FAILURE_SYSTEM_USER(" + STATUS_FAILURE_SYSTEM_USER + "), "
+                            + "STATUS_FAILURE_CURRENT_USER(" + STATUS_FAILURE_CURRENT_USER + ")");
+        }
+
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * Gets the user switch result status.
+     *
+     * @return either {@link UserStopResult#STATUS_SUCCESSFUL},
+     * {@link UserStopResult#STATUS_ANDROID_FAILURE},
+     * {@link UserStopResult#STATUS_USER_DOES_NOT_EXIST},
+     * {@link UserStopResult#STATUS_FAILURE_SYSTEM_USER}, or
+     * {@link UserStopResult#STATUS_FAILURE_CURRENT_USER}.
+     */
+    @DataClass.Generated.Member
+    public @Status int getStatus() {
+        return mStatus;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "UserStopResult { " +
+                "status = " + statusToString(mStatus) +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@android.annotation.NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeInt(mStatus);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ UserStopResult(@android.annotation.NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        int status = in.readInt();
+
+        this.mStatus = status;
+
+        if (!(mStatus == STATUS_SUCCESSFUL)
+                && !(mStatus == STATUS_ANDROID_FAILURE)
+                && !(mStatus == STATUS_USER_DOES_NOT_EXIST)
+                && !(mStatus == STATUS_FAILURE_SYSTEM_USER)
+                && !(mStatus == STATUS_FAILURE_CURRENT_USER)) {
+            throw new java.lang.IllegalArgumentException(
+                    "status was " + mStatus + " but must be one of: "
+                            + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), "
+                            + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), "
+                            + "STATUS_USER_DOES_NOT_EXIST(" + STATUS_USER_DOES_NOT_EXIST + "), "
+                            + "STATUS_FAILURE_SYSTEM_USER(" + STATUS_FAILURE_SYSTEM_USER + "), "
+                            + "STATUS_FAILURE_CURRENT_USER(" + STATUS_FAILURE_CURRENT_USER + ")");
+        }
+
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @android.annotation.NonNull Parcelable.Creator<UserStopResult> CREATOR
+            = new Parcelable.Creator<UserStopResult>() {
+        @Override
+        public UserStopResult[] newArray(int size) {
+            return new UserStopResult[size];
+        }
+
+        @Override
+        public UserStopResult createFromParcel(@android.annotation.NonNull android.os.Parcel in) {
+            return new UserStopResult(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1619209981496L,
+            codegenVersion = "1.0.23",
+            sourceFile = "packages/services/Car/car-lib/src/android/car/user/UserStopResult.java",
+            inputSignatures = "public static final  int STATUS_SUCCESSFUL\npublic static final  int STATUS_ANDROID_FAILURE\npublic static final  int STATUS_USER_DOES_NOT_EXIST\npublic static final  int STATUS_FAILURE_SYSTEM_USER\npublic static final  int STATUS_FAILURE_CURRENT_USER\nprivate final @android.car.user.UserStopResult.Status int mStatus\npublic static  boolean isSuccess(int)\npublic @java.lang.Override boolean isSuccess()\nclass UserStopResult extends java.lang.Object implements [android.os.Parcelable, android.car.user.OperationResult]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/car-lib/src/android/car/watchdog/CarWatchdogManager.java b/car-lib/src/android/car/watchdog/CarWatchdogManager.java
index 588ac13..05cba98 100644
--- a/car-lib/src/android/car/watchdog/CarWatchdogManager.java
+++ b/car-lib/src/android/car/watchdog/CarWatchdogManager.java
@@ -694,6 +694,7 @@
      * @param resourceOveruseFlag Flag to indicate the types of resource overuse configurations to
      *                            return.
      *
+     * @throws IllegalStateException if the system is in an invalid state.
      * @hide
      */
     @SystemApi
diff --git a/car-test-lib/src/android/car/test/mocks/JavaMockitoHelper.java b/car-test-lib/src/android/car/test/mocks/JavaMockitoHelper.java
index aaf12a7..9430723 100644
--- a/car-test-lib/src/android/car/test/mocks/JavaMockitoHelper.java
+++ b/car-test-lib/src/android/car/test/mocks/JavaMockitoHelper.java
@@ -89,8 +89,7 @@
      * {@value #ASYNC_TIMEOUT_MS} ms.
      */
     @NonNull
-    public static <T> T getResult(@NonNull Future<T> future)
-            throws InterruptedException, ExecutionException {
+    public static <T> T getResult(@NonNull Future<T> future) {
         return getResult(future, ASYNC_TIMEOUT_MS);
     }
 
diff --git a/car-test-lib/src/android/car/testapi/FakeCar.java b/car-test-lib/src/android/car/testapi/FakeCar.java
index 4a3a98a..0356774 100644
--- a/car-test-lib/src/android/car/testapi/FakeCar.java
+++ b/car-test-lib/src/android/car/testapi/FakeCar.java
@@ -24,7 +24,6 @@
 import android.car.diagnostic.ICarDiagnostic;
 import android.car.drivingstate.ICarDrivingState;
 import android.car.hardware.power.ICarPower;
-import android.car.media.ICarAudio;
 import android.car.storagemonitoring.ICarStorageMonitoring;
 import android.content.Context;
 import android.os.IBinder;
@@ -129,7 +128,6 @@
     }
 
     private static class FakeCarService extends ICar.Stub {
-        @Mock ICarAudio.Stub mCarAudio;
         @Mock ICarPackageManager.Stub mCarPackageManager;
         @Mock ICarDiagnostic.Stub mCarDiagnostic;
         @Mock ICarPower.Stub mCarPower;
@@ -138,6 +136,7 @@
         @Mock ICarStorageMonitoring.Stub mCarStorageMonitoring;
         @Mock ICarDrivingState.Stub mCarDrivingState;
 
+        private final FakeCarAudioService mCarAudio;
         private final FakeAppFocusService mAppFocus;
         private final FakeCarPropertyService mCarProperty;
         private final FakeCarProjectionService mCarProjection;
@@ -146,6 +145,7 @@
 
         FakeCarService(Context context) {
             MockitoAnnotations.initMocks(this);
+            mCarAudio = new FakeCarAudioService();
             mAppFocus = new FakeAppFocusService(context);
             mCarProperty = new FakeCarPropertyService();
             mCarProjection = new FakeCarProjectionService(context);
diff --git a/car-test-lib/src/android/car/testapi/FakeCarAudioService.java b/car-test-lib/src/android/car/testapi/FakeCarAudioService.java
new file mode 100644
index 0000000..7b0bb09
--- /dev/null
+++ b/car-test-lib/src/android/car/testapi/FakeCarAudioService.java
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+package android.car.testapi;
+
+import android.car.media.CarAudioPatchHandle;
+import android.car.media.ICarAudio;
+import android.media.AudioDeviceAttributes;
+import android.os.IBinder;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Fake service that is used by {@link FakeCar} to provide an implementation of {@link ICarAudio}.
+ * The reason we couldn't use a mock version of this service is that {@link AudioDeviceAttributes}
+ * is annotated with @hide, and Mockito fails to create a mock instance.
+ */
+final class FakeCarAudioService extends ICarAudio.Stub {
+    @Override
+    public boolean isAudioFeatureEnabled(int feature) {
+        return false;
+    }
+
+    @Override
+    public void setGroupVolume(int zoneId, int groupId, int index, int flags) {
+    }
+
+    @Override
+    public int getGroupMaxVolume(int zoneId, int groupId) {
+        return 0;
+    }
+
+    @Override
+    public int getGroupMinVolume(int zoneId, int groupId) {
+        return 0;
+    }
+
+    @Override
+    public int getGroupVolume(int zoneId, int groupId) {
+        return 0;
+    }
+
+    @Override
+    public void setFadeTowardFront(float value) {
+    }
+
+    @Override
+    public void setBalanceTowardRight(float value) {
+    }
+
+    @Override
+    public String[] getExternalSources() {
+        return new String[] {};
+    }
+
+    @Override
+    public CarAudioPatchHandle createAudioPatch(String sourceAddress, int usage,
+            int gainInMillibels) {
+        return null;
+    }
+
+    @Override
+    public void releaseAudioPatch(CarAudioPatchHandle patch) {
+    }
+
+    @Override
+    public int getVolumeGroupCount(int zoneId) {
+        return 0;
+    }
+
+    @Override
+    public int getVolumeGroupIdForUsage(int zoneId, int usage) {
+        return 0;
+    }
+
+    @Override
+    public int[] getUsagesForVolumeGroupId(int zoneId, int groupId) {
+        return new int[] {};
+    }
+
+    @Override
+    public int[] getAudioZoneIds() {
+        return new int[] {};
+    }
+
+    @Override
+    public int getZoneIdForUid(int uid) {
+        return 0;
+    }
+
+    @Override
+    public boolean setZoneIdForUid(int zoneId, int uid) {
+        return false;
+    }
+
+    @Override
+    public boolean clearZoneIdForUid(int uid) {
+        return false;
+    }
+
+    @Override
+    public boolean isVolumeGroupMuted(int zoneId, int groupId) {
+        return false;
+    }
+
+    @Override
+    public void setVolumeGroupMute(int zoneId, int groupId, boolean mute, int flags) {
+    }
+
+    @Override
+    public String getOutputDeviceAddressForUsage(int zoneId, int usage) {
+        return "";
+    }
+
+    @Override
+    public List<AudioDeviceAttributes> getInputDevicesForZoneId(int zoneId) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public boolean isPlaybackOnVolumeGroupActive(int volumeGroupId, int audioZoneId) {
+        return false;
+    }
+
+    @Override
+    public void registerVolumeCallback(IBinder binder) {
+    }
+
+    @Override
+    public void unregisterVolumeCallback(IBinder binder) {
+    }
+}
diff --git a/car_product/build/car_base.mk b/car_product/build/car_base.mk
index 41408eb..2f9b344 100644
--- a/car_product/build/car_base.mk
+++ b/car_product/build/car_base.mk
@@ -65,6 +65,9 @@
 # EVS service
 include packages/services/Car/cpp/evs/manager/evsmanager.mk
 
+# Automotive Telemetry services
+include packages/services/Car/cpp/telemetry/products/telemetry.mk
+
 # EVS manager overrides cameraserver on automotive implementations so
 # we need to configure Camera API to not connect to it
 PRODUCT_PROPERTY_OVERRIDES += config.disable_cameraservice=true
diff --git a/cpp/evs/OWNERS b/cpp/evs/OWNERS
index cc4938d..1830653 100644
--- a/cpp/evs/OWNERS
+++ b/cpp/evs/OWNERS
@@ -1,4 +1,5 @@
 # Project owners
 changyeon@google.com
+garysungang@google.com
 haoxiangl@google.com
-swan@google.com
+
diff --git a/cpp/evs/apps/default/config.json b/cpp/evs/apps/default/config.json
index 16148a7..dc2771c 100644
--- a/cpp/evs/apps/default/config.json
+++ b/cpp/evs/apps/default/config.json
@@ -8,7 +8,7 @@
   },
   "displays" : [
     {
-      "displayPort" : 136,
+      "displayPort" : 129,
       "frontRange" : 100,
       "rearRange" : 100
     },
diff --git a/cpp/security/OWNERS b/cpp/security/OWNERS
new file mode 100644
index 0000000..45f51c0
--- /dev/null
+++ b/cpp/security/OWNERS
@@ -0,0 +1,2 @@
+dbenisch@google.com
+skeys@google.com
diff --git a/cpp/surround_view/app/Android.bp b/cpp/surround_view/app/Android.bp
index 5145c5e..76753d3 100644
--- a/cpp/surround_view/app/Android.bp
+++ b/cpp/surround_view/app/Android.bp
@@ -23,6 +23,7 @@
     name: "sv_app",
 
     srcs: [
+        "SurroundViewAppCommon.cpp",
         "SurroundViewServiceCallback.cpp",
         "shader.cpp",
         "sv_app.cpp",
diff --git a/cpp/surround_view/app/SurroundViewAppCommon.cpp b/cpp/surround_view/app/SurroundViewAppCommon.cpp
new file mode 100644
index 0000000..b1a2792
--- /dev/null
+++ b/cpp/surround_view/app/SurroundViewAppCommon.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SurroundViewAppCommon.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace sv {
+namespace app {
+
+bool run2dSurroundView(sp<ISurroundViewService> pSurroundViewService, sp<IEvsDisplay> pDisplay) {
+    LOG(INFO) << "Run 2d Surround View demo";
+
+    // Call HIDL API "start2dSession"
+    sp<ISurroundView2dSession> surroundView2dSession;
+
+    SvResult svResult;
+    pSurroundViewService->start2dSession(
+            [&surroundView2dSession, &svResult](const sp<ISurroundView2dSession>& session,
+                                                SvResult result) {
+                surroundView2dSession = session;
+                svResult = result;
+            });
+
+    if (surroundView2dSession == nullptr || svResult != SvResult::OK) {
+        LOG(ERROR) << "Failed to start2dSession";
+        return false;
+    } else {
+        LOG(INFO) << "start2dSession succeeded";
+    }
+
+    sp<SurroundViewServiceCallback> sv2dCallback =
+            new SurroundViewServiceCallback(pDisplay, surroundView2dSession);
+
+    // Start 2d stream with callback with default quality and resolution.
+    // The quality is defaulted to be HIGH_QUALITY, and the default resolution
+    // is set in the sv config file.
+    if (surroundView2dSession->startStream(sv2dCallback) != SvResult::OK) {
+        LOG(ERROR) << "Failed to start 2d stream";
+        return false;
+    }
+
+    const int kTotalViewingTimeSecs = 10;
+
+    // Let the SV algorithm run for HIGH_QUALITY until the wait time finishes
+    std::this_thread::sleep_for(std::chrono::seconds(kTotalViewingTimeSecs));
+
+    // Switch to low quality and lower resolution
+    Sv2dConfig config = {.width = kLowResolutionWidth, .blending = SvQuality::LOW};
+    if (surroundView2dSession->set2dConfig(config) != SvResult::OK) {
+        LOG(ERROR) << "Failed to set2dConfig";
+        return false;
+    }
+
+    // Let the SV algorithm run for LOW_QUALITY until the wait time finishes
+    std::this_thread::sleep_for(std::chrono::seconds(kTotalViewingTimeSecs));
+
+    // TODO(b/150412555): wait for the last frame
+    // Stop the 2d stream and session
+    surroundView2dSession->stopStream();
+
+    pSurroundViewService->stop2dSession(surroundView2dSession);
+    surroundView2dSession = nullptr;
+
+    LOG(INFO) << "SV 2D session finished.";
+
+    return true;
+};
+
+// Given a valid sv 3d session and pose, viewid and hfov parameters, sets the view.
+bool setView(sp<ISurroundView3dSession> surroundView3dSession, uint32_t viewId, uint32_t poseIndex,
+             float hfov) {
+    const View3d view3d = {
+            .viewId = viewId,
+            .pose =
+                    {
+                            .rotation = {.x = kPoseRot[poseIndex][0],
+                                         .y = kPoseRot[poseIndex][1],
+                                         .z = kPoseRot[poseIndex][2],
+                                         .w = kPoseRot[poseIndex][3]},
+                            .translation = {.x = kPoseTrans[poseIndex][0],
+                                            .y = kPoseTrans[poseIndex][1],
+                                            .z = kPoseTrans[poseIndex][2]},
+                    },
+            .horizontalFov = hfov,
+    };
+
+    const std::vector<View3d> views = {view3d};
+    if (surroundView3dSession->setViews(views) != SvResult::OK) {
+        return false;
+    }
+    return true;
+}
+
+bool run3dSurroundView(sp<ISurroundViewService> pSurroundViewService, sp<IEvsDisplay> pDisplay) {
+    LOG(INFO) << "Run 3d Surround View demo";
+
+    // Call HIDL API "start3dSession"
+    sp<ISurroundView3dSession> surroundView3dSession;
+
+    SvResult svResult;
+    pSurroundViewService->start3dSession(
+            [&surroundView3dSession, &svResult](const sp<ISurroundView3dSession>& session,
+                                                SvResult result) {
+                surroundView3dSession = session;
+                svResult = result;
+            });
+
+    if (surroundView3dSession == nullptr || svResult != SvResult::OK) {
+        LOG(ERROR) << "Failed to start3dSession";
+        return false;
+    } else {
+        LOG(INFO) << "start3dSession succeeded";
+    }
+
+    sp<SurroundViewServiceCallback> sv3dCallback =
+            new SurroundViewServiceCallback(pDisplay, surroundView3dSession);
+
+    // A view must be set before the 3d stream is started.
+    if (!setView(surroundView3dSession, /*viewId=*/0, /*poseIndex=*/0, kHorizontalFov)) {
+        LOG(ERROR) << "Failed to setView of pose index :" << 0;
+        return false;
+    }
+
+    // Start 3d stream with callback with default quality and resolution.
+    // The quality is defaulted to be HIGH_QUALITY, and the default resolution
+    // is set in the sv config file.
+    if (surroundView3dSession->startStream(sv3dCallback) != SvResult::OK) {
+        LOG(ERROR) << "Failed to start 3d stream";
+        return false;
+    }
+
+    // Let the SV algorithm run for 10 seconds for HIGH_QUALITY
+    const int kTotalViewingTimeSecs = 10;
+    const std::chrono::milliseconds perPoseSleepTimeMs(kTotalViewingTimeSecs * 1000 / kPoseCount);
+    // Iterate through the pre-set views.
+    for (uint32_t i = 0; i < kPoseCount; i++) {
+        if (!setView(surroundView3dSession, /*viewId=*/i, /*poseIndex=*/i, kHorizontalFov)) {
+            LOG(WARNING) << "Failed to setView of pose index :" << i;
+        }
+        std::this_thread::sleep_for(perPoseSleepTimeMs);
+    }
+
+    // Switch to low quality and lower resolution
+    Sv3dConfig config = {.width = kLowResolutionWidth,
+                         .height = kLowResolutionHeight,
+                         .carDetails = SvQuality::LOW};
+
+    if (surroundView3dSession->set3dConfig(config) != SvResult::OK) {
+        LOG(ERROR) << "Failed to set3dConfig";
+        return false;
+    }
+
+    // Let the SV algorithm run for 10 seconds for LOW_QUALITY
+    for (uint32_t i = 0; i < kPoseCount; i++) {
+        if (!setView(surroundView3dSession, i + kPoseCount, i, kHorizontalFov)) {
+            LOG(WARNING) << "Failed to setView of pose index :" << i;
+        }
+        std::this_thread::sleep_for(perPoseSleepTimeMs);
+    }
+
+    // TODO(b/150412555): wait for the last frame
+    // Stop the 3d stream and session
+    surroundView3dSession->stopStream();
+
+    pSurroundViewService->stop3dSession(surroundView3dSession);
+    surroundView3dSession = nullptr;
+
+    LOG(DEBUG) << "SV 3D session finished.";
+
+    return true;
+};
+}  // namespace app
+}  // namespace sv
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/cpp/surround_view/app/SurroundViewAppCommon.h b/cpp/surround_view/app/SurroundViewAppCommon.h
new file mode 100644
index 0000000..04e59fa
--- /dev/null
+++ b/cpp/surround_view/app/SurroundViewAppCommon.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "SurroundViewServiceCallback.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundView2dSession.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundView3dSession.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundViewService.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Log.h>
+#include <utils/StrongPointer.h>
+
+#include <stdio.h>
+
+#include <thread>
+
+using namespace android::hardware::automotive::sv::V1_0;
+using namespace android::hardware::automotive::evs::V1_1;
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace sv {
+namespace app {
+
+const int kLowResolutionWidth = 120;
+const int kLowResolutionHeight = 90;
+
+enum DemoMode {
+    UNKNOWN,
+    DEMO_2D,
+    DEMO_3D,
+};
+
+const float kHorizontalFov = 90;
+
+// Number of views to generate.
+const uint32_t kPoseCount = 16;
+
+// Set of pose rotations expressed in quaternions.
+// Views are generated about a circle at a height about the car, point towards the center.
+const float kPoseRot[kPoseCount][4] = {{-0.251292, -0.251292, -0.660948, 0.660948},
+                                       {0.197439, 0.295488, 0.777193, -0.519304},
+                                       {0.135998, 0.328329, 0.86357, -0.357702},
+                                       {0.0693313, 0.348552, 0.916761, -0.182355},
+                                       {-7.76709e-09, 0.355381, 0.934722, 2.0429e-08},
+                                       {-0.0693313, 0.348552, 0.916761, 0.182355},
+                                       {-0.135998, 0.328329, 0.86357, 0.357702},
+                                       {-0.197439, 0.295488, 0.777193, 0.519304},
+                                       {-0.251292, 0.251292, 0.660948, 0.660948},
+                                       {-0.295488, 0.197439, 0.519304, 0.777193},
+                                       {-0.328329, 0.135998, 0.357702, 0.86357},
+                                       {-0.348552, 0.0693313, 0.182355, 0.916761},
+                                       {-0.355381, -2.11894e-09, -5.57322e-09, 0.934722},
+                                       {-0.348552, -0.0693313, -0.182355, 0.916761},
+                                       {-0.328329, -0.135998, -0.357702, 0.86357},
+                                       {-0.295488, -0.197439, -0.519304, 0.777193}};
+
+// Set of pose translations i.e. positions of the views.
+// Views are generated about a circle at a height about the car, point towards the center.
+const float kPoseTrans[kPoseCount][4] = {{4, 0, 2.5},
+                                         {3.69552, 1.53073, 2.5},
+                                         {2.82843, 2.82843, 2.5},
+                                         {1.53073, 3.69552, 2.5},
+                                         {-1.74846e-07, 4, 2.5},
+                                         {-1.53073, 3.69552, 2.5},
+                                         {-2.82843, 2.82843, 2.5},
+                                         {-3.69552, 1.53073, 2.5},
+                                         {-4, -3.49691e-07, 2.5},
+                                         {-3.69552, -1.53073, 2.5},
+                                         {-2.82843, -2.82843, 2.5},
+                                         {-1.53073, -3.69552, 2.5},
+                                         {4.76995e-08, -4, 2.5},
+                                         {1.53073, -3.69552, 2.5},
+                                         {2.82843, -2.82843, 2.5},
+                                         {3.69552, -1.53073, 2.5}};
+
+bool run2dSurroundView(sp<ISurroundViewService> pSurroundViewService, sp<IEvsDisplay> pDisplay);
+
+bool run3dSurroundView(sp<ISurroundViewService> pSurroundViewService, sp<IEvsDisplay> pDisplay);
+
+// Given a valid sv 3d session and pose, viewid and hfov parameters, sets the view.
+bool setView(sp<ISurroundView3dSession> surroundView3dSession, uint32_t viewId, uint32_t poseIndex,
+             float hfov);
+
+}  // namespace app
+}  // namespace sv
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/cpp/surround_view/app/SurroundViewServiceCallback.cpp b/cpp/surround_view/app/SurroundViewServiceCallback.cpp
index 12dba98..a3ce519 100644
--- a/cpp/surround_view/app/SurroundViewServiceCallback.cpp
+++ b/cpp/surround_view/app/SurroundViewServiceCallback.cpp
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include "SurroundViewServiceCallback.h"
 
 #include <android-base/logging.h>
@@ -441,15 +440,6 @@
             LOG(INFO) << "Successfully attached render target";
         }
 
-        // Call HIDL API "doneWithFrames" to return the ownership
-        // back to SV service
-        if (mSession == nullptr) {
-            LOG(ERROR) << "SurroundViewSession in callback is invalid";
-            return {};
-        } else {
-            mSession->doneWithFrames(svFramesDesc);
-        }
-
         // Render frame to EVS display
         LOG(INFO) << "Rendering to display buffer";
         sp<GraphicBuffer> graphicBuffer =
diff --git a/cpp/surround_view/app/SurroundViewServiceCallback.h b/cpp/surround_view/app/SurroundViewServiceCallback.h
index b2ab831..467c69a 100644
--- a/cpp/surround_view/app/SurroundViewServiceCallback.h
+++ b/cpp/surround_view/app/SurroundViewServiceCallback.h
@@ -13,6 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#pragma once
+
 #include <stdio.h>
 
 #include <utils/StrongPointer.h>
diff --git a/cpp/surround_view/app/sv_app.cpp b/cpp/surround_view/app/sv_app.cpp
index 43369c2..d07671d 100644
--- a/cpp/surround_view/app/sv_app.cpp
+++ b/cpp/surround_view/app/sv_app.cpp
@@ -14,17 +14,7 @@
  * limitations under the License.
  */
 
-#include <android-base/logging.h>
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
-#include <android/hardware/automotive/sv/1.0/ISurroundViewService.h>
-#include <android/hardware/automotive/sv/1.0/ISurroundView2dSession.h>
-#include <android/hardware/automotive/sv/1.0/ISurroundView3dSession.h>
-#include <hidl/HidlTransportSupport.h>
-#include <stdio.h>
-#include <utils/StrongPointer.h>
-#include <utils/Log.h>
-#include <thread>
-
+#include "SurroundViewAppCommon.h"
 #include "SurroundViewServiceCallback.h"
 
 // libhidl:
@@ -40,220 +30,7 @@
 
 using namespace android::hardware::automotive::sv::V1_0;
 using namespace android::hardware::automotive::evs::V1_1;
-
-const int kLowResolutionWidth = 120;
-const int kLowResolutionHeight = 90;
-
-enum DemoMode {
-    UNKNOWN,
-    DEMO_2D,
-    DEMO_3D,
-};
-
-const float kHorizontalFov = 90;
-
-// Number of views to generate.
-const uint32_t kPoseCount = 16;
-
-// Set of pose rotations expressed in quaternions.
-// Views are generated about a circle at a height about the car, point towards the center.
-const float kPoseRot[kPoseCount][4] = {
-    {-0.251292, -0.251292, -0.660948, 0.660948},
-    {0.197439, 0.295488, 0.777193, -0.519304},
-    {0.135998, 0.328329, 0.86357, -0.357702},
-    {0.0693313, 0.348552, 0.916761, -0.182355},
-    {-7.76709e-09, 0.355381, 0.934722, 2.0429e-08},
-    {-0.0693313, 0.348552, 0.916761, 0.182355},
-    {-0.135998, 0.328329, 0.86357, 0.357702},
-    {-0.197439, 0.295488, 0.777193, 0.519304},
-    {-0.251292, 0.251292, 0.660948, 0.660948},
-    {-0.295488, 0.197439, 0.519304, 0.777193},
-    {-0.328329, 0.135998, 0.357702, 0.86357},
-    {-0.348552, 0.0693313, 0.182355, 0.916761},
-    {-0.355381, -2.11894e-09, -5.57322e-09, 0.934722},
-    {-0.348552, -0.0693313, -0.182355, 0.916761},
-    {-0.328329, -0.135998, -0.357702, 0.86357},
-    {-0.295488, -0.197439, -0.519304, 0.777193}
-};
-
-// Set of pose translations i.e. positions of the views.
-// Views are generated about a circle at a height about the car, point towards the center.
-const float kPoseTrans[kPoseCount][4] = {
-    {4, 0, 2.5},
-    {3.69552, 1.53073, 2.5},
-    {2.82843, 2.82843, 2.5},
-    {1.53073, 3.69552, 2.5},
-    {-1.74846e-07, 4, 2.5},
-    {-1.53073, 3.69552, 2.5},
-    {-2.82843, 2.82843, 2.5},
-    {-3.69552, 1.53073, 2.5},
-    {-4, -3.49691e-07, 2.5},
-    {-3.69552, -1.53073, 2.5},
-    {-2.82843, -2.82843, 2.5},
-    {-1.53073, -3.69552, 2.5},
-    {4.76995e-08, -4, 2.5},
-    {1.53073, -3.69552, 2.5},
-    {2.82843, -2.82843, 2.5},
-    {3.69552, -1.53073, 2.5}
-};
-
-bool run2dSurroundView(sp<ISurroundViewService> pSurroundViewService,
-                       sp<IEvsDisplay> pDisplay) {
-    LOG(INFO) << "Run 2d Surround View demo";
-
-    // Call HIDL API "start2dSession"
-    sp<ISurroundView2dSession> surroundView2dSession;
-
-    SvResult svResult;
-    pSurroundViewService->start2dSession(
-        [&surroundView2dSession, &svResult](
-            const sp<ISurroundView2dSession>& session, SvResult result) {
-        surroundView2dSession = session;
-        svResult = result;
-    });
-
-    if (surroundView2dSession == nullptr || svResult != SvResult::OK) {
-        LOG(ERROR) << "Failed to start2dSession";
-        return false;
-    } else {
-        LOG(INFO) << "start2dSession succeeded";
-    }
-
-    sp<SurroundViewServiceCallback> sv2dCallback
-        = new SurroundViewServiceCallback(pDisplay, surroundView2dSession);
-
-    // Start 2d stream with callback
-    if (surroundView2dSession->startStream(sv2dCallback) != SvResult::OK) {
-        LOG(ERROR) << "Failed to start 2d stream";
-        return false;
-    }
-
-    // Let the SV algorithm run for 10 seconds for HIGH_QUALITY
-    std::this_thread::sleep_for(std::chrono::seconds(10));
-
-    // Switch to low quality and lower resolution
-    Sv2dConfig config;
-    config.width = kLowResolutionWidth;
-    config.blending = SvQuality::LOW;
-    if (surroundView2dSession->set2dConfig(config) != SvResult::OK) {
-        LOG(ERROR) << "Failed to set2dConfig";
-        return false;
-    }
-
-    // Let the SV algorithm run for 10 seconds for LOW_QUALITY
-    std::this_thread::sleep_for(std::chrono::seconds(10));
-
-    // TODO(b/150412555): wait for the last frame
-    // Stop the 2d stream and session
-    surroundView2dSession->stopStream();
-
-    pSurroundViewService->stop2dSession(surroundView2dSession);
-    surroundView2dSession = nullptr;
-
-    LOG(INFO) << "SV 2D session finished.";
-
-    return true;
-};
-
-// Given a valid sv 3d session and pose, viewid and hfov parameters, sets the view.
-bool setView(sp<ISurroundView3dSession> surroundView3dSession, uint32_t viewId,
-        uint32_t poseIndex, float hfov)
-{
-    const View3d view3d = {
-        .viewId = viewId,
-        .pose = {
-            .rotation = {.x=kPoseRot[poseIndex][0], .y=kPoseRot[poseIndex][1],
-                    .z=kPoseRot[poseIndex][2], .w=kPoseRot[poseIndex][3]},
-            .translation = {.x=kPoseTrans[poseIndex][0], .y=kPoseTrans[poseIndex][1],
-                    .z=kPoseTrans[poseIndex][2]},
-        },
-        .horizontalFov = hfov,
-    };
-
-    const std::vector<View3d> views = {view3d};
-    if (surroundView3dSession->setViews(views) != SvResult::OK) {
-        return false;
-    }
-    return true;
-}
-
-bool run3dSurroundView(sp<ISurroundViewService> pSurroundViewService,
-                       sp<IEvsDisplay> pDisplay) {
-    LOG(INFO) << "Run 3d Surround View demo";
-
-    // Call HIDL API "start3dSession"
-    sp<ISurroundView3dSession> surroundView3dSession;
-
-    SvResult svResult;
-    pSurroundViewService->start3dSession(
-        [&surroundView3dSession, &svResult](
-            const sp<ISurroundView3dSession>& session, SvResult result) {
-        surroundView3dSession = session;
-        svResult = result;
-    });
-
-    if (surroundView3dSession == nullptr || svResult != SvResult::OK) {
-        LOG(ERROR) << "Failed to start3dSession";
-        return false;
-    } else {
-        LOG(INFO) << "start3dSession succeeded";
-    }
-
-    sp<SurroundViewServiceCallback> sv3dCallback
-        = new SurroundViewServiceCallback(pDisplay, surroundView3dSession);
-
-    // A view must be set before the 3d stream is started.
-    if (!setView(surroundView3dSession, 0, 0, kHorizontalFov)) {
-        LOG(ERROR) << "Failed to setView of pose index :" << 0;
-        return false;
-    }
-
-    // Start 3d stream with callback
-    if (surroundView3dSession->startStream(sv3dCallback) != SvResult::OK) {
-        LOG(ERROR) << "Failed to start 3d stream";
-        return false;
-    }
-
-    // Let the SV algorithm run for 10 seconds for HIGH_QUALITY
-    const int totalViewingTimeSecs = 10;
-    const std::chrono::milliseconds
-            perPoseSleepTimeMs(totalViewingTimeSecs * 1000 / kPoseCount);
-    for(uint32_t i = 1; i < kPoseCount; i++) {
-        if (!setView(surroundView3dSession, i, i, kHorizontalFov)) {
-            LOG(WARNING) << "Failed to setView of pose index :" << i;
-        }
-        std::this_thread::sleep_for(perPoseSleepTimeMs);
-    }
-
-    // Switch to low quality and lower resolution
-    Sv3dConfig config;
-    config.width = kLowResolutionWidth;
-    config.height = kLowResolutionHeight;
-    config.carDetails = SvQuality::LOW;
-    if (surroundView3dSession->set3dConfig(config) != SvResult::OK) {
-        LOG(ERROR) << "Failed to set3dConfig";
-        return false;
-    }
-
-    // Let the SV algorithm run for 10 seconds for LOW_QUALITY
-    for(uint32_t i = 0; i < kPoseCount; i++) {
-        if(!setView(surroundView3dSession, i + kPoseCount, i, kHorizontalFov)) {
-            LOG(WARNING) << "Failed to setView of pose index :" << i;
-        }
-        std::this_thread::sleep_for(perPoseSleepTimeMs);
-    }
-
-    // TODO(b/150412555): wait for the last frame
-    // Stop the 3d stream and session
-    surroundView3dSession->stopStream();
-
-    pSurroundViewService->stop3dSession(surroundView3dSession);
-    surroundView3dSession = nullptr;
-
-    LOG(DEBUG) << "SV 3D session finished.";
-
-    return true;
-};
+using namespace android::hardware::automotive::sv::app;
 
 // Main entry point
 int main(int argc, char** argv) {
diff --git a/cpp/surround_view/service-impl/SurroundView2dSession.cpp b/cpp/surround_view/service-impl/SurroundView2dSession.cpp
index a92372c..2d837e0 100644
--- a/cpp/surround_view/service-impl/SurroundView2dSession.cpp
+++ b/cpp/surround_view/service-impl/SurroundView2dSession.cpp
@@ -53,6 +53,9 @@
 namespace V1_0 {
 namespace implementation {
 
+// Macro for obtaining a uint64_t memory_id from the camera index and buffer_id.
+#define GET_MEMORY_ID(cam_index, buffer_id) ((static_cast<uint64_t>(cam_index) << 32) | buffer_id)
+
 // TODO(b/158479099): There are a lot of redundant code between 2d and 3d.
 // Decrease the degree of redundancy.
 typedef struct {
@@ -153,6 +156,10 @@
                 }
 
                 mSession->mInputPointers[i].gpu_data_pointer = static_cast<void*>(hardwareBuffer);
+                // Set memory_id to enable buffer caching.
+                // higher 32 bits are for camera index, lower 32 bits for bufferId.
+                mSession->mInputPointers[i].memory_id
+                        = GET_MEMORY_ID(indices[i], buffers[indices[i]].bufferId);
 
                 // Keep a reference to the EVS graphic buffers, so we can
                 // release them after Surround View stitching is done.
@@ -747,6 +754,9 @@
             return false;
         }
         mOutputPointer.gpu_data_pointer = static_cast<void*>(mOutputHolder->toAHardwareBuffer());
+        // Set output memory id one time to a one time unique value.
+        // 0 to (kNumFrames - 1) are used for inputs, using kNumFrames as higher 32 bits.
+        mOutputPointer.memory_id = GET_MEMORY_ID(kNumFrames, 0x00);
     } else {
         mSvTexture = new GraphicBuffer(mOutputWidth, mOutputHeight, HAL_PIXEL_FORMAT_RGB_888, 1,
                                        GRALLOC_USAGE_HW_TEXTURE, "SvTexture");
diff --git a/cpp/surround_view/service-impl/core_lib.h b/cpp/surround_view/service-impl/core_lib.h
index fd8f1ec..a149f86 100644
--- a/cpp/surround_view/service-impl/core_lib.h
+++ b/cpp/surround_view/service-impl/core_lib.h
@@ -670,29 +670,54 @@
           car_parts(parts) {}
 };
 
+// Constant used as an invalid memory id for SurroundViewInputBufferPointers and
+// SurroundViewResultPointer. Setting to `memory_id` to kInvalidMemoryId implies
+// no caching is performed.
+const uint64_t kInvalidMemoryId = UINT64_MAX;
+
+// Currently we keep both cpu and gpu data pointers, and only one of them should
+// be valid at a certain point. Also, users are responsible to allocate and
+// de-allocate the pointers.
+// TODO(b/174778117): consider use only one data pointer once GPU migration is
+// done.
+// TODO(b/184870125): Consider merging with SurroundViewInputBufferPointers.
 struct SurroundViewInputBufferPointers {
     void* gpu_data_pointer;
     void* cpu_data_pointer;
     Format format;
     int width;
     int height;
+    // Unique identifier for the CPU/GPU data buffer. If memory id is the same as
+    // a previously provided input buffer, cached intermediate allocated data will
+    // be used for faster operation. If `memory_id` is kInvalidMemoryId no caching
+    // is performed. Currently supported: SV2D GPU pipeline with
+    // `gpu_data_pointer`.
+    // Recommend the `memory_id` provided by client to be created as:
+    // ((camera_index) << 32 )  | (graphics_buffer_id).
+    uint64_t memory_id;
     SurroundViewInputBufferPointers() :
-          gpu_data_pointer(nullptr), cpu_data_pointer(nullptr), width(0), height(0) {}
+          gpu_data_pointer(nullptr),
+          cpu_data_pointer(nullptr),
+          width(0),
+          height(0),
+          memory_id(kInvalidMemoryId) {}
     SurroundViewInputBufferPointers(void* gpu_data_pointer_, void* cpu_data_pointer_,
-                                    Format format_, int width_, int height_) :
+                                    Format format_, int width_, int height_,
+                                    uint64_t memory_id_ = kInvalidMemoryId) :
           gpu_data_pointer(gpu_data_pointer_),
           cpu_data_pointer(cpu_data_pointer_),
           format(format_),
           width(width_),
-          height(height_) {}
+          height(height_),
+          memory_id(memory_id_) {}
 };
 
 // Currently we keep both cpu and gpu data pointers, and only one of them should
 // be valid at a certain point. Users need to check null before they make use of
 // the data pointers.
 // TODO(b/174778117): consider use only one data pointer once GPU migration is
-// done. If we are going to keep both cpu and gpu data pointer, specify the type
-// of data for cpu data pointer, instead of using a void pointer.
+// done.
+// TODO(b/184870125): Consider merging with SurroundViewInputBufferPointers.
 struct SurroundViewResultPointer {
     void* gpu_data_pointer;
     void* cpu_data_pointer;
@@ -700,24 +725,32 @@
     int width;
     int height;
     bool is_data_preallocated;
+    // Unique identifier for the CPU/GPU data buffer. If memory id is the same as
+    // a previously provided result buffer, cached intermediate allocated data
+    // will be used for faster operation. If memory_id is kInvalidMemoryId no
+    // caching is performed. Currently supported: SV2D GPU pipeline with
+    // 'gpu_data_pointer'.
+    // Recommend the `memory_id` provided by client to be created as:
+    // ((camera_index) << 32 )  | (graphics_buffer_id).
+    uint64_t memory_id;
     SurroundViewResultPointer() :
           gpu_data_pointer(nullptr),
           cpu_data_pointer(nullptr),
           width(0),
           height(0),
-          is_data_preallocated(false) {}
+          is_data_preallocated(false),
+          memory_id(kInvalidMemoryId) {}
 
-    // Constructor with result data pointer being allocated within core lib.
+    // Constructor with result cpu data pointer being allocated within core lib.
     // Use for cases when no already existing buffer is available.
     SurroundViewResultPointer(Format format_, int width_, int height_) :
-          gpu_data_pointer(nullptr),
-          format(format_),
-          width(width_),
-          height(height_),
-          is_data_preallocated(false) {
+          format(format_), width(width_), height(height_) {
         // default formate is gray.
         const int byte_per_pixel = format_ == RGB ? 3 : format_ == RGBA ? 4 : 1;
         cpu_data_pointer = static_cast<void*>(new char[width * height * byte_per_pixel]);
+        gpu_data_pointer = nullptr;
+        is_data_preallocated = false;
+        memory_id = kInvalidMemoryId;
     }
 
     // Constructor with pre-allocated data.
@@ -730,7 +763,8 @@
           format(format_),
           width(width_),
           height(height_),
-          is_data_preallocated(true) {}
+          is_data_preallocated(true),
+          memory_id(kInvalidMemoryId) {}
 
     ~SurroundViewResultPointer() {
         if (cpu_data_pointer) {
diff --git a/cpp/surround_view/service-impl/lib/arm64/libcore_lib_shared.so b/cpp/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
index 4dfc535..8422731 100755
--- a/cpp/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
+++ b/cpp/surround_view/service-impl/lib/arm64/libcore_lib_shared.so
Binary files differ
diff --git a/cpp/telemetry/ARCHITECTURE.md b/cpp/telemetry/ARCHITECTURE.md
new file mode 100644
index 0000000..75dd194
--- /dev/null
+++ b/cpp/telemetry/ARCHITECTURE.md
@@ -0,0 +1,22 @@
+# Architecture of Car Telemetry Service
+
+## Names
+
+- C++ namespace `android.automotive.telemetry` - for all the car telemetry related projects.
+- android.telemetry.ICarTelemetry - AIDL interface for collecting car data.
+- cartelemetryd (android.automotive.telemetryd) -  a daemon that implements `ICarTelemetry`
+                                                   interface.
+- CarTelemetryService - a part of CarService that executes scrits. Located in car services dir.
+
+## Structure
+
+```
+aidl/                    - Internal AIDL declerations, for public AIDLs, please see
+                           //frameworks/hardware/interfaces/automotive/telemetry
+products/                - AAOS Telemetry product, it's included in car_base.mk
+sepolicy                 - SELinux policies
+src/                     - Source code
+   TelemetryServer.h     - The main class.
+*.rc                     - rc file to start services
+*.xml                    - VINTF manifest (TODO: needed?)
+```
diff --git a/cpp/telemetry/Android.bp b/cpp/telemetry/Android.bp
new file mode 100644
index 0000000..4e6c1c0
--- /dev/null
+++ b/cpp/telemetry/Android.bp
@@ -0,0 +1,94 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "cartelemetryd_defaults",
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-unused-parameter",
+    ],
+    shared_libs: [
+        "android.automotive.telemetry.internal-ndk_platform",
+        "android.frameworks.automotive.telemetry-V1-ndk_platform",
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+    ],
+    product_variables: {
+        debuggable: {
+            cflags: [
+                "-DCARTELEMETRYD_DEBUG=true",
+            ]
+        }
+    },
+}
+
+cc_library {
+    name: "android.automotive.telemetryd@1.0-impl",
+    defaults: [
+        "cartelemetryd_defaults",
+    ],
+    srcs: [
+        "src/CarTelemetryImpl.cpp",
+        "src/CarTelemetryInternalImpl.cpp",
+        "src/RingBuffer.cpp",
+        "src/TelemetryServer.cpp",
+    ],
+    // Allow dependents to use the header files.
+    export_include_dirs: [
+        "src",
+    ],
+}
+
+cc_test {
+    name: "cartelemetryd_impl_test",
+    defaults: [
+        "cartelemetryd_defaults",
+    ],
+    test_suites: ["general-tests"],
+    srcs: [
+        "tests/CarTelemetryImplTest.cpp",
+        "tests/CarTelemetryInternalImplTest.cpp",
+        "tests/RingBufferTest.cpp",
+    ],
+    // Statically link only in tests, for portability reason.
+    static_libs: [
+        "android.automotive.telemetryd@1.0-impl",
+        "android.automotive.telemetry.internal-ndk_platform",
+        "android.frameworks.automotive.telemetry-V1-ndk_platform",
+        "libgmock",
+        "libgtest",
+    ],
+}
+
+cc_binary {
+    name: "android.automotive.telemetryd@1.0",
+    defaults: [
+        "cartelemetryd_defaults",
+    ],
+    srcs: [
+        "src/main.cpp"
+    ],
+    init_rc: ["android.automotive.telemetryd@1.0.rc"],
+    vintf_fragments: ["android.automotive.telemetryd@1.0.xml"],
+    shared_libs: [
+        "android.automotive.telemetryd@1.0-impl"
+    ],
+}
diff --git a/cpp/telemetry/OWNERS b/cpp/telemetry/OWNERS
new file mode 100644
index 0000000..80794e1
--- /dev/null
+++ b/cpp/telemetry/OWNERS
@@ -0,0 +1,3 @@
+sgurun@google.com
+zhomart@google.com
+mdashouk@google.com
diff --git a/cpp/telemetry/README.md b/cpp/telemetry/README.md
new file mode 100644
index 0000000..a13116d
--- /dev/null
+++ b/cpp/telemetry/README.md
@@ -0,0 +1,19 @@
+# Automotive Telemetry Service
+
+A structured log collection service for CarTelemetryService. See ARCHITECTURE.md to learn internals.
+
+## Useful Commands
+
+**Dump service information**
+
+`adb shell dumpsys android.automotive.telemetry.internal.ICarTelemetryInternal/default`
+
+**Starting emulator**
+
+`aae emulator run -selinux permissive -writable-system`
+
+**Running tests**
+
+`atest cartelemetryd_impl_test:CarTelemetryInternalImplTest#TestSetListenerReturnsOk`
+
+`atest cartelemetryd_impl_test`
diff --git a/cpp/telemetry/aidl/Android.bp b/cpp/telemetry/aidl/Android.bp
new file mode 100644
index 0000000..b4cd9c7
--- /dev/null
+++ b/cpp/telemetry/aidl/Android.bp
@@ -0,0 +1,35 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.automotive.telemetry.internal",
+    unstable: true,
+    vendor_available: false,
+    srcs: [
+        "android/automotive/telemetry/internal/*.aidl",
+    ],
+    backend: {
+        ndk: {
+            enabled: true,
+        },
+        java: {
+            platform_apis: true,
+            enabled: true,
+        },
+    }
+}
diff --git a/cpp/telemetry/aidl/android/automotive/telemetry/internal/CarDataInternal.aidl b/cpp/telemetry/aidl/android/automotive/telemetry/internal/CarDataInternal.aidl
new file mode 100644
index 0000000..bf31169
--- /dev/null
+++ b/cpp/telemetry/aidl/android/automotive/telemetry/internal/CarDataInternal.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package android.automotive.telemetry.internal;
+
+/**
+ * Wrapper for {@code android.frameworks.automotive.telemetry.CarData}.
+ */
+parcelable CarDataInternal {
+  /**
+   * Must be a valid id. Scripts subscribe to data using this id.
+   */
+  int id;
+
+  /**
+   * Content corresponding to the schema defined by the id.
+   */
+  byte[] content;
+}
diff --git a/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarDataListener.aidl b/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarDataListener.aidl
new file mode 100644
index 0000000..48ab6f9
--- /dev/null
+++ b/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarDataListener.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package android.automotive.telemetry.internal;
+
+import android.automotive.telemetry.internal.CarDataInternal;
+
+/**
+ * Listener for {@code ICarTelemetryInternal#registerListener}.
+ */
+oneway interface ICarDataListener {
+  /**
+   * Called by ICarTelemetry when the data are available to be consumed. ICarTelemetry removes
+   * the delivered data when the callback succeeds.
+   *
+   * <p>If the collected data is too large, it will send only chunk of the data, and the callback
+   * will be fired again.
+   *
+   * @param dataList the pushed data.
+   */
+  void onCarDataReceived(in CarDataInternal[] dataList);
+}
diff --git a/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.aidl b/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.aidl
new file mode 100644
index 0000000..b8938ff
--- /dev/null
+++ b/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package android.automotive.telemetry.internal;
+
+import android.automotive.telemetry.internal.ICarDataListener;
+
+/**
+ * An internal API provided by cartelemetryd for receiving the collected data.
+ */
+interface ICarTelemetryInternal {
+  /**
+   * Sets a listener for CarData. If there are existing CarData in the buffer, the daemon will
+   * start pushing them to the listener. There can be only a single registered listener at a time.
+   *
+   * @param listener the only listener.
+   * @throws IllegalStateException if someone is already registered or the listener is dead.
+   */
+  void setListener(in ICarDataListener listener);
+
+  /**
+   * Clears the listener if exists. Silently ignores if there is no listener.
+   */
+  void clearListener();
+}
diff --git a/cpp/telemetry/android.automotive.telemetryd@1.0.rc b/cpp/telemetry/android.automotive.telemetryd@1.0.rc
new file mode 100644
index 0000000..1513fa8
--- /dev/null
+++ b/cpp/telemetry/android.automotive.telemetryd@1.0.rc
@@ -0,0 +1,9 @@
+service cartelemetryd_service /system/bin/android.automotive.telemetryd@1.0
+    class core
+    user system
+    group system
+    disabled  # starts below on early-init
+
+on early-init
+    # Start the service only after initializing the properties.
+    start cartelemetryd_service
diff --git a/cpp/telemetry/android.automotive.telemetryd@1.0.xml b/cpp/telemetry/android.automotive.telemetryd@1.0.xml
new file mode 100644
index 0000000..8156466
--- /dev/null
+++ b/cpp/telemetry/android.automotive.telemetryd@1.0.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 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.
+-->
+<!-- Required VINTF manifest for AIDL servers. -->
+<manifest version="1.0" type="framework">
+    <hal format="aidl">
+        <name>android.frameworks.automotive.telemetry</name>
+        <version>1</version>
+        <fqname>ICarTelemetry/default</fqname>
+    </hal>
+</manifest>
diff --git a/cpp/telemetry/products/telemetry.mk b/cpp/telemetry/products/telemetry.mk
new file mode 100644
index 0000000..634c9a9
--- /dev/null
+++ b/cpp/telemetry/products/telemetry.mk
@@ -0,0 +1,22 @@
+# 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.
+
+# cartelemetryd service
+PRODUCT_PACKAGES += android.automotive.telemetryd@1.0
+
+# Selinux public policies for cartelemetry
+PRODUCT_PUBLIC_SEPOLICY_DIRS += packages/services/Car/cpp/telemetry/sepolicy/public
+
+# Selinux private policies for cartelemetry
+PRODUCT_PRIVATE_SEPOLICY_DIRS += packages/services/Car/cpp/telemetry/sepolicy/private
diff --git a/cpp/telemetry/sampleclient/Android.bp b/cpp/telemetry/sampleclient/Android.bp
new file mode 100644
index 0000000..17fdee0
--- /dev/null
+++ b/cpp/telemetry/sampleclient/Android.bp
@@ -0,0 +1,37 @@
+// 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.
+
+// Sample client for ICarTelemetry service.
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+    name: "android.automotive.telemetryd-sampleclient",
+    srcs: [
+        "main.cpp",
+    ],
+    vendor: true,
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-unused-parameter",
+    ],
+    shared_libs: [
+        "android.frameworks.automotive.telemetry-V1-ndk_platform",
+        "libbase",
+        "libbinder_ndk",
+        "libutils",
+    ],
+}
diff --git a/cpp/telemetry/sampleclient/README.md b/cpp/telemetry/sampleclient/README.md
new file mode 100644
index 0000000..ebbaf16
--- /dev/null
+++ b/cpp/telemetry/sampleclient/README.md
@@ -0,0 +1,63 @@
+# ICarTelemetry Sample Client
+
+This is a sample vendor service that sends `CarData` to car telemetry service.
+
+## Running
+
+**1. Quick mode - under root**
+
+```
+m -j android.automotive.telemetryd-sampleclient
+
+adb remount  # make sure run "adb disable-verity" before remounting
+adb push $ANDROID_PRODUCT_OUT/vendor/bin/android.automotive.telemetryd-sampleclient /system/bin/
+
+adb shell /system/bin/android.automotive.telemetryd-sampleclient
+
+# Then check logcat and dumpsys to verify the results.
+```
+
+**2. Under vendor**
+
+To include it in the final image, add
+`PRODUCT_PACKAGES += android.automotive.telemetryd-sampleclient` to
+`//packages/services/Car/cpp/telemetry/products/telemetry.mk` (or other suitable mk file).
+
+```
+# this goes to products/telemetry.mk
+
+PRODUCT_PACKAGES += android.automotive.telemetryd-sampleclient
+```
+
+The sampleclient doesn't automatically start during boot, to start manually, run:
+`adb shell /vendor/bin/android.automotive.telemetryd-sampleclient`.
+
+If you want to test it by running `init`, add these SELinux rules:
+
+```
+# this goes to sepolicy/private/cartelemetryd.te
+
+type cartelemetryd_sample, domain;
+type cartelemetryd_sample_exec, vendor_file_type, exec_type, file_type;
+init_daemon_domain(cartelemetryd_sample)
+```
+
+```
+# this goes to sepolicy/private/file_contexts
+
+/vendor/bin/android\.automotive\.telemetryd-sampleclient  u:object_r:cartelemetryd_sample_exec:s0
+```
+
+And create an `.rc` file:
+
+```
+# File: cartelemetryd-sampleclient.rc
+# Don't forget to add `init_rc: ["cartelemetryd-sampleclient.rc"],` to the Android.bp
+
+service cartelemetryd_sample /vendor/bin/android.automotive.telemetryd-sampleclient
+    class hal
+    user system
+    group system
+    oneshot  # run once, otherwise init keeps restarting it
+    disabled  # do not start automatically
+```
diff --git a/cpp/telemetry/sampleclient/main.cpp b/cpp/telemetry/sampleclient/main.cpp
new file mode 100644
index 0000000..e45dc65
--- /dev/null
+++ b/cpp/telemetry/sampleclient/main.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "cartelemetryd_sample"
+
+#include <aidl/android/frameworks/automotive/telemetry/ICarTelemetry.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android/binder_manager.h>
+#include <utils/SystemClock.h>
+
+using ::aidl::android::frameworks::automotive::telemetry::CarData;
+using ::aidl::android::frameworks::automotive::telemetry::ICarTelemetry;
+using ::android::base::StringPrintf;
+
+int main(int argc, char* argv[]) {
+    const auto started_at_millis = android::elapsedRealtime();
+
+    // The name of the service is described in
+    // https://source.android.com/devices/architecture/aidl/aidl-hals#instance-names
+    const std::string instance = StringPrintf("%s/default", ICarTelemetry::descriptor);
+    LOG(INFO) << "Obtaining: " << instance;
+    std::shared_ptr<ICarTelemetry> service = ICarTelemetry::fromBinder(
+            ndk::SpAIBinder(AServiceManager_getService(instance.c_str())));
+    if (!service) {
+        LOG(ERROR) << "ICarTelemetry service not found, may be still initializing?";
+        return 1;
+    }
+
+    LOG(INFO) << "Building a CarData message, delta_since_start: "
+              << android::elapsedRealtime() - started_at_millis << " millis";
+
+    // Build a CarData message
+    // TODO(b/174608802): set a correct data ID and content
+    CarData msg;
+    msg.id = 101;
+    msg.content = {1, 0, 1, 0};
+
+    LOG(INFO) << "Sending the car data, delta_since_start: "
+              << android::elapsedRealtime() - started_at_millis << " millis";
+
+    // Send the data
+    ndk::ScopedAStatus writeStatus = service->write({msg});
+
+    if (!writeStatus.isOk()) {
+        LOG(WARNING) << "Failed to write to the service: " << writeStatus.getMessage();
+    }
+
+    // Note: On a device the delta_since_start was between 1ms to 4ms
+    //      (service side was not fully implemented yet during the test).
+    LOG(INFO) << "Finished, delta_since_start: " << android::elapsedRealtime() - started_at_millis
+              << " millis";
+
+    return 0;
+}
diff --git a/cpp/telemetry/sampleinternalclient/Android.bp b/cpp/telemetry/sampleinternalclient/Android.bp
new file mode 100644
index 0000000..d04ac09
--- /dev/null
+++ b/cpp/telemetry/sampleinternalclient/Android.bp
@@ -0,0 +1,36 @@
+// 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.
+
+// Sample client for ICarTelemetry service.
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+    name: "android.automotive.telemetryd-sampleinternalclient",
+    srcs: [
+        "main.cpp",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wno-unused-parameter",
+    ],
+    shared_libs: [
+        "android.automotive.telemetry.internal-ndk_platform",
+        "libbase",
+        "libbinder_ndk",
+        "libutils",
+    ],
+}
diff --git a/cpp/telemetry/sampleinternalclient/main.cpp b/cpp/telemetry/sampleinternalclient/main.cpp
new file mode 100644
index 0000000..06ca549
--- /dev/null
+++ b/cpp/telemetry/sampleinternalclient/main.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+// This is a sample reader client for ICarTelemetryInternal.
+// TODO(b/186017953): remove this client when CarTelemetryService is implemented.
+//
+// adb remount  # make sure run "adb disable-verity" before remounting
+// adb push $ANDROID_PRODUCT_OUT/system/bin/android.automotive.telemetryd-sampleinternalclient
+// /system/bin/
+//
+// adb shell /system/bin/android.automotive.telemetryd-sampleinternalclient
+
+#define LOG_TAG "cartelemetryd_sampleint"
+
+#include <aidl/android/automotive/telemetry/internal/BnCarDataListener.h>
+#include <aidl/android/automotive/telemetry/internal/CarDataInternal.h>
+#include <aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::aidl::android::automotive::telemetry::internal::BnCarDataListener;
+using ::aidl::android::automotive::telemetry::internal::CarDataInternal;
+using ::aidl::android::automotive::telemetry::internal::ICarDataListener;
+using ::aidl::android::automotive::telemetry::internal::ICarTelemetryInternal;
+using ::android::base::StringPrintf;
+
+class CarDataListenerImpl : public BnCarDataListener {
+public:
+    ::ndk::ScopedAStatus onCarDataReceived(
+            const std::vector<CarDataInternal>& in_dataList) override;
+};
+
+::ndk::ScopedAStatus CarDataListenerImpl::onCarDataReceived(
+        const std::vector<CarDataInternal>& dataList) {
+    LOG(INFO) << "Received data size = " << dataList.size();
+    for (const auto data : dataList) {
+        LOG(INFO) << "data.id = " << data.id;
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+int main(int argc, char* argv[]) {
+    // The name of the service is described in
+    // https://source.android.com/devices/architecture/aidl/aidl-hals#instance-names
+    const std::string instance = StringPrintf("%s/default", ICarTelemetryInternal::descriptor);
+    LOG(INFO) << "Obtaining: " << instance;
+    std::shared_ptr<ICarTelemetryInternal> service = ICarTelemetryInternal::fromBinder(
+            ndk::SpAIBinder(AServiceManager_getService(instance.c_str())));
+    if (!service) {
+        LOG(FATAL) << "ICarTelemetryInternal service not found, may be still initializing?";
+    }
+
+    LOG(INFO) << "Setting the listener";
+    std::shared_ptr<CarDataListenerImpl> listener = ndk::SharedRefBase::make<CarDataListenerImpl>();
+    auto status = service->setListener(listener);
+    if (!status.isOk()) {
+        LOG(FATAL) << "Failed to set the listener";
+    }
+
+    ::ABinderProcess_startThreadPool();
+    ::ABinderProcess_joinThreadPool();
+    return 1;  // not reachable
+}
diff --git a/cpp/telemetry/sepolicy/private/cartelemetryd.te b/cpp/telemetry/sepolicy/private/cartelemetryd.te
new file mode 100644
index 0000000..3baefb1
--- /dev/null
+++ b/cpp/telemetry/sepolicy/private/cartelemetryd.te
@@ -0,0 +1,9 @@
+### See //system/sepolicy/public/te_macros to learn about some SELinux macros.
+
+type cartelemetryd_exec, system_file_type, exec_type, file_type;
+
+binder_use(cartelemetryd)
+
+add_service(cartelemetryd, cartelemetryd_service)
+
+init_daemon_domain(cartelemetryd)
diff --git a/cpp/telemetry/sepolicy/private/file_contexts b/cpp/telemetry/sepolicy/private/file_contexts
new file mode 100644
index 0000000..0b0915d
--- /dev/null
+++ b/cpp/telemetry/sepolicy/private/file_contexts
@@ -0,0 +1 @@
+/system/bin/android\.automotive\.telemetryd@1\.0  u:object_r:cartelemetryd_exec:s0
diff --git a/cpp/telemetry/sepolicy/private/service_contexts b/cpp/telemetry/sepolicy/private/service_contexts
new file mode 100644
index 0000000..f26b5f8
--- /dev/null
+++ b/cpp/telemetry/sepolicy/private/service_contexts
@@ -0,0 +1,2 @@
+android.frameworks.automotive.telemetry.ICarTelemetry/default  u:object_r:cartelemetryd_service:s0
+android.automotive.telemetry.internal.ICarTelemetryInternal/default  u:object_r:cartelemetryd_service:s0
diff --git a/cpp/telemetry/sepolicy/public/cartelemetryd.te b/cpp/telemetry/sepolicy/public/cartelemetryd.te
new file mode 100644
index 0000000..fab4d58
--- /dev/null
+++ b/cpp/telemetry/sepolicy/public/cartelemetryd.te
@@ -0,0 +1 @@
+type cartelemetryd, domain, coredomain;
diff --git a/cpp/telemetry/sepolicy/public/service.te b/cpp/telemetry/sepolicy/public/service.te
new file mode 100644
index 0000000..f0beee8
--- /dev/null
+++ b/cpp/telemetry/sepolicy/public/service.te
@@ -0,0 +1 @@
+type cartelemetryd_service, service_manager_type;
diff --git a/cpp/telemetry/src/BufferedCarData.h b/cpp/telemetry/src/BufferedCarData.h
new file mode 100644
index 0000000..0c6ff4d
--- /dev/null
+++ b/cpp/telemetry/src/BufferedCarData.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifndef CPP_TELEMETRY_SRC_BUFFEREDCARDATA_H_
+#define CPP_TELEMETRY_SRC_BUFFEREDCARDATA_H_
+
+#include <stdint.h>
+
+#include <tuple>
+#include <vector>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+// Internally stored `CarData` with some extras.
+struct BufferedCarData {
+    BufferedCarData(BufferedCarData&& other) = default;
+    BufferedCarData(const BufferedCarData&) = default;
+    BufferedCarData& operator=(BufferedCarData&& other) = default;
+    BufferedCarData& operator=(const BufferedCarData&) = default;
+
+    inline bool operator==(const BufferedCarData& rhs) const {
+        return std::tie(mId, mContent, mPublisherUid) ==
+                std::tie(rhs.mId, rhs.mContent, rhs.mPublisherUid);
+    }
+
+    // Returns the size of the stored data. Note that it's not the exact size of the struct.
+    int32_t contentSizeInBytes() const { return mContent.size(); }
+
+    const int32_t mId;
+    const std::vector<uint8_t> mContent;
+
+    // The uid of the logging client.
+    const uid_t mPublisherUid;
+};
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_TELEMETRY_SRC_BUFFEREDCARDATA_H_
diff --git a/cpp/telemetry/src/CarTelemetryImpl.cpp b/cpp/telemetry/src/CarTelemetryImpl.cpp
new file mode 100644
index 0000000..34a4e60
--- /dev/null
+++ b/cpp/telemetry/src/CarTelemetryImpl.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#include "CarTelemetryImpl.h"
+
+#include "BufferedCarData.h"
+
+#include <aidl/android/frameworks/automotive/telemetry/CarData.h>
+#include <android/binder_ibinder.h>
+
+#include <stdio.h>
+
+#include <memory>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+using ::aidl::android::frameworks::automotive::telemetry::CarData;
+
+CarTelemetryImpl::CarTelemetryImpl(RingBuffer* buffer) : mRingBuffer(buffer) {}
+
+// TODO(b/174608802): Add 10kb size check for the `dataList`, see the AIDL for the limits
+ndk::ScopedAStatus CarTelemetryImpl::write(const std::vector<CarData>& dataList) {
+    uid_t publisherUid = ::AIBinder_getCallingUid();
+    for (auto&& data : dataList) {
+        mRingBuffer->push({.mId = data.id,
+                           .mContent = std::move(data.content),
+                           .mPublisherUid = publisherUid});
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/src/CarTelemetryImpl.h b/cpp/telemetry/src/CarTelemetryImpl.h
new file mode 100644
index 0000000..a3bb6c1
--- /dev/null
+++ b/cpp/telemetry/src/CarTelemetryImpl.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifndef CPP_TELEMETRY_SRC_CARTELEMETRYIMPL_H_
+#define CPP_TELEMETRY_SRC_CARTELEMETRYIMPL_H_
+
+#include "RingBuffer.h"
+
+#include <aidl/android/frameworks/automotive/telemetry/BnCarTelemetry.h>
+#include <aidl/android/frameworks/automotive/telemetry/CarData.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+#include <vector>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+// Implementation of android.frameworks.automotive.telemetry.ICarTelemetry.
+class CarTelemetryImpl : public aidl::android::frameworks::automotive::telemetry::BnCarTelemetry {
+public:
+    // Doesn't own `buffer`.
+    explicit CarTelemetryImpl(RingBuffer* buffer);
+
+    ndk::ScopedAStatus write(
+            const std::vector<aidl::android::frameworks::automotive::telemetry::CarData>& dataList)
+            override;
+
+private:
+    RingBuffer* mRingBuffer;  // not owned
+};
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_TELEMETRY_SRC_CARTELEMETRYIMPL_H_
diff --git a/cpp/telemetry/src/CarTelemetryInternalImpl.cpp b/cpp/telemetry/src/CarTelemetryInternalImpl.cpp
new file mode 100644
index 0000000..7a3b141
--- /dev/null
+++ b/cpp/telemetry/src/CarTelemetryInternalImpl.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#include "CarTelemetryInternalImpl.h"
+
+#include <aidl/android/automotive/telemetry/internal/BnCarDataListener.h>
+#include <aidl/android/automotive/telemetry/internal/CarDataInternal.h>
+#include <aidl/android/automotive/telemetry/internal/ICarDataListener.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+using ::aidl::android::automotive::telemetry::internal::BnCarDataListener;
+using ::aidl::android::automotive::telemetry::internal::CarDataInternal;
+using ::aidl::android::automotive::telemetry::internal::ICarDataListener;
+using ::android::base::StringPrintf;
+
+CarTelemetryInternalImpl::CarTelemetryInternalImpl(RingBuffer* buffer) :
+      mRingBuffer(buffer),
+      mBinderDeathRecipient(
+              ::AIBinder_DeathRecipient_new(CarTelemetryInternalImpl::listenerBinderDied)) {}
+
+ndk::ScopedAStatus CarTelemetryInternalImpl::setListener(
+        const std::shared_ptr<ICarDataListener>& listener) {
+    const std::scoped_lock<std::mutex> lock(mMutex);
+
+    if (mCarDataListener != nullptr) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(::EX_ILLEGAL_STATE,
+                                                                "ICarDataListener is already set.");
+    }
+
+    // If passed a local binder, AIBinder_linkToDeath will do nothing and return
+    // STATUS_INVALID_OPERATION. We ignore this case because we only use local binders in tests
+    // where this is not an error.
+    if (listener->isRemote()) {
+        auto status = ndk::ScopedAStatus::fromStatus(
+                ::AIBinder_linkToDeath(listener->asBinder().get(), mBinderDeathRecipient.get(),
+                                       this));
+        if (!status.isOk()) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(::EX_ILLEGAL_STATE,
+                                                                    status.getMessage());
+        }
+    }
+
+    mCarDataListener = listener;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus CarTelemetryInternalImpl::clearListener() {
+    const std::scoped_lock<std::mutex> lock(mMutex);
+    if (mCarDataListener == nullptr) {
+        LOG(INFO) << __func__ << ": No ICarDataListener, ignoring the call";
+        return ndk::ScopedAStatus::ok();
+    }
+    auto status = ndk::ScopedAStatus::fromStatus(
+            ::AIBinder_unlinkToDeath(mCarDataListener->asBinder().get(),
+                                     mBinderDeathRecipient.get(), this));
+    if (!status.isOk()) {
+        LOG(WARNING) << __func__
+                     << ": unlinkToDeath failed, continuing anyway: " << status.getMessage();
+    }
+    mCarDataListener = nullptr;
+    return ndk::ScopedAStatus::ok();
+}
+
+binder_status_t CarTelemetryInternalImpl::dump(int fd, const char** args, uint32_t numArgs) {
+    dprintf(fd, "ICarTelemetryInternal:\n");
+    mRingBuffer->dump(fd);
+    return ::STATUS_OK;
+}
+
+// Removes the listener if its binder dies.
+void CarTelemetryInternalImpl::listenerBinderDiedImpl() {
+    LOG(WARNING) << "A ICarDataListener died, removing the listener.";
+    const std::scoped_lock<std::mutex> lock(mMutex);
+    mCarDataListener = nullptr;
+}
+
+void CarTelemetryInternalImpl::listenerBinderDied(void* cookie) {
+    auto thiz = static_cast<CarTelemetryInternalImpl*>(cookie);
+    thiz->listenerBinderDiedImpl();
+}
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/src/CarTelemetryInternalImpl.h b/cpp/telemetry/src/CarTelemetryInternalImpl.h
new file mode 100644
index 0000000..12ad5cd
--- /dev/null
+++ b/cpp/telemetry/src/CarTelemetryInternalImpl.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#ifndef CPP_TELEMETRY_SRC_CARTELEMETRYINTERNALIMPL_H_
+#define CPP_TELEMETRY_SRC_CARTELEMETRYINTERNALIMPL_H_
+
+#include "RingBuffer.h"
+
+#include <aidl/android/automotive/telemetry/internal/BnCarTelemetryInternal.h>
+#include <aidl/android/automotive/telemetry/internal/CarDataInternal.h>
+#include <aidl/android/automotive/telemetry/internal/ICarDataListener.h>
+#include <android/binder_status.h>
+#include <utils/Mutex.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+// Implementation of android.automotive.telemetry.ICarTelemetryInternal.
+class CarTelemetryInternalImpl :
+      public aidl::android::automotive::telemetry::internal::BnCarTelemetryInternal {
+public:
+    // Doesn't own `buffer`.
+    explicit CarTelemetryInternalImpl(RingBuffer* buffer);
+
+    ndk::ScopedAStatus setListener(
+            const std::shared_ptr<aidl::android::automotive::telemetry::internal::ICarDataListener>&
+                    listener) override;
+
+    ndk::ScopedAStatus clearListener() override;
+
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+private:
+    // Death recipient callback that is called when ICarDataListener dies.
+    // The cookie is a pointer to a CarTelemetryInternalImpl object.
+    static void listenerBinderDied(void* cookie);
+
+    void listenerBinderDiedImpl();
+
+    RingBuffer* mRingBuffer;  // not owned
+    ndk::ScopedAIBinder_DeathRecipient mBinderDeathRecipient;
+    std::mutex mMutex;  // a mutex for the whole instance
+
+    std::shared_ptr<aidl::android::automotive::telemetry::internal::ICarDataListener>
+            mCarDataListener GUARDED_BY(mMutex);
+};
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_TELEMETRY_SRC_CARTELEMETRYINTERNALIMPL_H_
diff --git a/cpp/telemetry/src/RingBuffer.cpp b/cpp/telemetry/src/RingBuffer.cpp
new file mode 100644
index 0000000..36de3f8
--- /dev/null
+++ b/cpp/telemetry/src/RingBuffer.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#include "RingBuffer.h"
+
+#include <android-base/logging.h>
+
+#include <inttypes.h>  // for PRIu64 and friends
+
+#include <memory>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+RingBuffer::RingBuffer(int32_t limit) : mSizeLimit(limit) {}
+
+void RingBuffer::push(BufferedCarData&& data) {
+    const std::scoped_lock<std::mutex> lock(mMutex);
+    mList.push_back(std::move(data));
+    while (mList.size() > mSizeLimit) {
+        mList.pop_front();
+        mTotalDroppedDataCount += 1;
+    }
+}
+
+BufferedCarData RingBuffer::popFront() {
+    const std::scoped_lock<std::mutex> lock(mMutex);
+    auto result = std::move(mList.front());
+    mList.pop_front();
+    return result;
+}
+
+void RingBuffer::dump(int fd) const {
+    const std::scoped_lock<std::mutex> lock(mMutex);
+    dprintf(fd, "RingBuffer:\n");
+    dprintf(fd, "  mSizeLimit=%d\n", mSizeLimit);
+    dprintf(fd, "  mList.size=%zu\n", mList.size());
+    dprintf(fd, "  mTotalDroppedDataCount=%" PRIu64 "\n", mTotalDroppedDataCount);
+}
+
+int32_t RingBuffer::size() const {
+    const std::scoped_lock<std::mutex> lock(mMutex);
+    return mList.size();
+}
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/src/RingBuffer.h b/cpp/telemetry/src/RingBuffer.h
new file mode 100644
index 0000000..07ce709
--- /dev/null
+++ b/cpp/telemetry/src/RingBuffer.h
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#ifndef CPP_TELEMETRY_SRC_RINGBUFFER_H_
+#define CPP_TELEMETRY_SRC_RINGBUFFER_H_
+
+#include "BufferedCarData.h"
+
+#include <list>
+#include <mutex>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+// A ring buffer that holds BufferedCarData. It drops old data if it's full.
+// Thread-safe.
+class RingBuffer {
+public:
+    // RingBuffer limits the number of elements in the buffer to the given param `sizeLimit`.
+    // Doesn't pre-allocate the memory.
+    explicit RingBuffer(int32_t sizeLimit);
+
+    // Not copyable or movable
+    RingBuffer(const RingBuffer&) = delete;
+    RingBuffer& operator=(const RingBuffer&) = delete;
+    RingBuffer(RingBuffer&&) = delete;
+    RingBuffer& operator=(RingBuffer&&) = delete;
+
+    // Pushes the data to the buffer. If the buffer is full, it removes the oldest data.
+    // Supports moving the data to the RingBuffer.
+    void push(BufferedCarData&& data);
+
+    // Returns the oldest element from the ring buffer and removes it from the buffer.
+    BufferedCarData popFront();
+
+    // Dumps the current state for dumpsys.
+    void dump(int fd) const;
+
+    // Returns the number of elements in the buffer.
+    int32_t size() const;
+
+private:
+    mutable std::mutex mMutex;  // a mutex for the whole instance
+
+    const int32_t mSizeLimit;
+
+    // TODO(b/174608802): Improve dropped CarData handling, see ag/13818937 for details.
+    int64_t mTotalDroppedDataCount;
+
+    // Linked list that holds all the data and allows deleting old data when the buffer is full.
+    std::list<BufferedCarData> mList;
+};
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_TELEMETRY_SRC_RINGBUFFER_H_
diff --git a/cpp/telemetry/src/TelemetryServer.cpp b/cpp/telemetry/src/TelemetryServer.cpp
new file mode 100644
index 0000000..54cd3c4
--- /dev/null
+++ b/cpp/telemetry/src/TelemetryServer.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#include "TelemetryServer.h"
+
+#include "CarTelemetryImpl.h"
+#include "RingBuffer.h"
+
+#include <android-base/chrono_utils.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <inttypes.h>  // for PRIu64 and friends
+
+#include <memory>
+#include <thread>  // NOLINT(build/c++11)
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+using ::android::automotive::telemetry::RingBuffer;
+
+constexpr const char kCarTelemetryServiceName[] =
+        "android.frameworks.automotive.telemetry.ICarTelemetry/default";
+constexpr const char kCarTelemetryInternalServiceName[] =
+        "android.automotive.telemetry.internal.ICarTelemetryInternal/default";
+
+// TODO(b/183444070): make it configurable using sysprop
+// CarData count limit in the RingBuffer. In worst case it will use kMaxBufferSize * 10Kb memory,
+// which is ~ 1MB.
+const int kMaxBufferSize = 100;
+
+TelemetryServer::TelemetryServer() : mRingBuffer(kMaxBufferSize) {}
+
+void TelemetryServer::registerServices() {
+    std::shared_ptr<CarTelemetryImpl> telemetry =
+            ndk::SharedRefBase::make<CarTelemetryImpl>(&mRingBuffer);
+    std::shared_ptr<CarTelemetryInternalImpl> telemetryInternal =
+            ndk::SharedRefBase::make<CarTelemetryInternalImpl>(&mRingBuffer);
+
+    // Wait for the service manager before starting ICarTelemetry service.
+    while (android::base::GetProperty("init.svc.servicemanager", "") != "running") {
+        // Poll frequent enough so the writer clients can connect to the service during boot.
+        std::this_thread::sleep_for(250ms);
+    }
+
+    LOG(VERBOSE) << "Registering " << kCarTelemetryServiceName;
+    binder_exception_t exception =
+            ::AServiceManager_addService(telemetry->asBinder().get(), kCarTelemetryServiceName);
+    if (exception != ::EX_NONE) {
+        LOG(FATAL) << "Unable to register " << kCarTelemetryServiceName
+                   << ", exception=" << exception;
+    }
+
+    LOG(VERBOSE) << "Registering " << kCarTelemetryInternalServiceName;
+    exception = ::AServiceManager_addService(telemetryInternal->asBinder().get(),
+                                             kCarTelemetryInternalServiceName);
+    if (exception != ::EX_NONE) {
+        LOG(FATAL) << "Unable to register " << kCarTelemetryInternalServiceName
+                   << ", exception=" << exception;
+    }
+}
+
+void TelemetryServer::startAndJoinThreadPool() {
+    ::ABinderProcess_startThreadPool();  // Starts the default 15 binder threads.
+    ::ABinderProcess_joinThreadPool();
+}
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/src/TelemetryServer.h b/cpp/telemetry/src/TelemetryServer.h
new file mode 100644
index 0000000..0b400a1
--- /dev/null
+++ b/cpp/telemetry/src/TelemetryServer.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#ifndef CPP_TELEMETRY_SRC_TELEMETRYSERVER_H_
+#define CPP_TELEMETRY_SRC_TELEMETRYSERVER_H_
+
+#include "CarTelemetryImpl.h"
+#include "CarTelemetryInternalImpl.h"
+
+#include <utils/Errors.h>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+class TelemetryServer {
+public:
+    TelemetryServer();
+
+    // Registers all the implemented AIDL services. Waits until `servicemanager` is available.
+    // Aborts the process if fails.
+    void registerServices();
+
+    // Blocks the thread.
+    void startAndJoinThreadPool();
+
+private:
+    RingBuffer mRingBuffer;
+};
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_TELEMETRY_SRC_TELEMETRYSERVER_H_
diff --git a/cpp/telemetry/src/main.cpp b/cpp/telemetry/src/main.cpp
new file mode 100644
index 0000000..1bd0dde
--- /dev/null
+++ b/cpp/telemetry/src/main.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#include "TelemetryServer.h"
+
+#include <android-base/logging.h>
+
+using ::android::automotive::telemetry::TelemetryServer;
+
+// TODO(b/174608802): handle SIGQUIT/SIGTERM
+
+int main(void) {
+    LOG(INFO) << "Starting cartelemetryd";
+
+    TelemetryServer server;
+
+    // Register AIDL services. Aborts the server if fails.
+    server.registerServices();
+
+    LOG(VERBOSE) << "Service is created, joining the threadpool";
+    server.startAndJoinThreadPool();
+    return 1;  // never reaches
+}
diff --git a/cpp/telemetry/tests/CarTelemetryImplTest.cpp b/cpp/telemetry/tests/CarTelemetryImplTest.cpp
new file mode 100644
index 0000000..0286477
--- /dev/null
+++ b/cpp/telemetry/tests/CarTelemetryImplTest.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright 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.
+ */
+
+#include "CarTelemetryImpl.h"
+#include "RingBuffer.h"
+
+#include <aidl/android/frameworks/automotive/telemetry/CarData.h>
+#include <aidl/android/frameworks/automotive/telemetry/ICarTelemetry.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <unistd.h>
+
+#include <memory>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+using ::aidl::android::frameworks::automotive::telemetry::CarData;
+using ::aidl::android::frameworks::automotive::telemetry::ICarTelemetry;
+using ::testing::ContainerEq;
+
+const size_t kMaxBufferSize = 5;
+
+CarData buildCarData(int id, const std::vector<uint8_t>& content) {
+    CarData msg;
+    msg.id = id;
+    msg.content = content;
+    return msg;
+}
+
+BufferedCarData buildBufferedCarData(const CarData& data, uid_t publisherUid) {
+    return {.mId = data.id, .mContent = std::move(data.content), .mPublisherUid = publisherUid};
+}
+
+class CarTelemetryImplTest : public ::testing::Test {
+protected:
+    CarTelemetryImplTest() :
+          mBuffer(RingBuffer(kMaxBufferSize)),
+          mTelemetry(ndk::SharedRefBase::make<CarTelemetryImpl>(&mBuffer)) {}
+
+    RingBuffer mBuffer;
+    std::shared_ptr<ICarTelemetry> mTelemetry;
+};
+
+TEST_F(CarTelemetryImplTest, WriteReturnsOkStatus) {
+    CarData msg = buildCarData(101, {1, 0, 1, 0});
+
+    auto status = mTelemetry->write({msg});
+
+    EXPECT_TRUE(status.isOk()) << status.getMessage();
+}
+
+TEST_F(CarTelemetryImplTest, WriteAddsCarDataToRingBuffer) {
+    CarData msg = buildCarData(101, {1, 0, 1, 0});
+
+    mTelemetry->write({msg});
+
+    EXPECT_EQ(mBuffer.popFront(), buildBufferedCarData(msg, getuid()));
+}
+
+TEST_F(CarTelemetryImplTest, WriteBuffersOnlyLimitedAmount) {
+    RingBuffer buffer(/* sizeLimit= */ 3);
+    auto telemetry = ndk::SharedRefBase::make<CarTelemetryImpl>(&buffer);
+
+    CarData msg101_2 = buildCarData(101, {1, 0});
+    CarData msg101_4 = buildCarData(101, {1, 0, 1, 0});
+    CarData msg201_3 = buildCarData(201, {3, 3, 3});
+
+    // Inserting 5 elements
+    telemetry->write({msg101_2, msg101_4, msg101_4, msg201_3});
+    telemetry->write({msg201_3});
+
+    EXPECT_EQ(buffer.size(), 3);
+    std::vector<BufferedCarData> result = {buffer.popFront(), buffer.popFront(), buffer.popFront()};
+    std::vector<BufferedCarData> expected = {buildBufferedCarData(msg101_4, getuid()),
+                                             buildBufferedCarData(msg201_3, getuid()),
+                                             buildBufferedCarData(msg201_3, getuid())};
+    EXPECT_THAT(result, ContainerEq(expected));
+    EXPECT_EQ(buffer.size(), 0);
+}
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/tests/CarTelemetryInternalImplTest.cpp b/cpp/telemetry/tests/CarTelemetryInternalImplTest.cpp
new file mode 100644
index 0000000..22838cd
--- /dev/null
+++ b/cpp/telemetry/tests/CarTelemetryInternalImplTest.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright 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.
+ */
+
+#include "CarTelemetryInternalImpl.h"
+#include "RingBuffer.h"
+
+#include <aidl/android/automotive/telemetry/internal/BnCarDataListener.h>
+#include <aidl/android/automotive/telemetry/internal/CarDataInternal.h>
+#include <aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <unistd.h>
+
+#include <memory>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+using ::aidl::android::automotive::telemetry::internal::BnCarDataListener;
+using ::aidl::android::automotive::telemetry::internal::CarDataInternal;
+using ::aidl::android::automotive::telemetry::internal::ICarTelemetryInternal;
+using ::ndk::ScopedAStatus;
+
+const size_t kMaxBufferSize = 5;
+
+class MockCarDataListener : public BnCarDataListener {
+public:
+    MOCK_METHOD(ScopedAStatus, onCarDataReceived, (const std::vector<CarDataInternal>& dataList),
+                (override));
+};
+
+// The main test class.
+class CarTelemetryInternalImplTest : public ::testing::Test {
+protected:
+    CarTelemetryInternalImplTest() :
+          mBuffer(RingBuffer(kMaxBufferSize)),
+          mTelemetryInternal(ndk::SharedRefBase::make<CarTelemetryInternalImpl>(&mBuffer)),
+          mMockCarDataListener(ndk::SharedRefBase::make<MockCarDataListener>()) {}
+
+    RingBuffer mBuffer;
+    std::shared_ptr<ICarTelemetryInternal> mTelemetryInternal;
+    std::shared_ptr<MockCarDataListener> mMockCarDataListener;
+};
+
+TEST_F(CarTelemetryInternalImplTest, SetListenerReturnsOk) {
+    auto status = mTelemetryInternal->setListener(mMockCarDataListener);
+
+    EXPECT_TRUE(status.isOk()) << status.getMessage();
+}
+
+TEST_F(CarTelemetryInternalImplTest, SetListenerFailsWhenAlreadySubscribed) {
+    mTelemetryInternal->setListener(mMockCarDataListener);
+
+    auto status = mTelemetryInternal->setListener(ndk::SharedRefBase::make<MockCarDataListener>());
+
+    EXPECT_EQ(status.getExceptionCode(), ::EX_ILLEGAL_STATE) << status.getMessage();
+}
+
+TEST_F(CarTelemetryInternalImplTest, ClearListenerWorks) {
+    mTelemetryInternal->setListener(mMockCarDataListener);
+
+    mTelemetryInternal->clearListener();
+    auto status = mTelemetryInternal->setListener(mMockCarDataListener);
+
+    EXPECT_TRUE(status.isOk()) << status.getMessage();
+}
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/tests/RingBufferTest.cpp b/cpp/telemetry/tests/RingBufferTest.cpp
new file mode 100644
index 0000000..c5b5bc7
--- /dev/null
+++ b/cpp/telemetry/tests/RingBufferTest.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 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.
+ */
+
+#include "RingBuffer.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <memory>
+
+// NOTE: many of RingBuffer's behaviors are tested as part of CarTelemetryImpl.
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+
+using testing::ContainerEq;
+
+BufferedCarData buildBufferedCarData(int32_t id, const std::vector<uint8_t>& content) {
+    return {.mId = id, .mContent = content, .mPublisherUid = 0};
+}
+
+TEST(RingBufferTest, PopFrontReturnsCorrectResults) {
+    RingBuffer buffer(/* sizeLimit= */ 10);
+    buffer.push(buildBufferedCarData(101, {7}));
+    buffer.push(buildBufferedCarData(102, {7}));
+
+    BufferedCarData result = buffer.popFront();
+
+    EXPECT_EQ(result, buildBufferedCarData(101, {7}));
+}
+
+TEST(RingBufferTest, PopFrontRemovesFromBuffer) {
+    RingBuffer buffer(/* sizeLimit= */ 10);
+    buffer.push(buildBufferedCarData(101, {7}));
+    buffer.push(buildBufferedCarData(102, {7, 8}));
+
+    buffer.popFront();
+
+    EXPECT_EQ(buffer.size(), 1);  // only ID=102 left
+}
+
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdog.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdog.aidl
index 7345448..57d82ca 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdog.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdog.aidl
@@ -19,8 +19,8 @@
 import android.automotive.watchdog.internal.ComponentType;
 import android.automotive.watchdog.internal.ICarWatchdogMonitor;
 import android.automotive.watchdog.internal.ICarWatchdogServiceForSystem;
-import android.automotive.watchdog.internal.IoOveruseConfiguration;
 import android.automotive.watchdog.internal.PackageResourceOveruseAction;
+import android.automotive.watchdog.internal.ResourceOveruseConfiguration;
 import android.automotive.watchdog.internal.StateType;
 
 /**
@@ -106,15 +106,20 @@
   void notifySystemStateChange(in StateType type, in int arg1, in int arg2);
 
   /**
-   * CarWatchdogService uses this API to forward the I/O overuse configuration update received from
-   * the system or OEM applications.
+   * Update the given resource overuse configurations.
    * The caller should have system UID. Otherwise, returns security exception binder error.
    *
-   * @param type                 Component type for which the I/O overuse configuration update was
-   *                             received.
-   * @param config               I/O overuse configuration.
+   * @param configs              List of resource overuse configurations.
    */
-  void updateIoOveruseConfiguration(in ComponentType type, in IoOveruseConfiguration config);
+  void updateResourceOveruseConfigurations(in List<ResourceOveruseConfiguration> configs);
+
+  /**
+   * Return the latest list of resource overuse configuration per component.
+   * The caller should have system UID. Otherwise, returns security exception binder error.
+   *
+   * @return configs             List of resource overuse configurations.
+   */
+  List<ResourceOveruseConfiguration> getResourceOveruseConfigurations();
 
   /**
    * CarWatchdogService notifies the native service with the actions taken on the resource overusing
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl
index 9aa234f..ef68dbc 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl
@@ -52,7 +52,8 @@
    * @param uids                        List of UIDs to resolve the package infos.
    * @param vendorPackagePrefixes       List of vendor package prefixes.
    */
-  List<PackageInfo> getPackageInfosForUids(in int[] uids, in List<String> vendorPackagePrefixes);
+  List<PackageInfo> getPackageInfosForUids(
+            in int[] uids, in @utf8InCpp List<String> vendorPackagePrefixes);
 
   /**
    * Pushes the latest I/O overuse stats to the watchdog server.
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/IoOveruseConfiguration.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/IoOveruseConfiguration.aidl
index c2f0aec..7522a22 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/IoOveruseConfiguration.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/IoOveruseConfiguration.aidl
@@ -45,21 +45,8 @@
   List<PerStateIoOveruseThreshold> categorySpecificThresholds;
 
   /**
-   * List of only non-critical system and vendor packages that are safe to kill on disk I/O
-   * overuse. All third-party packages are considered safe to kill.
-   */
-  List<String> safeToKillPackages;
-
-  /**
    * Array of system-wide I/O overuse thresholds that triggers the system-wide disk I/O overuse
    * alert. This must be defined only by the system component.
    */
   List<IoOveruseAlertThreshold> systemWideThresholds;
-
-  /**
-   * Defines the list of vendor package prefixes. Any pre-installed package name starting with one
-   * of these prefixes will be identified as a vendor package in addition to packages under the
-   * vendor partition. This must be defined only by the vendor component.
-   */
-  List<String> vendorPackagePrefixes;
 }
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageIdentifier.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageIdentifier.aidl
index fa6e36b..c0dd86e 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageIdentifier.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageIdentifier.aidl
@@ -23,7 +23,7 @@
   /**
    * Name of the package.
    */
-  String name;
+  @utf8InCpp String name;
 
   /**
    * UID of the package.
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageInfo.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageInfo.aidl
index bd3dd1a..2deb5f3 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageInfo.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageInfo.aidl
@@ -38,7 +38,7 @@
   /**
    * List of packages owned by the package. This list is empty when the UID is not a shared UID.
    */
-  List<String> sharedUidPackages;
+  @utf8InCpp List<String> sharedUidPackages;
 
   /**
    * Component type of the package and the owned packages.
@@ -48,5 +48,5 @@
   /**
    * Application category type of the package and the owned packages.
    */
-  ApplicationCategoryType appCategoryType;
+  ApplicationCategoryType appCategoryType = ApplicationCategoryType.OTHERS;
 }
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageMetadata.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageMetadata.aidl
new file mode 100644
index 0000000..46e6693
--- /dev/null
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PackageMetadata.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package android.automotive.watchdog.internal;
+
+import android.automotive.watchdog.internal.ApplicationCategoryType;
+
+/**
+ * Structure that describes the package metadata.
+ */
+parcelable PackageMetadata {
+  /**
+   * Name of the package.
+   */
+  @utf8InCpp String packageName;
+
+  /**
+   * Application category type of the package.
+   *
+   * This must be defined only by the system and vendor component configurations.
+   */
+  ApplicationCategoryType appCategoryType = ApplicationCategoryType.OTHERS;
+}
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/PerStateIoOveruseThreshold.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PerStateIoOveruseThreshold.aidl
index 00a3c93..65f50ce 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/PerStateIoOveruseThreshold.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/PerStateIoOveruseThreshold.aidl
@@ -29,7 +29,7 @@
    * 2. package name for package specific thresholds.
    * 3. string equivalent of ApplicationCategoryType enum for category specific thresholds.
    */
-  String name;
+  @utf8InCpp String name;
 
   /**
    * Defines the I/O overuse thresholds for a package. The thresholds are defined in terms of
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ResourceOveruseConfiguration.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ResourceOveruseConfiguration.aidl
new file mode 100644
index 0000000..26ae106
--- /dev/null
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ResourceOveruseConfiguration.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package android.automotive.watchdog.internal;
+
+import android.automotive.watchdog.internal.ComponentType;
+import android.automotive.watchdog.internal.PackageMetadata;
+import android.automotive.watchdog.internal.ResourceSpecificConfiguration;
+
+/**
+ * Structure that describes the resource overuse configuration for a component.
+ */
+parcelable ResourceOveruseConfiguration {
+  /**
+   * Type of the component.
+   */
+  ComponentType componentType;
+
+  /**
+   * List of only non-critical system and vendor packages that are safe to kill on disk I/O
+   * overuse. All third-party packages are considered safe to kill.
+   */
+  @utf8InCpp List<String> safeToKillPackages;
+
+  /**
+   * Defines the list of vendor package prefixes. Any pre-installed package name starting with one
+   * of these prefixes will be identified as a vendor package in addition to packages under the
+   * vendor partition. This must be defined only by the vendor component.
+   */
+  @utf8InCpp List<String> vendorPackagePrefixes;
+
+  /**
+   * Defines the package metadata.
+   */
+  List<PackageMetadata> packageMetadata;
+
+  /**
+   * Defines resource specific overuse configurations for the current component.
+   */
+  List<ResourceSpecificConfiguration> resourceSpecificConfigurations;
+}
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ResourceSpecificConfiguration.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ResourceSpecificConfiguration.aidl
new file mode 100644
index 0000000..34a8c92
--- /dev/null
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ResourceSpecificConfiguration.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.automotive.watchdog.internal;
+
+import android.automotive.watchdog.internal.IoOveruseConfiguration;
+
+/**
+ * Overuse configuration interface for specific resource types.
+ */
+union ResourceSpecificConfiguration {
+  /**
+   * I/O overuse configuration.
+   */
+  IoOveruseConfiguration ioOveruseConfiguration;
+  // Overuse configuration for other resource types may be added in the future.
+}
diff --git a/cpp/watchdog/car-watchdog-lib/src/android/car/watchdoglib/CarWatchdogDaemonHelper.java b/cpp/watchdog/car-watchdog-lib/src/android/car/watchdoglib/CarWatchdogDaemonHelper.java
index 0f6cce1..57d18b0 100644
--- a/cpp/watchdog/car-watchdog-lib/src/android/car/watchdoglib/CarWatchdogDaemonHelper.java
+++ b/cpp/watchdog/car-watchdog-lib/src/android/car/watchdoglib/CarWatchdogDaemonHelper.java
@@ -24,6 +24,7 @@
 import android.automotive.watchdog.internal.ICarWatchdogMonitor;
 import android.automotive.watchdog.internal.ICarWatchdogServiceForSystem;
 import android.automotive.watchdog.internal.PackageResourceOveruseAction;
+import android.automotive.watchdog.internal.ResourceOveruseConfiguration;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -34,6 +35,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -46,9 +48,11 @@
 public final class CarWatchdogDaemonHelper {
 
     private static final String TAG = CarWatchdogDaemonHelper.class.getSimpleName();
-    // Carwatchdog daemon polls for the service manager status once every 250 milliseconds.
-    // CAR_WATCHDOG_DAEMON_BIND_RETRY_INTERVAL_MS value should be at least twice the poll interval
-    // used by the daemon.
+    /*
+     * Car watchdog daemon polls for the service manager status once every 250 milliseconds.
+     * CAR_WATCHDOG_DAEMON_BIND_RETRY_INTERVAL_MS value should be at least twice the poll interval
+     * used by the daemon.
+     */
     private static final long CAR_WATCHDOG_DAEMON_BIND_RETRY_INTERVAL_MS = 500;
     private static final long CAR_WATCHDOG_DAEMON_FIND_MARGINAL_TIME_MS = 300;
     private static final int CAR_WATCHDOG_DAEMON_BIND_MAX_RETRY = 3;
@@ -250,10 +254,37 @@
     }
 
     /**
+     * Sets the given resource overuse configurations.
+     *
+     * @param configurations Resource overuse configuration per component type.
+     * @throws IllegalArgumentException If the configurations are invalid.
+     * @throws RemoteException
+     */
+    public void updateResourceOveruseConfigurations(
+            List<ResourceOveruseConfiguration> configurations) throws RemoteException {
+        invokeDaemonMethod((daemon) -> daemon.updateResourceOveruseConfigurations(configurations));
+    }
+
+    /**
+     * Returns the available resource overuse configurations.
+     *
+     * @throws RemoteException
+     */
+    public List<ResourceOveruseConfiguration> getResourceOveruseConfigurations()
+            throws RemoteException {
+        List<ResourceOveruseConfiguration> configurations = new ArrayList<>();
+        invokeDaemonMethod((daemon) -> {
+            configurations.addAll(daemon.getResourceOveruseConfigurations());
+        });
+        return configurations;
+    }
+
+    /**
      * Notifies car watchdog daemon with the actions taken on resource overuse.
      *
      * @param actions List of actions taken on resource overuse. One action taken per resource
      *                overusing user package.
+     * @throws RemoteException
      */
     public void actionTakenOnResourceOveruse(List<PackageResourceOveruseAction> actions)
             throws RemoteException {
diff --git a/cpp/watchdog/server/src/IoOveruseConfigs.cpp b/cpp/watchdog/server/src/IoOveruseConfigs.cpp
index 3c2cf3e..90a73df 100644
--- a/cpp/watchdog/server/src/IoOveruseConfigs.cpp
+++ b/cpp/watchdog/server/src/IoOveruseConfigs.cpp
@@ -21,7 +21,6 @@
 #include "PackageInfoResolver.h"
 
 #include <android-base/strings.h>
-#include <utils/String8.h>
 
 #include <inttypes.h>
 
@@ -31,15 +30,16 @@
 namespace automotive {
 namespace watchdog {
 
-using ::android::String16;
-using ::android::String8;
 using ::android::automotive::watchdog::PerStateBytes;
 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
 using ::android::automotive::watchdog::internal::ComponentType;
 using ::android::automotive::watchdog::internal::IoOveruseAlertThreshold;
 using ::android::automotive::watchdog::internal::IoOveruseConfiguration;
 using ::android::automotive::watchdog::internal::PackageInfo;
+using ::android::automotive::watchdog::internal::PackageMetadata;
 using ::android::automotive::watchdog::internal::PerStateIoOveruseThreshold;
+using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
+using ::android::automotive::watchdog::internal::ResourceSpecificConfiguration;
 using ::android::automotive::watchdog::internal::UidType;
 using ::android::base::Error;
 using ::android::base::Result;
@@ -50,24 +50,36 @@
 
 namespace {
 
-// Enum to filter the updatable I/O overuse configs by each component.
-enum IoOveruseConfigEnum {
-    COMPONENT_SPECIFIC_GENERIC_THRESHOLDS = 1 << 0,
-    COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS = 1 << 1,
-    COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES = 1 << 2,
-    PER_CATEGORY_THRESHOLDS = 1 << 3,
-    VENDOR_PACKAGE_PREFIXES = 1 << 4,
-    SYSTEM_WIDE_ALERT_THRESHOLDS = 1 << 5,
+// Enum to filter the updatable overuse configs by each component.
+enum OveruseConfigEnum {
+    COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES = 1 << 0,
+    VENDOR_PACKAGE_PREFIXES = 1 << 1,
+    PACKAGE_APP_CATEGORY_MAPPINGS = 1 << 2,
+    COMPONENT_SPECIFIC_GENERIC_THRESHOLDS = 1 << 3,
+    COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS = 1 << 4,
+    PER_CATEGORY_THRESHOLDS = 1 << 5,
+    SYSTEM_WIDE_ALERT_THRESHOLDS = 1 << 6,
 };
 
-const int32_t kSystemComponentUpdatableConfigs = COMPONENT_SPECIFIC_GENERIC_THRESHOLDS |
-        COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS | COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES |
-        SYSTEM_WIDE_ALERT_THRESHOLDS;
-const int32_t kVendorComponentUpdatableConfigs = COMPONENT_SPECIFIC_GENERIC_THRESHOLDS |
-        COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS | COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES |
-        PER_CATEGORY_THRESHOLDS | VENDOR_PACKAGE_PREFIXES;
+const int32_t kSystemComponentUpdatableConfigs = COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES |
+        PACKAGE_APP_CATEGORY_MAPPINGS | COMPONENT_SPECIFIC_GENERIC_THRESHOLDS |
+        COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS | SYSTEM_WIDE_ALERT_THRESHOLDS;
+const int32_t kVendorComponentUpdatableConfigs = COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES |
+        VENDOR_PACKAGE_PREFIXES | PACKAGE_APP_CATEGORY_MAPPINGS |
+        COMPONENT_SPECIFIC_GENERIC_THRESHOLDS | COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS |
+        PER_CATEGORY_THRESHOLDS;
 const int32_t kThirdPartyComponentUpdatableConfigs = COMPONENT_SPECIFIC_GENERIC_THRESHOLDS;
 
+const std::vector<std::string> toStringVector(const std::unordered_set<std::string>& values) {
+    std::vector<std::string> output;
+    for (const auto& v : values) {
+        if (!v.empty()) {
+            output.emplace_back(v);
+        }
+    }
+    return output;
+}
+
 bool isZeroValueThresholds(const PerStateIoOveruseThreshold& thresholds) {
     return thresholds.perStateWriteBytes.foregroundBytes == 0 &&
             thresholds.perStateWriteBytes.backgroundBytes == 0 &&
@@ -77,14 +89,13 @@
 std::string toString(const PerStateIoOveruseThreshold& thresholds) {
     return StringPrintf("name=%s, foregroundBytes=%" PRId64 ", backgroundBytes=%" PRId64
                         ", garageModeBytes=%" PRId64,
-                        String8(thresholds.name).c_str(),
-                        thresholds.perStateWriteBytes.foregroundBytes,
+                        thresholds.name.c_str(), thresholds.perStateWriteBytes.foregroundBytes,
                         thresholds.perStateWriteBytes.backgroundBytes,
                         thresholds.perStateWriteBytes.garageModeBytes);
 }
 
 Result<void> containsValidThresholds(const PerStateIoOveruseThreshold& thresholds) {
-    if (thresholds.name.size() == 0) {
+    if (thresholds.name.empty()) {
         return Error() << "Doesn't contain threshold name";
     }
 
@@ -122,28 +133,85 @@
 
 Result<void> isValidIoOveruseConfiguration(const ComponentType componentType,
                                            const int32_t updatableConfigsFilter,
-                                           const IoOveruseConfiguration& updateConfig) {
-    if (auto result = containsValidThresholds(updateConfig.componentLevelThresholds);
-        (updatableConfigsFilter & IoOveruseConfigEnum::COMPONENT_SPECIFIC_GENERIC_THRESHOLDS) &&
-        !result.ok()) {
-        return Error() << "Invalid " << toString(componentType)
-                       << " component level generic thresholds: " << result.error();
+                                           const IoOveruseConfiguration& ioOveruseConfig) {
+    auto componentTypeStr = toString(componentType);
+    if (updatableConfigsFilter & OveruseConfigEnum::COMPONENT_SPECIFIC_GENERIC_THRESHOLDS) {
+        if (auto result = containsValidThresholds(ioOveruseConfig.componentLevelThresholds);
+            !result.ok()) {
+            return Error() << "Invalid " << toString(componentType)
+                           << " component level generic thresholds: " << result.error();
+        }
+        if (ioOveruseConfig.componentLevelThresholds.name != componentTypeStr) {
+            return Error() << "Invalid component name "
+                           << ioOveruseConfig.componentLevelThresholds.name
+                           << " in component level generic thresholds for component "
+                           << componentTypeStr;
+        }
     }
     const auto containsValidSystemWideThresholds = [&]() -> bool {
-        if (updateConfig.systemWideThresholds.empty()) {
+        if (ioOveruseConfig.systemWideThresholds.empty()) {
             return false;
         }
-        for (const auto& threshold : updateConfig.systemWideThresholds) {
+        for (const auto& threshold : ioOveruseConfig.systemWideThresholds) {
             if (auto result = containsValidThreshold(threshold); !result.ok()) {
                 return false;
             }
         }
         return true;
     };
-    if ((updatableConfigsFilter & IoOveruseConfigEnum::SYSTEM_WIDE_ALERT_THRESHOLDS) &&
+    if ((updatableConfigsFilter & OveruseConfigEnum::SYSTEM_WIDE_ALERT_THRESHOLDS) &&
         !containsValidSystemWideThresholds()) {
-        return Error() << "Invalid system-wide alert threshold provided in "
-                       << toString(componentType) << " config";
+        return Error() << "Invalid system-wide alert threshold provided in " << componentTypeStr
+                       << " config";
+    }
+    return {};
+}
+
+Result<int32_t> getComponentFilter(const ComponentType componentType) {
+    switch (componentType) {
+        case ComponentType::SYSTEM:
+            return kSystemComponentUpdatableConfigs;
+        case ComponentType::VENDOR:
+            return kVendorComponentUpdatableConfigs;
+        case ComponentType::THIRD_PARTY:
+            return kThirdPartyComponentUpdatableConfigs;
+        default:
+            return Error() << "Invalid component type: " << static_cast<int32_t>(componentType);
+    }
+}
+
+Result<void> isValidConfigs(
+        const std::vector<ResourceOveruseConfiguration>& resourceOveruseConfigs) {
+    std::unordered_set<ComponentType> seenComponentTypes;
+    for (const auto& resourceOveruseConfig : resourceOveruseConfigs) {
+        if (seenComponentTypes.count(resourceOveruseConfig.componentType) > 0) {
+            return Error() << "Cannot provide duplicate configs for the same component type "
+                           << toString(resourceOveruseConfig.componentType);
+        }
+        const auto filter = getComponentFilter(resourceOveruseConfig.componentType);
+        if (!filter.ok()) {
+            return Error() << filter.error();
+        }
+        seenComponentTypes.insert(resourceOveruseConfig.componentType);
+        if (resourceOveruseConfig.resourceSpecificConfigurations.size() != 1) {
+            return Error() << "Must provide exactly one I/O overuse configuration. Received "
+                           << resourceOveruseConfig.resourceSpecificConfigurations.size()
+                           << " configurations";
+        }
+        for (const auto& config : resourceOveruseConfig.resourceSpecificConfigurations) {
+            if (config.getTag() != ResourceSpecificConfiguration::ioOveruseConfiguration) {
+                return Error() << "Invalid resource type: " << config.getTag();
+            }
+            const auto& ioOveruseConfig =
+                    config.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+            if (auto result = isValidIoOveruseConfiguration(resourceOveruseConfig.componentType,
+                                                            *filter, ioOveruseConfig);
+                !result.ok()) {
+                return Error() << "Invalid config for component "
+                               << toString(resourceOveruseConfig.componentType).c_str()
+                               << result.error();
+            }
+        }
     }
     return {};
 }
@@ -159,38 +227,36 @@
     }
     std::string errorMsgs;
     for (const auto& packageThreshold : thresholds) {
-        std::string packageName = std::string(String8(packageThreshold.name));
-        if (packageName.empty()) {
+        if (packageThreshold.name.empty()) {
             StringAppendF(&errorMsgs, "\tSkipping per-package threshold without package name\n");
             continue;
         }
-        maybeAppendVendorPackagePrefixes(packageName);
+        maybeAppendVendorPackagePrefixes(packageThreshold.name);
         if (auto result = containsValidThresholds(packageThreshold); !result.ok()) {
             StringAppendF(&errorMsgs,
                           "\tSkipping invalid package specific thresholds for package %s: %s\n",
-                          packageName.c_str(), result.error().message().c_str());
+                          packageThreshold.name.c_str(), result.error().message().c_str());
             continue;
         }
-        if (const auto& it = mPerPackageThresholds.find(packageName);
+        if (const auto& it = mPerPackageThresholds.find(packageThreshold.name);
             it != mPerPackageThresholds.end()) {
             StringAppendF(&errorMsgs, "\tDuplicate threshold received for package '%s'\n",
-                          packageName.c_str());
+                          packageThreshold.name.c_str());
         }
-        mPerPackageThresholds[packageName] = packageThreshold;
+        mPerPackageThresholds[packageThreshold.name] = packageThreshold;
     }
     return errorMsgs.empty() ? Result<void>{} : Error() << errorMsgs;
 }
 
 Result<void> ComponentSpecificConfig::updateSafeToKillPackages(
-        const std::vector<String16>& packages,
+        const std::vector<std::string>& packages,
         const std::function<void(const std::string&)>& maybeAppendVendorPackagePrefixes) {
     mSafeToKillPackages.clear();
     if (packages.empty()) {
         return Error() << "\tNo safe-to-kill packages provided so clearing it\n";
     }
     std::string errorMsgs;
-    for (const auto& packageNameStr16 : packages) {
-        std::string packageName = std::string(String8(packageNameStr16));
+    for (const auto& packageName : packages) {
         if (packageName.empty()) {
             StringAppendF(&errorMsgs, "\tSkipping empty safe-to-kill package name");
             continue;
@@ -224,15 +290,15 @@
                           result.error().message().c_str());
             continue;
         }
-        std::string name = std::string(String8(categoryThreshold.name));
-        if (auto category = toApplicationCategoryType(name);
+        if (auto category = toApplicationCategoryType(categoryThreshold.name);
             category == ApplicationCategoryType::OTHERS) {
-            StringAppendF(&errorMsgs, "\tInvalid application category %s\n", name.c_str());
+            StringAppendF(&errorMsgs, "\tInvalid application category %s\n",
+                          categoryThreshold.name.c_str());
         } else {
             if (const auto& it = mPerCategoryThresholds.find(category);
                 it != mPerCategoryThresholds.end()) {
                 StringAppendF(&errorMsgs, "\tDuplicate threshold received for category: '%s'\n",
-                              name.c_str());
+                              categoryThreshold.name.c_str());
             }
             mPerCategoryThresholds[category] = categoryThreshold;
         }
@@ -262,60 +328,90 @@
     return errorMsgs.empty() ? Result<void>{} : Error() << errorMsgs;
 }
 
-Result<void> IoOveruseConfigs::update(const ComponentType componentType,
-                                      const IoOveruseConfiguration& updateConfig) {
-    const std::string componentTypeStr = toString(componentType);
-    if (auto configComponentTypeStr = String8(updateConfig.componentLevelThresholds.name).string();
-        configComponentTypeStr != componentTypeStr) {
-        return Error(Status::EX_ILLEGAL_ARGUMENT)
-                << "Invalid config: Config's component name '" << configComponentTypeStr
-                << "' != component name in update request '" << componentTypeStr << "'";
-    }
-    ComponentSpecificConfig* targetComponentConfig;
-    int32_t updatableConfigsFilter = 0;
-    switch (componentType) {
-        case ComponentType::SYSTEM:
-            targetComponentConfig = &mSystemConfig;
-            updatableConfigsFilter = kSystemComponentUpdatableConfigs;
-            break;
-        case ComponentType::VENDOR:
-            targetComponentConfig = &mVendorConfig;
-            updatableConfigsFilter = kVendorComponentUpdatableConfigs;
-            break;
-        case ComponentType::THIRD_PARTY:
-            targetComponentConfig = &mThirdPartyConfig;
-            updatableConfigsFilter = kThirdPartyComponentUpdatableConfigs;
-            break;
-        default:
-            return Error(Status::EX_ILLEGAL_ARGUMENT)
-                    << "Invalid component type " << componentTypeStr;
-    }
-    if (auto result =
-                isValidIoOveruseConfiguration(componentType, updatableConfigsFilter, updateConfig);
-        !result.ok()) {
+Result<void> IoOveruseConfigs::update(
+        const std::vector<ResourceOveruseConfiguration>& resourceOveruseConfigs) {
+    if (auto result = isValidConfigs(resourceOveruseConfigs); !result.ok()) {
         return Error(Status::EX_ILLEGAL_ARGUMENT) << result.error();
     }
 
-    if ((updatableConfigsFilter & IoOveruseConfigEnum::COMPONENT_SPECIFIC_GENERIC_THRESHOLDS)) {
-        targetComponentConfig->mGeneric = updateConfig.componentLevelThresholds;
+    for (const auto& resourceOveruseConfig : resourceOveruseConfigs) {
+        ComponentSpecificConfig* targetComponentConfig;
+        int32_t updatableConfigsFilter = 0;
+        switch (resourceOveruseConfig.componentType) {
+            case ComponentType::SYSTEM:
+                targetComponentConfig = &mSystemConfig;
+                updatableConfigsFilter = kSystemComponentUpdatableConfigs;
+                break;
+            case ComponentType::VENDOR:
+                targetComponentConfig = &mVendorConfig;
+                updatableConfigsFilter = kVendorComponentUpdatableConfigs;
+                break;
+            case ComponentType::THIRD_PARTY:
+                targetComponentConfig = &mThirdPartyConfig;
+                updatableConfigsFilter = kThirdPartyComponentUpdatableConfigs;
+                break;
+            default:
+                // This case shouldn't execute as it is caught during validation.
+                continue;
+        }
+
+        const std::string componentTypeStr = toString(resourceOveruseConfig.componentType);
+        for (const auto& resourceSpecificConfig :
+             resourceOveruseConfig.resourceSpecificConfigurations) {
+            /*
+             * |resourceSpecificConfig| should contain only ioOveruseConfiguration as it is verified
+             * during validation.
+             */
+            const auto& ioOveruseConfig =
+                    resourceSpecificConfig
+                            .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+            if (auto res = update(resourceOveruseConfig, ioOveruseConfig, updatableConfigsFilter,
+                                  targetComponentConfig);
+                !res.ok()) {
+                ALOGE("Invalid I/O overuse configurations received for %s component:\n%s",
+                      componentTypeStr.c_str(), res.error().message().c_str());
+            }
+        }
+    }
+    return {};
+}
+
+Result<void> IoOveruseConfigs::update(
+        const ResourceOveruseConfiguration& resourceOveruseConfiguration,
+        const IoOveruseConfiguration& ioOveruseConfiguration, int32_t updatableConfigsFilter,
+        ComponentSpecificConfig* targetComponentConfig) {
+    if ((updatableConfigsFilter & OveruseConfigEnum::COMPONENT_SPECIFIC_GENERIC_THRESHOLDS)) {
+        targetComponentConfig->mGeneric = ioOveruseConfiguration.componentLevelThresholds;
     }
 
     std::string nonUpdatableConfigMsgs;
-    if (updatableConfigsFilter & IoOveruseConfigEnum::VENDOR_PACKAGE_PREFIXES) {
+    if (updatableConfigsFilter & OveruseConfigEnum::VENDOR_PACKAGE_PREFIXES) {
         mVendorPackagePrefixes.clear();
-        for (const auto& prefixStr16 : updateConfig.vendorPackagePrefixes) {
-            if (auto prefix = std::string(String8(prefixStr16)); !prefix.empty()) {
+        for (const auto& prefix : resourceOveruseConfiguration.vendorPackagePrefixes) {
+            if (!prefix.empty()) {
                 mVendorPackagePrefixes.insert(prefix);
             }
         }
-    } else if (!updateConfig.vendorPackagePrefixes.empty()) {
+    } else if (!resourceOveruseConfiguration.vendorPackagePrefixes.empty()) {
         StringAppendF(&nonUpdatableConfigMsgs, "%svendor packages prefixes",
                       !nonUpdatableConfigMsgs.empty() ? ", " : "");
     }
 
+    if (updatableConfigsFilter & OveruseConfigEnum::PACKAGE_APP_CATEGORY_MAPPINGS) {
+        mPackagesToAppCategories.clear();
+        for (const auto& meta : resourceOveruseConfiguration.packageMetadata) {
+            if (!meta.packageName.empty()) {
+                mPackagesToAppCategories[meta.packageName] = meta.appCategoryType;
+            }
+        }
+    } else if (!resourceOveruseConfiguration.packageMetadata.empty()) {
+        StringAppendF(&nonUpdatableConfigMsgs, "%spackage to application category mappings",
+                      !nonUpdatableConfigMsgs.empty() ? ", " : "");
+    }
+
     std::string errorMsgs;
     const auto maybeAppendVendorPackagePrefixes =
-            [& componentType = std::as_const(componentType),
+            [&componentType = std::as_const(resourceOveruseConfiguration.componentType),
              &vendorPackagePrefixes = mVendorPackagePrefixes](const std::string& packageName) {
                 if (componentType != ComponentType::VENDOR) {
                     return;
@@ -328,46 +424,49 @@
                 vendorPackagePrefixes.insert(packageName);
             };
 
-    if (updatableConfigsFilter & IoOveruseConfigEnum::COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS) {
-        if (auto result =
-                    targetComponentConfig
-                            ->updatePerPackageThresholds(updateConfig.packageSpecificThresholds,
-                                                         maybeAppendVendorPackagePrefixes);
+    if (updatableConfigsFilter & OveruseConfigEnum::COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS) {
+        if (auto result = targetComponentConfig
+                                  ->updatePerPackageThresholds(ioOveruseConfiguration
+                                                                       .packageSpecificThresholds,
+                                                               maybeAppendVendorPackagePrefixes);
             !result.ok()) {
             StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
         }
-    } else if (!updateConfig.packageSpecificThresholds.empty()) {
+    } else if (!ioOveruseConfiguration.packageSpecificThresholds.empty()) {
         StringAppendF(&nonUpdatableConfigMsgs, "%sper-package thresholds",
                       !nonUpdatableConfigMsgs.empty() ? ", " : "");
     }
 
-    if (updatableConfigsFilter & IoOveruseConfigEnum::COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES) {
+    if (updatableConfigsFilter & OveruseConfigEnum::COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES) {
         if (auto result = targetComponentConfig
-                                  ->updateSafeToKillPackages(updateConfig.safeToKillPackages,
+                                  ->updateSafeToKillPackages(resourceOveruseConfiguration
+                                                                     .safeToKillPackages,
                                                              maybeAppendVendorPackagePrefixes);
             !result.ok()) {
             StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
         }
-    } else if (!updateConfig.safeToKillPackages.empty()) {
+    } else if (!resourceOveruseConfiguration.safeToKillPackages.empty()) {
         StringAppendF(&nonUpdatableConfigMsgs, "%ssafe-to-kill list",
                       !nonUpdatableConfigMsgs.empty() ? ", " : "");
     }
 
-    if (updatableConfigsFilter & IoOveruseConfigEnum::PER_CATEGORY_THRESHOLDS) {
-        if (auto result = updatePerCategoryThresholds(updateConfig.categorySpecificThresholds);
+    if (updatableConfigsFilter & OveruseConfigEnum::PER_CATEGORY_THRESHOLDS) {
+        if (auto result =
+                    updatePerCategoryThresholds(ioOveruseConfiguration.categorySpecificThresholds);
             !result.ok()) {
             StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
         }
-    } else if (!updateConfig.categorySpecificThresholds.empty()) {
+    } else if (!ioOveruseConfiguration.categorySpecificThresholds.empty()) {
         StringAppendF(&nonUpdatableConfigMsgs, "%scategory specific thresholds",
                       !nonUpdatableConfigMsgs.empty() ? ", " : "");
     }
 
-    if (updatableConfigsFilter & IoOveruseConfigEnum::SYSTEM_WIDE_ALERT_THRESHOLDS) {
-        if (auto result = updateAlertThresholds(updateConfig.systemWideThresholds); !result.ok()) {
+    if (updatableConfigsFilter & OveruseConfigEnum::SYSTEM_WIDE_ALERT_THRESHOLDS) {
+        if (auto result = updateAlertThresholds(ioOveruseConfiguration.systemWideThresholds);
+            !result.ok()) {
             StringAppendF(&errorMsgs, "%s", result.error().message().c_str());
         }
-    } else if (!updateConfig.systemWideThresholds.empty()) {
+    } else if (!ioOveruseConfiguration.systemWideThresholds.empty()) {
         StringAppendF(&nonUpdatableConfigMsgs, "%ssystem-wide alert thresholds",
                       !nonUpdatableConfigMsgs.empty() ? ", " : "");
     }
@@ -377,17 +476,84 @@
                       nonUpdatableConfigMsgs.c_str());
     }
     if (!errorMsgs.empty()) {
-        ALOGE("Invalid I/O overuse configs received for %s component:\n%s",
-              componentTypeStr.c_str(), errorMsgs.c_str());
+        return Error() << errorMsgs.c_str();
     }
     return {};
 }
 
+void IoOveruseConfigs::get(std::vector<ResourceOveruseConfiguration>* resourceOveruseConfigs) {
+    auto systemConfig = get(mSystemConfig, kSystemComponentUpdatableConfigs);
+    if (systemConfig.has_value()) {
+        systemConfig->componentType = ComponentType::SYSTEM;
+        resourceOveruseConfigs->emplace_back(std::move(*systemConfig));
+    }
+
+    auto vendorConfig = get(mVendorConfig, kVendorComponentUpdatableConfigs);
+    if (vendorConfig.has_value()) {
+        vendorConfig->componentType = ComponentType::VENDOR;
+        resourceOveruseConfigs->emplace_back(std::move(*vendorConfig));
+    }
+
+    auto thirdPartyConfig = get(mThirdPartyConfig, kThirdPartyComponentUpdatableConfigs);
+    if (thirdPartyConfig.has_value()) {
+        thirdPartyConfig->componentType = ComponentType::THIRD_PARTY;
+        resourceOveruseConfigs->emplace_back(std::move(*thirdPartyConfig));
+    }
+}
+
+std::optional<ResourceOveruseConfiguration> IoOveruseConfigs::get(
+        const ComponentSpecificConfig& componentSpecificConfig, const int32_t componentFilter) {
+    if (componentSpecificConfig.mGeneric.name == kDefaultThresholdName) {
+        return {};
+    }
+    ResourceOveruseConfiguration resourceOveruseConfiguration;
+    IoOveruseConfiguration ioOveruseConfiguration;
+    if ((componentFilter & OveruseConfigEnum::COMPONENT_SPECIFIC_GENERIC_THRESHOLDS)) {
+        ioOveruseConfiguration.componentLevelThresholds = componentSpecificConfig.mGeneric;
+    }
+    if (componentFilter & OveruseConfigEnum::VENDOR_PACKAGE_PREFIXES) {
+        resourceOveruseConfiguration.vendorPackagePrefixes = toStringVector(mVendorPackagePrefixes);
+    }
+    if (componentFilter & OveruseConfigEnum::PACKAGE_APP_CATEGORY_MAPPINGS) {
+        for (const auto& [packageName, appCategoryType] : mPackagesToAppCategories) {
+            PackageMetadata meta;
+            meta.packageName = packageName;
+            meta.appCategoryType = appCategoryType;
+            resourceOveruseConfiguration.packageMetadata.push_back(meta);
+        }
+    }
+    if (componentFilter & OveruseConfigEnum::COMPONENT_SPECIFIC_PER_PACKAGE_THRESHOLDS) {
+        for (const auto& [packageName, threshold] : componentSpecificConfig.mPerPackageThresholds) {
+            ioOveruseConfiguration.packageSpecificThresholds.push_back(threshold);
+        }
+    }
+    if (componentFilter & OveruseConfigEnum::COMPONENT_SPECIFIC_SAFE_TO_KILL_PACKAGES) {
+        resourceOveruseConfiguration.safeToKillPackages =
+                toStringVector(componentSpecificConfig.mSafeToKillPackages);
+    }
+    if (componentFilter & OveruseConfigEnum::PER_CATEGORY_THRESHOLDS) {
+        for (const auto& [category, threshold] : mPerCategoryThresholds) {
+            ioOveruseConfiguration.categorySpecificThresholds.push_back(threshold);
+        }
+    }
+    if (componentFilter & OveruseConfigEnum::SYSTEM_WIDE_ALERT_THRESHOLDS) {
+        for (const auto& threshold : mAlertThresholds) {
+            ioOveruseConfiguration.systemWideThresholds.push_back(threshold);
+        }
+    }
+    ResourceSpecificConfiguration resourceSpecificConfig;
+    resourceSpecificConfig.set<ResourceSpecificConfiguration::ioOveruseConfiguration>(
+            ioOveruseConfiguration);
+    resourceOveruseConfiguration.resourceSpecificConfigurations.emplace_back(
+            std::move(resourceSpecificConfig));
+    return resourceOveruseConfiguration;
+}
+
 PerStateBytes IoOveruseConfigs::fetchThreshold(const PackageInfo& packageInfo) const {
-    const std::string packageName = std::string(String8(packageInfo.packageIdentifier.name));
     switch (packageInfo.componentType) {
         case ComponentType::SYSTEM:
-            if (const auto it = mSystemConfig.mPerPackageThresholds.find(packageName);
+            if (const auto it = mSystemConfig.mPerPackageThresholds.find(
+                        packageInfo.packageIdentifier.name);
                 it != mSystemConfig.mPerPackageThresholds.end()) {
                 return it->second.perStateWriteBytes;
             }
@@ -397,7 +563,8 @@
             }
             return mSystemConfig.mGeneric.perStateWriteBytes;
         case ComponentType::VENDOR:
-            if (const auto it = mVendorConfig.mPerPackageThresholds.find(packageName);
+            if (const auto it = mVendorConfig.mPerPackageThresholds.find(
+                        packageInfo.packageIdentifier.name);
                 it != mVendorConfig.mPerPackageThresholds.end()) {
                 return it->second.perStateWriteBytes;
             }
@@ -424,13 +591,12 @@
         // Native packages can't be disabled so don't kill them on I/O overuse.
         return false;
     }
-    const std::string packageName = std::string(String8(packageInfo.packageIdentifier.name));
     switch (packageInfo.componentType) {
         case ComponentType::SYSTEM:
-            return mSystemConfig.mSafeToKillPackages.find(packageName) !=
+            return mSystemConfig.mSafeToKillPackages.find(packageInfo.packageIdentifier.name) !=
                     mSystemConfig.mSafeToKillPackages.end();
         case ComponentType::VENDOR:
-            return mVendorConfig.mSafeToKillPackages.find(packageName) !=
+            return mVendorConfig.mSafeToKillPackages.find(packageInfo.packageIdentifier.name) !=
                     mVendorConfig.mSafeToKillPackages.end();
         default:
             return true;
diff --git a/cpp/watchdog/server/src/IoOveruseConfigs.h b/cpp/watchdog/server/src/IoOveruseConfigs.h
index 84577f1..cd80a95 100644
--- a/cpp/watchdog/server/src/IoOveruseConfigs.h
+++ b/cpp/watchdog/server/src/IoOveruseConfigs.h
@@ -23,10 +23,9 @@
 #include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
 #include <android/automotive/watchdog/internal/ComponentType.h>
 #include <android/automotive/watchdog/internal/IoOveruseAlertThreshold.h>
-#include <android/automotive/watchdog/internal/IoOveruseConfiguration.h>
 #include <android/automotive/watchdog/internal/PackageInfo.h>
 #include <android/automotive/watchdog/internal/PerStateIoOveruseThreshold.h>
-#include <utils/String16.h>
+#include <android/automotive/watchdog/internal/ResourceOveruseConfiguration.h>
 
 #include <optional>
 #include <string>
@@ -37,11 +36,12 @@
 namespace android {
 namespace automotive {
 namespace watchdog {
+constexpr const char* kDefaultThresholdName = "default";
 
 inline const android::automotive::watchdog::internal::PerStateIoOveruseThreshold
 defaultThreshold() {
     android::automotive::watchdog::internal::PerStateIoOveruseThreshold threshold;
-    threshold.name = android::String16("default");
+    threshold.name = kDefaultThresholdName;
     threshold.perStateWriteBytes.foregroundBytes = std::numeric_limits<uint64_t>::max();
     threshold.perStateWriteBytes.backgroundBytes = std::numeric_limits<uint64_t>::max();
     threshold.perStateWriteBytes.garageModeBytes = std::numeric_limits<uint64_t>::max();
@@ -53,10 +53,14 @@
  */
 class IIoOveruseConfigs : public android::RefBase {
 public:
-    // Overwrites the existing configuration for the given |componentType|.
-    virtual android::base::Result<void> update(
-            const android::automotive::watchdog::internal::ComponentType componentType,
-            const android::automotive::watchdog::internal::IoOveruseConfiguration& config) = 0;
+    // Overwrites the existing configurations.
+    virtual android::base::Result<void>
+    update(const std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
+                   configs) = 0;
+    // Returns the existing configurations.
+    virtual void get(
+            std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
+                    resourceOveruseConfigs) = 0;
 
     /*
      * Returns the list of vendor package prefixes. Any pre-installed package matching one of these
@@ -64,6 +68,13 @@
      */
     virtual const std::unordered_set<std::string>& vendorPackagePrefixes() = 0;
 
+    /*
+     * Returns the package names to application category mappings.
+     */
+    virtual const std::unordered_map<
+            std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
+    packagesToAppCategories() = 0;
+
     // Fetches the I/O overuse thresholds for the given package.
     virtual PerStateBytes fetchThreshold(
             const android::automotive::watchdog::internal::PackageInfo& packageInfo) const = 0;
@@ -118,7 +129,7 @@
      * Updates |mSafeToKillPackages|.
      */
     android::base::Result<void> updateSafeToKillPackages(
-            const std::vector<android::String16>& packages,
+            const std::vector<std::string>& packages,
             const std::function<void(const std::string&)>& maybeAppendVendorPackagePrefixes);
 
     /*
@@ -155,10 +166,12 @@
         mAlertThresholds.clear();
     }
 
-    // Overwrites the existing configuration for the given |componentType|.
-    android::base::Result<void> update(
-            const android::automotive::watchdog::internal::ComponentType componentType,
-            const android::automotive::watchdog::internal::IoOveruseConfiguration& config);
+    android::base::Result<void>
+    update(const std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
+                   configs);
+
+    void get(std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
+                     resourceOveruseConfigs);
 
     PerStateBytes fetchThreshold(
             const android::automotive::watchdog::internal::PackageInfo& packageInfo) const;
@@ -172,13 +185,33 @@
         return mVendorPackagePrefixes;
     }
 
+    const std::unordered_map<std::string,
+                             android::automotive::watchdog::internal::ApplicationCategoryType>&
+    packagesToAppCategories() {
+        return mPackagesToAppCategories;
+    }
+
 private:
+    android::base::Result<void> update(
+            const android::automotive::watchdog::internal::ResourceOveruseConfiguration&
+                    resourceOveruseConfiguration,
+            const android::automotive::watchdog::internal::IoOveruseConfiguration&
+                    ioOveruseConfiguration,
+            int32_t updatableConfigsFilter, ComponentSpecificConfig* targetComponentConfig);
+
+    std::optional<android::automotive::watchdog::internal::ResourceOveruseConfiguration> get(
+            const ComponentSpecificConfig& componentSpecificConfig, const int32_t componentFilter);
+
     // System component specific configuration.
     ComponentSpecificConfig mSystemConfig;
     // Vendor component specific configuration.
     ComponentSpecificConfig mVendorConfig;
     // Third-party component specific configuration.
     ComponentSpecificConfig mThirdPartyConfig;
+    // Package name to application category mappings.
+    std::unordered_map<std::string,
+                       android::automotive::watchdog::internal::ApplicationCategoryType>
+            mPackagesToAppCategories;
     // I/O overuse thresholds per category.
     std::unordered_map<android::automotive::watchdog::internal::ApplicationCategoryType,
                        android::automotive::watchdog::internal::PerStateIoOveruseThreshold>
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.cpp b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
index 8b25a83..080b284 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.cpp
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "carwatchdogd"
+#define DEBUG false  // STOPSHIP if true.
 
 #include "IoOveruseMonitor.h"
 
@@ -27,6 +28,8 @@
 #include <binder/Status.h>
 #include <cutils/multiuser.h>
 
+#include <limits>
+
 namespace android {
 namespace automotive {
 namespace watchdog {
@@ -38,18 +41,23 @@
 using ::android::automotive::watchdog::internal::PackageInfo;
 using ::android::automotive::watchdog::internal::PackageIoOveruseStats;
 using ::android::automotive::watchdog::internal::PackageResourceOveruseAction;
+using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
 using ::android::automotive::watchdog::internal::UidType;
 using ::android::base::Error;
 using ::android::base::Result;
 using ::android::binder::Status;
 
+// Minimum written bytes to sync the stats with the Watchdog service.
+constexpr uint64_t kMinSyncWrittenBytes = 100 * 1024;
+// Minimum percentage of threshold to warn killable applications.
 constexpr double kDefaultIoOveruseWarnPercentage = 80;
+// Maximum numer of system-wide stats (from periodic monitoring) to cache.
 constexpr size_t kMaxPeriodicMonitorBufferSize = 1000;
 
 namespace {
 
 std::string uniquePackageIdStr(const PackageIdentifier& id) {
-    return StringPrintf("%s:%" PRId32, String8(id.name).c_str(), multiuser_get_user_id(id.uid));
+    return StringPrintf("%s:%" PRId32, id.name.c_str(), multiuser_get_user_id(id.uid));
 }
 
 PerStateBytes diff(const PerStateBytes& lhs, const PerStateBytes& rhs) {
@@ -75,6 +83,15 @@
     return std::make_tuple(startTime, currentEpochSeconds - startTime);
 }
 
+uint64_t totalPerStateBytes(PerStateBytes perStateBytes) {
+    const auto sum = [](const uint64_t& l, const uint64_t& r) -> uint64_t {
+        return std::numeric_limits<uint64_t>::max() - l > r ? (l + r)
+                                                            : std::numeric_limits<uint64_t>::max();
+    };
+    return sum(perStateBytes.foregroundBytes,
+               sum(perStateBytes.backgroundBytes, perStateBytes.garageModeBytes));
+}
+
 }  // namespace
 
 std::tuple<int64_t, int64_t> calculateStartAndDuration(const time_t& currentTime) {
@@ -83,6 +100,19 @@
     return calculateStartAndDuration(currentGmt);
 }
 
+IoOveruseMonitor::IoOveruseMonitor(
+        const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper) :
+      mMinSyncWrittenBytes(kMinSyncWrittenBytes),
+      mWatchdogServiceHelper(watchdogServiceHelper),
+      mSystemWideWrittenBytes({}),
+      mPeriodicMonitorBufferSize(0),
+      mLastSystemWideIoMonitorTime(0),
+      mUserPackageDailyIoUsageById({}),
+      mIoOveruseWarnPercentage(0),
+      mLastUserPackageIoMonitorTime(0),
+      mOveruseListenersByUid({}),
+      mBinderDeathRecipient(new BinderDeathRecipient(this)) {}
+
 Result<void> IoOveruseMonitor::init() {
     std::unique_lock writeLock(mRwMutex);
     if (isInitializedLocked()) {
@@ -99,7 +129,7 @@
     mIoOveruseWarnPercentage = static_cast<double>(
             sysprop::ioOveruseWarnPercentage().value_or(kDefaultIoOveruseWarnPercentage));
     /*
-     * TODO(b/167240592): Read the latest I/O overuse config.
+     * TODO(b/185287136): Read the latest I/O overuse config.
      *  The latest I/O overuse config is read in this order:
      *  1. From /data partition as this contains the latest config and any updates received from OEM
      *    and system applications.
@@ -108,9 +138,13 @@
      */
 
     mIoOveruseConfigs = new IoOveruseConfigs();
-    // TODO(b/167240592): Read the vendor package prefixes from disk before the below call.
+    // TODO(b/185287136): Read the vendor package prefixes from disk before the below call.
     mPackageInfoResolver = PackageInfoResolver::getInstance();
-    mPackageInfoResolver->setVendorPackagePrefixes(mIoOveruseConfigs->vendorPackagePrefixes());
+    mPackageInfoResolver->setPackageConfigurations(mIoOveruseConfigs->vendorPackagePrefixes(),
+                                                   mIoOveruseConfigs->packagesToAppCategories());
+    if (DEBUG) {
+        ALOGD("Initialized %s data processor", name().c_str());
+    }
     return {};
 }
 
@@ -127,6 +161,9 @@
     }
     mBinderDeathRecipient.clear();
     mOveruseListenersByUid.clear();
+    if (DEBUG) {
+        ALOGD("Terminated %s data processor", name().c_str());
+    }
     return;
 }
 
@@ -146,7 +183,7 @@
         /*
          * Date changed so reset the daily I/O usage cache.
          *
-         * TODO(b/170741935): Ping CarWatchdogService on date change so it can re-enable the daily
+         * TODO(b/185287136): Ping CarWatchdogService on date change so it can re-enable the daily
          *  disabled packages. Also sync prev day's stats with CarWatchdogService.
          */
         mUserPackageDailyIoUsageById.clear();
@@ -154,14 +191,26 @@
     mLastUserPackageIoMonitorTime = time;
     const auto [startTime, durationInSeconds] = calculateStartAndDuration(curGmt);
 
-    const auto perUidIoUsage = uidIoStats.promote()->deltaStats();
+    auto perUidIoUsage = uidIoStats.promote()->deltaStats();
     /*
-     * TODO(b/167240592): Maybe move the packageInfo fetching logic into UidIoStats module.
+     * TODO(b/185849350): Maybe move the packageInfo fetching logic into UidIoStats module.
      *  This will also help avoid fetching package names in IoPerfCollection module.
      */
     std::vector<uid_t> seenUids;
-    for (const auto& [uid, uidIoStats] : perUidIoUsage) {
-        seenUids.push_back(uid);
+    for (auto it = perUidIoUsage.begin(); it != perUidIoUsage.end();) {
+        /*
+         * UidIoStats::deltaStats returns entries with zero write bytes because other metrics
+         * in these entries are non-zero.
+         */
+        if (it->second.ios.sumWriteBytes() == 0) {
+            it = perUidIoUsage.erase(it);
+            continue;
+        }
+        seenUids.push_back(it->first);
+        ++it;
+    }
+    if (perUidIoUsage.empty()) {
+        return {};
     }
     const auto packageInfosByUid = mPackageInfoResolver->getPackageInfosForUids(seenUids);
     std::unordered_map<uid_t, IoOveruseStats> overusingNativeStats;
@@ -171,7 +220,7 @@
             continue;
         }
         /*
-         * TODO(b/167240592): Derive the garage mode status from the collection flag, which will
+         * TODO(b/185498771): Derive the garage mode status from the collection flag, which will
          *  be added to the |onPeriodicCollection| API.
          */
         UserPackageIoUsage curUsage(packageInfo->second, uidIoStats.ios,
@@ -202,6 +251,16 @@
                 mIoOveruseConfigs->isSafeToKill(dailyIoUsage->packageInfo);
 
         const auto& remainingWriteBytes = stats.ioOveruseStats.remainingWriteBytes;
+        const auto exceedsWarnThreshold = [&](double remaining, double threshold) {
+            if (threshold == 0) {
+                return true;
+            }
+            double usedPercent = (100 - (remaining / threshold) * 100);
+            return usedPercent > mIoOveruseWarnPercentage;
+        };
+        bool shouldSyncWatchdogService =
+                (totalPerStateBytes(dailyIoUsage->writtenBytes) -
+                 dailyIoUsage->lastSyncedWrittenBytes) >= mMinSyncWrittenBytes;
         if (remainingWriteBytes.foregroundBytes == 0 || remainingWriteBytes.backgroundBytes == 0 ||
             remainingWriteBytes.garageModeBytes == 0) {
             stats.ioOveruseStats.totalOveruses = ++dailyIoUsage->totalOveruses;
@@ -219,45 +278,44 @@
             if (dailyIoUsage->packageInfo.uidType == UidType::NATIVE) {
                 overusingNativeStats[uid] = stats.ioOveruseStats;
             }
-            mLatestIoOveruseStats.emplace_back(std::move(stats));
-            continue;
-        }
-        if (dailyIoUsage->packageInfo.uidType == UidType::NATIVE ||
-            !stats.ioOveruseStats.killableOnOveruse || dailyIoUsage->isPackageWarned) {
+            shouldSyncWatchdogService = true;
+        } else if (dailyIoUsage->packageInfo.uidType != UidType::NATIVE &&
+                   stats.ioOveruseStats.killableOnOveruse && !dailyIoUsage->isPackageWarned &&
+                   (exceedsWarnThreshold(remainingWriteBytes.foregroundBytes,
+                                         threshold.foregroundBytes) ||
+                    exceedsWarnThreshold(remainingWriteBytes.backgroundBytes,
+                                         threshold.backgroundBytes) ||
+                    exceedsWarnThreshold(remainingWriteBytes.garageModeBytes,
+                                         threshold.garageModeBytes))) {
             /*
              * No need to warn native services or applications that won't be killed on I/O overuse
              * as they will be sent a notification when they exceed their daily threshold.
              */
-            mLatestIoOveruseStats.emplace_back(std::move(stats));
-            continue;
-        }
-        const auto exceedsWarnThreshold = [&](double remaining, double threshold) {
-            if (threshold == 0) {
-                return true;
-            }
-            double usedPercent = (100 - (remaining / threshold) * 100);
-            return usedPercent > mIoOveruseWarnPercentage;
-        };
-        if (exceedsWarnThreshold(remainingWriteBytes.foregroundBytes, threshold.foregroundBytes) ||
-            exceedsWarnThreshold(remainingWriteBytes.backgroundBytes, threshold.backgroundBytes) ||
-            exceedsWarnThreshold(remainingWriteBytes.garageModeBytes, threshold.garageModeBytes)) {
             stats.shouldNotify = true;
             // Avoid duplicate warning before the daily threshold exceeded notification is sent.
             dailyIoUsage->isPackageWarned = true;
+            shouldSyncWatchdogService = true;
         }
-        mLatestIoOveruseStats.emplace_back(std::move(stats));
+        if (shouldSyncWatchdogService) {
+            dailyIoUsage->lastSyncedWrittenBytes = totalPerStateBytes(dailyIoUsage->writtenBytes);
+            mLatestIoOveruseStats.emplace_back(std::move(stats));
+        }
     }
-
     if (!overusingNativeStats.empty()) {
         notifyNativePackagesLocked(overusingNativeStats);
     }
-
+    if (mLatestIoOveruseStats.empty()) {
+        return {};
+    }
     if (const auto status = mWatchdogServiceHelper->latestIoOveruseStats(mLatestIoOveruseStats);
         !status.isOk()) {
         // Don't clear the cache as it can be pushed again on the next collection.
         ALOGW("Failed to push the latest I/O overuse stats to watchdog service");
     } else {
         mLatestIoOveruseStats.clear();
+        if (DEBUG) {
+            ALOGD("Pushed latest I/O overuse stats to watchdog service");
+        }
     }
 
     return {};
@@ -277,6 +335,8 @@
     if (procDiskStats == nullptr) {
         return Error() << "Proc disk stats collector must not be null";
     }
+
+    std::unique_lock writeLock(mRwMutex);
     if (mLastSystemWideIoMonitorTime == 0) {
         /*
          * Do not record the first disk stats as it reflects the aggregated disks stats since the
@@ -324,12 +384,12 @@
 }
 
 Result<void> IoOveruseMonitor::onShutdownPrepareComplete() {
-    // TODO(b/167240592): Flush in-memory stats to disk.
+    // TODO(b/185287136): Flush in-memory stats to disk.
     return {};
 }
 
 Result<void> IoOveruseMonitor::onDump([[maybe_unused]] int fd) {
-    // TODO(b/167240592): Dump the list of killed/disabled packages. Dump the list of packages that
+    // TODO(b/183436216): Dump the list of killed/disabled packages. Dump the list of packages that
     //  exceed xx% of their threshold.
     return {};
 }
@@ -347,21 +407,37 @@
         stats.set<ResourceOveruseStats::ioOveruseStats>(ioOveruseStats);
         listener->onOveruse(stats);
     }
-    // TODO(b/167240592): Upload I/O overuse metrics for native packages.
+    if (DEBUG) {
+        ALOGD("Notified native packages on I/O overuse");
+    }
+    // TODO(b/184310189): Upload I/O overuse metrics for native packages.
 }
 
-Result<void> IoOveruseMonitor::updateIoOveruseConfiguration(ComponentType type,
-                                                            const IoOveruseConfiguration& config) {
+Result<void> IoOveruseMonitor::updateResourceOveruseConfigurations(
+        const std::vector<ResourceOveruseConfiguration>& configs) {
     std::unique_lock writeLock(mRwMutex);
     if (!isInitializedLocked()) {
         return Error(Status::EX_ILLEGAL_STATE) << name() << " is not initialized";
     }
-    return mIoOveruseConfigs->update(type, config);
+    return mIoOveruseConfigs->update(configs);
+}
+
+Result<void> IoOveruseMonitor::getResourceOveruseConfigurations(
+        std::vector<ResourceOveruseConfiguration>* configs) {
+    std::shared_lock readLock(mRwMutex);
+    if (!isInitializedLocked()) {
+        return Error(Status::EX_ILLEGAL_STATE) << name() << " is not initialized";
+    }
+    mIoOveruseConfigs->get(configs);
+    return {};
 }
 
 Result<void> IoOveruseMonitor::actionTakenOnIoOveruse(
         [[maybe_unused]] const std::vector<PackageResourceOveruseAction>& actions) {
-    // TODO(b/167240592): Upload metrics.
+    // TODO(b/184310189): Upload metrics.
+    if (DEBUG) {
+        ALOGD("Recorded action taken on I/O overuse");
+    }
     return {};
 }
 
@@ -381,6 +457,9 @@
                 << "(pid " << callingPid << ", uid: " << callingUid << ") is dead";
     }
     mOveruseListenersByUid[callingUid] = listener;
+    if (DEBUG) {
+        ALOGD("Added I/O overuse listener for uid: %d", callingUid);
+    }
     return {};
 }
 
@@ -396,11 +475,14 @@
         !findListenerAndProcessLocked(binder, processor)) {
         return Error(Status::EX_ILLEGAL_ARGUMENT) << "Listener is not previously registered";
     }
+    if (DEBUG) {
+        ALOGD("Removed I/O overuse listener for uid: %d", IPCThreadState::self()->getCallingUid());
+    }
     return {};
 }
 
 Result<void> IoOveruseMonitor::getIoOveruseStats(IoOveruseStats* ioOveruseStats) {
-    if (std::shared_lock readLock(mRwMutex); !isInitializedLocked()) {
+    if (!isInitialized()) {
         return Error(Status::EX_ILLEGAL_STATE) << "I/O overuse monitor is not initialized";
     }
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -433,6 +515,9 @@
             calculateStartAndDuration(mLastUserPackageIoMonitorTime);
     ioOveruseStats->startTime = startTime;
     ioOveruseStats->durationInSeconds = durationInSeconds;
+    if (DEBUG) {
+        ALOGD("Returning I/O overuse listener for uid: %d", callingUid);
+    }
     return {};
 }
 
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.h b/cpp/watchdog/server/src/IoOveruseMonitor.h
index e96f749..7040353 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.h
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.h
@@ -66,10 +66,17 @@
  */
 class IIoOveruseMonitor : virtual public IDataProcessorInterface {
 public:
+    // Returns whether or not the monitor is initialized.
+    virtual bool isInitialized() = 0;
+
     // Below API is from internal/ICarWatchdog.aidl. Please refer to the AIDL for description.
-    virtual android::base::Result<void> updateIoOveruseConfiguration(
-            android::automotive::watchdog::internal::ComponentType type,
-            const android::automotive::watchdog::internal::IoOveruseConfiguration& config) = 0;
+    virtual android::base::Result<void> updateResourceOveruseConfigurations(
+            const std::vector<
+                    android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
+                    configs) = 0;
+    virtual android::base::Result<void> getResourceOveruseConfigurations(
+            std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
+                    configs) = 0;
     virtual android::base::Result<void> actionTakenOnIoOveruse(
             const std::vector<
                     android::automotive::watchdog::internal::PackageResourceOveruseAction>&
@@ -88,19 +95,15 @@
 class IoOveruseMonitor final : public IIoOveruseMonitor {
 public:
     explicit IoOveruseMonitor(
-            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper) :
-          mWatchdogServiceHelper(watchdogServiceHelper),
-          mSystemWideWrittenBytes({}),
-          mPeriodicMonitorBufferSize(0),
-          mLastSystemWideIoMonitorTime(0),
-          mUserPackageDailyIoUsageById({}),
-          mIoOveruseWarnPercentage(0),
-          mLastUserPackageIoMonitorTime(0),
-          mOveruseListenersByUid({}),
-          mBinderDeathRecipient(new BinderDeathRecipient(this)) {}
+            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper);
 
     ~IoOveruseMonitor() { terminate(); }
 
+    bool isInitialized() {
+        std::shared_lock readLock(mRwMutex);
+        return isInitializedLocked();
+    }
+
     // Below methods implement IDataProcessorInterface.
     std::string name() { return "IoOveruseMonitor"; }
     friend std::ostream& operator<<(std::ostream& os, const IoOveruseMonitor& monitor);
@@ -112,7 +115,7 @@
         return {};
     }
 
-    // TODO(b/167240592): Forward WatchdogBinderMediator's notifySystemStateChange call to
+    // TODO(b/185498771): Forward WatchdogBinderMediator's notifySystemStateChange call to
     //  WatchdogPerfService. On POWER_CYCLE_SHUTDOWN_PREPARE, switch to garage mode collection
     //  and pass collection flag as a param in this API to indicate garage mode collection.
     android::base::Result<void> onPeriodicCollection(time_t time,
@@ -129,7 +132,7 @@
             time_t time, const android::wp<IProcDiskStatsInterface>& procDiskStats,
             const std::function<void()>& alertHandler);
 
-    // TODO(b/167240592): Forward WatchdogBinderMediator's notifySystemStateChange call to
+    // TODO(b/185498771): Forward WatchdogBinderMediator's notifySystemStateChange call to
     //  WatchdogProcessService. On POWER_CYCLE_SHUTDOWN_PREPARE_COMPLETE, call this method via
     //  the IDataProcessorInterface. onShutdownPrepareComplete, IoOveruseMonitor will flush
     //  in-memory stats to disk.
@@ -143,9 +146,14 @@
     }
 
     // Below methods implement AIDL interfaces.
-    android::base::Result<void> updateIoOveruseConfiguration(
-            android::automotive::watchdog::internal::ComponentType type,
-            const android::automotive::watchdog::internal::IoOveruseConfiguration& config);
+    android::base::Result<void> updateResourceOveruseConfigurations(
+            const std::vector<
+                    android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
+                    configs);
+
+    android::base::Result<void> getResourceOveruseConfigurations(
+            std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
+                    configs);
 
     android::base::Result<void> actionTakenOnIoOveruse(
             const std::vector<
@@ -178,6 +186,7 @@
         PerStateBytes forgivenWriteBytes = {};
         int totalOveruses = 0;
         bool isPackageWarned = false;
+        uint64_t lastSyncedWrittenBytes = 0;
 
         UserPackageIoUsage& operator+=(const UserPackageIoUsage& r);
 
@@ -208,14 +217,15 @@
     using Processor = std::function<void(ListenersByUidMap&, ListenersByUidMap::const_iterator)>;
     bool findListenerAndProcessLocked(const sp<IBinder>& binder, const Processor& processor);
 
-    // Local IPackageInfoResolverInterface instance. Useful to mock in tests.
-    sp<IPackageInfoResolverInterface> mPackageInfoResolver;
+    // Local IPackageInfoResolver instance. Useful to mock in tests.
+    sp<IPackageInfoResolver> mPackageInfoResolver;
+    // Minimum written bytes to sync the stats with the Watchdog service.
+    double mMinSyncWrittenBytes;
+    android::sp<IWatchdogServiceHelperInterface> mWatchdogServiceHelper;
 
     // Makes sure only one collection is running at any given time.
     mutable std::shared_mutex mRwMutex;
 
-    android::sp<IWatchdogServiceHelperInterface> mWatchdogServiceHelper GUARDED_BY(mRwMutex);
-
     // Summary of configs available for all the components and system-wide overuse alert thresholds.
     sp<IIoOveruseConfigs> mIoOveruseConfigs GUARDED_BY(mRwMutex);
 
diff --git a/cpp/watchdog/server/src/IoPerfCollection.cpp b/cpp/watchdog/server/src/IoPerfCollection.cpp
index 059059a..22dc45f 100644
--- a/cpp/watchdog/server/src/IoPerfCollection.cpp
+++ b/cpp/watchdog/server/src/IoPerfCollection.cpp
@@ -421,9 +421,6 @@
 
     for (const auto& uIt : usages) {
         const UidIoUsage& curUsage = uIt.second;
-        if (curUsage.ios.isZero()) {
-            continue;
-        }
         uids.push_back(curUsage.uid);
         uidIoPerfData->total[READ_BYTES][FOREGROUND] +=
                 curUsage.ios.metrics[READ_BYTES][FOREGROUND];
diff --git a/cpp/watchdog/server/src/IoPerfCollection.h b/cpp/watchdog/server/src/IoPerfCollection.h
index c8a9627..e86320f 100644
--- a/cpp/watchdog/server/src/IoPerfCollection.h
+++ b/cpp/watchdog/server/src/IoPerfCollection.h
@@ -195,8 +195,8 @@
     // Top N per-process stats per subcategory.
     int mTopNStatsPerSubcategory;
 
-    // Local IPackageInfoResolverInterface instance. Useful to mock in tests.
-    sp<IPackageInfoResolverInterface> mPackageInfoResolver;
+    // Local IPackageInfoResolver instance. Useful to mock in tests.
+    sp<IPackageInfoResolver> mPackageInfoResolver;
 
     // Makes sure only one collection is running at any given time.
     Mutex mMutex;
diff --git a/cpp/watchdog/server/src/PackageInfoResolver.cpp b/cpp/watchdog/server/src/PackageInfoResolver.cpp
index 2e22909..1a4346a 100644
--- a/cpp/watchdog/server/src/PackageInfoResolver.cpp
+++ b/cpp/watchdog/server/src/PackageInfoResolver.cpp
@@ -23,10 +23,10 @@
 #include <android/automotive/watchdog/internal/ComponentType.h>
 #include <android/automotive/watchdog/internal/UidType.h>
 #include <cutils/android_filesystem_config.h>
-#include <utils/String16.h>
 
 #include <inttypes.h>
 
+#include <iterator>
 #include <string_view>
 
 namespace android {
@@ -35,7 +35,6 @@
 
 using ::android::IBinder;
 using ::android::sp;
-using ::android::String16;
 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
 using ::android::automotive::watchdog::internal::ComponentType;
 using ::android::automotive::watchdog::internal::PackageInfo;
@@ -46,10 +45,13 @@
 using ::android::binder::Status;
 
 using GetpwuidFunction = std::function<struct passwd*(uid_t)>;
+using PackageToAppCategoryMap =
+        std::unordered_map<std::string,
+                           android::automotive::watchdog::internal::ApplicationCategoryType>;
 
 namespace {
 
-constexpr const char16_t* kSharedPackagePrefix = u"shared:";
+constexpr const char* kSharedPackagePrefix = "shared:";
 
 ComponentType getComponentTypeForNativeUid(uid_t uid, std::string_view packageName,
                                            const std::vector<std::string>& vendorPackagePrefixes) {
@@ -79,15 +81,11 @@
         return Error() << "Failed to fetch package name";
     }
     const char* packageName = usrpwd->pw_name;
-    packageInfo.packageIdentifier.name = String16(packageName);
+    packageInfo.packageIdentifier.name = packageName;
     packageInfo.packageIdentifier.uid = uid;
     packageInfo.uidType = UidType::NATIVE;
     packageInfo.componentType =
             getComponentTypeForNativeUid(uid, packageName, vendorPackagePrefixes);
-    /**
-     * TODO(b/167240592): Identify application category type using the package names. Vendor
-     *  should define the mappings from package name to the application category type.
-     */
     packageInfo.appCategoryType = ApplicationCategoryType::OTHERS;
     packageInfo.sharedUidPackages = {};
 
@@ -99,7 +97,7 @@
 sp<PackageInfoResolver> PackageInfoResolver::sInstance = nullptr;
 GetpwuidFunction PackageInfoResolver::sGetpwuidHandler = &getpwuid;
 
-sp<IPackageInfoResolverInterface> PackageInfoResolver::getInstance() {
+sp<IPackageInfoResolver> PackageInfoResolver::getInstance() {
     if (sInstance == nullptr) {
         sInstance = new PackageInfoResolver();
     }
@@ -123,13 +121,15 @@
     return {};
 }
 
-void PackageInfoResolver::setVendorPackagePrefixes(
-        const std::unordered_set<std::string>& prefixes) {
+void PackageInfoResolver::setPackageConfigurations(
+        const std::unordered_set<std::string>& vendorPackagePrefixes,
+        const PackageToAppCategoryMap& packagesToAppCategories) {
     std::unique_lock writeLock(mRWMutex);
     mVendorPackagePrefixes.clear();
-    for (const auto& prefix : prefixes) {
-        mVendorPackagePrefixes.push_back(prefix);
-    }
+    std::copy(vendorPackagePrefixes.begin(), vendorPackagePrefixes.end(),
+              std::back_inserter(mVendorPackagePrefixes));
+    mPackagesToAppCategories = packagesToAppCategories;
+    // Clear the package info cache as the package configurations have changed.
     mUidToPackageInfoMapping.clear();
 }
 
@@ -151,7 +151,7 @@
             continue;
         }
         mUidToPackageInfoMapping[uid] = *result;
-        if (result->packageIdentifier.name.startsWith(kSharedPackagePrefix)) {
+        if (StartsWith(result->packageIdentifier.name, kSharedPackagePrefix)) {
             // When the UID is shared, poll car watchdog service to fetch the shared packages info.
             missingUids.emplace_back(static_cast<int32_t>(uid));
         }
@@ -174,11 +174,16 @@
               status.exceptionMessage().c_str());
         return;
     }
-    for (const auto& packageInfo : packageInfos) {
-        if (packageInfo.packageIdentifier.name.size() == 0) {
+    for (auto& packageInfo : packageInfos) {
+        const auto& id = packageInfo.packageIdentifier;
+        if (id.name.empty()) {
             continue;
         }
-        mUidToPackageInfoMapping[packageInfo.packageIdentifier.uid] = packageInfo;
+        if (const auto it = mPackagesToAppCategories.find(id.name);
+            packageInfo.uidType == UidType::APPLICATION && it != mPackagesToAppCategories.end()) {
+            packageInfo.appCategoryType = it->second;
+        }
+        mUidToPackageInfoMapping[id.uid] = packageInfo;
     }
 }
 
@@ -193,8 +198,8 @@
         std::shared_lock readLock(mRWMutex);
         for (const auto& uid : uids) {
             if (mUidToPackageInfoMapping.find(uid) != mUidToPackageInfoMapping.end()) {
-                uidToPackageNameMapping[uid] = std::string(
-                        String8(mUidToPackageInfoMapping.at(uid).packageIdentifier.name));
+                uidToPackageNameMapping[uid] =
+                        mUidToPackageInfoMapping.at(uid).packageIdentifier.name;
             }
         }
     }
diff --git a/cpp/watchdog/server/src/PackageInfoResolver.h b/cpp/watchdog/server/src/PackageInfoResolver.h
index c0fc139..e13f47b 100644
--- a/cpp/watchdog/server/src/PackageInfoResolver.h
+++ b/cpp/watchdog/server/src/PackageInfoResolver.h
@@ -20,6 +20,7 @@
 #include "WatchdogServiceHelper.h"
 
 #include <android-base/result.h>
+#include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
 #include <android/automotive/watchdog/internal/PackageInfo.h>
 #include <binder/IBinder.h>
 #include <gtest/gtest_prod.h>
@@ -49,7 +50,7 @@
 
 }  // namespace internal
 
-class IPackageInfoResolverInterface : public android::RefBase {
+class IPackageInfoResolver : public android::RefBase {
 public:
     virtual std::unordered_map<uid_t, std::string> getPackageNamesForUids(
             const std::vector<uid_t>& uids) = 0;
@@ -59,7 +60,11 @@
 protected:
     virtual android::base::Result<void> initWatchdogServiceHelper(
             const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper) = 0;
-    virtual void setVendorPackagePrefixes(const std::unordered_set<std::string>& prefixes) = 0;
+    virtual void setPackageConfigurations(
+            const std::unordered_set<std::string>& vendorPackagePrefixes,
+            const std::unordered_map<
+                    std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
+                    packagesToAppCategories) = 0;
 
 private:
     friend class ServiceManager;
@@ -75,13 +80,13 @@
  * TODO(b/158131194): Extend IUidObserver in WatchdogBinderMediator and use the onUidGone API to
  *  keep the local mapping cache up-to-date.
  */
-class PackageInfoResolver : public IPackageInfoResolverInterface {
+class PackageInfoResolver : public IPackageInfoResolver {
 public:
     /*
      * Initializes the PackageInfoResolver's singleton instance only on the first call. Main thread
      * should make the first call as this method doesn't offer multi-threading protection.
      */
-    static sp<IPackageInfoResolverInterface> getInstance();
+    static sp<IPackageInfoResolver> getInstance();
 
     /*
      * Resolves the given |uids| and returns a mapping of uids to package names. If the mapping
@@ -109,7 +114,11 @@
     android::base::Result<void> initWatchdogServiceHelper(
             const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper);
 
-    void setVendorPackagePrefixes(const std::unordered_set<std::string>& prefixes);
+    virtual void setPackageConfigurations(
+            const std::unordered_set<std::string>& vendorPackagePrefixes,
+            const std::unordered_map<
+                    std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
+                    packagesToAppCategories);
 
 private:
     // PackageInfoResolver instance can only be obtained via |getInstance|.
@@ -136,6 +145,9 @@
     std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
             mUidToPackageInfoMapping GUARDED_BY(mRWMutex);
     std::vector<std::string> mVendorPackagePrefixes GUARDED_BY(mRWMutex);
+    std::unordered_map<std::string,
+                       android::automotive::watchdog::internal::ApplicationCategoryType>
+            mPackagesToAppCategories GUARDED_BY(mRWMutex);
 
     friend class ServiceManager;
     friend class IoOveruseMonitor;
diff --git a/cpp/watchdog/server/src/ServiceManager.cpp b/cpp/watchdog/server/src/ServiceManager.cpp
index 7e8e93b..6bcba40 100644
--- a/cpp/watchdog/server/src/ServiceManager.cpp
+++ b/cpp/watchdog/server/src/ServiceManager.cpp
@@ -26,7 +26,6 @@
 namespace watchdog {
 
 using ::android::sp;
-using ::android::String16;
 using ::android::automotive::watchdog::WatchdogPerfService;
 using ::android::automotive::watchdog::WatchdogProcessService;
 using ::android::base::Error;
@@ -48,7 +47,7 @@
      * by calling the getInstance method before starting other service as they may access
      * PackageInfoResolver's instance during initialization.
      */
-    sp<IPackageInfoResolverInterface> packageInfoResolver = PackageInfoResolver::getInstance();
+    sp<IPackageInfoResolver> packageInfoResolver = PackageInfoResolver::getInstance();
     if (const auto result = startProcessAnrMonitor(looper); !result.ok()) {
         return result;
     }
diff --git a/cpp/watchdog/server/src/UidIoStats.cpp b/cpp/watchdog/server/src/UidIoStats.cpp
index 31cd0d9..ce7b351 100644
--- a/cpp/watchdog/server/src/UidIoStats.cpp
+++ b/cpp/watchdog/server/src/UidIoStats.cpp
@@ -113,11 +113,16 @@
 
     mDeltaUidIoUsages.clear();
     for (const auto& it : *uidIoUsages) {
-        const UidIoUsage& curUsage = it.second;
-        mDeltaUidIoUsages[it.first] = curUsage;
-        if (mLatestUidIoUsages.find(it.first) != mLatestUidIoUsages.end()) {
-            mDeltaUidIoUsages[it.first] -= mLatestUidIoUsages[it.first];
+        UidIoUsage curUsage = it.second;
+        if (curUsage.ios.isZero()) {
+            continue;
         }
+        if (mLatestUidIoUsages.find(it.first) != mLatestUidIoUsages.end()) {
+            if (curUsage -= mLatestUidIoUsages[it.first]; curUsage.ios.isZero()) {
+                continue;
+            }
+        }
+        mDeltaUidIoUsages[it.first] = curUsage;
     }
     mLatestUidIoUsages = *uidIoUsages;
     return {};
diff --git a/cpp/watchdog/server/src/UidIoStats.h b/cpp/watchdog/server/src/UidIoStats.h
index c6e87d1..3cc6a76 100644
--- a/cpp/watchdog/server/src/UidIoStats.h
+++ b/cpp/watchdog/server/src/UidIoStats.h
@@ -18,6 +18,7 @@
 #define CPP_WATCHDOG_SERVER_SRC_UIDIOSTATS_H_
 
 #include <android-base/result.h>
+#include <android-base/stringprintf.h>
 #include <utils/Mutex.h>
 #include <utils/RefBase.h>
 
@@ -87,6 +88,10 @@
         ios -= rhs.ios;
         return *this;
     }
+    bool operator==(const UidIoUsage& rhs) const { return uid == rhs.uid && ios == rhs.ios; }
+    std::string toString() const {
+        return android::base::StringPrintf("Uid: %d, Usage: {%s}", uid, ios.toString().c_str());
+    }
 };
 
 class UidIoStats : public RefBase {
diff --git a/cpp/watchdog/server/src/WatchdogBinderMediator.cpp b/cpp/watchdog/server/src/WatchdogBinderMediator.cpp
index b27d9a9..0a4eb25 100644
--- a/cpp/watchdog/server/src/WatchdogBinderMediator.cpp
+++ b/cpp/watchdog/server/src/WatchdogBinderMediator.cpp
@@ -32,6 +32,7 @@
 using ::android::defaultServiceManager;
 using ::android::IBinder;
 using ::android::sp;
+using ::android::String16;
 using ::android::base::Error;
 using ::android::base::Join;
 using ::android::base::ParseUint;
@@ -170,7 +171,6 @@
         ALOGW("Failed to dump I/O perf collection: %s", ret.error().message().c_str());
         return ret.error().code();
     }
-    // TODO(b/167240592): Add a dump call to I/O overuse monitor and relevant tests.
     return OK;
 }
 
diff --git a/cpp/watchdog/server/src/WatchdogBinderMediator.h b/cpp/watchdog/server/src/WatchdogBinderMediator.h
index e470290..63b687b 100644
--- a/cpp/watchdog/server/src/WatchdogBinderMediator.h
+++ b/cpp/watchdog/server/src/WatchdogBinderMediator.h
@@ -66,7 +66,7 @@
     ~WatchdogBinderMediator() { terminate(); }
 
     // Implements ICarWatchdog.aidl APIs.
-    status_t dump(int fd, const Vector<String16>& args) override;
+    status_t dump(int fd, const Vector<android::String16>& args) override;
     android::binder::Status registerClient(const android::sp<ICarWatchdogClient>& client,
                                            TimeoutLength timeout) override;
     android::binder::Status unregisterClient(
diff --git a/cpp/watchdog/server/src/WatchdogInternalHandler.cpp b/cpp/watchdog/server/src/WatchdogInternalHandler.cpp
index 0ed7cb8..556f9f1 100644
--- a/cpp/watchdog/server/src/WatchdogInternalHandler.cpp
+++ b/cpp/watchdog/server/src/WatchdogInternalHandler.cpp
@@ -34,9 +34,10 @@
 
 using aawi::ComponentType;
 using aawi::ICarWatchdogServiceForSystem;
-using aawi::IoOveruseConfiguration;
 using aawi::PackageResourceOveruseAction;
+using aawi::ResourceOveruseConfiguration;
 using ::android::sp;
+using ::android::String16;
 using ::android::binder::Status;
 
 namespace {
@@ -65,6 +66,18 @@
     return mBinderMediator->dump(fd, args);
 }
 
+void WatchdogInternalHandler::checkAndRegisterIoOveruseMonitor() {
+    if (mIoOveruseMonitor->isInitialized()) {
+        return;
+    }
+    if (const auto result = mWatchdogPerfService->registerDataProcessor(mIoOveruseMonitor);
+        !result.ok()) {
+        ALOGE("Failed to register I/O overuse monitor to watchdog performance service: %s",
+              result.error().message().c_str());
+    }
+    return;
+}
+
 Status WatchdogInternalHandler::registerCarWatchdogService(
         const sp<ICarWatchdogServiceForSystem>& service) {
     Status status = checkSystemUser();
@@ -74,6 +87,12 @@
     if (service == nullptr) {
         return fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, kNullCarWatchdogServiceError);
     }
+    /*
+     * I/O overuse monitor reads from system, vendor, and data partitions during initialization.
+     * When CarService is running these partitions are available to read, thus register the I/O
+     * overuse monitor on processing the request to register CarService.
+     */
+    checkAndRegisterIoOveruseMonitor();
     return mWatchdogServiceHelper->registerService(service);
 }
 
@@ -167,19 +186,6 @@
                 if (const auto result = mWatchdogPerfService->onBootFinished(); !result.ok()) {
                     return fromExceptionCode(result.error().code(), result.error().message());
                 }
-                /*
-                 * I/O overuse monitor reads from data partition on init so register the I/O
-                 * overuse monitor only on boot-complete.
-                 *
-                 * TODO(b/167240592): Uncomment the below code block after the I/O overuse monitor
-                 *  is completely implemented.
-                 * if (const auto result
-                 *          = mWatchdogPerfService->registerDataProcessor(mIoOveruseMonitor);
-                 *     !result.ok()) {
-                 *    ALOGW("Failed to register I/O overuse monitor to watchdog performance "
-                 *          "service: %s", result.error().message().c_str());
-                 * }
-                 */
             }
             return Status::ok();
         }
@@ -188,13 +194,30 @@
                              StringPrintf("Invalid state change type %d", type));
 }
 
-Status WatchdogInternalHandler::updateIoOveruseConfiguration(ComponentType type,
-                                                             const IoOveruseConfiguration& config) {
+Status WatchdogInternalHandler::updateResourceOveruseConfigurations(
+        const std::vector<ResourceOveruseConfiguration>& configs) {
     Status status = checkSystemUser();
     if (!status.isOk()) {
         return status;
     }
-    if (const auto result = mIoOveruseMonitor->updateIoOveruseConfiguration(type, config);
+    // Maybe retry registring I/O overuse monitor if failed to initialize previously.
+    checkAndRegisterIoOveruseMonitor();
+    if (const auto result = mIoOveruseMonitor->updateResourceOveruseConfigurations(configs);
+        !result.ok()) {
+        return fromExceptionCode(result.error().code(), result.error().message());
+    }
+    return Status::ok();
+}
+
+Status WatchdogInternalHandler::getResourceOveruseConfigurations(
+        std::vector<ResourceOveruseConfiguration>* configs) {
+    Status status = checkSystemUser();
+    if (!status.isOk()) {
+        return status;
+    }
+    // Maybe retry registring I/O overuse monitor if failed to initialize previously.
+    checkAndRegisterIoOveruseMonitor();
+    if (const auto result = mIoOveruseMonitor->getResourceOveruseConfigurations(configs);
         !result.ok()) {
         return fromExceptionCode(result.error().code(), result.error().message());
     }
diff --git a/cpp/watchdog/server/src/WatchdogInternalHandler.h b/cpp/watchdog/server/src/WatchdogInternalHandler.h
index 9254ed6..098b0dd 100644
--- a/cpp/watchdog/server/src/WatchdogInternalHandler.h
+++ b/cpp/watchdog/server/src/WatchdogInternalHandler.h
@@ -26,12 +26,13 @@
 #include <android/automotive/watchdog/internal/ComponentType.h>
 #include <android/automotive/watchdog/internal/ICarWatchdogMonitor.h>
 #include <android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.h>
-#include <android/automotive/watchdog/internal/IoOveruseConfiguration.h>
 #include <android/automotive/watchdog/internal/PackageResourceOveruseAction.h>
+#include <android/automotive/watchdog/internal/ResourceOveruseConfiguration.h>
 #include <android/automotive/watchdog/internal/StateType.h>
 #include <binder/Status.h>
 #include <gtest/gtest_prod.h>
 #include <utils/Errors.h>
+#include <utils/String16.h>
 #include <utils/Vector.h>
 
 namespace android {
@@ -55,7 +56,7 @@
           mIoOveruseMonitor(ioOveruseMonitor) {}
     ~WatchdogInternalHandler() { terminate(); }
 
-    status_t dump(int fd, const Vector<String16>& args) override;
+    status_t dump(int fd, const Vector<android::String16>& args) override;
     android::binder::Status registerCarWatchdogService(
             const android::sp<
                     android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>& service)
@@ -81,9 +82,13 @@
     android::binder::Status notifySystemStateChange(
             android::automotive::watchdog::internal::StateType type, int32_t arg1,
             int32_t arg2) override;
-    android::binder::Status updateIoOveruseConfiguration(
-            android::automotive::watchdog::internal::ComponentType type,
-            const android::automotive::watchdog::internal::IoOveruseConfiguration& config) override;
+    android::binder::Status updateResourceOveruseConfigurations(
+            const std::vector<
+                    android::automotive::watchdog::internal::ResourceOveruseConfiguration>& configs)
+            override;
+    android::binder::Status getResourceOveruseConfigurations(
+            std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
+                    configs) override;
     android::binder::Status actionTakenOnResourceOveruse(
             const std::vector<
                     android::automotive::watchdog::internal::PackageResourceOveruseAction>&
@@ -99,6 +104,8 @@
     }
 
 private:
+    void checkAndRegisterIoOveruseMonitor();
+
     android::sp<WatchdogBinderMediator> mBinderMediator;
     android::sp<IWatchdogServiceHelperInterface> mWatchdogServiceHelper;
     android::sp<WatchdogProcessService> mWatchdogProcessService;
diff --git a/cpp/watchdog/server/src/WatchdogPerfService.cpp b/cpp/watchdog/server/src/WatchdogPerfService.cpp
index 79177ad..214a16c 100644
--- a/cpp/watchdog/server/src/WatchdogPerfService.cpp
+++ b/cpp/watchdog/server/src/WatchdogPerfService.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "carwatchdogd"
+#define DEBUG false  // STOPSHIP if true.
 
 #include "WatchdogPerfService.h"
 
@@ -36,6 +37,7 @@
 namespace watchdog {
 
 using ::android::String16;
+using ::android::String8;
 using ::android::base::Error;
 using ::android::base::Join;
 using ::android::base::ParseUint;
@@ -140,6 +142,9 @@
     }
     Mutex::Autolock lock(mMutex);
     mDataProcessors.push_back(processor);
+    if (DEBUG) {
+        ALOGD("Successfully registered %s to %s", processor->name().c_str(), kServiceName);
+    }
     return {};
 }
 
@@ -241,6 +246,9 @@
     }
     if (mCollectionThread.joinable()) {
         mCollectionThread.join();
+        if (DEBUG) {
+            ALOGD("%s collection thread terminated", kServiceName);
+        }
     }
 }
 
@@ -260,6 +268,9 @@
     mBoottimeCollection.lastUptime = mHandlerLooper->now();
     mHandlerLooper->removeMessages(this);
     mHandlerLooper->sendMessage(this, SwitchMessage::END_BOOTTIME_COLLECTION);
+    if (DEBUG) {
+        ALOGD("Boot-time event finished");
+    }
     return {};
 }
 
@@ -471,6 +482,9 @@
         }
     }
 
+    if (DEBUG) {
+        ALOGD("Custom event finished");
+    }
     WriteStringToFd(kDumpMajorDelimiter, fd);
     return {};
 }
@@ -564,6 +578,9 @@
               toString(mCurrCollectionEvent));
         return {};
     }
+    if (DEBUG) {
+        ALOGD("Processing %s collection event", toString(metadata->eventType));
+    }
     if (metadata->interval < kMinEventInterval) {
         return Error()
                 << "Collection interval of "
@@ -636,6 +653,9 @@
     if (metadata->eventType != static_cast<int>(EventType::PERIODIC_MONITOR)) {
         return Error() << "Invalid monitor event " << toString(metadata->eventType);
     }
+    if (DEBUG) {
+        ALOGD("Processing %s monitor event", toString(metadata->eventType));
+    }
     if (metadata->interval < kMinEventInterval) {
         return Error()
                 << "Monitor interval of "
diff --git a/cpp/watchdog/server/src/WatchdogPerfService.h b/cpp/watchdog/server/src/WatchdogPerfService.h
index c44659b..0551d35 100644
--- a/cpp/watchdog/server/src/WatchdogPerfService.h
+++ b/cpp/watchdog/server/src/WatchdogPerfService.h
@@ -171,7 +171,8 @@
     // 1. Starts a custom collection.
     // 2. Or ends the current custom collection and dumps the collected data.
     // Returns any error observed during the dump generation.
-    virtual android::base::Result<void> onCustomCollection(int fd, const Vector<String16>& args);
+    virtual android::base::Result<void> onCustomCollection(int fd,
+                                                           const Vector<android::String16>& args);
 
     // Generates a dump from the boot-time and periodic collection events.
     virtual android::base::Result<void> onDump(int fd);
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.cpp b/cpp/watchdog/server/src/WatchdogProcessService.cpp
index 7af7ecc..952c83e 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.cpp
+++ b/cpp/watchdog/server/src/WatchdogProcessService.cpp
@@ -48,6 +48,7 @@
 using aawi::ICarWatchdogServiceForSystem;
 using ::android::IBinder;
 using ::android::sp;
+using ::android::String16;
 using ::android::base::Error;
 using ::android::base::GetProperty;
 using ::android::base::ReadFileToString;
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.h b/cpp/watchdog/server/src/WatchdogProcessService.h
index c4ae2cb..288f99e 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.h
+++ b/cpp/watchdog/server/src/WatchdogProcessService.h
@@ -50,7 +50,8 @@
 
     android::base::Result<void> start();
     void terminate();
-    virtual android::base::Result<void> dump(int fd, const android::Vector<String16>& args);
+    virtual android::base::Result<void> dump(int fd,
+                                             const android::Vector<android::String16>& args);
     void doHealthCheck(int what);
 
     virtual android::base::Result<void> registerWatchdogServiceHelper(
diff --git a/cpp/watchdog/server/src/WatchdogServiceHelper.cpp b/cpp/watchdog/server/src/WatchdogServiceHelper.cpp
index f89942e..03f3305 100644
--- a/cpp/watchdog/server/src/WatchdogServiceHelper.cpp
+++ b/cpp/watchdog/server/src/WatchdogServiceHelper.cpp
@@ -34,7 +34,6 @@
 using aawi::PackageIoOveruseStats;
 using ::android::IBinder;
 using ::android::sp;
-using ::android::String16;
 using ::android::wp;
 using ::android::base::Error;
 using ::android::base::Result;
@@ -180,21 +179,17 @@
 Status WatchdogServiceHelper::getPackageInfosForUids(
         const std::vector<int32_t>& uids, const std::vector<std::string>& vendorPackagePrefixes,
         std::vector<PackageInfo>* packageInfos) {
-    /*
-     * The expected number of vendor package prefixes is in the order of 10s. Thus the overhead of
-     * forwarding these in each get call is very low.
-     */
-    std::vector<String16> prefixes;
-    for (const auto& prefix : vendorPackagePrefixes) {
-        prefixes.push_back(String16(prefix.c_str()));
-    }
     sp<ICarWatchdogServiceForSystem> service;
     if (std::shared_lock readLock(mRWMutex); mService == nullptr) {
         return fromExceptionCode(Status::EX_ILLEGAL_STATE, "Watchdog service is not initialized");
     } else {
         service = mService;
     }
-    return service->getPackageInfosForUids(uids, prefixes, packageInfos);
+    /*
+     * The expected number of vendor package prefixes is in the order of 10s. Thus the overhead of
+     * forwarding these in each get call is very low.
+     */
+    return service->getPackageInfosForUids(uids, vendorPackagePrefixes, packageInfos);
 }
 
 Status WatchdogServiceHelper::latestIoOveruseStats(
diff --git a/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp b/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
index e1602f8..433f027 100644
--- a/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
+++ b/cpp/watchdog/server/tests/IoOveruseConfigsTest.cpp
@@ -18,7 +18,6 @@
 
 #include <android-base/strings.h>
 #include <gmock/gmock.h>
-#include <utils/String8.h>
 
 #include <inttypes.h>
 
@@ -26,40 +25,38 @@
 namespace automotive {
 namespace watchdog {
 
-using ::android::String16;
-using ::android::String8;
+using ::android::sp;
 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
 using ::android::automotive::watchdog::internal::ComponentType;
 using ::android::automotive::watchdog::internal::IoOveruseAlertThreshold;
 using ::android::automotive::watchdog::internal::IoOveruseConfiguration;
 using ::android::automotive::watchdog::internal::PackageInfo;
+using ::android::automotive::watchdog::internal::PackageMetadata;
 using ::android::automotive::watchdog::internal::PerStateIoOveruseThreshold;
+using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
+using ::android::automotive::watchdog::internal::ResourceSpecificConfiguration;
 using ::android::automotive::watchdog::internal::UidType;
+using ::android::base::StringAppendF;
 using ::android::base::StringPrintf;
+using ::testing::AllOf;
 using ::testing::AnyOf;
+using ::testing::ExplainMatchResult;
+using ::testing::Field;
 using ::testing::IsEmpty;
+using ::testing::Matcher;
 using ::testing::UnorderedElementsAre;
+using ::testing::UnorderedElementsAreArray;
 using ::testing::Value;
 
 namespace {
 
-PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const std::string& name,
-                                                        const int64_t fgBytes,
-                                                        const int64_t bgBytes,
-                                                        const int64_t garageModeBytes) {
-    PerStateIoOveruseThreshold threshold;
-    threshold.name = String16(String8(name.c_str()));
-    threshold.perStateWriteBytes.foregroundBytes = fgBytes;
-    threshold.perStateWriteBytes.backgroundBytes = bgBytes;
-    threshold.perStateWriteBytes.garageModeBytes = garageModeBytes;
-    return threshold;
-}
-
-PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const ComponentType type,
-                                                        const int64_t fgBytes,
-                                                        const int64_t bgBytes,
-                                                        const int64_t garageModeBytes) {
-    return toPerStateIoOveruseThreshold(toString(type), fgBytes, bgBytes, garageModeBytes);
+PerStateBytes toPerStateBytes(const int64_t fgBytes, const int64_t bgBytes,
+                              const int64_t garageModeBytes) {
+    PerStateBytes perStateBytes;
+    perStateBytes.foregroundBytes = fgBytes;
+    perStateBytes.backgroundBytes = bgBytes;
+    perStateBytes.garageModeBytes = garageModeBytes;
+    return perStateBytes;
 }
 
 IoOveruseAlertThreshold toIoOveruseAlertThreshold(const int64_t durationInSeconds,
@@ -70,430 +67,726 @@
     return threshold;
 }
 
-std::vector<String16> toString16Vector(const std::vector<std::string>& values) {
-    std::vector<String16> output;
-    for (const auto v : values) {
-        output.emplace_back(String16(String8(v.c_str())));
+const PerStateBytes SYSTEM_COMPONENT_LEVEL_THRESHOLDS = toPerStateBytes(200, 100, 500);
+const PerStateBytes SYSTEM_PACKAGE_A_THRESHOLDS = toPerStateBytes(600, 400, 1000);
+const PerStateBytes SYSTEM_PACKAGE_B_THRESHOLDS = toPerStateBytes(1200, 800, 1500);
+const PerStateBytes VENDOR_COMPONENT_LEVEL_THRESHOLDS = toPerStateBytes(100, 50, 900);
+const PerStateBytes VENDOR_PACKAGE_A_THRESHOLDS = toPerStateBytes(800, 300, 500);
+const PerStateBytes VENDOR_PKG_B_THRESHOLDS = toPerStateBytes(1600, 600, 1000);
+const PerStateBytes MAPS_THRESHOLDS = toPerStateBytes(700, 900, 1300);
+const PerStateBytes MEDIA_THRESHOLDS = toPerStateBytes(1800, 1900, 2100);
+const PerStateBytes THIRD_PARTY_COMPONENT_LEVEL_THRESHOLDS = toPerStateBytes(300, 150, 1900);
+const std::vector<IoOveruseAlertThreshold> ALERT_THRESHOLDS = {toIoOveruseAlertThreshold(5, 200),
+                                                               toIoOveruseAlertThreshold(30,
+                                                                                         40000)};
+
+PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const std::string& name,
+                                                        const PerStateBytes& perStateBytes) {
+    PerStateIoOveruseThreshold threshold;
+    threshold.name = name;
+    threshold.perStateWriteBytes = perStateBytes;
+    return threshold;
+}
+
+PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const ComponentType type,
+                                                        const PerStateBytes& perStateBytes) {
+    return toPerStateIoOveruseThreshold(toString(type), perStateBytes);
+}
+
+PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const std::string& name,
+                                                        const int64_t fgBytes,
+                                                        const int64_t bgBytes,
+                                                        const int64_t garageModeBytes) {
+    PerStateIoOveruseThreshold threshold;
+    threshold.name = name;
+    threshold.perStateWriteBytes = toPerStateBytes(fgBytes, bgBytes, garageModeBytes);
+    return threshold;
+}
+
+PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const ComponentType type,
+                                                        const int64_t fgBytes,
+                                                        const int64_t bgBytes,
+                                                        const int64_t garageModeBytes) {
+    return toPerStateIoOveruseThreshold(toString(type), fgBytes, bgBytes, garageModeBytes);
+}
+
+PackageMetadata toPackageMetadata(std::string packageName, ApplicationCategoryType type) {
+    PackageMetadata meta;
+    meta.packageName = packageName;
+    meta.appCategoryType = type;
+    return meta;
+}
+
+std::unordered_map<std::string, ApplicationCategoryType> toPackageToAppCategoryMappings(
+        const std::vector<PackageMetadata>& metas) {
+    std::unordered_map<std::string, ApplicationCategoryType> mappings;
+    for (const auto& meta : metas) {
+        mappings[meta.packageName] = meta.appCategoryType;
     }
-    return output;
+    return mappings;
 }
 
 PackageInfo constructPackageInfo(
         const char* packageName, const ComponentType componentType,
         const ApplicationCategoryType appCategoryType = ApplicationCategoryType::OTHERS) {
     PackageInfo packageInfo;
-    packageInfo.packageIdentifier.name = String16(packageName);
+    packageInfo.packageIdentifier.name = packageName;
     packageInfo.uidType = UidType::APPLICATION;
     packageInfo.componentType = componentType;
     packageInfo.appCategoryType = appCategoryType;
     return packageInfo;
 }
 
-struct PackageConfigTest {
-    PackageInfo packageInfo;
-    PerStateBytes expectedThreshold;
-    bool expectedIsSafeToKill;
-};
+ResourceOveruseConfiguration constructResourceOveruseConfig(
+        const ComponentType type, const std::vector<std::string>&& safeToKill,
+        const std::vector<std::string>&& vendorPrefixes,
+        const std::vector<PackageMetadata> packageMetadata,
+        const IoOveruseConfiguration& ioOveruseConfiguration) {
+    ResourceOveruseConfiguration resourceOveruseConfig;
+    resourceOveruseConfig.componentType = type;
+    resourceOveruseConfig.safeToKillPackages = safeToKill;
+    resourceOveruseConfig.vendorPackagePrefixes = vendorPrefixes;
+    resourceOveruseConfig.packageMetadata = packageMetadata;
+    ResourceSpecificConfiguration config;
+    config.set<ResourceSpecificConfiguration::ioOveruseConfiguration>(ioOveruseConfiguration);
+    resourceOveruseConfig.resourceSpecificConfigurations.push_back(config);
+    return resourceOveruseConfig;
+}
+
+IoOveruseConfiguration constructIoOveruseConfig(
+        PerStateIoOveruseThreshold componentLevel,
+        const std::vector<PerStateIoOveruseThreshold>& packageSpecific,
+        const std::vector<PerStateIoOveruseThreshold>& categorySpecific,
+        const std::vector<IoOveruseAlertThreshold>& systemWide) {
+    IoOveruseConfiguration config;
+    config.componentLevelThresholds = componentLevel;
+    config.packageSpecificThresholds = packageSpecific;
+    config.categorySpecificThresholds = categorySpecific;
+    config.systemWideThresholds = systemWide;
+    return config;
+}
+
+std::string toString(std::vector<ResourceOveruseConfiguration> configs) {
+    std::string buffer;
+    StringAppendF(&buffer, "[");
+    for (const auto& config : configs) {
+        if (buffer.size() > 1) {
+            StringAppendF(&buffer, ",\n");
+        }
+        StringAppendF(&buffer, "%s", config.toString().c_str());
+    }
+    StringAppendF(&buffer, "]\n");
+    return buffer;
+}
+
+MATCHER_P(IsIoOveruseConfiguration, config, "") {
+    return arg.componentLevelThresholds == config.componentLevelThresholds &&
+            ExplainMatchResult(UnorderedElementsAreArray(config.packageSpecificThresholds),
+                               arg.packageSpecificThresholds, result_listener) &&
+            ExplainMatchResult(UnorderedElementsAreArray(config.categorySpecificThresholds),
+                               arg.categorySpecificThresholds, result_listener) &&
+            ExplainMatchResult(UnorderedElementsAreArray(config.systemWideThresholds),
+                               arg.systemWideThresholds, result_listener);
+}
+
+MATCHER_P(IsResourceSpecificConfiguration, config, "") {
+    if (arg.getTag() != config.getTag()) {
+        return false;
+    }
+    // Reference with the actual datatype so the templated get method can be called.
+    const ResourceSpecificConfiguration& expected = config;
+    const ResourceSpecificConfiguration& actual = arg;
+    switch (arg.getTag()) {
+        case ResourceSpecificConfiguration::ioOveruseConfiguration: {
+            const auto& expectedIoConfig =
+                    expected.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+            const auto& actualIoConfig =
+                    actual.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
+            return ExplainMatchResult(IsIoOveruseConfiguration(expectedIoConfig), actualIoConfig,
+                                      result_listener);
+        }
+        default:
+            return true;
+    }
+}
+
+Matcher<const ResourceOveruseConfiguration> IsResourceOveruseConfiguration(
+        const ResourceOveruseConfiguration& config) {
+    std::vector<Matcher<const ResourceSpecificConfiguration>> matchers;
+    for (const auto& resourceSpecificConfig : config.resourceSpecificConfigurations) {
+        matchers.push_back(IsResourceSpecificConfiguration(resourceSpecificConfig));
+    }
+
+    return AllOf(Field(&ResourceOveruseConfiguration::componentType, config.componentType),
+                 Field(&ResourceOveruseConfiguration::safeToKillPackages,
+                       UnorderedElementsAreArray(config.safeToKillPackages)),
+                 Field(&ResourceOveruseConfiguration::vendorPackagePrefixes,
+                       UnorderedElementsAreArray(config.vendorPackagePrefixes)),
+                 Field(&ResourceOveruseConfiguration::resourceSpecificConfigurations,
+                       UnorderedElementsAreArray(matchers)));
+}
+
+std::vector<Matcher<const ResourceOveruseConfiguration>> IsResourceOveruseConfigurations(
+        const std::vector<ResourceOveruseConfiguration>& configs) {
+    std::vector<Matcher<const ResourceOveruseConfiguration>> matchers;
+    for (const auto config : configs) {
+        matchers.push_back(IsResourceOveruseConfiguration(config));
+    }
+    return matchers;
+}
+
+ResourceOveruseConfiguration sampleSystemConfig() {
+    auto systemIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
+                                                            SYSTEM_COMPONENT_LEVEL_THRESHOLDS),
+            /*packageSpecific=*/
+            {toPerStateIoOveruseThreshold("systemPackageA", SYSTEM_PACKAGE_A_THRESHOLDS),
+             toPerStateIoOveruseThreshold("systemPackageB", SYSTEM_PACKAGE_B_THRESHOLDS)},
+            /*categorySpecific=*/{},
+            /*systemWide=*/ALERT_THRESHOLDS);
+    return constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageA"},
+                                          /*vendorPrefixes=*/{},
+                                          /*packageMetadata=*/
+                                          {toPackageMetadata("systemPackageA",
+                                                             ApplicationCategoryType::MEDIA),
+                                           toPackageMetadata("vendorPkgB",
+                                                             ApplicationCategoryType::MAPS)},
+                                          systemIoConfig);
+}
+
+ResourceOveruseConfiguration sampleVendorConfig() {
+    auto vendorIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
+                                                            VENDOR_COMPONENT_LEVEL_THRESHOLDS),
+            /*packageSpecific=*/
+            {toPerStateIoOveruseThreshold("vendorPackageA", VENDOR_PACKAGE_A_THRESHOLDS),
+             toPerStateIoOveruseThreshold("vendorPkgB", VENDOR_PKG_B_THRESHOLDS)},
+            /*categorySpecific=*/
+            {toPerStateIoOveruseThreshold("MAPS", MAPS_THRESHOLDS),
+             toPerStateIoOveruseThreshold("MEDIA", MEDIA_THRESHOLDS)},
+            /*systemWide=*/{});
+    return constructResourceOveruseConfig(ComponentType::VENDOR,
+                                          /*safeToKill=*/{"vendorPackageA"},
+                                          /*vendorPrefixes=*/{"vendorPackage"},
+                                          /*packageMetadata=*/
+                                          {toPackageMetadata("systemPackageA",
+                                                             ApplicationCategoryType::MEDIA),
+                                           toPackageMetadata("vendorPkgB",
+                                                             ApplicationCategoryType::MAPS)},
+                                          vendorIoConfig);
+}
+
+ResourceOveruseConfiguration sampleThirdPartyConfig() {
+    auto thirdPartyIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/
+            toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
+                                         THIRD_PARTY_COMPONENT_LEVEL_THRESHOLDS),
+            /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{});
+    return constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
+                                          /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
+                                          thirdPartyIoConfig);
+}
+
+sp<IoOveruseConfigs> sampleIoOveruseConfigs() {
+    sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
+    EXPECT_RESULT_OK(ioOveruseConfigs->update(
+            {sampleSystemConfig(), sampleVendorConfig(), sampleThirdPartyConfig()}));
+    return ioOveruseConfigs;
+}
 
 }  // namespace
 
 TEST(IoOveruseConfigsTest, TestUpdateWithValidConfigs) {
-    IoOveruseConfiguration systemComponentConfig;
-    systemComponentConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 200, 100, 500);
-    systemComponentConfig.packageSpecificThresholds =
-            {toPerStateIoOveruseThreshold("systemPackageA", 600, 400, 1000),
-             toPerStateIoOveruseThreshold("systemPackageB", 1200, 800, 1500)};
-    systemComponentConfig.safeToKillPackages = toString16Vector({"systemPackageA"});
-    systemComponentConfig.systemWideThresholds = {toIoOveruseAlertThreshold(5, 200),
-                                                  toIoOveruseAlertThreshold(30, 40000)};
-
-    IoOveruseConfiguration vendorComponentConfig;
-    vendorComponentConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::VENDOR, 100, 50, 900);
-    vendorComponentConfig.packageSpecificThresholds =
-            {toPerStateIoOveruseThreshold("vendorPackageA", 800, 300, 500),
-             toPerStateIoOveruseThreshold("vendorPkgB", 1600, 600, 1000)};
-    vendorComponentConfig.safeToKillPackages =
-            toString16Vector({"vendorPackageGeneric", "vendorPackageA"});
-    vendorComponentConfig.vendorPackagePrefixes = toString16Vector({"vendorPackage", "vendorPkg"});
-    vendorComponentConfig.categorySpecificThresholds = {toPerStateIoOveruseThreshold("MAPS", 600,
-                                                                                     400, 1000),
-                                                        toPerStateIoOveruseThreshold("MEDIA", 1200,
-                                                                                     800, 1500)};
-
-    IoOveruseConfiguration thirdPartyComponentConfig;
-    thirdPartyComponentConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 300, 150, 1900);
+    auto systemResourceConfig = sampleSystemConfig();
+    auto vendorResourceConfig = sampleVendorConfig();
+    auto thirdPartyResourceConfig = sampleThirdPartyConfig();
 
     IoOveruseConfigs ioOveruseConfigs;
-    ASSERT_RESULT_OK(ioOveruseConfigs.update(ComponentType::SYSTEM, systemComponentConfig));
-    ASSERT_RESULT_OK(ioOveruseConfigs.update(ComponentType::VENDOR, vendorComponentConfig));
-    ASSERT_RESULT_OK(
-            ioOveruseConfigs.update(ComponentType::THIRD_PARTY, thirdPartyComponentConfig));
+    ASSERT_RESULT_OK(ioOveruseConfigs.update(
+            {systemResourceConfig, vendorResourceConfig, thirdPartyResourceConfig}));
 
-    std::vector<PackageConfigTest> packageConfigTests = {
-            {.packageInfo = constructPackageInfo("systemPackageGeneric", ComponentType::SYSTEM),
-             .expectedThreshold = systemComponentConfig.componentLevelThresholds.perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("systemPackageA", ComponentType::SYSTEM),
-             .expectedThreshold =
-                     systemComponentConfig.packageSpecificThresholds[0].perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-            {.packageInfo = constructPackageInfo("systemPackageB", ComponentType::SYSTEM,
-                                                 ApplicationCategoryType::MEDIA),
-             .expectedThreshold =
-                     systemComponentConfig.packageSpecificThresholds[1].perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("systemPackageC", ComponentType::SYSTEM,
-                                                 ApplicationCategoryType::MAPS),
-             .expectedThreshold =
-                     vendorComponentConfig.categorySpecificThresholds[0].perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("vendorPackageGeneric", ComponentType::VENDOR),
-             .expectedThreshold = vendorComponentConfig.componentLevelThresholds.perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-            {.packageInfo = constructPackageInfo("vendorPackageA", ComponentType::VENDOR),
-             .expectedThreshold =
-                     vendorComponentConfig.packageSpecificThresholds[0].perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-            {.packageInfo = constructPackageInfo("vendorPkgB", ComponentType::VENDOR,
-                                                 ApplicationCategoryType::MAPS),
-             .expectedThreshold =
-                     vendorComponentConfig.packageSpecificThresholds[1].perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("vendorPackageC", ComponentType::VENDOR,
-                                                 ApplicationCategoryType::MEDIA),
-             .expectedThreshold =
-                     vendorComponentConfig.categorySpecificThresholds[1].perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("vendorPkgB", ComponentType::THIRD_PARTY),
-             .expectedThreshold =
-                     thirdPartyComponentConfig.componentLevelThresholds.perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-            {.packageInfo = constructPackageInfo("3pMapsPackage", ComponentType::THIRD_PARTY,
-                                                 ApplicationCategoryType::MAPS),
-             .expectedThreshold =
-                     vendorComponentConfig.categorySpecificThresholds[0].perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-            {.packageInfo = constructPackageInfo("3pMediaPackage", ComponentType::THIRD_PARTY,
-                                                 ApplicationCategoryType::MEDIA),
-             .expectedThreshold =
-                     vendorComponentConfig.categorySpecificThresholds[1].perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-    };
+    vendorResourceConfig.vendorPackagePrefixes.push_back("vendorPkgB");
+    std::vector<ResourceOveruseConfiguration> expected = {systemResourceConfig,
+                                                          vendorResourceConfig,
+                                                          thirdPartyResourceConfig};
 
-    for (const auto& test : packageConfigTests) {
-        const auto actualThreshold = ioOveruseConfigs.fetchThreshold(test.packageInfo);
-        EXPECT_THAT(actualThreshold, test.expectedThreshold)
-                << test.packageInfo.toString()
-                << ": \nExpected threshold: " << test.expectedThreshold.toString()
-                << "\nActual threshold: " << actualThreshold.toString();
-        EXPECT_THAT(ioOveruseConfigs.isSafeToKill(test.packageInfo), test.expectedIsSafeToKill)
-                << test.packageInfo.toString() << ": doesn't match expected safe-to-kill value";
-    }
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
 
-    EXPECT_THAT(ioOveruseConfigs.systemWideAlertThresholds(),
-                UnorderedElementsAre(systemComponentConfig.systemWideThresholds[0],
-                                     systemComponentConfig.systemWideThresholds[1]));
-
-    EXPECT_THAT(ioOveruseConfigs.vendorPackagePrefixes(),
-                UnorderedElementsAre(std::string(String8(
-                                             vendorComponentConfig.vendorPackagePrefixes[0])),
-                                     std::string(String8(
-                                             vendorComponentConfig.vendorPackagePrefixes[1]))));
+    EXPECT_THAT(actual, UnorderedElementsAreArray(IsResourceOveruseConfigurations(expected)))
+            << "Expected: " << toString(expected) << "Actual:" << toString(actual);
 
     // Check whether previous configs are overwritten.
-    systemComponentConfig = {};
-    systemComponentConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 300, 400, 600);
-    systemComponentConfig.packageSpecificThresholds =
+    auto systemIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 300, 400, 600),
+            /*packageSpecific=*/
             {toPerStateIoOveruseThreshold("systemPackageC", 700, 100, 200),
-             toPerStateIoOveruseThreshold("systemPackageC", 300, 200, 300)};
-    systemComponentConfig.safeToKillPackages = toString16Vector({"systemPackageC"});
-    systemComponentConfig.systemWideThresholds = {toIoOveruseAlertThreshold(6, 4),
-                                                  toIoOveruseAlertThreshold(6, 10)};
+             toPerStateIoOveruseThreshold("systemPackageC", 300, 200, 300)},
+            /*categorySpecific=*/{},
+            /*systemWide=*/
+            {toIoOveruseAlertThreshold(6, 4), toIoOveruseAlertThreshold(6, 10)});
+    systemResourceConfig =
+            constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageC"},
+                                           /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
+                                           systemIoConfig);
 
-    vendorComponentConfig = {};
-    vendorComponentConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::VENDOR, 10, 90, 300);
     /*
      * Not adding any safe to kill packages list or package specific thresholds should clear
      * previous entries after update.
      */
-    vendorComponentConfig.vendorPackagePrefixes = toString16Vector({"vendorPackage", "vendorPkg"});
-    vendorComponentConfig
-            .categorySpecificThresholds = {toPerStateIoOveruseThreshold("MAPS", 800, 900, 2000),
-                                           toPerStateIoOveruseThreshold("MEDIA", 1200, 800, 1500),
-                                           toPerStateIoOveruseThreshold("MEDIA", 1400, 1600, 2000)};
+    auto vendorIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR, 10, 90, 300),
+            /*packageSpecific=*/{},
+            /*categorySpecific=*/
+            {toPerStateIoOveruseThreshold("MAPS", 800, 900, 2000),
+             toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100),
+             toPerStateIoOveruseThreshold("MEDIA", 1400, 1600, 2000)},
+            /*systemWide=*/{});
+    vendorResourceConfig =
+            constructResourceOveruseConfig(ComponentType::VENDOR, /*safeToKill=*/{},
+                                           /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
+                                           /*packageMetadata=*/{}, vendorIoConfig);
 
-    thirdPartyComponentConfig = {};
-    thirdPartyComponentConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 600, 300, 2300);
+    auto thirdPartyIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/
+            toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 600, 300, 2300),
+            /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{});
+    thirdPartyResourceConfig =
+            constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
+                                           /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
+                                           thirdPartyIoConfig);
 
-    ASSERT_RESULT_OK(ioOveruseConfigs.update(ComponentType::SYSTEM, systemComponentConfig));
-    ASSERT_RESULT_OK(ioOveruseConfigs.update(ComponentType::VENDOR, vendorComponentConfig));
-    ASSERT_RESULT_OK(
-            ioOveruseConfigs.update(ComponentType::THIRD_PARTY, thirdPartyComponentConfig));
+    ASSERT_RESULT_OK(ioOveruseConfigs.update(
+            {systemResourceConfig, vendorResourceConfig, thirdPartyResourceConfig}));
 
-    packageConfigTests = {
-            {.packageInfo = constructPackageInfo("systemPackageA", ComponentType::SYSTEM),
-             .expectedThreshold = systemComponentConfig.componentLevelThresholds.perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("systemPackageC", ComponentType::SYSTEM),
-             .expectedThreshold =
-                     systemComponentConfig.packageSpecificThresholds[1].perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-            {.packageInfo = constructPackageInfo("systemMapsPackage", ComponentType::SYSTEM,
-                                                 ApplicationCategoryType::MAPS),
-             .expectedThreshold =
-                     vendorComponentConfig.categorySpecificThresholds[0].perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("vendorPackageA", ComponentType::VENDOR),
-             .expectedThreshold = vendorComponentConfig.componentLevelThresholds.perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("vendorMediaPackage", ComponentType::VENDOR,
-                                                 ApplicationCategoryType::MEDIA),
-             .expectedThreshold =
-                     vendorComponentConfig.categorySpecificThresholds[2].perStateWriteBytes,
-             .expectedIsSafeToKill = false},
-            {.packageInfo = constructPackageInfo("3pPackage", ComponentType::THIRD_PARTY),
-             .expectedThreshold =
-                     thirdPartyComponentConfig.componentLevelThresholds.perStateWriteBytes,
-             .expectedIsSafeToKill = true},
-    };
+    systemIoConfig.packageSpecificThresholds.erase(
+            systemIoConfig.packageSpecificThresholds.begin());
+    systemIoConfig.systemWideThresholds.erase(systemIoConfig.systemWideThresholds.begin() + 1);
+    systemResourceConfig =
+            constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageC"},
+                                           /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
+                                           systemIoConfig);
 
-    for (const auto& test : packageConfigTests) {
-        const auto actualThreshold = ioOveruseConfigs.fetchThreshold(test.packageInfo);
-        EXPECT_THAT(actualThreshold, test.expectedThreshold)
-                << test.packageInfo.toString()
-                << ": \nExpected threshold: " << test.expectedThreshold.toString()
-                << "\nActual threshold: " << actualThreshold.toString();
-        EXPECT_THAT(ioOveruseConfigs.isSafeToKill(test.packageInfo), test.expectedIsSafeToKill)
-                << test.packageInfo.toString() << ": doesn't match expected safe-to-kill value";
-    }
+    vendorIoConfig.categorySpecificThresholds.erase(
+            vendorIoConfig.categorySpecificThresholds.begin() + 1);
+    vendorResourceConfig =
+            constructResourceOveruseConfig(ComponentType::VENDOR, /*safeToKill=*/{},
+                                           /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
+                                           /*packageMetadata=*/{}, vendorIoConfig);
 
-    EXPECT_THAT(ioOveruseConfigs.systemWideAlertThresholds(),
-                UnorderedElementsAre(AnyOf(systemComponentConfig.systemWideThresholds[0],
-                                           systemComponentConfig.systemWideThresholds[1])));
+    expected = {systemResourceConfig, vendorResourceConfig, thirdPartyResourceConfig};
 
-    EXPECT_THAT(ioOveruseConfigs.vendorPackagePrefixes(),
-                UnorderedElementsAre(std::string(String8(
-                                             vendorComponentConfig.vendorPackagePrefixes[0])),
-                                     std::string(String8(
-                                             vendorComponentConfig.vendorPackagePrefixes[1]))));
+    actual.clear();
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, UnorderedElementsAreArray(IsResourceOveruseConfigurations(expected)))
+            << "Expected: " << toString(expected) << "Actual:" << toString(actual);
 }
 
 TEST(IoOveruseConfigsTest, TestDefaultConfigWithoutUpdate) {
-    std::vector<PackageConfigTest> packageConfigTests =
-            {{.packageInfo = constructPackageInfo("systemPackage", ComponentType::SYSTEM),
-              .expectedThreshold = defaultThreshold().perStateWriteBytes,
-              .expectedIsSafeToKill = false},
-             {.packageInfo = constructPackageInfo("vendorPackage", ComponentType::VENDOR,
-                                                  ApplicationCategoryType::MEDIA),
-              .expectedThreshold = defaultThreshold().perStateWriteBytes,
-              .expectedIsSafeToKill = false},
-             {.packageInfo = constructPackageInfo("3pPackage", ComponentType::THIRD_PARTY,
-                                                  ApplicationCategoryType::MAPS),
-              .expectedThreshold = defaultThreshold().perStateWriteBytes,
-              .expectedIsSafeToKill = true}};
+    PerStateBytes defaultPerStateBytes = defaultThreshold().perStateWriteBytes;
     IoOveruseConfigs ioOveruseConfigs;
 
-    for (const auto& test : packageConfigTests) {
-        const auto actualThreshold = ioOveruseConfigs.fetchThreshold(test.packageInfo);
-        EXPECT_THAT(actualThreshold, test.expectedThreshold)
-                << test.packageInfo.toString()
-                << ": \nExpected threshold: " << test.expectedThreshold.toString()
-                << "\nActual threshold: " << actualThreshold.toString();
-        EXPECT_THAT(ioOveruseConfigs.isSafeToKill(test.packageInfo), test.expectedIsSafeToKill)
-                << test.packageInfo.toString() << ": doesn't match expected safe-to-kill value";
-    }
+    auto packageInfo = constructPackageInfo("systemPackage", ComponentType::SYSTEM);
+    EXPECT_THAT(ioOveruseConfigs.fetchThreshold(packageInfo), defaultPerStateBytes)
+            << "System package should have default threshold";
+    EXPECT_FALSE(ioOveruseConfigs.isSafeToKill(packageInfo))
+            << "System package shouldn't be killed by default";
+
+    packageInfo = constructPackageInfo("vendorPackage", ComponentType::VENDOR,
+                                       ApplicationCategoryType::MEDIA);
+    EXPECT_THAT(ioOveruseConfigs.fetchThreshold(packageInfo), defaultPerStateBytes)
+            << "Vendor package should have default threshold";
+    EXPECT_FALSE(ioOveruseConfigs.isSafeToKill(packageInfo))
+            << "Vendor package shouldn't be killed by default";
+
+    packageInfo = constructPackageInfo("3pPackage", ComponentType::THIRD_PARTY,
+                                       ApplicationCategoryType::MAPS);
+    EXPECT_THAT(ioOveruseConfigs.fetchThreshold(packageInfo), defaultPerStateBytes)
+            << "Third-party package should have default threshold";
+    EXPECT_TRUE(ioOveruseConfigs.isSafeToKill(packageInfo))
+            << "Third-party package should be killed by default";
 
     EXPECT_THAT(ioOveruseConfigs.systemWideAlertThresholds(), IsEmpty());
     EXPECT_THAT(ioOveruseConfigs.vendorPackagePrefixes(), IsEmpty());
+
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, IsEmpty());
 }
 
 TEST(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentName) {
-    IoOveruseConfiguration updateConfig;
-    updateConfig.componentLevelThresholds =
+    IoOveruseConfiguration randomIoConfig;
+    randomIoConfig.componentLevelThresholds =
             toPerStateIoOveruseThreshold("random name", 200, 100, 500);
 
     IoOveruseConfigs ioOveruseConfigs;
-    EXPECT_FALSE(ioOveruseConfigs.update(ComponentType::SYSTEM, updateConfig).ok());
+    EXPECT_FALSE(ioOveruseConfigs
+                         .update({constructResourceOveruseConfig(ComponentType::SYSTEM, {}, {}, {},
+                                                                 randomIoConfig)})
+                         .ok());
 
-    EXPECT_FALSE(ioOveruseConfigs.update(ComponentType::VENDOR, updateConfig).ok());
+    EXPECT_FALSE(ioOveruseConfigs
+                         .update({constructResourceOveruseConfig(ComponentType::VENDOR, {}, {}, {},
+                                                                 randomIoConfig)})
+                         .ok());
 
-    EXPECT_FALSE(ioOveruseConfigs.update(ComponentType::THIRD_PARTY, updateConfig).ok());
+    EXPECT_FALSE(ioOveruseConfigs
+                         .update({constructResourceOveruseConfig(ComponentType::THIRD_PARTY, {}, {},
+                                                                 {}, randomIoConfig)})
+                         .ok());
+
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, IsEmpty());
 }
 
-TEST(IoOveruseConfigsTest, TestFailsUpdateOnInvalidConfigs) {
-    IoOveruseConfiguration updateConfig;
-    updateConfig.componentLevelThresholds =
+TEST(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentLevelThresholds) {
+    IoOveruseConfiguration ioConfig;
+    ioConfig.componentLevelThresholds =
             toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 0, 0, 0);
-    const IoOveruseConfigs expected = {};
 
     IoOveruseConfigs ioOveruseConfigs;
-
-    EXPECT_FALSE(ioOveruseConfigs.update(ComponentType::THIRD_PARTY, updateConfig).ok())
+    EXPECT_FALSE(ioOveruseConfigs
+                         .update({constructResourceOveruseConfig(ComponentType::THIRD_PARTY, {}, {},
+                                                                 {}, ioConfig)})
+                         .ok())
             << "Should error on invalid component level thresholds";
 
-    updateConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 100, 200, 300);
-    updateConfig.systemWideThresholds = {toIoOveruseAlertThreshold(0, 0)};
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
 
-    EXPECT_FALSE(ioOveruseConfigs.update(ComponentType::SYSTEM, updateConfig).ok())
+    EXPECT_THAT(actual, IsEmpty());
+}
+
+TEST(IoOveruseConfigsTest, TestFailsUpdateOnInvalidSystemWideAlertThresholds) {
+    IoOveruseConfiguration ioConfig;
+    ioConfig.componentLevelThresholds =
+            toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 100, 200, 300);
+    ioConfig.systemWideThresholds = {toIoOveruseAlertThreshold(0, 0)};
+
+    IoOveruseConfigs ioOveruseConfigs;
+    EXPECT_FALSE(ioOveruseConfigs
+                         .update({constructResourceOveruseConfig(ComponentType::SYSTEM, {}, {}, {},
+                                                                 ioConfig)})
+                         .ok())
             << "Should error on invalid system-wide thresholds";
+
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, IsEmpty());
+}
+
+TEST(IoOveruseConfigsTest, TestFailsUpdateOnDuplicateConfigsForSameComponent) {
+    IoOveruseConfigs ioOveruseConfigs;
+    EXPECT_FALSE(ioOveruseConfigs.update({sampleThirdPartyConfig(), sampleThirdPartyConfig()}).ok())
+            << "Should error on duplicate configs for the same component";
+
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, IsEmpty());
+}
+
+TEST(IoOveruseConfigsTest, TestFailsUpdateOnNoIoOveruseConfiguration) {
+    ResourceOveruseConfiguration resConfig;
+    resConfig.componentType = ComponentType::THIRD_PARTY;
+
+    IoOveruseConfigs ioOveruseConfigs;
+    EXPECT_FALSE(ioOveruseConfigs.update({resConfig}).ok())
+            << "Should error on no I/O overuse configuration";
+
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, IsEmpty());
+}
+
+TEST(IoOveruseConfigsTest, TestFailsUpdateOnMultipleIoOveruseConfigurations) {
+    IoOveruseConfiguration ioConfig;
+    ioConfig.componentLevelThresholds =
+            toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 100, 200, 300);
+
+    ResourceOveruseConfiguration resConfig;
+    resConfig.componentType = ComponentType::THIRD_PARTY;
+    ResourceSpecificConfiguration resourceSpecificConfig;
+    resourceSpecificConfig.set<ResourceSpecificConfiguration::ioOveruseConfiguration>(ioConfig);
+    resConfig.resourceSpecificConfigurations.push_back(resourceSpecificConfig);
+    resConfig.resourceSpecificConfigurations.push_back(resourceSpecificConfig);
+
+    IoOveruseConfigs ioOveruseConfigs;
+    EXPECT_FALSE(ioOveruseConfigs.update({resConfig}).ok())
+            << "Should error on multiple I/O overuse configuration";
+
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, IsEmpty());
 }
 
 TEST(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsBySystemComponent) {
-    IoOveruseConfiguration updateConfig;
-    updateConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 200, 100, 500);
-    updateConfig.packageSpecificThresholds = {toPerStateIoOveruseThreshold("systemPackageA", 600,
-                                                                           400, 1000),
-                                              toPerStateIoOveruseThreshold("systemPackageB", 1200,
-                                                                           800, 1500)};
-    updateConfig.safeToKillPackages = toString16Vector({"systemPackageA"});
-    updateConfig.vendorPackagePrefixes = toString16Vector({"vendorPackage"});
-    updateConfig.categorySpecificThresholds = {toPerStateIoOveruseThreshold("MAPS", 600, 400, 1000),
-                                               toPerStateIoOveruseThreshold("MEDIA", 1200, 800,
-                                                                            1500)};
-    updateConfig.systemWideThresholds = {toIoOveruseAlertThreshold(5, 200),
-                                         toIoOveruseAlertThreshold(30, 40000)};
+    auto systemIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 200, 100, 500),
+            /*packageSpecific=*/
+            {toPerStateIoOveruseThreshold("systemPackageA", 600, 400, 1000),
+             toPerStateIoOveruseThreshold("systemPackageB", 1200, 800, 1500)},
+            /*categorySpecific=*/
+            {toPerStateIoOveruseThreshold("MAPS", 700, 900, 1300),
+             toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100)},
+            /*systemWide=*/
+            {toIoOveruseAlertThreshold(5, 200), toIoOveruseAlertThreshold(30, 40000)});
+    auto systemResourceConfig =
+            constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageA"},
+                                           /*vendorPrefixes=*/{"vendorPackage"},
+                                           /*packageMetadata=*/{}, systemIoConfig);
 
     IoOveruseConfigs ioOveruseConfigs;
-    ASSERT_RESULT_OK(ioOveruseConfigs.update(ComponentType::SYSTEM, updateConfig));
+    ASSERT_RESULT_OK(ioOveruseConfigs.update({systemResourceConfig}));
 
-    std::vector<PackageConfigTest> packageConfigTests =
-            {{.packageInfo = constructPackageInfo("systemMapsPackage", ComponentType::SYSTEM,
-                                                  ApplicationCategoryType::MAPS),
-              .expectedThreshold = updateConfig.componentLevelThresholds.perStateWriteBytes,
-              .expectedIsSafeToKill = false},
-             {.packageInfo = constructPackageInfo("systemPackageA", ComponentType::SYSTEM),
-              .expectedThreshold = updateConfig.packageSpecificThresholds[0].perStateWriteBytes,
-              .expectedIsSafeToKill = true},
-             {.packageInfo = constructPackageInfo("systemPackageB", ComponentType::SYSTEM,
-                                                  ApplicationCategoryType::MEDIA),
-              .expectedThreshold = updateConfig.packageSpecificThresholds[1].perStateWriteBytes,
-              .expectedIsSafeToKill = false}};
+    // Drop fields that aren't updatable by system component.
+    systemIoConfig.categorySpecificThresholds.clear();
+    systemResourceConfig =
+            constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageA"},
+                                           /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
+                                           systemIoConfig);
 
-    for (const auto& test : packageConfigTests) {
-        const auto actualThreshold = ioOveruseConfigs.fetchThreshold(test.packageInfo);
-        EXPECT_THAT(actualThreshold, test.expectedThreshold)
-                << test.packageInfo.toString()
-                << ": \nExpected threshold: " << test.expectedThreshold.toString()
-                << "\nActual threshold: " << actualThreshold.toString();
-        EXPECT_THAT(ioOveruseConfigs.isSafeToKill(test.packageInfo), test.expectedIsSafeToKill)
-                << test.packageInfo.toString() << ": doesn't match expected safe-to-kill value";
-    }
+    std::vector<ResourceOveruseConfiguration> expected = {systemResourceConfig};
 
-    EXPECT_THAT(ioOveruseConfigs.systemWideAlertThresholds(),
-                UnorderedElementsAre(updateConfig.systemWideThresholds[0],
-                                     updateConfig.systemWideThresholds[1]));
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
 
-    EXPECT_THAT(ioOveruseConfigs.vendorPackagePrefixes(), IsEmpty())
-            << "System component config shouldn't update vendor package prefixes. Only vendor "
-            << "component config should update this";
+    EXPECT_THAT(actual, UnorderedElementsAreArray(IsResourceOveruseConfigurations(expected)))
+            << "Expected: " << toString(expected) << "Actual:" << toString(actual);
 }
 
 TEST(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByVendorComponent) {
-    IoOveruseConfiguration updateConfig;
-    updateConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::VENDOR, 100, 50, 900);
-    updateConfig.packageSpecificThresholds = {toPerStateIoOveruseThreshold("vendorPackageA", 800,
-                                                                           300, 500),
-                                              toPerStateIoOveruseThreshold("systemPackageB", 1600,
-                                                                           600, 1000)};
-    updateConfig.safeToKillPackages = toString16Vector({"vendorPackageA"});
-    updateConfig.vendorPackagePrefixes = toString16Vector({"vendorPackage"});
-    updateConfig.categorySpecificThresholds = {toPerStateIoOveruseThreshold("MAPS", 600, 400, 1000),
-                                               toPerStateIoOveruseThreshold("MEDIA", 1200, 800,
-                                                                            1500)};
-    updateConfig.systemWideThresholds = {toIoOveruseAlertThreshold(5, 200),
-                                         toIoOveruseAlertThreshold(30, 40000)};
+    auto vendorIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR, 100, 50, 900),
+            /*packageSpecific=*/
+            {toPerStateIoOveruseThreshold("vendorPackageA", 800, 300, 500),
+             toPerStateIoOveruseThreshold("vendorPkgB", 1600, 600, 1000)},
+            /*categorySpecific=*/
+            {toPerStateIoOveruseThreshold("MAPS", 700, 900, 1300),
+             toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100)},
+            /*systemWide=*/
+            {toIoOveruseAlertThreshold(5, 200), toIoOveruseAlertThreshold(30, 40000)});
+    auto vendorResourceConfig =
+            constructResourceOveruseConfig(ComponentType::VENDOR,
+                                           /*safeToKill=*/
+                                           {"vendorPackageA"},
+                                           /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
+                                           /*packageMetadata=*/{}, vendorIoConfig);
 
     IoOveruseConfigs ioOveruseConfigs;
-    ASSERT_RESULT_OK(ioOveruseConfigs.update(ComponentType::VENDOR, updateConfig));
+    ASSERT_RESULT_OK(ioOveruseConfigs.update({vendorResourceConfig}));
 
-    std::vector<PackageConfigTest> packageConfigTests =
-            {{.packageInfo = constructPackageInfo("vendorPackageGeneric", ComponentType::VENDOR),
-              .expectedThreshold = updateConfig.componentLevelThresholds.perStateWriteBytes,
-              .expectedIsSafeToKill = false},
-             {.packageInfo = constructPackageInfo("vendorPackageA", ComponentType::VENDOR),
-              .expectedThreshold = updateConfig.packageSpecificThresholds[0].perStateWriteBytes,
-              .expectedIsSafeToKill = true},
-             {.packageInfo = constructPackageInfo("systemPackageB", ComponentType::VENDOR,
-                                                  ApplicationCategoryType::MEDIA),
-              .expectedThreshold = updateConfig.packageSpecificThresholds[1].perStateWriteBytes,
-              .expectedIsSafeToKill = false},
-             {.packageInfo = constructPackageInfo("vendorMapsPackage", ComponentType::VENDOR,
-                                                  ApplicationCategoryType::MAPS),
-              .expectedThreshold = updateConfig.categorySpecificThresholds[0].perStateWriteBytes,
-              .expectedIsSafeToKill = false}};
+    // Drop fields that aren't updatable by vendor component.
+    vendorIoConfig.systemWideThresholds.clear();
+    vendorResourceConfig =
+            constructResourceOveruseConfig(ComponentType::VENDOR,
+                                           /*safeToKill=*/
+                                           {"vendorPackageA"},
+                                           /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
+                                           /*packageMetadata=*/{}, vendorIoConfig);
 
-    for (const auto& test : packageConfigTests) {
-        const auto actualThreshold = ioOveruseConfigs.fetchThreshold(test.packageInfo);
-        EXPECT_THAT(actualThreshold, test.expectedThreshold)
-                << test.packageInfo.toString()
-                << ": \nExpected threshold: " << test.expectedThreshold.toString()
-                << "\nActual threshold: " << actualThreshold.toString();
-        EXPECT_THAT(ioOveruseConfigs.isSafeToKill(test.packageInfo), test.expectedIsSafeToKill)
-                << test.packageInfo.toString() << ": doesn't match expected safe-to-kill value";
-    }
+    std::vector<ResourceOveruseConfiguration> expected = {vendorResourceConfig};
 
-    EXPECT_THAT(ioOveruseConfigs.systemWideAlertThresholds(), IsEmpty())
-            << "Vendor component config shouldn't update system wide alert thresholds. Only system "
-            << "component config should update this";
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
 
-    EXPECT_THAT(ioOveruseConfigs.vendorPackagePrefixes(),
-                UnorderedElementsAre("vendorPackage", "systemPackageB"));
+    EXPECT_THAT(actual, UnorderedElementsAreArray(IsResourceOveruseConfigurations(expected)))
+            << "Expected: " << toString(expected) << "Actual:" << toString(actual);
 }
 
 TEST(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByThirdPartyComponent) {
-    IoOveruseConfiguration updateConfig;
-    updateConfig.componentLevelThresholds =
-            toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 300, 150, 1900);
-    updateConfig.packageSpecificThresholds = {toPerStateIoOveruseThreshold("vendorPackageA", 800,
-                                                                           300, 500),
-                                              toPerStateIoOveruseThreshold("systemPackageB", 1600,
-                                                                           600, 1000)};
-    updateConfig.safeToKillPackages = toString16Vector({"vendorPackageA", "systemPackageB"});
-    updateConfig.vendorPackagePrefixes = toString16Vector({"vendorPackage"});
-    updateConfig.categorySpecificThresholds = {toPerStateIoOveruseThreshold("MAPS", 600, 400, 1000),
-                                               toPerStateIoOveruseThreshold("MEDIA", 1200, 800,
-                                                                            1500)};
-    updateConfig.systemWideThresholds = {toIoOveruseAlertThreshold(5, 200),
-                                         toIoOveruseAlertThreshold(30, 40000)};
+    auto thirdPartyIoConfig = constructIoOveruseConfig(
+            /*componentLevel=*/
+            toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 300, 150, 1900),
+            /*packageSpecific=*/
+            {toPerStateIoOveruseThreshold("vendorPackageA", 800, 300, 500),
+             toPerStateIoOveruseThreshold("systemPackageB", 1600, 600, 1000)},
+            /*categorySpecific=*/
+            {toPerStateIoOveruseThreshold("MAPS", 700, 900, 1300),
+             toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100)},
+            /*systemWide=*/
+            {toIoOveruseAlertThreshold(5, 200), toIoOveruseAlertThreshold(30, 40000)});
+    auto thirdPartyResourceConfig =
+            constructResourceOveruseConfig(ComponentType::THIRD_PARTY,
+                                           /*safeToKill=*/{"vendorPackageA", "systemPackageB"},
+                                           /*vendorPrefixes=*/{"vendorPackage"},
+                                           /*packageMetadata=*/{}, thirdPartyIoConfig);
 
     IoOveruseConfigs ioOveruseConfigs;
-    ASSERT_RESULT_OK(ioOveruseConfigs.update(ComponentType::THIRD_PARTY, updateConfig));
+    ASSERT_RESULT_OK(ioOveruseConfigs.update({thirdPartyResourceConfig}));
 
-    std::vector<PackageConfigTest> packageConfigTests =
-            {{.packageInfo = constructPackageInfo("vendorPackageA", ComponentType::THIRD_PARTY,
-                                                  ApplicationCategoryType::MAPS),
-              .expectedThreshold = updateConfig.componentLevelThresholds.perStateWriteBytes,
-              .expectedIsSafeToKill = true},
-             {.packageInfo = constructPackageInfo("systemPackageB", ComponentType::SYSTEM,
-                                                  ApplicationCategoryType::MAPS),
-              .expectedThreshold = defaultThreshold().perStateWriteBytes,
-              .expectedIsSafeToKill = false}};
+    // Drop fields that aren't updatable by third-party component.
+    thirdPartyIoConfig.packageSpecificThresholds.clear();
+    thirdPartyIoConfig.categorySpecificThresholds.clear();
+    thirdPartyIoConfig.systemWideThresholds.clear();
+    thirdPartyResourceConfig =
+            constructResourceOveruseConfig(ComponentType::THIRD_PARTY,
+                                           /*safeToKill=*/{}, /*vendorPrefixes=*/{},
+                                           /*packageMetadata=*/{}, thirdPartyIoConfig);
 
-    for (const auto& test : packageConfigTests) {
-        const auto actualThreshold = ioOveruseConfigs.fetchThreshold(test.packageInfo);
-        EXPECT_THAT(actualThreshold, test.expectedThreshold)
-                << test.packageInfo.toString()
-                << ": \nExpected threshold: " << test.expectedThreshold.toString()
-                << "\nActual threshold: " << actualThreshold.toString();
-        EXPECT_THAT(ioOveruseConfigs.isSafeToKill(test.packageInfo), test.expectedIsSafeToKill)
-                << test.packageInfo.toString() << ": doesn't match expected safe-to-kill value";
-    }
+    std::vector<ResourceOveruseConfiguration> expected = {thirdPartyResourceConfig};
 
-    EXPECT_THAT(ioOveruseConfigs.systemWideAlertThresholds(), IsEmpty())
-            << "Third-party component config shouldn't update system wide alert thresholds. "
-            << "Only system component config should update this";
-    EXPECT_THAT(ioOveruseConfigs.vendorPackagePrefixes(), IsEmpty())
-            << "Third-party component config shouldn't update vendor package prefixes. Only vendor "
-            << "component config should update this";
+    std::vector<ResourceOveruseConfiguration> actual;
+    ioOveruseConfigs.get(&actual);
+
+    EXPECT_THAT(actual, UnorderedElementsAreArray(IsResourceOveruseConfigurations(expected)))
+            << "Expected: " << toString(expected) << "Actual:" << toString(actual);
+}
+
+TEST(IoOveruseConfigsTest, TestFetchThresholdForSystemPackages) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+
+    auto actual = ioOveruseConfigs->fetchThreshold(
+            constructPackageInfo("systemPackageGeneric", ComponentType::SYSTEM));
+
+    EXPECT_THAT(actual, SYSTEM_COMPONENT_LEVEL_THRESHOLDS);
+
+    actual = ioOveruseConfigs->fetchThreshold(
+            constructPackageInfo("systemPackageA", ComponentType::SYSTEM));
+
+    EXPECT_THAT(actual, SYSTEM_PACKAGE_A_THRESHOLDS);
+
+    actual = ioOveruseConfigs->fetchThreshold(constructPackageInfo("systemPackageB",
+                                                                   ComponentType::SYSTEM,
+                                                                   ApplicationCategoryType::MEDIA));
+
+    // Package specific thresholds get priority over media category thresholds.
+    EXPECT_THAT(actual, SYSTEM_PACKAGE_B_THRESHOLDS);
+
+    actual = ioOveruseConfigs->fetchThreshold(constructPackageInfo("systemPackageC",
+                                                                   ComponentType::SYSTEM,
+                                                                   ApplicationCategoryType::MEDIA));
+
+    // Media category thresholds as there is no package specific thresholds.
+    EXPECT_THAT(actual, MEDIA_THRESHOLDS);
+}
+
+TEST(IoOveruseConfigsTest, TestFetchThresholdForVendorPackages) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+
+    auto actual = ioOveruseConfigs->fetchThreshold(
+            constructPackageInfo("vendorPackageGeneric", ComponentType::VENDOR));
+
+    EXPECT_THAT(actual, VENDOR_COMPONENT_LEVEL_THRESHOLDS);
+
+    actual = ioOveruseConfigs->fetchThreshold(
+            constructPackageInfo("vendorPkgB", ComponentType::VENDOR));
+
+    EXPECT_THAT(actual, VENDOR_PKG_B_THRESHOLDS);
+
+    actual = ioOveruseConfigs->fetchThreshold(constructPackageInfo("vendorPackageC",
+                                                                   ComponentType::VENDOR,
+                                                                   ApplicationCategoryType::MAPS));
+
+    // Maps category thresholds as there is no package specific thresholds.
+    EXPECT_THAT(actual, MAPS_THRESHOLDS);
+}
+
+TEST(IoOveruseConfigsTest, TestFetchThresholdForThirdPartyPackages) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+
+    auto actual = ioOveruseConfigs->fetchThreshold(
+            constructPackageInfo("vendorPackageGenericImpostor", ComponentType::THIRD_PARTY));
+
+    EXPECT_THAT(actual, THIRD_PARTY_COMPONENT_LEVEL_THRESHOLDS);
+
+    actual = ioOveruseConfigs->fetchThreshold(constructPackageInfo("3pMapsPackage",
+                                                                   ComponentType::THIRD_PARTY,
+                                                                   ApplicationCategoryType::MAPS));
+
+    EXPECT_THAT(actual, MAPS_THRESHOLDS);
+
+    actual = ioOveruseConfigs->fetchThreshold(constructPackageInfo("3pMediaPackage",
+                                                                   ComponentType::THIRD_PARTY,
+                                                                   ApplicationCategoryType::MEDIA));
+
+    EXPECT_THAT(actual, MEDIA_THRESHOLDS);
+}
+
+TEST(IoOveruseConfigsTest, TestIsSafeToKillSystemPackages) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+    EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(
+            constructPackageInfo("systemPackageGeneric", ComponentType::SYSTEM)));
+
+    EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
+            constructPackageInfo("systemPackageA", ComponentType::SYSTEM)));
+}
+
+TEST(IoOveruseConfigsTest, TestIsSafeToKillVendorPackages) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+    EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(
+            constructPackageInfo("vendorPackageGeneric", ComponentType::VENDOR)));
+
+    EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
+            constructPackageInfo("vendorPackageA", ComponentType::VENDOR)));
+}
+
+TEST(IoOveruseConfigsTest, TestIsSafeToKillThirdPartyPackages) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+    EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
+            constructPackageInfo("vendorPackageGenericImpostor", ComponentType::THIRD_PARTY)));
+
+    EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
+            constructPackageInfo("3pMapsPackage", ComponentType::THIRD_PARTY,
+                                 ApplicationCategoryType::MAPS)));
+}
+
+TEST(IoOveruseConfigsTest, TestIsSafeToKillNativePackages) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+
+    PackageInfo packageInfo;
+    packageInfo.packageIdentifier.name = "native package";
+    packageInfo.uidType = UidType::NATIVE;
+    packageInfo.componentType = ComponentType::SYSTEM;
+
+    EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo));
+
+    packageInfo.componentType = ComponentType::VENDOR;
+
+    EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo));
+}
+
+TEST(IoOveruseConfigsTest, TestSystemWideAlertThresholds) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+
+    EXPECT_THAT(ioOveruseConfigs->systemWideAlertThresholds(),
+                UnorderedElementsAreArray(ALERT_THRESHOLDS));
+}
+
+TEST(IoOveruseConfigsTest, TestVendorPackagePrefixes) {
+    const auto ioOveruseConfigs = sampleIoOveruseConfigs();
+
+    EXPECT_THAT(ioOveruseConfigs->vendorPackagePrefixes(),
+                UnorderedElementsAre("vendorPackage", "vendorPkgB"));
+}
+
+TEST(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithSystemConfig) {
+    IoOveruseConfigs ioOveruseConfigs;
+    const auto resourceOveruseConfig = sampleSystemConfig();
+
+    ASSERT_RESULT_OK(ioOveruseConfigs.update({resourceOveruseConfig}));
+
+    EXPECT_THAT(ioOveruseConfigs.packagesToAppCategories(),
+                UnorderedElementsAreArray(
+                        toPackageToAppCategoryMappings(resourceOveruseConfig.packageMetadata)));
+}
+
+TEST(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithVendorConfig) {
+    IoOveruseConfigs ioOveruseConfigs;
+    const auto resourceOveruseConfig = sampleVendorConfig();
+
+    ASSERT_RESULT_OK(ioOveruseConfigs.update({resourceOveruseConfig}));
+
+    EXPECT_THAT(ioOveruseConfigs.packagesToAppCategories(),
+                UnorderedElementsAreArray(
+                        toPackageToAppCategoryMappings(resourceOveruseConfig.packageMetadata)));
 }
 
 }  // namespace watchdog
diff --git a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
index 1f28704..4ee94eb 100644
--- a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
+++ b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
@@ -31,12 +31,12 @@
 namespace watchdog {
 
 constexpr size_t kTestMonitorBufferSize = 3;
+constexpr uint64_t KTestMinSyncWrittenBytes = 5'000;
 constexpr double kTestIoOveruseWarnPercentage = 80;
 constexpr std::chrono::seconds kTestMonitorInterval = 5s;
 
 using ::android::IPCThreadState;
 using ::android::RefBase;
-using ::android::String16;
 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
 using ::android::automotive::watchdog::internal::ComponentType;
 using ::android::automotive::watchdog::internal::IoOveruseAlertThreshold;
@@ -69,7 +69,7 @@
 
 PackageIdentifier constructPackageIdentifier(const char* packageName, const int32_t uid) {
     PackageIdentifier packageIdentifier;
-    packageIdentifier.name = String16(String8(packageName));
+    packageIdentifier.name = packageName;
     packageIdentifier.uid = uid;
     return packageIdentifier;
 }
@@ -171,10 +171,11 @@
           mIoOveruseMonitor(ioOveruseMonitor) {}
 
     Result<void> init(const sp<IIoOveruseConfigs>& ioOveruseConfigs,
-                      const sp<IPackageInfoResolverInterface>& packageInfoResolver) {
+                      const sp<IPackageInfoResolver>& packageInfoResolver) {
         if (const auto result = mIoOveruseMonitor->init(); !result.ok()) {
             return result;
         }
+        mIoOveruseMonitor->mMinSyncWrittenBytes = KTestMinSyncWrittenBytes;
         mIoOveruseMonitor->mPeriodicMonitorBufferSize = kTestMonitorBufferSize;
         mIoOveruseMonitor->mIoOveruseWarnPercentage = kTestIoOveruseWarnPercentage;
         mIoOveruseMonitor->mIoOveruseConfigs = ioOveruseConfigs;
@@ -220,23 +221,22 @@
 };
 
 TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollection) {
-    std::unordered_map<uid_t, PackageInfo> packageInfoMapping = {
-            {1001000,
-             constructPackageInfo(
-                     /*packageName=*/"system.daemon", /*uid=*/1001000, UidType::NATIVE)},
-            {1112345,
-             constructPackageInfo(
-                     /*packageName=*/"com.android.google.package", /*uid=*/1112345,
-                     UidType::APPLICATION)},
-            {1212345,
-             constructPackageInfo(
-                     /*packageName=*/"com.android.google.package", /*uid=*/1212345,
-                     UidType::APPLICATION)},
-            {1113999,
-             constructPackageInfo(
-                     /*packageName=*/"com.android.google.package", /*uid=*/1113999,
-                     UidType::APPLICATION)},
-    };
+    std::unordered_map<uid_t, PackageInfo> packageInfoMapping =
+            {{1001000,
+              constructPackageInfo(
+                      /*packageName=*/"system.daemon", /*uid=*/1001000, UidType::NATIVE)},
+             {1112345,
+              constructPackageInfo(
+                      /*packageName=*/"com.android.google.package", /*uid=*/1112345,
+                      UidType::APPLICATION)},
+             {1212345,
+              constructPackageInfo(
+                      /*packageName=*/"com.android.google.package", /*uid=*/1212345,
+                      UidType::APPLICATION)},
+             {1113999,
+              constructPackageInfo(
+                      /*packageName=*/"com.android.google.package", /*uid=*/1113999,
+                      UidType::APPLICATION)}};
     ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
             .WillByDefault(Return(packageInfoMapping));
     mMockIoOveruseConfigs->injectPackageConfigs({
@@ -272,24 +272,25 @@
 
     ASSERT_RESULT_OK(
             mIoOveruseMonitor->onPeriodicCollection(currentTime, mockUidIoStats, nullptr, nullptr));
-    std::vector<PackageIoOveruseStats> expectedIoOveruseStats = {
-            constructPackageIoOveruseStats(/*uid*=*/1001000, /*shouldNotify=*/false,
-                                           /*isKillable=*/false, /*remaining=*/
-                                           constructPerStateBytes(10'000, 20'000, 100'000),
-                                           /*written=*/constructPerStateBytes(70'000, 20'000, 0),
-                                           /*totalOveruses=*/0, startTime, durationInSeconds),
-            constructPackageIoOveruseStats(/*uid*=*/1112345, /*shouldNotify=*/false,
-                                           /*isKillable=*/true, /*remaining=*/
-                                           constructPerStateBytes(35'000, 15'000, 100'000),
-                                           /*written=*/constructPerStateBytes(35'000, 15'000, 0),
-                                           /*totalOveruses=*/0, startTime, durationInSeconds),
-            // Exceeds threshold.
-            constructPackageIoOveruseStats(/*uid*=*/1212345, /*shouldNotify=*/true,
-                                           /*isKillable=*/true,
-                                           /*remaining=*/constructPerStateBytes(0, 10'000, 100'000),
-                                           /*written=*/constructPerStateBytes(70'000, 20'000, 0),
-                                           /*totalOveruses=*/1, startTime, durationInSeconds),
-    };
+
+    std::vector<PackageIoOveruseStats> expectedIoOveruseStats =
+            {constructPackageIoOveruseStats(/*uid*=*/1001000, /*shouldNotify=*/false,
+                                            /*isKillable=*/false, /*remaining=*/
+                                            constructPerStateBytes(10'000, 20'000, 100'000),
+                                            /*written=*/constructPerStateBytes(70'000, 20'000, 0),
+                                            /*totalOveruses=*/0, startTime, durationInSeconds),
+             constructPackageIoOveruseStats(/*uid*=*/1112345, /*shouldNotify=*/false,
+                                            /*isKillable=*/true, /*remaining=*/
+                                            constructPerStateBytes(35'000, 15'000, 100'000),
+                                            /*written=*/constructPerStateBytes(35'000, 15'000, 0),
+                                            /*totalOveruses=*/0, startTime, durationInSeconds),
+             // Exceeds threshold.
+             constructPackageIoOveruseStats(/*uid*=*/1212345, /*shouldNotify=*/true,
+                                            /*isKillable=*/true,
+                                            /*remaining=*/
+                                            constructPerStateBytes(0, 10'000, 100'000),
+                                            /*written=*/constructPerStateBytes(70'000, 20'000, 0),
+                                            /*totalOveruses=*/1, startTime, durationInSeconds)};
     EXPECT_THAT(actualIoOveruseStats, UnorderedElementsAreArray(expectedIoOveruseStats))
             << "Expected: " << toString(expectedIoOveruseStats)
             << "\nActual: " << toString(actualIoOveruseStats);
@@ -384,15 +385,171 @@
             << "\nActual: " << toString(actualIoOveruseStats);
 }
 
+TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithZeroWriteBytes) {
+    sp<MockUidIoStats> mockUidIoStats = new MockUidIoStats();
+    mockUidIoStats->expectDeltaStats(
+            {{1001000, IoUsage(10, 0, /*fgWrBytes=*/0, /*bgWrBytes=*/0, 1, 0)},
+             {1112345, IoUsage(0, 20, /*fgWrBytes=*/0, /*bgWrBytes=*/0, 0, 0)},
+             {1212345, IoUsage(0, 00, /*fgWrBytes=*/0, /*bgWrBytes=*/0, 0, 1)}});
+
+    EXPECT_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_)).Times(0);
+    EXPECT_CALL(*mMockIoOveruseConfigs, fetchThreshold(_)).Times(0);
+    EXPECT_CALL(*mMockIoOveruseConfigs, isSafeToKill(_)).Times(0);
+    EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_)).Times(0);
+
+    ASSERT_RESULT_OK(
+            mIoOveruseMonitor->onPeriodicCollection(std::chrono::system_clock::to_time_t(
+                                                            std::chrono::system_clock::now()),
+                                                    mockUidIoStats, nullptr, nullptr));
+}
+
+TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithSmallWrittenBytes) {
+    std::unordered_map<uid_t, PackageInfo> packageInfoMapping =
+            {{1001000,
+              constructPackageInfo(
+                      /*packageName=*/"system.daemon", /*uid=*/1001000, UidType::NATIVE)},
+             {1112345,
+              constructPackageInfo(
+                      /*packageName=*/"com.android.google.package", /*uid=*/1112345,
+                      UidType::APPLICATION)},
+             {1212345,
+              constructPackageInfo(
+                      /*packageName=*/"com.android.google.package", /*uid=*/1212345,
+                      UidType::APPLICATION)},
+             {1312345,
+              constructPackageInfo(
+                      /*packageName=*/"com.android.google.package", /*uid=*/1312345,
+                      UidType::APPLICATION)}};
+    EXPECT_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
+            .WillRepeatedly(Return(packageInfoMapping));
+    mMockIoOveruseConfigs->injectPackageConfigs(
+            {{"system.daemon",
+              {constructPerStateBytes(/*fgBytes=*/80'000, /*bgBytes=*/40'000, /*gmBytes=*/100'000),
+               /*isSafeToKill=*/false}},
+             {"com.android.google.package",
+              {constructPerStateBytes(/*fgBytes=*/70'000, /*bgBytes=*/30'000, /*gmBytes=*/100'000),
+               /*isSafeToKill=*/true}}});
+
+    sp<MockUidIoStats> mockUidIoStats = new MockUidIoStats();
+    /*
+     * UID 1212345 current written bytes < |KTestMinSyncWrittenBytes| so the UID's stats are not
+     * synced.
+     */
+    mockUidIoStats->expectDeltaStats(
+            {{1001000, IoUsage(10, 0, /*fgWrBytes=*/59'200, /*bgWrBytes=*/0, 1, 0)},
+             {1112345, IoUsage(0, 20, /*fgWrBytes=*/0, /*bgWrBytes=*/25'200, 0, 0)},
+             {1212345, IoUsage(0, 00, /*fgWrBytes=*/300, /*bgWrBytes=*/600, 0, 1)},
+             {1312345, IoUsage(0, 00, /*fgWrBytes=*/51'200, /*bgWrBytes=*/0, 0, 1)}});
+
+    std::vector<PackageIoOveruseStats> actualIoOveruseStats;
+    EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_))
+            .WillOnce(DoAll(SaveArg<0>(&actualIoOveruseStats), Return(Status::ok())));
+
+    time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+    const auto [startTime, durationInSeconds] = calculateStartAndDuration(currentTime);
+
+    ASSERT_RESULT_OK(
+            mIoOveruseMonitor->onPeriodicCollection(currentTime, mockUidIoStats, nullptr, nullptr));
+
+    std::vector<PackageIoOveruseStats> expectedIoOveruseStats =
+            {constructPackageIoOveruseStats(/*uid*=*/1001000, /*shouldNotify=*/false,
+                                            /*isKillable=*/false, /*remaining=*/
+                                            constructPerStateBytes(20'800, 40'000, 100'000),
+                                            /*written=*/
+                                            constructPerStateBytes(59'200, 0, 0),
+                                            /*totalOveruses=*/0, startTime, durationInSeconds),
+             constructPackageIoOveruseStats(/*uid*=*/1112345, /*shouldNotify=*/true,
+                                            /*isKillable=*/true, /*remaining=*/
+                                            constructPerStateBytes(70'000, 4'800, 100'000),
+                                            /*written=*/constructPerStateBytes(0, 25'200, 0),
+                                            /*totalOveruses=*/0, startTime, durationInSeconds),
+             constructPackageIoOveruseStats(/*uid*=*/1312345, /*shouldNotify=*/false,
+                                            /*isKillable=*/true, /*remaining=*/
+                                            constructPerStateBytes(18'800, 30'000, 100'000),
+                                            /*written=*/constructPerStateBytes(51'200, 0, 0),
+                                            /*totalOveruses=*/0, startTime, durationInSeconds)};
+
+    EXPECT_THAT(actualIoOveruseStats, UnorderedElementsAreArray(expectedIoOveruseStats))
+            << "Expected: " << toString(expectedIoOveruseStats)
+            << "\nActual: " << toString(actualIoOveruseStats);
+
+    actualIoOveruseStats.clear();
+    EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_))
+            .WillOnce(DoAll(SaveArg<0>(&actualIoOveruseStats), Return(Status::ok())));
+
+    /*
+     * UID 1001000 current written bytes is < |kTestMinSyncWrittenBytes| but exceeds warn threshold
+     * but not killable so the UID's stats are not synced.
+     * UID 1112345 current written bytes is < |kTestMinSyncWrittenBytes| but exceeds threshold so
+     * the UID's stats are synced.
+     * UID 1212345 current written bytes is < |kTestMinSyncWrittenBytes| but total written bytes
+     * since last synced > |kTestMinSyncWrittenBytes| so the UID's stats are synced.
+     * UID 1312345 current written bytes is < |kTestMinSyncWrittenBytes| but exceeds warn threshold
+     * and killable so the UID's stat are synced.
+     */
+    mockUidIoStats->expectDeltaStats(
+            {{1001000,
+              IoUsage(10, 0, /*fgWrBytes=*/KTestMinSyncWrittenBytes - 100, /*bgWrBytes=*/0, 1, 0)},
+             {1112345,
+              IoUsage(0, 20, /*fgWrBytes=*/0, /*bgWrBytes=*/KTestMinSyncWrittenBytes - 100, 0, 0)},
+             {1212345,
+              IoUsage(0, 00, /*fgWrBytes=*/KTestMinSyncWrittenBytes - 300, /*bgWrBytes=*/0, 0, 1)},
+             {1312345,
+              IoUsage(0, 00, /*fgWrBytes=*/KTestMinSyncWrittenBytes - 100, /*bgWrBytes=*/0, 0,
+                      1)}});
+
+    ASSERT_RESULT_OK(
+            mIoOveruseMonitor->onPeriodicCollection(currentTime, mockUidIoStats, nullptr, nullptr));
+
+    expectedIoOveruseStats =
+            {constructPackageIoOveruseStats(/*uid*=*/1112345, /*shouldNotify=*/true,
+                                            /*isKillable=*/true, /*remaining=*/
+                                            constructPerStateBytes(70'000, 0, 100'000),
+                                            /*written=*/constructPerStateBytes(0, 30'100, 0),
+                                            /*totalOveruses=*/1, startTime, durationInSeconds),
+             constructPackageIoOveruseStats(/*uid*=*/1212345, /*shouldNotify=*/false,
+                                            /*isKillable=*/true, /*remaining=*/
+                                            constructPerStateBytes(65'000, 29'400, 100'000),
+                                            /*written=*/constructPerStateBytes(5'000, 600, 0),
+                                            /*totalOveruses=*/0, startTime, durationInSeconds),
+             constructPackageIoOveruseStats(/*uid*=*/1312345, /*shouldNotify=*/true,
+                                            /*isKillable=*/true, /*remaining=*/
+                                            constructPerStateBytes(13'900, 30'000, 100'000),
+                                            /*written=*/constructPerStateBytes(56'100, 0, 0),
+                                            /*totalOveruses=*/0, startTime, durationInSeconds)};
+    EXPECT_THAT(actualIoOveruseStats, UnorderedElementsAreArray(expectedIoOveruseStats))
+            << "Expected: " << toString(expectedIoOveruseStats)
+            << "\nActual: " << toString(actualIoOveruseStats);
+}
+
+TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithNoPackageInfo) {
+    sp<MockUidIoStats> mockUidIoStats = new MockUidIoStats();
+    mockUidIoStats->expectDeltaStats(
+            {{1001000, IoUsage(0, 0, /*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000, 0, 0)},
+             {1112345, IoUsage(0, 0, /*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000, 0, 0)},
+             {1212345, IoUsage(0, 0, /*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000, 0, 0)}});
+
+    ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
+            .WillByDefault(Return(std::unordered_map<uid_t, PackageInfo>{}));
+
+    EXPECT_CALL(*mMockIoOveruseConfigs, fetchThreshold(_)).Times(0);
+    EXPECT_CALL(*mMockIoOveruseConfigs, isSafeToKill(_)).Times(0);
+    EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_)).Times(0);
+
+    ASSERT_RESULT_OK(
+            mIoOveruseMonitor->onPeriodicCollection(std::chrono::system_clock::to_time_t(
+                                                            std::chrono::system_clock::now()),
+                                                    mockUidIoStats, nullptr, nullptr));
+}
+
 TEST_F(IoOveruseMonitorTest, TestOnPeriodicMonitor) {
-    IIoOveruseConfigs::IoOveruseAlertThresholdSet alertThresholds = {
-            toIoOveruseAlertThreshold(
-                    /*durationInSeconds=*/10, /*writtenBytesPerSecond=*/15'360),
-            toIoOveruseAlertThreshold(
-                    /*durationInSeconds=*/17, /*writtenBytesPerSecond=*/10'240),
-            toIoOveruseAlertThreshold(
-                    /*durationInSeconds=*/23, /*writtenBytesPerSecond=*/7'168),
-    };
+    IIoOveruseConfigs::IoOveruseAlertThresholdSet alertThresholds =
+            {toIoOveruseAlertThreshold(
+                     /*durationInSeconds=*/10, /*writtenBytesPerSecond=*/15'360),
+             toIoOveruseAlertThreshold(
+                     /*durationInSeconds=*/17, /*writtenBytesPerSecond=*/10'240),
+             toIoOveruseAlertThreshold(
+                     /*durationInSeconds=*/23, /*writtenBytesPerSecond=*/7'168)};
     ON_CALL(*mMockIoOveruseConfigs, systemWideAlertThresholds())
             .WillByDefault(ReturnRef(alertThresholds));
 
diff --git a/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h b/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h
index 8ea4ba3..c8f1614 100644
--- a/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h
+++ b/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h
@@ -24,7 +24,6 @@
 #include <binder/Status.h>
 #include <gmock/gmock.h>
 #include <utils/RefBase.h>
-#include <utils/String16.h>
 #include <utils/StrongPointer.h>
 
 namespace android {
@@ -45,7 +44,7 @@
                 (int32_t, android::automotive::watchdog::internal::TimeoutLength), (override));
     MOCK_METHOD(android::binder::Status, prepareProcessTermination, (), (override));
     MOCK_METHOD(android::binder::Status, getPackageInfosForUids,
-                (const std::vector<int32_t>&, const std::vector<android::String16>&,
+                (const std::vector<int32_t>&, const std::vector<std::string>&,
                  std::vector<android::automotive::watchdog::internal::PackageInfo>*),
                 (override));
     MOCK_METHOD(
diff --git a/cpp/watchdog/server/tests/MockDataProcessor.h b/cpp/watchdog/server/tests/MockDataProcessor.h
index e120ff7..34a572e 100644
--- a/cpp/watchdog/server/tests/MockDataProcessor.h
+++ b/cpp/watchdog/server/tests/MockDataProcessor.h
@@ -28,7 +28,7 @@
 class MockDataProcessor : virtual public IDataProcessorInterface {
 public:
     MockDataProcessor() {
-        ON_CALL(*this, name()).WillByDefault(::testing::Return("MockedDataProcessor"));
+        EXPECT_CALL(*this, name()).WillRepeatedly(::testing::Return("MockedDataProcessor"));
     }
     MOCK_METHOD(std::string, name, (), (override));
     MOCK_METHOD(android::base::Result<void>, init, (), (override));
diff --git a/cpp/watchdog/server/tests/MockIoOveruseConfigs.h b/cpp/watchdog/server/tests/MockIoOveruseConfigs.h
index 9d4091d..cc88c1d 100644
--- a/cpp/watchdog/server/tests/MockIoOveruseConfigs.h
+++ b/cpp/watchdog/server/tests/MockIoOveruseConfigs.h
@@ -21,9 +21,10 @@
 
 #include <android-base/result.h>
 #include <android/automotive/watchdog/PerStateBytes.h>
+#include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
 #include <android/automotive/watchdog/internal/ComponentType.h>
-#include <android/automotive/watchdog/internal/IoOveruseConfiguration.h>
 #include <android/automotive/watchdog/internal/PackageInfo.h>
+#include <android/automotive/watchdog/internal/ResourceOveruseConfiguration.h>
 #include <gmock/gmock.h>
 
 namespace android {
@@ -35,12 +36,22 @@
     MockIoOveruseConfigs() {}
     ~MockIoOveruseConfigs() {}
     MOCK_METHOD(android::base::Result<void>, update,
-                (const android::automotive::watchdog::internal::ComponentType,
-                 const android::automotive::watchdog::internal::IoOveruseConfiguration&),
+                (const std::vector<
+                        android::automotive::watchdog::internal::ResourceOveruseConfiguration>&),
                 (override));
 
+    MOCK_METHOD(
+            void, get,
+            (std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*),
+            (override));
+
     MOCK_METHOD((const std::unordered_set<std::string>&), vendorPackagePrefixes, (), (override));
 
+    MOCK_METHOD((const std::unordered_map<
+                        std::string,
+                        android::automotive::watchdog::internal::ApplicationCategoryType>&),
+                packagesToAppCategories, (), (override));
+
     MOCK_METHOD(PerStateBytes, fetchThreshold,
                 (const android::automotive::watchdog::internal::PackageInfo&), (const, override));
 
@@ -60,8 +71,7 @@
                 .WillByDefault([perPackageConfig = perPackageConfig](
                                        const android::automotive::watchdog::internal::PackageInfo&
                                                packageInfo) {
-                    const std::string packageName =
-                            std::string(String8(packageInfo.packageIdentifier.name));
+                    const std::string packageName = packageInfo.packageIdentifier.name;
                     if (const auto it = perPackageConfig.find(packageName);
                         it != perPackageConfig.end()) {
                         return it->second.threshold;
@@ -72,8 +82,7 @@
                 .WillByDefault([perPackageConfig = perPackageConfig](
                                        const android::automotive::watchdog::internal::PackageInfo&
                                                packageInfo) {
-                    const std::string packageName =
-                            std::string(String8(packageInfo.packageIdentifier.name));
+                    const std::string packageName = packageInfo.packageIdentifier.name;
                     if (const auto it = perPackageConfig.find(packageName);
                         it != perPackageConfig.end()) {
                         return it->second.isSafeToKill;
diff --git a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
index d6ca484..cb7d0c5 100644
--- a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
+++ b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
@@ -35,11 +35,15 @@
         ON_CALL(*this, name()).WillByDefault(::testing::Return("MockIoOveruseMonitor"));
     }
     ~MockIoOveruseMonitor() {}
-
-    MOCK_METHOD(android::base::Result<void>, updateIoOveruseConfiguration,
-                (android::automotive::watchdog::internal::ComponentType,
-                 const android::automotive::watchdog::internal::IoOveruseConfiguration&),
+    MOCK_METHOD(bool, isInitialized, (), (override));
+    MOCK_METHOD(android::base::Result<void>, updateResourceOveruseConfigurations,
+                (const std::vector<
+                        android::automotive::watchdog::internal::ResourceOveruseConfiguration>&),
                 (override));
+    MOCK_METHOD(
+            android::base::Result<void>, getResourceOveruseConfigurations,
+            (std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*),
+            (override));
     MOCK_METHOD(android::base::Result<void>, actionTakenOnIoOveruse,
                 (const std::vector<
                         android::automotive::watchdog::internal::PackageResourceOveruseAction>&
diff --git a/cpp/watchdog/server/tests/MockPackageInfoResolver.h b/cpp/watchdog/server/tests/MockPackageInfoResolver.h
index d50a723..e3da3b6 100644
--- a/cpp/watchdog/server/tests/MockPackageInfoResolver.h
+++ b/cpp/watchdog/server/tests/MockPackageInfoResolver.h
@@ -29,7 +29,7 @@
 namespace automotive {
 namespace watchdog {
 
-class MockPackageInfoResolver : public IPackageInfoResolverInterface {
+class MockPackageInfoResolver : public IPackageInfoResolver {
 public:
     MockPackageInfoResolver() {}
     MOCK_METHOD(android::base::Result<void>, initWatchdogServiceHelper,
@@ -39,7 +39,11 @@
                 (const std::vector<uid_t>& uids), (override));
     MOCK_METHOD((std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>),
                 getPackageInfosForUids, (const std::vector<uid_t>& uids), (override));
-    MOCK_METHOD(void, setVendorPackagePrefixes, (const std::unordered_set<std::string>& prefixes),
+    MOCK_METHOD(void, setPackageConfigurations,
+                ((const std::unordered_set<std::string>&),
+                 (const std::unordered_map<
+                         std::string,
+                         android::automotive::watchdog::internal::ApplicationCategoryType>&)),
                 (override));
 };
 
diff --git a/cpp/watchdog/server/tests/MockWatchdogPerfService.h b/cpp/watchdog/server/tests/MockWatchdogPerfService.h
index 5d14837..60d165b 100644
--- a/cpp/watchdog/server/tests/MockWatchdogPerfService.h
+++ b/cpp/watchdog/server/tests/MockWatchdogPerfService.h
@@ -36,7 +36,7 @@
     MOCK_METHOD(void, terminate, (), (override));
     MOCK_METHOD(android::base::Result<void>, onBootFinished, (), (override));
     MOCK_METHOD(android::base::Result<void>, onCustomCollection,
-                (int fd, const Vector<String16>& args), (override));
+                (int fd, const Vector<android::String16>& args), (override));
     MOCK_METHOD(android::base::Result<void>, onDump, (int fd), (override));
 };
 
diff --git a/cpp/watchdog/server/tests/MockWatchdogProcessService.h b/cpp/watchdog/server/tests/MockWatchdogProcessService.h
index 8c35f10..b720d91 100644
--- a/cpp/watchdog/server/tests/MockWatchdogProcessService.h
+++ b/cpp/watchdog/server/tests/MockWatchdogProcessService.h
@@ -40,7 +40,7 @@
 class MockWatchdogProcessService : public WatchdogProcessService {
 public:
     MockWatchdogProcessService() : WatchdogProcessService(nullptr) {}
-    MOCK_METHOD(android::base::Result<void>, dump, (int fd, const Vector<String16>& args),
+    MOCK_METHOD(android::base::Result<void>, dump, (int fd, const Vector<android::String16>& args),
                 (override));
     MOCK_METHOD(android::base::Result<void>, registerWatchdogServiceHelper,
                 (const android::sp<IWatchdogServiceHelperInterface>& helper), (override));
diff --git a/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp b/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp
index a3c126c..f2fe3a6 100644
--- a/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp
+++ b/cpp/watchdog/server/tests/PackageInfoResolverTest.cpp
@@ -17,22 +17,22 @@
 #include "MockWatchdogServiceHelper.h"
 #include "PackageInfoResolver.h"
 
+#include <android-base/stringprintf.h>
 #include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
 #include <android/automotive/watchdog/internal/ComponentType.h>
 #include <android/automotive/watchdog/internal/UidType.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-#include <utils/String16.h>
 
 namespace android {
 namespace automotive {
 namespace watchdog {
 
-using ::android::String16;
 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
 using ::android::automotive::watchdog::internal::ComponentType;
 using ::android::automotive::watchdog::internal::PackageInfo;
 using ::android::automotive::watchdog::internal::UidType;
+using ::android::base::StringAppendF;
 using ::testing::_;
 using ::testing::DoAll;
 using ::testing::NotNull;
@@ -40,15 +40,20 @@
 using ::testing::Return;
 using ::testing::SetArgPointee;
 using ::testing::UnorderedElementsAre;
+using ::testing::UnorderedElementsAreArray;
 
 namespace {
 
+using PackageToAppCategoryMap =
+        std::unordered_map<std::string,
+                           android::automotive::watchdog::internal::ApplicationCategoryType>;
+
 PackageInfo constructPackageInfo(const char* packageName, int32_t uid, UidType uidType,
                                  ComponentType componentType,
                                  ApplicationCategoryType appCategoryType,
-                                 std::vector<String16> sharedUidPackages = {}) {
+                                 std::vector<std::string> sharedUidPackages = {}) {
     PackageInfo packageInfo;
-    packageInfo.packageIdentifier.name = String16(packageName);
+    packageInfo.packageIdentifier.name = packageName;
     packageInfo.packageIdentifier.uid = uid;
     packageInfo.uidType = uidType;
     packageInfo.componentType = componentType;
@@ -57,6 +62,18 @@
     return packageInfo;
 }
 
+std::string toString(const std::unordered_map<uid_t, PackageInfo>& mappings) {
+    std::string buffer = "{";
+    for (const auto& [uid, info] : mappings) {
+        if (buffer.size() > 1) {
+            StringAppendF(&buffer, ", ");
+        }
+        StringAppendF(&buffer, "{%d: %s}", uid, info.toString().c_str());
+    }
+    StringAppendF(&buffer, "}");
+    return buffer;
+}
+
 }  // namespace
 
 namespace internal {
@@ -80,8 +97,10 @@
         mPackageInfoResolver->mUidToPackageInfoMapping = mapping;
     }
 
-    void setVendorPackagePrefixes(const std::unordered_set<std::string>& prefixes) {
-        mPackageInfoResolver->setVendorPackagePrefixes(prefixes);
+    void setPackageConfigurations(const std::unordered_set<std::string>& vendorPackagePrefixes,
+                                  const PackageToAppCategoryMap& packagesToAppCategories) {
+        mPackageInfoResolver->setPackageConfigurations(vendorPackagePrefixes,
+                                                       packagesToAppCategories);
     }
 
     void stubGetpwuid(const std::unordered_map<uid_t, std::string>& nativeUidToPackageNameMapping) {
@@ -133,6 +152,13 @@
 TEST(PackageInfoResolverTest, TestGetPackageInfosForUidsViaGetpwuid) {
     internal::PackageInfoResolverPeer peer;
     auto packageInfoResolver = PackageInfoResolver::getInstance();
+    PackageToAppCategoryMap packagesToAppCategories = {
+            // These mappings should be ignored for native packages.
+            {"system.package.B", ApplicationCategoryType::MAPS},
+            {"vendor.package.A", ApplicationCategoryType::MEDIA},
+            {"vendor.pkg.maps", ApplicationCategoryType::MAPS},
+    };
+    peer.setPackageConfigurations({"vendor.pkg"}, packagesToAppCategories);
 
     std::unordered_map<uid_t, PackageInfo> expectedMappings{
             {7700,
@@ -142,29 +168,35 @@
              constructPackageInfo("vendor.package.A", 5100, UidType::NATIVE, ComponentType::VENDOR,
                                   ApplicationCategoryType::OTHERS)},
             {6700,
-             constructPackageInfo("vendor.pkg", 6700, UidType::NATIVE, ComponentType::VENDOR,
+             constructPackageInfo("vendor.package.B", 6700, UidType::NATIVE, ComponentType::VENDOR,
+                                  ApplicationCategoryType::OTHERS)},
+            {9997,
+             constructPackageInfo("vendor.pkg.C", 9997, UidType::NATIVE, ComponentType::VENDOR,
                                   ApplicationCategoryType::OTHERS)},
     };
 
-    peer.stubGetpwuid(
-            {{7700, "system.package.B"}, {5100, "vendor.package.A"}, {6700, "vendor.pkg"}});
+    peer.stubGetpwuid({{7700, "system.package.B"},
+                       {5100, "vendor.package.A"},
+                       {6700, "vendor.package.B"},
+                       {9997, "vendor.pkg.C"}});
     EXPECT_CALL(*peer.mockWatchdogServiceHelper, getPackageInfosForUids(_, _, _)).Times(0);
 
-    auto actualMappings = packageInfoResolver->getPackageInfosForUids({7700, 5100, 6700});
+    auto actualMappings = packageInfoResolver->getPackageInfosForUids({7700, 5100, 6700, 9997});
 
-    for (const auto& it : expectedMappings) {
-        ASSERT_TRUE(actualMappings.find(it.first) != actualMappings.end())
-                << "Mapping not found for UID" << it.first;
-        EXPECT_EQ(actualMappings.find(it.first)->second, it.second)
-                << "Expected: " << it.second.toString() << "\n"
-                << "Actual: " << actualMappings.find(it.first)->second.toString();
-    }
+    EXPECT_THAT(actualMappings, UnorderedElementsAreArray(expectedMappings))
+            << "Expected: " << toString(expectedMappings)
+            << "\nActual: " << toString(actualMappings);
 }
 
 TEST(PackageInfoResolverTest, TestGetPackageInfosForUidsViaWatchdogService) {
     internal::PackageInfoResolverPeer peer;
     auto packageInfoResolver = PackageInfoResolver::getInstance();
-    peer.setVendorPackagePrefixes({"vendor.pkg"});
+    PackageToAppCategoryMap packagesToAppCategories = {
+            // system.package.B is native package so this should be ignored.
+            {"system.package.B", ApplicationCategoryType::MAPS},
+            {"vendor.package.A", ApplicationCategoryType::MEDIA},
+    };
+    peer.setPackageConfigurations({"vendor.pkg"}, packagesToAppCategories);
     /*
      * Shared UID should be resolved with car watchdog service as well to get the shared packages
      * list.
@@ -175,13 +207,13 @@
             {6100,
              constructPackageInfo("shared:system.package.A", 6100, UidType::NATIVE,
                                   ComponentType::SYSTEM, ApplicationCategoryType::OTHERS,
-                                  {String16("system.pkg.1"), String16("system.pkg.2")})},
+                                  {"system.pkg.1", "system.pkg.2"})},
             {7700,
              constructPackageInfo("system.package.B", 7700, UidType::NATIVE, ComponentType::SYSTEM,
                                   ApplicationCategoryType::OTHERS)},
             {15100,
-             constructPackageInfo("vendor.package.A", 15100, UidType::NATIVE, ComponentType::VENDOR,
-                                  ApplicationCategoryType::OTHERS)},
+             constructPackageInfo("vendor.package.A", 15100, UidType::APPLICATION,
+                                  ComponentType::VENDOR, ApplicationCategoryType::MEDIA)},
             {16700,
              constructPackageInfo("vendor.pkg", 16700, UidType::NATIVE, ComponentType::VENDOR,
                                   ApplicationCategoryType::OTHERS)},
@@ -199,30 +231,28 @@
 
     auto actualMappings = packageInfoResolver->getPackageInfosForUids({6100, 7700, 15100, 16700});
 
-    for (const auto& it : expectedMappings) {
-        ASSERT_TRUE(actualMappings.find(it.first) != actualMappings.end())
-                << "Mapping not found for UID" << it.first;
-        EXPECT_EQ(actualMappings.find(it.first)->second, it.second)
-                << "Expected: " << it.second.toString() << "\n"
-                << "Actual: " << actualMappings.find(it.first)->second.toString();
-    }
+    EXPECT_THAT(actualMappings, UnorderedElementsAreArray(expectedMappings))
+            << "Expected: " << toString(expectedMappings)
+            << "\nActual: " << toString(actualMappings);
 }
 
 TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromLocalCache) {
     internal::PackageInfoResolverPeer peer;
     auto packageInfoResolver = PackageInfoResolver::getInstance();
-    PackageInfo expectedPackageInfo =
-            constructPackageInfo("vendor.package", 1003456, UidType::NATIVE, ComponentType::SYSTEM,
-                                 ApplicationCategoryType::OTHERS);
-    peer.injectCacheMapping({{1003456, expectedPackageInfo}});
+    std::unordered_map<uid_t, PackageInfo> expectedMappings{
+            {1003456,
+             constructPackageInfo("vendor.package", 1003456, UidType::NATIVE, ComponentType::SYSTEM,
+                                  ApplicationCategoryType::OTHERS)}};
+    peer.injectCacheMapping(expectedMappings);
 
     peer.stubGetpwuid({});
     EXPECT_CALL(*peer.mockWatchdogServiceHelper, getPackageInfosForUids(_, _, _)).Times(0);
 
     auto actualMappings = packageInfoResolver->getPackageInfosForUids({1003456});
 
-    ASSERT_TRUE(actualMappings.find(1003456) != actualMappings.end());
-    EXPECT_EQ(actualMappings.find(1003456)->second, expectedPackageInfo);
+    EXPECT_THAT(actualMappings, UnorderedElementsAreArray(expectedMappings))
+            << "Expected: " << toString(expectedMappings)
+            << "\nActual: " << toString(actualMappings);
 }
 
 }  // namespace watchdog
diff --git a/cpp/watchdog/server/tests/UidIoStatsTest.cpp b/cpp/watchdog/server/tests/UidIoStatsTest.cpp
index 2326381..6e88ed5 100644
--- a/cpp/watchdog/server/tests/UidIoStatsTest.cpp
+++ b/cpp/watchdog/server/tests/UidIoStatsTest.cpp
@@ -17,6 +17,7 @@
 #include "UidIoStats.h"
 
 #include <android-base/file.h>
+#include <android-base/stringprintf.h>
 #include <gmock/gmock.h>
 
 #include <unordered_map>
@@ -25,25 +26,37 @@
 namespace automotive {
 namespace watchdog {
 
+using ::android::base::StringAppendF;
 using ::android::base::WriteStringToFile;
+using ::testing::UnorderedElementsAreArray;
+
+namespace {
+
+std::string toString(std::unordered_map<uid_t, UidIoUsage> usages) {
+    std::string buffer;
+    for (const auto& [uid, usage] : usages) {
+        StringAppendF(&buffer, "{%s}\n", usage.toString().c_str());
+    }
+    return buffer;
+}
+
+}  // namespace
 
 TEST(UidIoStatsTest, TestValidStatFile) {
     // Format: uid fgRdChar fgWrChar fgRdBytes fgWrBytes bgRdChar bgWrChar bgRdBytes bgWrBytes
     // fgFsync bgFsync
-    constexpr char firstSnapshot[] =
-        "1001234 5000 1000 3000 500 0 0 0 0 20 0\n"
-        "1005678 500 100 30 50 300 400 100 200 45 60\n"
-        "1009 0 0 0 0 40000 50000 20000 30000 0 300\n"
-        "1001000 4000 3000 2000 1000 400 300 200 100 50 10\n";
-    std::unordered_map<uid_t, UidIoUsage> expectedFirstUsage = {
-            {1001234,
-             {.uid = 1001234,
-              .ios = {/*fgRdBytes=*/3000, /*bgRdBytes=*/0, /*fgWrBytes=*/500,
-                      /*bgWrBytes=*/0, /*fgFsync=*/20, /*bgFsync=*/0}}},
-            {1005678, {.uid = 1005678, .ios = {30, 100, 50, 200, 45, 60}}},
-            {1009, {.uid = 1009, .ios = {0, 20000, 0, 30000, 0, 300}}},
-            {1001000, {.uid = 1001000, .ios = {2000, 200, 1000, 100, 50, 10}}},
-    };
+    constexpr char firstSnapshot[] = "1001234 5000 1000 3000 500 0 0 0 0 20 0\n"
+                                     "1005678 500 100 30 50 300 400 100 200 45 60\n"
+                                     "1009 0 0 0 0 40000 50000 20000 30000 0 300\n"
+                                     "1001000 4000 3000 2000 1000 400 300 200 100 50 10\n";
+    std::unordered_map<uid_t, UidIoUsage> expectedFirstUsage =
+            {{1001234,
+              {.uid = 1001234,
+               .ios = {/*fgRdBytes=*/3000, /*bgRdBytes=*/0, /*fgWrBytes=*/500,
+                       /*bgWrBytes=*/0, /*fgFsync=*/20, /*bgFsync=*/0}}},
+             {1005678, {.uid = 1005678, .ios = {30, 100, 50, 200, 45, 60}}},
+             {1009, {.uid = 1009, .ios = {0, 20000, 0, 30000, 0, 300}}},
+             {1001000, {.uid = 1001000, .ios = {2000, 200, 1000, 100, 50, 10}}}};
     TemporaryFile tf;
     ASSERT_NE(tf.fd, -1);
     ASSERT_TRUE(WriteStringToFile(firstSnapshot, tf.path));
@@ -53,62 +66,38 @@
     ASSERT_RESULT_OK(uidIoStats.collect());
 
     const auto& actualFirstUsage = uidIoStats.deltaStats();
-    EXPECT_EQ(expectedFirstUsage.size(), actualFirstUsage.size());
+    EXPECT_THAT(actualFirstUsage, UnorderedElementsAreArray(expectedFirstUsage))
+            << "Expected: " << toString(expectedFirstUsage)
+            << "Actual: " << toString(actualFirstUsage);
 
-    for (const auto& it : expectedFirstUsage) {
-        if (actualFirstUsage.find(it.first) == actualFirstUsage.end()) {
-            ADD_FAILURE() << "Expected uid " << it.first << " not found in the first snapshot";
-        }
-        const UidIoUsage& expected = it.second;
-        const UidIoUsage& actual = actualFirstUsage.at(it.first);
-        EXPECT_EQ(expected.uid, actual.uid);
-        EXPECT_EQ(expected.ios, actual.ios)
-            << "Unexpected I/O usage for uid " << it.first << " in first snapshot.\nExpected:\n"
-            << expected.ios.toString() << "\nActual:\n"<< actual.ios.toString();
-    }
-
-    constexpr char secondSnapshot[] =
-        "1001234 10000 2000 7000 950 0 0 0 0 45 0\n"
-        "1005678 600 100 40 50 1000 1000 1000 600 50 70\n"
-        "1003456 300 500 200 300 0 0 0 0 50 0\n"
-        "1001000 400 300 200 100 40 30 20 10 5 1\n";
-    std::unordered_map<uid_t, UidIoUsage> expectedSecondUsage = {
-            {1001234,
-             {.uid = 1001234,
-              .ios = {/*fgRdBytes=*/4000, /*bgRdBytes=*/0,
-                      /*fgWrBytes=*/450, /*bgWrBytes=*/0, /*fgFsync=*/25,
-                      /*bgFsync=*/0}}},
-            {1005678, {.uid = 1005678, .ios = {10, 900, 0, 400, 5, 10}}},
-            {1003456, {.uid = 1003456, .ios = {200, 0, 300, 0, 50, 0}}},
-            {1001000, {.uid = 1001000, .ios = {0, 0, 0, 0, 0, 0}}},
-    };
+    constexpr char secondSnapshot[] = "1001234 10000 2000 7000 950 0 0 0 0 45 0\n"
+                                      "1005678 600 100 40 50 1000 1000 1000 600 50 70\n"
+                                      "1003456 300 500 200 300 0 0 0 0 50 0\n"
+                                      "1001000 400 300 200 100 40 30 20 10 5 1\n";
+    std::unordered_map<uid_t, UidIoUsage> expectedSecondUsage =
+            {{1001234,
+              {.uid = 1001234,
+               .ios = {/*fgRdBytes=*/4000, /*bgRdBytes=*/0,
+                       /*fgWrBytes=*/450, /*bgWrBytes=*/0, /*fgFsync=*/25,
+                       /*bgFsync=*/0}}},
+             {1005678, {.uid = 1005678, .ios = {10, 900, 0, 400, 5, 10}}},
+             {1003456, {.uid = 1003456, .ios = {200, 0, 300, 0, 50, 0}}}};
     ASSERT_TRUE(WriteStringToFile(secondSnapshot, tf.path));
     ASSERT_RESULT_OK(uidIoStats.collect());
 
     const auto& actualSecondUsage = uidIoStats.deltaStats();
-    EXPECT_EQ(expectedSecondUsage.size(), actualSecondUsage.size());
-
-    for (const auto& it : expectedSecondUsage) {
-        if (actualSecondUsage.find(it.first) == actualSecondUsage.end()) {
-            ADD_FAILURE() << "Expected uid " << it.first << " not found in the second snapshot";
-        }
-        const UidIoUsage& expected = it.second;
-        const UidIoUsage& actual = actualSecondUsage.at(it.first);
-        EXPECT_EQ(expected.uid, actual.uid);
-        EXPECT_EQ(expected.ios, actual.ios)
-            << "Unexpected I/O usage for uid " << it.first << " in second snapshot:.\nExpected:\n"
-            << expected.ios.toString() << "\nActual:\n"<< actual.ios.toString();
-    }
+    EXPECT_THAT(actualSecondUsage, UnorderedElementsAreArray(expectedSecondUsage))
+            << "Expected: " << toString(expectedSecondUsage)
+            << "Actual: " << toString(actualSecondUsage);
 }
 
 TEST(UidIoStatsTest, TestErrorOnInvalidStatFile) {
     // Format: uid fgRdChar fgWrChar fgRdBytes fgWrBytes bgRdChar bgWrChar bgRdBytes bgWrBytes
     // fgFsync bgFsync
-    constexpr char contents[] =
-        "1001234 5000 1000 3000 500 0 0 0 0 20 0\n"
-        "1005678 500 100 30 50 300 400 100 200 45 60\n"
-        "1009012 0 0 0 0 40000 50000 20000 30000 0 300\n"
-        "1001000 4000 3000 2000 1000 CORRUPTED DATA\n";
+    constexpr char contents[] = "1001234 5000 1000 3000 500 0 0 0 0 20 0\n"
+                                "1005678 500 100 30 50 300 400 100 200 45 60\n"
+                                "1009012 0 0 0 0 40000 50000 20000 30000 0 300\n"
+                                "1001000 4000 3000 2000 1000 CORRUPTED DATA\n";
     TemporaryFile tf;
     ASSERT_NE(tf.fd, -1);
     ASSERT_TRUE(WriteStringToFile(contents, tf.path));
diff --git a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
index aae920a..f5dd7dc 100644
--- a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
@@ -45,12 +45,14 @@
 using aawi::ComponentType;
 using aawi::ICarWatchdogServiceForSystem;
 using aawi::ICarWatchdogServiceForSystemDefault;
-using aawi::IoOveruseConfiguration;
 using aawi::PackageResourceOveruseAction;
+using aawi::ResourceOveruseConfiguration;
 using ::android::sp;
+using ::android::String16;
 using ::android::base::Result;
 using ::android::binder::Status;
 using ::testing::_;
+using ::testing::Pointer;
 using ::testing::Return;
 
 namespace {
@@ -66,7 +68,7 @@
                                          -> Result<void> { return Result<void>{}; }) {}
     ~MockWatchdogBinderMediator() {}
 
-    MOCK_METHOD(status_t, dump, (int fd, const Vector<String16>& args), (override));
+    MOCK_METHOD(status_t, dump, (int fd, const Vector<android::String16>& args), (override));
 };
 
 class ScopedChangeCallingUid : public RefBase {
@@ -369,22 +371,37 @@
     ASSERT_FALSE(status.isOk()) << status;
 }
 
-TEST_F(WatchdogInternalHandlerTest, TestUpdateIoOveruseConfiguration) {
+TEST_F(WatchdogInternalHandlerTest, TestUpdateResourceOveruseConfigurations) {
     setSystemCallingUid();
-    EXPECT_CALL(*mMockIoOveruseMonitor, updateIoOveruseConfiguration(ComponentType::SYSTEM, _))
+    EXPECT_CALL(*mMockIoOveruseMonitor, updateResourceOveruseConfigurations(_))
             .WillOnce(Return(Result<void>()));
-    Status status =
-            mWatchdogInternalHandler->updateIoOveruseConfiguration(ComponentType::SYSTEM,
-                                                                   IoOveruseConfiguration{});
+    Status status = mWatchdogInternalHandler->updateResourceOveruseConfigurations(
+            std::vector<ResourceOveruseConfiguration>{});
     ASSERT_TRUE(status.isOk()) << status;
 }
 
 TEST_F(WatchdogInternalHandlerTest,
-       TestErrorOnUpdateIoOveruseConfigurationWithNonSystemCallingUid) {
-    EXPECT_CALL(*mMockIoOveruseMonitor, updateIoOveruseConfiguration(_, _)).Times(0);
-    Status status =
-            mWatchdogInternalHandler->updateIoOveruseConfiguration(ComponentType::SYSTEM,
-                                                                   IoOveruseConfiguration{});
+       TestErrorOnUpdateResourceOveruseConfigurationsWithNonSystemCallingUid) {
+    EXPECT_CALL(*mMockIoOveruseMonitor, updateResourceOveruseConfigurations(_)).Times(0);
+    Status status = mWatchdogInternalHandler->updateResourceOveruseConfigurations(
+            std::vector<ResourceOveruseConfiguration>{});
+    ASSERT_FALSE(status.isOk()) << status;
+}
+
+TEST_F(WatchdogInternalHandlerTest, TestGetResourceOveruseConfigurations) {
+    setSystemCallingUid();
+    std::vector<ResourceOveruseConfiguration> configs;
+    EXPECT_CALL(*mMockIoOveruseMonitor, getResourceOveruseConfigurations(Pointer(&configs)))
+            .WillOnce(Return(Result<void>()));
+    Status status = mWatchdogInternalHandler->getResourceOveruseConfigurations(&configs);
+    ASSERT_TRUE(status.isOk()) << status;
+}
+
+TEST_F(WatchdogInternalHandlerTest,
+       TestErrorOnGetResourceOveruseConfigurationsWithNonSystemCallingUid) {
+    EXPECT_CALL(*mMockIoOveruseMonitor, getResourceOveruseConfigurations(_)).Times(0);
+    std::vector<ResourceOveruseConfiguration> configs;
+    Status status = mWatchdogInternalHandler->getResourceOveruseConfigurations(&configs);
     ASSERT_FALSE(status.isOk()) << status;
 }
 
diff --git a/cpp/watchdog/server/tests/WatchdogPerfServiceTest.cpp b/cpp/watchdog/server/tests/WatchdogPerfServiceTest.cpp
index c7de12b..3873195 100644
--- a/cpp/watchdog/server/tests/WatchdogPerfServiceTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogPerfServiceTest.cpp
@@ -39,6 +39,7 @@
 namespace automotive {
 namespace watchdog {
 
+using ::android::String16;
 using ::android::wp;
 using ::android::automotive::watchdog::testing::LooperStub;
 using ::android::base::Error;
diff --git a/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp b/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp
index 681d900..17edadf 100644
--- a/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp
@@ -22,7 +22,6 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <utils/RefBase.h>
-#include <utils/String16.h>
 
 namespace android {
 namespace automotive {
@@ -41,7 +40,6 @@
 using ::android::IBinder;
 using ::android::RefBase;
 using ::android::sp;
-using ::android::String16;
 using ::android::base::Error;
 using ::android::base::Result;
 using ::android::binder::Status;
@@ -80,7 +78,7 @@
                                  ComponentType componentType,
                                  ApplicationCategoryType appCategoryType) {
     PackageInfo packageInfo;
-    packageInfo.packageIdentifier.name = String16(packageName);
+    packageInfo.packageIdentifier.name = packageName;
     packageInfo.packageIdentifier.uid = uid;
     packageInfo.uidType = uidType;
     packageInfo.componentType = componentType;
@@ -329,7 +327,6 @@
 TEST_F(WatchdogServiceHelperTest, TestGetPackageInfosForUids) {
     std::vector<int32_t> uids = {1000};
     std::vector<std::string> prefixesStr = {"vendor.package"};
-    std::vector<String16> prefixesStr16 = {String16("vendor.package")};
     std::vector<PackageInfo> expectedPackageInfo{
             constructPackageInfo("vendor.package.A", 120000, UidType::NATIVE, ComponentType::VENDOR,
                                  ApplicationCategoryType::OTHERS),
@@ -340,7 +337,7 @@
 
     registerCarWatchdogService();
 
-    EXPECT_CALL(*mMockCarWatchdogServiceForSystem, getPackageInfosForUids(uids, prefixesStr16, _))
+    EXPECT_CALL(*mMockCarWatchdogServiceForSystem, getPackageInfosForUids(uids, prefixesStr, _))
             .WillOnce(DoAll(SetArgPointee<2>(expectedPackageInfo), Return(Status::ok())));
 
     Status status =
diff --git a/service/jni/Android.bp b/service/jni/Android.bp
index 6048d06..86f3455 100644
--- a/service/jni/Android.bp
+++ b/service/jni/Android.bp
@@ -14,6 +14,10 @@
 //
 //
 //#################################
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_library_shared {
     name: "libcarservicejni",
     srcs: [
diff --git a/service/res/values-af/strings.xml b/service/res/values-af/strings.xml
index c4c74ee..819c007 100644
--- a/service/res/values-af/strings.xml
+++ b/service/res/values-af/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Luister na bestuurstaatveranderinge."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Gebruik motor se EVS-diens"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Teken in op EVS-videostrome"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitor motor se EVS-diensstatus"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitor \'n status van CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Versoek die EVS-voorskouaktiwiteit"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Versoek die stelsel om die EVS-voorskouaktiwiteit te begin"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Beheer die EVS-voorskouaktiwiteit"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Beheer die EVS-voorskouaktiwiteit van die stelsel"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Gebruik die EVS-kamera"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Teken in op EVS-kamerastrome"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitor die status van die EVS-diens"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Luister na die statusveranderinge van die EVS-diens"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"toegang tot motor se gedetailleerde enjininligting"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Toegang tot jou motor se gedetailleerde enjininligting."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"toegang tot motor se brandstofdeur en laaipoort"</string>
diff --git a/service/res/values-am/strings.xml b/service/res/values-am/strings.xml
index 9de6091..9d327d9 100644
--- a/service/res/values-am/strings.xml
+++ b/service/res/values-am/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ለመኪና አነዳድ ሁኔታ ለውጦች ያዳምጡ።"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"የመኪና ኢቪኤስ አገልግሎት ይጠቀሙ"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"ለኢቪኤስ ቪዲዮ ዥረቶች ይመዝገቡ"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"የመኪና ኢቪኤስ አገልግሎት ሁኔታን ይከታተሉ"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"የCarEvsService ሁኔታን ይከታተሉ"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"የኢቪኤስ ቅድመ-እይታ እንቅስቃሴን መጠየቅ"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"የኢቪኤስ ቅድመ-እይታ እንቅስቃሴን ለማስጀመር ስርዓቱን መጠየቅ"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"የኢቪኤስ ቅድመ-እይታ እንቅስቃሴን መቆጣጠር"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"የስርዓቱን የኢቪኤስ ቅድመ-እይታ እንቅስቃሴ መቆጣጠር"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"የኢቪኤስ ካሜራን መጠቀም"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"ለኢቪኤስ የካሜራ ዥረቶች ደንበኝነት መመዝገብ"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"የኢቪኤስ አገልግሎት ሁኔታን መከታተል"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"የኢቪኤስ አገልግሎት ሁኔታ ለውጦችን ማዳመጥ"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"የመኪና ሞተርን ዝርዝሮች ድረስባቸው"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"የእርስዎን መኪና በዝርዝር የቀረበ የሞተር መረጃ ይድረሱበት።"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"የመኪናውን የነዳጅ በር እና የኃይል መሙያ በር ድረስበት"</string>
diff --git a/service/res/values-ar/strings.xml b/service/res/values-ar/strings.xml
index 7579241..ae10792 100644
--- a/service/res/values-ar/strings.xml
+++ b/service/res/values-ar/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"يمكنك الاستماع إلى التغيُّرات في حالة \"القيادة\"."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"الاستفادة من خدمة EVS للسيارة"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"الاشتراك في فيديوهات EVS المضمّنة"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"مراقبة حالة خدمة EVS للسيارة"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"مراقبة إحدى حالات CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"طلب نشاط معاينة خدمة EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"إرسال طلب إلى النظام لإطلاق نشاط معاينة EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"التحكم بنشاط معاينة EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"التحكم بنشاط معاينة خدمة EVS الخاصة بالنظام"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"استخدام كاميرا EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"الاشتراك في خدمة بث كاميرا EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"مراقبة حالة خدمة EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"الاستماع إلى تغييرات الحالة لخدمة EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"الحصول على معلومات عن تفاصيل المحرّك"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"يمكنك الحصول على معلومات تفصيلية عن محرّك السيارة."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"الحصول على معلومات عن .باب خزان الوقود ومنفذ الشحن"</string>
diff --git a/service/res/values-as/strings.xml b/service/res/values-as/strings.xml
index d784eff..945a2b2 100644
--- a/service/res/values-as/strings.xml
+++ b/service/res/values-as/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"গাড়ী চালনাৰ স্থিতি সলনি হ’লে সেইয়া জানিব।"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"গাড়ীৰ EVS ছাৰ্ভিচ ব্যৱহাৰ কৰক"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ভিডিঅ’ ষ্ট্ৰীম ছাবস্ক্ৰাইব কৰক"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"গাড়ীৰ EVS ছাৰ্ভিচৰ স্থিতি নিৰীক্ষণ কৰক"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsServiceৰ এটা স্থিতি নিৰীক্ষণ কৰক"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS পূৰ্বদৰ্শন কাৰ্যটোৰ অনুৰোধ জনাওক"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"ছিষ্টেমটোক EVS পূৰ্বদৰ্শন কাৰ্যটো লঞ্চ কৰিবলৈ অনুৰোধ জনাওক"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS পূৰ্বদৰ্শন কাৰ্যটো নিয়ন্ত্ৰণ কৰক"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"ছিষ্টেমটোৰ EVS পূৰ্বদৰ্শন কাৰ্যটো নিয়ন্ত্ৰণ কৰক"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS কেমেৰাটো ব্যৱহাৰ কৰক"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS কেমেৰা ষ্ট্ৰীম ছাবস্ক্ৰাইব কৰক"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS সেৱাটোৰ স্থিতি নিৰীক্ষণ কৰক"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS সেৱাটোৰ স্থিতি সালসলনিসমূহ শুনক"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"গাড়ীৰ ইঞ্জিনৰ সবিশেষ তথ্য এক্সেছ কৰিব"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"আপোনাৰ গাড়ীৰ ইঞ্জিনৰ সবিশেষ তথ্য এক্সেছ কৰিব।"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"গাড়ীৰ ইন্ধনৰ দৰ্জা আৰু চাৰ্জ প’ৰ্ট এক্সেছ কৰিব"</string>
diff --git a/service/res/values-az/strings.xml b/service/res/values-az/strings.xml
index 453e877..62aa062 100644
--- a/service/res/values-az/strings.xml
+++ b/service/res/values-az/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Sürücülük vəziyyəti dəyişikliklərini dinləmək."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Avtomobilin EVS Xidmətindən istifadə edin"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS video yayımlarına abunə olun"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Avtomobilin EVS Xidmət statusunu izləyin"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Avtomobilin EVS Xidmət statusunu izləyin"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS önizləmə fəaliyyətini istəmək"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Sistemdən EVS önizləmə fəaliyyətini başlatmasını istəmək"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS önizləmə fəaliyyətinə nəzarət etmək"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Sistemin EVS önizləmə fəaliyyətinə nəzarət etmək"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS kamerasını istifadə etmək"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS kamera yayımlarına abunə olmaq"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS xidmətinin vəziyyətini izləmək"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS xidmətinin vəziyyət dəyişikliklərini dinləmək"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"avtomobilin mühərrik məlumatlarına giriş"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Avtomobilin ətraflı mühərrik məlumatlarına giriş."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"avtomobilin yanacaq bölməsinin qapağı və enerji doldurma portuna giriş"</string>
diff --git a/service/res/values-b+sr+Latn/strings.xml b/service/res/values-b+sr+Latn/strings.xml
index 90278ce..1e47f09 100644
--- a/service/res/values-b+sr+Latn/strings.xml
+++ b/service/res/values-b+sr+Latn/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Slušanje promene statusa vožnje."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Korišćenje usluge EVS za automobil"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Praćenje video strimove EVS-a"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Praćenje statusa usluge EVS za automobil"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Praćenje statusa koji se odnosi na CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Zahtev za EVS aktivnosti prikaza"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Zahtev da sistem pokrene EVS aktivnosti prikaza"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kontrola EVS aktivnosti prikaza"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kontrola EVS aktivnosti prikaza za sistem"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Korišćenje EVS kamere"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Korišćenje EVS strimova kamera"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Praćenje statusa EVS usluge"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Praćenje promena statusa usluge EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"pristup detaljnim podacima o motoru automobila"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Pristup detaljnim podacima o motoru automobila."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"pristup poklopcu rezervoara za gorivo i portu za punjenje"</string>
diff --git a/service/res/values-be/strings.xml b/service/res/values-be/strings.xml
index 0629c33..d08e25e 100644
--- a/service/res/values-be/strings.xml
+++ b/service/res/values-be/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Адсочванне змен падчас язды."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Выкарыстоўваць Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Падпісацца на відэастрымы EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Ажыццяўляць маніторынг стану Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Ажыццяўляць маніторынг стану CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Запытваць перадпрагляд EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Запытваць у сістэмы запуск перадпрагляду EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Кіраваць перадпраглядам EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Кіраваць перадпраглядам EVS сістэмы"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Выкарыстоўваць камеру EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Падпісвацца на плыневую перадачу відэа з камер EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Адсочваць стан сэрвісу EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Ажыццяўляць маніторынг змен стану сэрвісу EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"дазволіць доступ да інфармацыі пра рухавік аўтамабіля"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Доступ да падрабязнай інфармацыі пра рухавік аўтамабіля."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"дазволіць доступ да лючка паліўнага бака і порта зарадкі аўтамабіля"</string>
diff --git a/service/res/values-bg/strings.xml b/service/res/values-bg/strings.xml
index 5073a45..869a7d9 100644
--- a/service/res/values-bg/strings.xml
+++ b/service/res/values-bg/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Слушане за промени в състоянието на шофиране."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Използване на автомобилната услуга за ЕПС"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Абониране за видеопотоците на ЕПС"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Наблюдаване на състоянието на автомобилната услуга за ЕПС"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Наблюдаване на състоянието на CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Заявяване на активността за визуализация на ЕПС"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Поискване от системата да стартира активността за визуализация на ЕПС"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Управление на активността за визуализация на ЕПС"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Управление на активността за визуализация на ЕПС в системата"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Използване на камерата на ЕПС"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Абониране за потоците на камерата на ЕПС"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Наблюдение на състоянието на услугата за ЕПС"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Слушане на промените в състоянието на услугата за ЕПС"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"достъп до подробни данни за двигателя на автомобила"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Достъп до подробна информация за двигателя на автомобила."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"достъп до капака за резервоара и порта за зареждане на автомобила"</string>
diff --git a/service/res/values-bn/strings.xml b/service/res/values-bn/strings.xml
index bc1f480..753cc2b 100644
--- a/service/res/values-bn/strings.xml
+++ b/service/res/values-bn/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ড্রাইভিংয়ের স্ট্যাটাস পরিবর্তন করার বিষয়ে শোনা।"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"গাড়ি EVS পরিষেবা ব্যবহার করুন"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ভিডিও স্ট্রিমে সাবস্ক্রাইব করুন"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"গাড়ি EVS পরিষেবার স্ট্যাটাস মনিটর করুন"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService-এর স্ট্যাটাস মনিটর করুন"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS প্রিভিউ অ্যাক্টিভিটির অনুরোধ করুন"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS প্রিভিউ অ্যাক্টিভিটি চালু করার জন্য সিস্টেমকে অনুরোধ করুন"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS প্রিভিউ অ্যাক্টিভিটি নিয়ন্ত্রণ করুন"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"সিস্টেমের EVS প্রিভিউ অ্যাক্টিভিটি নিয়ন্ত্রণ করুন"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS ক্যামেরা ব্যবহার করুন"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS ক্যামেরা স্ট্রিমে সাবস্ক্রাইব করুন"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS পরিষেবার স্ট্যাটাস মনিটর করুন"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS পরিষেবার স্ট্যাটাস পরিবর্তনগুলি শুনুন"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"গাড়ির ইঞ্জিনের বিবরণ অ্যাক্সেস করা"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"আপনার গাড়ির ইঞ্জিনের বিশদ তথ্য অ্যাক্সেস করা।"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"গাড়ির জ্বালানীর চেম্বারের ঢাকনা ও চার্জ পোর্ট অ্যাক্সেস করা"</string>
diff --git a/service/res/values-bs/strings.xml b/service/res/values-bs/strings.xml
index 9dc82a7..1fd16cc 100644
--- a/service/res/values-bs/strings.xml
+++ b/service/res/values-bs/strings.xml
@@ -21,17 +21,17 @@
     <string name="car_permission_label_camera" msgid="3725702064841827180">"pristupiti kameri automobila"</string>
     <string name="car_permission_desc_camera" msgid="917024932164501426">"Pristupiti kameri(ama) automobila."</string>
     <string name="car_permission_label_energy" msgid="7409144323527821558">"pristupiti informacijama o energiji automobila"</string>
-    <string name="car_permission_desc_energy" msgid="3392963810053235407">"Pristupiti informacijama o energiji automobila."</string>
-    <string name="car_permission_label_adjust_range_remaining" msgid="839033553999920138">"podesi preostali domet automobila"</string>
-    <string name="car_permission_desc_adjust_range_remaining" msgid="2369321650437370673">"Podesi vrijednost preostalog dometa automobila."</string>
+    <string name="car_permission_desc_energy" msgid="3392963810053235407">"pristupiti informacijama o energiji automobila"</string>
+    <string name="car_permission_label_adjust_range_remaining" msgid="839033553999920138">"podesiti preostali domet automobila"</string>
+    <string name="car_permission_desc_adjust_range_remaining" msgid="2369321650437370673">"podesiti vrijednost preostalog dometa automobila"</string>
     <string name="car_permission_label_hvac" msgid="1499454192558727843">"pristupiti grijanju, ventilaciji i klimatizaciji automobila"</string>
     <string name="car_permission_desc_hvac" msgid="3754229695589774195">"Pristupiti grijanju, ventilaciji i klimatizaciji automobila."</string>
     <string name="car_permission_label_mileage" msgid="4661317074631150551">"pristupiti informacijama o pređenim kilometrima automobila"</string>
-    <string name="car_permission_desc_mileage" msgid="7179735693278681090">"Pristupiti informacijama o pređenim kilometrima."</string>
+    <string name="car_permission_desc_mileage" msgid="7179735693278681090">"pristupiti informacijama o pređenim kilometrima"</string>
     <string name="car_permission_label_speed" msgid="1149027717860529745">"očitati brzinu automobila"</string>
-    <string name="car_permission_desc_speed" msgid="2047965198165448241">"Pristupiti informacijama o brzini automobila."</string>
+    <string name="car_permission_desc_speed" msgid="2047965198165448241">"pristupiti informacijama o brzini automobila"</string>
     <string name="car_permission_label_vehicle_dynamics_state" msgid="313779267420048367">"pristupiti stanju dinamike automobila"</string>
-    <string name="car_permission_desc_vehicle_dynamics_state" msgid="8891506193446375660">"Pristupiti stanju dinamike automobila."</string>
+    <string name="car_permission_desc_vehicle_dynamics_state" msgid="8891506193446375660">"pristupiti stanju dinamike automobila"</string>
     <string name="car_permission_label_vendor_extension" msgid="7141601811734127361">"pristupiti kanalu trgovca automobilima"</string>
     <string name="car_permission_desc_vendor_extension" msgid="2970718502334714035">"Pristupiti kanalu trgovca automobilima radi razmjene posebnih informacija o automobilu."</string>
     <string name="car_permission_label_radio" msgid="6009465291685935112">"upravljati radiom automobila"</string>
@@ -47,11 +47,11 @@
     <string name="car_permission_label_mock_vehicle_hal" msgid="7198852512207405935">"emulirati HAL vozila"</string>
     <string name="car_permission_label_receive_ducking" msgid="4884538660766756573">"prijem događaja sa smanjivanjem jačine zvuka tokom govora"</string>
     <string name="car_permission_desc_receive_ducking" msgid="776376388266656512">"Dozvoljava aplikaciji da primi obavještenje kada se glasnoća smanji uslijed reproduciranja drugog zvučnog zapisa u automobilu."</string>
-    <string name="car_permission_desc_mock_vehicle_hal" msgid="5235596491098649155">"Emulirati HAL vozila u svrhu internog testiranja."</string>
-    <string name="car_permission_desc_audio_volume" msgid="536626185654307889">"Kontrolirati jačinu zvuka u automobilu."</string>
+    <string name="car_permission_desc_mock_vehicle_hal" msgid="5235596491098649155">"emulirati HAL vozila u svrhu internog testiranja"</string>
+    <string name="car_permission_desc_audio_volume" msgid="536626185654307889">"kontrolirati jačinu zvuka u automobilu"</string>
     <string name="car_permission_desc_audio_settings" msgid="7192007170677915937">"Kontrolirajte postavke zvuka automobila."</string>
     <string name="car_permission_label_control_app_blocking" msgid="9112678596919993386">"Blokiranje aplikacija"</string>
-    <string name="car_permission_desc_control_app_blocking" msgid="7539378161760696190">"Kontrolirati blokiranje aplikacija tokom vožnje."</string>
+    <string name="car_permission_desc_control_app_blocking" msgid="7539378161760696190">"kontrolirati blokiranje aplikacija tokom vožnje"</string>
     <string name="car_permission_car_navigation_manager" msgid="5895461364007854077">"Upravitelj navigacije"</string>
     <string name="car_permission_desc_car_navigation_manager" msgid="6188751054665471537">"Dostaviti podatke o navigaciji kontrolnoj tabli"</string>
     <string name="car_permission_car_display_in_cluster" msgid="4005987646292458684">"Direktno iscrtavanje na kontrolnoj ploči"</string>
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Slušati izmjene stanja vožnje."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Korištenje usluge Car EVS"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Pretplaćivanje na video prijenose usluge EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Nadziranje statusa usluge Car EVS"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Nadziranje statusa usluge CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Zahtijevanje pregleda aktivnosti usluge EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Zahtijevanje od sistema da pokrene aktivnost pregleda usluge EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kontroliranje aktivnosti pregleda usluge EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kontroliranje pregleda aktivnosti sistema usluge EVS"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Korištenje kamere usluge EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Pretplata na prijenose kamere usluge EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Praćenje statusa usluge EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Slušanje promjena statusa usluge EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"pristupiti detaljima o motoru automobila"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Pristupiti detaljnim informacijama o motoru automobila."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"pristupiti poklopcu rezervoara za gorivo i priključku za punjenje"</string>
diff --git a/service/res/values-ca/strings.xml b/service/res/values-ca/strings.xml
index 81a5c20..6250c91 100644
--- a/service/res/values-ca/strings.xml
+++ b/service/res/values-ca/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Escolta els canvis en l\'estat de conducció."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Utilitza el servei EVS del cotxe"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Subscriu-me a les reproduccions en continu de vídeo d\'EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitora l\'estat del servei EVS del cotxe"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitora un estat de CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Sol·licitar l\'activitat de previsualització d\'EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Sol·licitar al sistema que iniciï l\'activitat de previsualització d\'EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Controlar l\'activitat de previsualització d\'EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Controlar l\'activitat de previsualització d\'EVS del sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Utilitzar la càmera EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Subscriure\'s a les reproduccions en continu de la càmera EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitorar l\'estat del servei d\'EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Escoltar els canvis d\'estat del servei EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"accedeix a la informació detallada sobre el motor del cotxe"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Accedeix a la informació detallada sobre el motor del cotxe."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"accedeix a la porta del combustible i al port de càrrega del cotxe"</string>
diff --git a/service/res/values-cs/strings.xml b/service/res/values-cs/strings.xml
index 0e06abf..a717cba 100644
--- a/service/res/values-cs/strings.xml
+++ b/service/res/values-cs/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Poslech změn stavu jízdy autem."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Používání služby EVS pro auto"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Odběr videostreamů EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Sledování stavu služby EVS pro auto"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Sledování stavu CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Žádost o náhled aktivity EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Žádost systému o spuštění aktivity náhledu EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Ovládání aktivity náhledu EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Ovládání aktivity náhledu systému EVS"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Používání kamery EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Odběr streamů z kamery EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Sledování stavu služby EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Poslech změn stavu služby EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"přístup k podrobným informacím o motoru auta"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Přístup k podrobným údajům o motoru auta."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"přístup ke vstupu do nádrže a nabíjecímu portu auta"</string>
diff --git a/service/res/values-da/strings.xml b/service/res/values-da/strings.xml
index 506603e..a9393f0 100644
--- a/service/res/values-da/strings.xml
+++ b/service/res/values-da/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Lyt til ændringer i tilstanden Kører."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Brug Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Abonner på EVS-videostreams"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Følg med i status for Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Følg med i en status for CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Anmode om aktivitet med EVS-forhåndsvisning"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Anmode systemet om at åbne aktivitet med EVS-forhåndsvisning"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Styre aktivitet med EVS-forhåndsvisning"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kontrollere systemets aktivitet med EVS-forhåndsvisning"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Bruge EVS-kameraet"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Abonnere på EVS-kamerastreams"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Holde øje med EVS-tjenestens status"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Høre statusændringer for EVS-tjenesten"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"få adgang til detaljerede oplysninger om bilens motor"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Få adgang til detaljerede oplysninger om bilens motor."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"få adgang til bilens tankdæksel og opladningsport"</string>
diff --git a/service/res/values-de/strings.xml b/service/res/values-de/strings.xml
index 5a97e2f..f936a9d 100644
--- a/service/res/values-de/strings.xml
+++ b/service/res/values-de/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Informationen zu Fahrzustandsänderungen entgegennehmen."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Car EVS Service verwenden"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS-Videostreams abonnieren"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Car EVS Service-Status überwachen"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Einen Status von CarEvsService überwachen"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS-Vorschauaktivität anfordern"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Das System auffordern, die EVS-Vorschauaktivität zu starten"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS-Vorschauaktivität steuern"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"EVS-Vorschauaktivität des Systems steuern"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS-Kamera verwenden"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS-Kamerastreams abonnieren"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Status des EVS-Diensts prüfen"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Statusänderungen des EVS-Diensts prüfen"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"auf detaillierte Motorinformationen zuzugreifen"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Auf detaillierte Motorinformationen zugreifen."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"auf die Tankklappe und die Ladebuchse zuzugreifen"</string>
diff --git a/service/res/values-el/strings.xml b/service/res/values-el/strings.xml
index edec482..540e78a 100644
--- a/service/res/values-el/strings.xml
+++ b/service/res/values-el/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Ακρόαση αλλαγών κατάστασης οδήγησης."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Χρήση Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Εγγραφή στις ροές βίντεο EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Παρακολούθηση κατάστασης Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Παρακολούθηση κατάστασης CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Υποβολή αιτήματος για τη δραστηριότητα προεπισκόπησης EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Υποβολή αιτήματος στο σύστημα για εκκίνηση της δραστηριότητας προεπισκόπησης EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Έλεγχος της δραστηριότητας προεπισκόπησης EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Έλεγχος της δραστηριότητας προεπισκόπησης EVS του συστήματος"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Χρήση της κάμερας EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Εγγραφή σε ροές κάμερας EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Παρακολούθηση της κατάστασης της υπηρεσίας EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Παρακολούθηση των αλλαγών κατάστασης της υπηρεσίας EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"πρόσβαση στις λεπτομέρειες του κινητήρα του αυτοκινήτου"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Πρόσβαση σε λεπτομερείς πληροφορίες του κινητήρα του αυτοκινήτου."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"πρόσβαση στο πορτάκι του ρεζερβουάρ και της θύρας φόρτισης"</string>
diff --git a/service/res/values-en-rAU/strings.xml b/service/res/values-en-rAU/strings.xml
index 30854bd..06574a9 100644
--- a/service/res/values-en-rAU/strings.xml
+++ b/service/res/values-en-rAU/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Listen to driving state changes."</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_monitor_evs_status" msgid="8586151402220417700">"Monitor car EVS service status"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitor a status of CarEvsService"</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 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>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Listen to the status changes of the EVS service"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"access car’s engine detailed"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Access your car’s detailed engine information."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"access car’s fuel door and charge port"</string>
diff --git a/service/res/values-en-rCA/strings.xml b/service/res/values-en-rCA/strings.xml
index 30854bd..06574a9 100644
--- a/service/res/values-en-rCA/strings.xml
+++ b/service/res/values-en-rCA/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Listen to driving state changes."</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_monitor_evs_status" msgid="8586151402220417700">"Monitor car EVS service status"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitor a status of CarEvsService"</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 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>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Listen to the status changes of the EVS service"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"access car’s engine detailed"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Access your car’s detailed engine information."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"access car’s fuel door and charge port"</string>
diff --git a/service/res/values-en-rGB/strings.xml b/service/res/values-en-rGB/strings.xml
index 30854bd..06574a9 100644
--- a/service/res/values-en-rGB/strings.xml
+++ b/service/res/values-en-rGB/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Listen to driving state changes."</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_monitor_evs_status" msgid="8586151402220417700">"Monitor car EVS service status"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitor a status of CarEvsService"</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 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>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Listen to the status changes of the EVS service"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"access car’s engine detailed"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Access your car’s detailed engine information."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"access car’s fuel door and charge port"</string>
diff --git a/service/res/values-en-rIN/strings.xml b/service/res/values-en-rIN/strings.xml
index 30854bd..06574a9 100644
--- a/service/res/values-en-rIN/strings.xml
+++ b/service/res/values-en-rIN/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Listen to driving state changes."</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_monitor_evs_status" msgid="8586151402220417700">"Monitor car EVS service status"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitor a status of CarEvsService"</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 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>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Listen to the status changes of the EVS service"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"access car’s engine detailed"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Access your car’s detailed engine information."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"access car’s fuel door and charge port"</string>
diff --git a/service/res/values-en-rXC/strings.xml b/service/res/values-en-rXC/strings.xml
index 0a638d9..b0dfaa1 100644
--- a/service/res/values-en-rXC/strings.xml
+++ b/service/res/values-en-rXC/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎Listen to Driving state changes.‎‏‎‎‏‎"</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_monitor_evs_status" msgid="8586151402220417700">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎Monitor Car EVS Service status‎‏‎‎‏‎"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎Monitor a status of CarEvsService‎‏‎‎‏‎"</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_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>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎Listen to the status changes of the EVS service‎‏‎‎‏‎"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎access car’s engine detailed‎‏‎‎‏‎"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎Access your car’s detailed engine information.‎‏‎‎‏‎"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‎access car’s fuel door and charge port‎‏‎‎‏‎"</string>
diff --git a/service/res/values-es-rUS/strings.xml b/service/res/values-es-rUS/strings.xml
index f7b3971..f1c077b 100644
--- a/service/res/values-es-rUS/strings.xml
+++ b/service/res/values-es-rUS/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Escuchar los cambios de estado de conducción."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Usar servicio EVS del vehículo"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Suscribirse a las transmisiones de video por Internet de EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Supervisar el estado del servicio EVS del vehículo"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Supervisar un estado de CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Solicitar la actividad de vista previa de EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Solicitar que el sistema inicie la actividad de vista previa de EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Controlar la actividad de vista previa de EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Controlar la actividad de vista previa de EVS del sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Usar la cámara de EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Suscribirse a transmisiones de cámaras de EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Supervisar el estado del servicio de EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Detectar los cambios de estado del servicio de EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"acceder a detalles del motor del vehículo"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Acceder a información detallada del motor del vehículo."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"acceder a la puerta de combustible del vehículo y al puerto de carga"</string>
diff --git a/service/res/values-es/strings.xml b/service/res/values-es/strings.xml
index 79e7605..bdbe760 100644
--- a/service/res/values-es/strings.xml
+++ b/service/res/values-es/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Detectar cambios en el estado de conducción."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Utilizar servicio EVS del coche"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Suscribirse a streams de vídeo de EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitorizar estado del servicio EVS del coche"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitorizar un estado de CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Solicitar la actividad de vista previa de EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Solicitar al sistema que inicie la actividad de vista previa de EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Controlar la actividad de vista previa de EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Controlar la actividad de vista previa de EVS del sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Utilizar la cámara de EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Suscribirse a flujos de cámara de EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitorizar el estado del servicio EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Monitorizar los cambios de estado del servicio EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"acceder a los detalles del motor del coche"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Acceder a información detallada sobre el motor del coche."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"acceder al puerto de carga y al depósito de combustible"</string>
diff --git a/service/res/values-et/strings.xml b/service/res/values-et/strings.xml
index 67e48e5..ea80e70 100644
--- a/service/res/values-et/strings.xml
+++ b/service/res/values-et/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Sõitmise oleku muudatuste kuulamine."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Auto EVS-i teenuse kasutamine"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS-i videovoogude kasutajaks registreerumine"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Auto EVS-i teenuse oleku jälgimine"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Teenuse CarEvsService oleku jälgimine"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS-i eelvaatetegevuste taotlemine"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Süsteemil EVS-i eelvaatetegevuste käivitamise taotlemine"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS-i eelvaatetegevuste juhtimine"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Süsteemi EVS-i eelvaatetegevuste kontrollimine"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS-i kaamera kasutamine"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS-i kaameravoogude tellimine"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS-i teenuse oleku jälgimine"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS-i teenuse olekumuudatuste kuulmine"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"juurdepääs auto mootori üksikasjalikule teabele"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Juurdepääs auto üksikasjalikule mootoriteabele."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"juurdepääs auto kütusepaagi luugile ja avale"</string>
diff --git a/service/res/values-eu/strings.xml b/service/res/values-eu/strings.xml
index a12a1d5..addec81 100644
--- a/service/res/values-eu/strings.xml
+++ b/service/res/values-eu/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Entzun gidatze-egoeraren inguruko aldaketak."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Erabili autoko EVS zerbitzua"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Harpidetu EVSren bideo-igorpenetara"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Kontrolatu autoko EVS zerbitzuaren egoera"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Kontrolatu CarEvsService-ren egoera"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Eskatu EVSko aurrebistaren jarduera"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Eskatu sistemari EVSko aurrebista abiarazteko"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kontrolatu EVSko aurrebistaren jarduera"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kontrolatu sistemaren EVSko aurrebistaren jarduera"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Erabili EVSaren kamera"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Harpidetu EVSaren kamera-igorpenetara"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Gainbegiratu EVS zerbitzuaren egoera"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Gainbegiratu EVS zerbitzuaren egoera-aldaketak"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"atzitu autoaren motorrari buruzko informazio xehatua"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Atzitu autoaren motorrari buruzko informazio xehatua."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"atzitu autoaren erregai-deposituaren ataka eta korrontera konektatzeko ataka"</string>
diff --git a/service/res/values-fa/strings.xml b/service/res/values-fa/strings.xml
index 3a827c4..6700349 100644
--- a/service/res/values-fa/strings.xml
+++ b/service/res/values-fa/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"به تغییرات حالت رانندگی گوش دهید."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"استفاده از «سرویس EVS خودرو»"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"مشترک شدن در جاری‌سازی ویدیویی EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"نظارت بر وضعیت «سرویس EVS خودرو»"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"نظارت بر وضعیت CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"درخواست فعالیت پیش‌نمای EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"درخواست از سیستم برای راه‌اندازی فعالیت پیش‌نمای EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"کنترل کردن فعالیت پیش‌نمای EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"کنترل کردن فعالیت پیش‌نمای EVS در سیستم"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"استفاده از دوربین EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"مشترک شدن در جاری‌سازی دوربین EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"نظارت بر وضعیت سرویس EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"گوش دادن به تغییرات وضعیت سرویس EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"دسترسی به اطلاعات کامل موتور"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"به اطلاعات کامل موتور خودرو دسترسی پیدا کنید."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"دسترسی به درب باک و درگاه شارژ خودرو"</string>
diff --git a/service/res/values-fi/strings.xml b/service/res/values-fi/strings.xml
index 281dadb..44e5096 100644
--- a/service/res/values-fi/strings.xml
+++ b/service/res/values-fi/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"kuunnella ajotilan muutoksia"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"käyttää auton EVS-palvelua"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"tilata EVS-videostriimit"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"seurata auton EVS-palvelun tilaa"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"valvoa CarEvsServicen tilaa"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"pyytää EVS-esikatselutoimintaa"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"pyytää järjestelmää käynnistämään EVS-esikatselutoiminnan"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"ohjata EVS-esikatselutoimintaa"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"ohjata järjestelmän EVS-esikatselutoimintaa"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"käyttää EVS-kameraa"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"tilata EVS-kamerastriimit"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"seurata EVS-palvelun tilaa"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"kuunnella muutoksia EVS-palvelun tilassa"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"käyttää auton moottorin yksityiskohtaisia tietoja"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"käyttää auton moottorin yksityiskohtaisia tietoja"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"käyttää auton polttoaineluukkua ja latausliitäntää"</string>
diff --git a/service/res/values-fr-rCA/strings.xml b/service/res/values-fr-rCA/strings.xml
index fb79451..5878a5d 100644
--- a/service/res/values-fr-rCA/strings.xml
+++ b/service/res/values-fr-rCA/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Détecter les changements relatifs à la conduite."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Utiliser le service EVS du véhicule"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"S\'abonner aux flux vidéo EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Surveiller l\'état du service EVS du véhicule"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Surveiller l\'état de CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Demander l\'activité d\'aperçu EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Demander au système de lancer l\'activité d\'aperçu EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Contrôler l\'activité d\'aperçu EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Contrôler l\'activité d\'aperçu EVS du système"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Utiliser la caméra EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"S\'abonner aux flux de la caméra EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Surveiller l\'état du service EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Écouter les changements d\'état du service EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"accéder aux détails sur le moteur de la voiture"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Accéder aux renseignements détaillés sur le moteur de votre voiture."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"accéder à la porte du réservoir de carburant et au port de recharge de la voiture"</string>
diff --git a/service/res/values-fr/strings.xml b/service/res/values-fr/strings.xml
index 32def69..407ab8a 100644
--- a/service/res/values-fr/strings.xml
+++ b/service/res/values-fr/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Détecter les changements de conduite."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Utiliser Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"S\'abonner aux flux vidéo EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Surveiller un état Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Surveiller un état CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Demander l\'activité d\'aperçu EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Demander le lancement de l\'activité d\'aperçu EVS par le système"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Contrôler l\'activité d\'aperçu EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Contrôler l\'activité d\'aperçu EVS du système"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Utiliser la caméra EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"S\'abonner aux flux de la caméra EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Surveiller l\'état du service EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Écouter les changements d\'état du service EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"Accéder aux informations détaillées sur le moteur de la voiture"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Accéder à des informations détaillées sur le moteur de la voiture."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"Accéder à la trappe à carburant et au port de recharge de la voiture"</string>
diff --git a/service/res/values-gl/strings.xml b/service/res/values-gl/strings.xml
index 22e8d56..24fcbb1 100644
--- a/service/res/values-gl/strings.xml
+++ b/service/res/values-gl/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Escoitar cambios no estado de condución."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Utilizar o servizo EVS do coche"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Subscribirse ás transmisións en vídeo de EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Supervisar o estado do servizo EVS do coche"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Supervisar un estado de CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Solicitar a actividade de vista previa do servizo EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Solicitar que o sistema inicie a actividade de vista previa do servizo EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Controlar a actividade de vista previa do servizo EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Controlar a actividade de vista previa do servizo EVS do sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Usar a cámara do servizo EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Subscribirse á reprodución en tempo real das cámaras do servizo EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Supervisar o estado do servizo EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Supervisar os cambios de estado do servizo EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"acceder a información do motor do coche"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Acceder a información detallada do motor do coche."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"acceder ao depósito de combustible e ao porto de carga do coche"</string>
diff --git a/service/res/values-gu/strings.xml b/service/res/values-gu/strings.xml
index 9a690a0..931b0e7 100644
--- a/service/res/values-gu/strings.xml
+++ b/service/res/values-gu/strings.xml
@@ -96,8 +96,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ડ્રાઇવ કરવાની સ્થિતિના ફેરફારો વિશે સાંભળો."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"કાર EVS સર્વિસનો ઉપયોગ કરો"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS વીડિયો સ્ટ્રીમને સબ્સ્ક્રાઇબ કરો"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"કાર EVS સર્વિસના સ્ટેટસનું નિરીક્ષણ કરો"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"કાર EVS સર્વિસના સ્ટેટસનું નિરીક્ષણ કરો"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS પ્રીવ્યૂ પ્રવૃત્તિ માટે વિનંતી કરો"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS પ્રીવ્યૂ પ્રવૃત્તિ લૉન્ચ કરવા માટે, સિસ્ટમને વિનંતી કરો"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS પ્રીવ્યૂ પ્રવૃત્તિ નિયંત્રિત કરો"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"સિસ્ટમની EVS પ્રીવ્યૂ પ્રવૃત્તિ નિયંત્રિત કરો"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS કૅમેરાનો ઉપયોગ કરો"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS કૅમેરા સ્ટ્રીમને સબ્સ્ક્રાઇબ કરો"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS સેવાનું સ્ટેટસ મૉનિટર કરો"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS સેવાના સ્ટેટસમાં થનારા ફેરફારો સાંભળો"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"કારના એન્જિનની વિગતવાર માહિતીને ઍક્સેસ કરો"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"તમારી કારના એન્જિનની વિગતવાર માહિતીને ઍક્સેસ કરો."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"કારના ઇંધણના દરવાજા અને ચાર્જ પોર્ટને ઍક્સેસ કરો"</string>
diff --git a/service/res/values-hi/strings.xml b/service/res/values-hi/strings.xml
index 789c78b..6ff2cbd 100644
--- a/service/res/values-hi/strings.xml
+++ b/service/res/values-hi/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"गाड़ी चलाते समय होने वाले बदलावों को सुन सकता है."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"कार की ईवीएस सेवा का इस्तेमाल करें"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"ईवीएस वीडियो स्ट्रीम की सदस्यता लें"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"कार की ईवीएस सेवा की स्थिति को मॉनिटर करें"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService की स्थिति को मॉनिटर करें"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"ईवीएस की झलक से जुड़ी गतिविधि का अनुरोध करें"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"ईवीएस की झलक से जुड़ी गतिविधि लॉन्च करने के लिए सिस्टम से अनुरोध करें"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"ईवीएस की झलक से जुड़ी गतिविधि कंट्रोल करें"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"सिस्टम की ईवीएस की झलक से जुड़ी गतिविधि कंट्रोल करें"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"ईवीएस कैमरा इस्तेमाल करें"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"ईवीएस कैमरा स्ट्रीम की सदस्यता लें"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"ईवीएस सेवा के स्टेटस पर नज़र रखें"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"ईवीएस सेवा के स्टेटस में हुए बदलावों पर नज़र रखें"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"कार के इंजन की जानकारी ऐक्सेस कर सकता है"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"आपकी कार के इंजन की पूरी जानकारी ऐक्सेस कर सकता है."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"कार की ईंधन टंकी का ढक्कन और चार्जिंग पोर्ट ऐक्सेस कर सकता है"</string>
diff --git a/service/res/values-hr/strings.xml b/service/res/values-hr/strings.xml
index 57358ca..0662614 100644
--- a/service/res/values-hr/strings.xml
+++ b/service/res/values-hr/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"slušati promjene stanja vožnje"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"koristiti EVS uslugu za automobil"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"pretplatiti se na videostreamove EVS-a"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"nadzirati status EVS usluge za automobil"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"nadzirati status koji se odnosi na CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"zahtijevati aktivnost pregleda EVS-a"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"zahtijevati da sustav pokrene aktivnost pregleda EVS-a"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"upravljati aktivnošću pregleda EVS-a"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"upravljati aktivnošću pregleda EVS-a u sustavu"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"koristiti kameru EVS-a"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"pretplatiti se na streamove kamere EVS-a"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"nadzirati status usluge EVS-a"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"slušati promjene statusa usluge EVS-a"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"pristupiti pojedinostima o automobilskom motoru"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"pristupiti detaljnim podacima o motoru automobila"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"pristupiti poklopcu spremnika za gorivo i priključku za punjenje na automobilu"</string>
diff --git a/service/res/values-hu/strings.xml b/service/res/values-hu/strings.xml
index 7772d51..07e69cd 100644
--- a/service/res/values-hu/strings.xml
+++ b/service/res/values-hu/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Meghallgathatja a vezetési állapot változásait."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Az autó EVS-szolgáltatásának használata"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Feliratkozás az EVS-videóstreamekre"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Az autó EVS-szolgáltatása állapotának figyelése"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService állapotának figyelése"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Az EVS-előnézeti tevékenység kérése"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Annak kérése a rendszertől, hogy indítsa el az EVS-előnézeti tevékenységet"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Az EVS-előnézeti tevékenységek irányítása"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"A rendszer EVS-előnézeti tevékenységeinek irányítása"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Az EVS-kamera használata"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Feliratkozás EVS-kamerastreamekre"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Az EVS szolgáltatás állapotának figyelése"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Az EVS szolgáltatás állapotváltozásainak figyelése"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"hozzáférhet az autó motorjával kapcsolatos részletes adatokhoz"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Hozzáférhet az autó motorjának részletes adataihoz."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"hozzáférhet az autó tanksapkájához és töltőnyílásához"</string>
diff --git a/service/res/values-hy/strings.xml b/service/res/values-hy/strings.xml
index 859e64a..d48f548 100644
--- a/service/res/values-hy/strings.xml
+++ b/service/res/values-hy/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Հետագծել վարելու ռեժիմի փոփոխությունները։"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Օգտագործել ավտոմեքենայի EVS ծառայությունը"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Բաժանորդագրվել EVS տեսահոսքին"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Վերահսկել ավտոմեքենայի EVS ծառայության կարգավիճակը"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Վերահսկել CarEvsService-ի կարգավիճակը"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS նախադիտման գործողություններ գործարկելու հարցում ուղարկել"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Համակարգին EVS նախադիտման գործողությունները գործարկելու հարցում ուղարկել"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Վերահսկել EVS նախադիտման գործողությունները"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Վերահսկել համակարգի EVS նախադիտման գործողությունները"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Օգտագործել EVS տեսախցիկը"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Բաժանորդագրվել EVS տեսահոսքին"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Վերահսկել EVS ծառայության կարգավիճակը"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Լսել EVS ծառայության կարգավիճակի փոփոխությունները"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"օգտագործել մեքենայի շարժիչի մանրամասն տվյալները"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Օգտագործել շարժիչի մանրամասն տվյալները։"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"օգտագործել մեքենայի վառելիքի բաքի կափարիչի և լիցքավորման վարդակի տվյալները"</string>
diff --git a/service/res/values-in/strings.xml b/service/res/values-in/strings.xml
index 9f8ad12..3a039b6 100644
--- a/service/res/values-in/strings.xml
+++ b/service/res/values-in/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Memproses perubahan status Mengemudi."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Menggunakan CarEvsService"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Berlangganan streaming video EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Memantau status CarEvsService"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Memantau status CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Meminta aktivitas pratinjau EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Meminta sistem meluncurkan aktivitas pratinjau EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Mengontrol aktivitas pratinjau EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Mengontrol aktivitas pratinjau EVS dari sistem"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Menggunakan kamera EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Berlangganan streaming kamera EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Memantau status layanan EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Mendengarkan perubahan status layanan EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"mengakses detail mesin mobil"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Mengakses informasi mendetail tentang mesin mobil Anda."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"mengakses tutup tangki bahan bakar dan lubang colokan pengisi daya mobil"</string>
diff --git a/service/res/values-is/strings.xml b/service/res/values-is/strings.xml
index 855d694..45932c6 100644
--- a/service/res/values-is/strings.xml
+++ b/service/res/values-is/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Hlusta á breytingar í akstursstöðu."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Nota EVS-þjónustu bíls"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Gerast áskrifandi að EVS-vídeóstraumi"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Fylgjast með stöðu EVS-þjónustu bíls"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Fylgjast með stöðu CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Biðja um EVS-forskoðunaraðgerðir"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Biðja kerfið um að ræsa EVS-forskoðunaraðgerðir"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Stjórna EVS-forskoðunaraðgerðum"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Stjórna EVS-forskoðunaraðgerðum í kerfinu"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Nota EVS-myndavélina"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Fá áskrift að EVS-myndavélastreymi"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Fylgjast með stöðu EVS-þjónustunnar"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Hlusta eftir stöðubreytingum EVS-þjónustunnar"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"fá aðgang að upplýsingum um vél"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Fá aðgang að ítarlegum upplýsingum um vél bílsins."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"fá aðgang að bensínloki og hleðslutengi bílsins"</string>
diff --git a/service/res/values-it/strings.xml b/service/res/values-it/strings.xml
index a6a299b..cc45ee2 100644
--- a/service/res/values-it/strings.xml
+++ b/service/res/values-it/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Consente di ascoltare le modifiche dello stato Alla guida."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Usa il servizio CarEvsService"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Consente di abbonarsi ai video stream EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitora lo stato del servizio CarEvsService"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Consente di monitorare lo stato del servizio CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Richiedere l\'attività di anteprima EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Richiedere al sistema di lanciare l\'attività di anteprima EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Controllare l\'attività di anteprima EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Controllare l\'attività di anteprima EVS del sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Utilizzare la videocamera EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Abbonarsi agli stream della videocamera EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitorare lo stato del servizio EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Ascoltare le modifiche dello stato del servizio EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"Accesso alle informazioni dettagliate sul motore dell\'automobile"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Consente di accedere a informazioni dettagliate sul motore dell\'automobile."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"Accesso al coperchio del serbatoio e allo sportello di ricarica dell\'automobile"</string>
diff --git a/service/res/values-iw/strings.xml b/service/res/values-iw/strings.xml
index 466fe82..af01ba3 100644
--- a/service/res/values-iw/strings.xml
+++ b/service/res/values-iw/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"האזנה לשינויים במצב הנהיגה."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"שימוש ב-Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"הרשמה לשידורי וידאו של EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"מעקב אחר הסטטוס של Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"מעקב אחר הסטטוס של CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"לבקש את פעילות התצוגה המקדימה של מערכת התצוגה החיצונית (EVS)"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"לבקש מהמערכת להפעיל את פעילות התצוגה המקדימה של מערכת התצוגה החיצונית (EVS)"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"לשלוט בפעילות התצוגה המקדימה של מערכת התצוגה החיצונית (EVS)"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"לשלוט בפעילות התצוגה המקדימה של מערכת התצוגה החיצונית (EVS)"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"להשתמש במצלמה של מערכת התצוגה החיצונית (EVS)"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"להירשם לשידורי הווידאו של מערכת התצוגה החיצונית (EVS)"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"לעקוב אחר הסטטוס של שירות מערכת התצוגה החיצונית (EVS)"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"להתעדכן בשינויי הסטטוס של שירות מערכת התצוגה החיצונית (EVS)"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"גישה למידע מפורט על מנוע הרכב"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"גישה למידע מפורט על מנוע הרכב."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"גישה לפתח מכל הדלק וליציאת הטעינה של הרכב"</string>
diff --git a/service/res/values-ja/strings.xml b/service/res/values-ja/strings.xml
index 21b1504..83f15a3 100644
--- a/service/res/values-ja/strings.xml
+++ b/service/res/values-ja/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"運転状態の変更にアクセスします。"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Car EVS Service の使用"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS 動画ストリーミングのチャンネル登録"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Car EVS Service のステータスのモニタリング"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService のステータスのモニタリング"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS プレビュー アクティビティをリクエストします"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS プレビュー アクティビティの開始をシステムにリクエストします"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS プレビュー アクティビティを制御します"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"システムの EVS プレビュー アクティビティを制御します"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS カメラを使用します"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS カメラ ストリーミングに登録します"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS サービスの状態をモニタリングします"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS サービスの状態の変更をリッスンします"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"車のエンジンの詳細情報へのアクセス"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"車の詳細なエンジン情報にアクセスします。"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"車の給油口と充電ポートへのアクセス"</string>
diff --git a/service/res/values-ka/strings.xml b/service/res/values-ka/strings.xml
index d460e84..90100ea 100644
--- a/service/res/values-ka/strings.xml
+++ b/service/res/values-ka/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"მანქანის მართვის მდგომარეობის ცვლილებებისთვის თვალის მიდევნება."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"მანქანის EVS სერვისით სარგებლობა"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ვიდეონაკადების გამოწერა"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"მანქანის EVS სერვისის სტატუსის მონიტორინგი"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService სტატუსის მონიტორინგი"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS-ის გადახედვის აქტივობის მოთხოვნა"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"სისტემისთვის EVS-ის გადახედვის აქტივობის გაშვების მოთხოვნა"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS-ის გადახედვის აქტივობის კონტროლი"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"სისტემის EVS-ის გადახედვის აქტივობის კონტროლი"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS კამერის გამოყენება"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS კამერის ნაკადების გამოწერა"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS სერვისის სტატუსის მონიტორინგი"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS სერვისის სტატუსის ცვლილებების მოსმენა"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"მანქანის ძრავის დეტალურ ინფორმაციაზე წვდომა"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"მანქანის ძრავის დეტალურ ინფორმაციაზე წვდომა."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"მანქანის საწვავის ავზის ხუფზე და დამტენ პორტზე წვდომა"</string>
diff --git a/service/res/values-kk/strings.xml b/service/res/values-kk/strings.xml
index edfa2c8..af0f662 100644
--- a/service/res/values-kk/strings.xml
+++ b/service/res/values-kk/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Көлік жүргізу күйінің өзгерістерін білу."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Car EVS Service пайдалану"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS бейне ағыны қызметіне жазылу"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Car EVS Service күйін қадағалау"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService күйін қадағалау"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS әрекетін алдын ала қарауды сұрау"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS әрекетін алдын ала қарай бастауды сұрау"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS әрекетін алдын ала қарауды басқару"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Жүйенің EVS әрекетін алдын ала қарауды басқару"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS камерасын пайдалану"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS камера трансляциясына жазылу"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS қызметінің күйін бақылау"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS қызметінің күйіндегі өзгерістерді бақылау"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"көлік қозғалтқышы туралы толық деректерді көру"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Көліктің қозғалтқышы туралы толық ақпаратты пайдалану."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"көліктің жанармай құю саңылауын және зарядтау портын пайдалану"</string>
diff --git a/service/res/values-km/strings.xml b/service/res/values-km/strings.xml
index 34da856..26c0862 100644
--- a/service/res/values-km/strings.xml
+++ b/service/res/values-km/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ស្តាប់អំពី​ការផ្លាស់ប្ដូរ​ស្ថានភាព​បើកបរ។"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"ប្រើ Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"ជាវ​ការស្ទ្រីមវីដេអូ EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"ត្រួតពិនិត្យ​ស្ថានភាព Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"ត្រួតពិនិត្យ​ស្ថានភាព CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"ស្នើសុំ​សកម្មភាព​មើល EVS សាកល្បង"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"ស្នើឱ្យ​ប្រព័ន្ធ​ចាប់ផ្ដើម​សកម្មភាព​មើល EVS សាកល្បង"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"គ្រប់គ្រង​សកម្មភាព​មើល EVS សាកល្បង"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"គ្រប់គ្រង​សកម្មភាព​មើល EVS សាកល្បង​នៃប្រព័ន្ធ"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"ប្រើ​កាមេរ៉ា EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"ជាវ​ការស្ទ្រីម​តាមកាមេរ៉ា EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"តាមដាន​ស្ថានភាព​នៃ​សេវាកម្ម EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"ស្ដាប់​ការផ្លាស់ប្ដូរ​ស្ថានភាព​នៃសេវាកម្ម EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"ចូលប្រើព័ត៌មាន​លម្អិត​អំពីម៉ាស៊ីន​រថយន្ត"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"ចូលប្រើ​ព័ត៌មាន​លម្អិត​អំពីម៉ាស៊ីនរថយន្តរបស់អ្នក។"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"ចូលប្រើ​គម្របសាំង និងរន្ធសាក​អាគុយរថយន្ត។"</string>
diff --git a/service/res/values-kn/strings.xml b/service/res/values-kn/strings.xml
index beffe7f..9ee5d88 100644
--- a/service/res/values-kn/strings.xml
+++ b/service/res/values-kn/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ಚಾಲನೆಯ ಸ್ಥಿತಿಯ ಬದಲಾವಣೆಗಳನ್ನು ಆಲಿಸಿ."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"ಕಾರ್ EVS ಸೇವೆಯನ್ನು ಬಳಸಿ"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ವೀಡಿಯೋ ಸ್ಟ್ರೀಮ್‌ಗಳಿಗೆ ಸಬ್‌ಸ್ಕ್ರೈಬ್ ಮಾಡಿ"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"ಕಾರ್ EVS ಸೇವೆಯ ಸ್ಥಿತಿಯ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService ನ ಸ್ಥಿತಿಯ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS ಪೂರ್ವವೀಕ್ಷಣೆ ಚಟುವಟಿಕೆಯನ್ನು ವಿನಂತಿಸಿ"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS ಪೂರ್ವವೀಕ್ಷಣೆ ಚಟುವಟಿಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಲು ಸಿಸ್ಟಂ ಅನ್ನು ವಿನಂತಿಸಿ"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS ಪೂರ್ವವೀಕ್ಷಣೆ ಚಟುವಟಿಕೆಯನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"ಸಿಸ್ಟಂನ EVS ಪೂರ್ವವೀಕ್ಷಣೆ ಚಟುವಟಿಕೆಯನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS ಕ್ಯಾಮರಾ ಬಳಸಿ"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS ಕ್ಯಾಮರಾ ಸ್ಟ್ರೀಮ್‌ಗಳಿಗೆ ಸಬ್‌ಸ್ಕ್ರೈಬ್ ಮಾಡಿ"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS ಸೇವೆಯ ಸ್ಥಿತಿಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS ಸೇವೆಯ ಸ್ಥಿತಿ ಬದಲಾವಣೆಗಳನ್ನು ಆಲಿಸಿ"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"ಕಾರಿನ ಇಂಜಿನ್‌ನ ಕುರಿತು ವಿವರಣೆಗಳನ್ನು ಓದಿ"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"ಕಾರಿನ ಇಂಜಿನ್‌ನ ವಿವರಣೆಯ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಿ."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"ಕಾರಿನ ಇಂಧನ ಪಂಪ್‌ನ ಮುಚ್ಚಳ ಮತ್ತು ಚಾರ್ಜ್ ಪೋರ್ಟ್ ಮಾಹಿತಿ ಪಡೆಯಿರಿ"</string>
diff --git a/service/res/values-ko/strings.xml b/service/res/values-ko/strings.xml
index d8a5609..53bf0c9 100644
--- a/service/res/values-ko/strings.xml
+++ b/service/res/values-ko/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"운전 상태 변화를 감지합니다."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"자동차 EVS 서비스 사용하기"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS 동영상 스트림 구독하기"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"자동차 EVS 서비스 상태 모니터링하기"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"자동차 EVS 서비스 상태 모니터링하기"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS 미리보기 활동 요청"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"시스템에 EVS 미리보기 활동 실행 요청"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS 미리보기 활동 제어"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"시스템의 EVS 미리보기 활동 제어"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS 카메라 사용"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS 카메라 스트림 구독"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS 서비스 상태 모니터링"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS 서비스의 상태 변경사항 감지"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"차량 엔진 상세 정보에 액세스"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"차량의 상세한 엔진 정보에 액세스합니다."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"차량 주유구 캡 및 충전 포트 액세스"</string>
diff --git a/service/res/values-ky/strings.xml b/service/res/values-ky/strings.xml
index c8a7a04..5954cb6 100644
--- a/service/res/values-ky/strings.xml
+++ b/service/res/values-ky/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Унаа айдоо абалынын өзгөрүүлөрүн угуу."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Унаанын EVS кызматын колдонуу"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS видео агымдарына жазылуу"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Унаанын EVS кызматынын статусуна көз салуу"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService статусуна көз салуу"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS\'ти алдын ала көрүү аракетин сурануу"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Тутумдан EVS\'ти алдын ала көрүү аракетин иштетүүнү сурануу"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS\'ти алдын ала көрүү аракетин көзөмөлдөө"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Тутумдун EVS\'ти алдын ала көрүү аракетин көзөмөлдөө"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS камерасын иштетүү"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS камерасынын агымдарына жазылуу"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS кызматынын статусун көзөмөлдөө"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS кызматынын статусунун өзгөрүшү тууралуу маалыматты угуу"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"унаа кыймылдаткычынын чоо-жайына мүмкүнчүлүк алуу"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Унааңыздын кыймылдаткычы тууралуу толук маалыматты көрүү."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"унаанын май куюучу тешигине жана кубаттоо оюкчасына мүмкүнчүлүк алуу"</string>
diff --git a/service/res/values-lo/strings.xml b/service/res/values-lo/strings.xml
index 6f6ae23..5522c9d 100644
--- a/service/res/values-lo/strings.xml
+++ b/service/res/values-lo/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ຟັງການປ່ຽນແປງສະພາບການຂັບຂີ່."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"ໃຊ້ການບໍລິການ EVS ຂອງລົດ"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"ຕິດຕາມວິດີໂອສະຕຣີມ EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"ຕິດຕາມສະຖານະການບໍລິການ EVS ຂອງລົດ"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"ຕິດຕາມສະຖານະຂອງ CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"ຮ້ອງຂໍການເຄື່ອນໄຫວສະແດງຕົວຢ່າງ EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"ຮ້ອງຂໍໃຫ້ລະບົບເປີດນຳໃຊ້ການເຄື່ອນໄຫວສະແດງຕົວຢ່າງ EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"ຄວບຄຸມການເຄື່ອນໄຫວສະແດງຕົວຢ່າງ EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"ຄວບຄຸມການເຄື່ອນໄຫວສະແດງຕົວຢ່າງ EVS ຂອງລະບົບ"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"ໃຊ້ກ້ອງ EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"ຕິດຕາມການສະຕຣີມກ້ອງ EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"ຕິດຕາມສະຖານະບໍລິການ EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"ຟັງການປ່ຽນສະຖານະຂອງບໍລິການ EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"ເຂົ້າເຖິງລາຍລະອຽດເຄື່ອງຈັກຂອງລົດ"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"ເຂົ້າເຖິງຂໍ້ມູນເຄື່ອງຈັກລະອຽດຂອງລົດທ່ານ."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"ເຂົ້າເຖິງຂໍ້ມູນຝານໍ້າມັນ ແລະ ຮູສາກໄຟຂອງລົດ"</string>
diff --git a/service/res/values-lt/strings.xml b/service/res/values-lt/strings.xml
index 56162d1..db60428 100644
--- a/service/res/values-lt/strings.xml
+++ b/service/res/values-lt/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Klausyti vairavimo būsenos pakeitimų."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Naudoti automobilio EVS paslaugą"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Prenumeruoti EVS vaizdo transliacijas"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Stebėti automobilio EVS paslaugos būseną"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Stebėti automobilio EVS paslaugos būseną"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Pateikti užklausą dėl EVS peržiūros veiklos"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Pateikti sistemai užklausą paleisti EVS peržiūros veiklą"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Valdyti EVS peržiūros veiklą"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Valdyti sistemos EVS peržiūros veiklą"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Naudoti EVS kamerą"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Prenumeruoti EVS kameros transliacijas"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Stebėti EVS paslaugos būseną"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Klausyti EVS paslaugos būsenos pakeitimus"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"pasiekti išsamią automobilio variklio informaciją"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Pasiekti išsamią automobilio variklio informaciją."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"pasiekti automobilio degalų bako dureles ir įkrovimo prievadą"</string>
diff --git a/service/res/values-lv/strings.xml b/service/res/values-lv/strings.xml
index ff63984..ece37da 100644
--- a/service/res/values-lv/strings.xml
+++ b/service/res/values-lv/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Uztvert kustības stāvokļa izmaiņas."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Izmantot automašīnas EVS pakalpojumu"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Abonēt EVS video plūsmas"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Pārraudzīt automašīnas EVS pakalpojuma statusu"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Pārraudzīt CarEvsService statusu"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Pieprasīt EVS darbību priekšskatījumu"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Pieprasīt sistēmai palaist EVS darbību priekšskatījumu"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kontrolēt EVS darbību priekšskatījumu"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kontrolēt sistēmas EVS darbību priekšskatījumu"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Izmantot EVS kameru"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Abonēt EVS kameras straumes"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Pārraudzīt EVS pakalpojuma darbību"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Pārraudzīt EVS pakalpojuma statusa izmaiņas"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"piekļūt detalizētai informācijai par automašīnas dzinēju"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Piekļūt detalizētai informācijai par automašīnas dzinēju."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"piekļūt automašīnas degvielas tvertnes vāciņam un uzlādes pieslēgvietai"</string>
diff --git a/service/res/values-mk/strings.xml b/service/res/values-mk/strings.xml
index a246914..bcb9ba6 100644
--- a/service/res/values-mk/strings.xml
+++ b/service/res/values-mk/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Ги слуша промените во состојбата на возење."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Користење „EVS-сервис за автомобили“"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Претплата на EVS-видеопреноси"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Следење статус на „EVS-сервис за автомобили“"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Следење статус на CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"да ја побара активноста за преглед на електричните возила"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"да побара системот да ја стартува активноста за преглед на електричните возила"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"да ја контролира активноста за преглед на електричните возила"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"да ја контролира активноста за преглед на системот на електричните возила"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"да ја користи камерата на електричните возила"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"да се претплати на преносите од камерите на електричните возила"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"да го следи статусот на услугата за електричните возила"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"да ги слуша промените во статусот на услугата за електричните возила"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"пристапува до деталите за моторот на автомобилот"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Пристапува до деталните информации за моторот на автомобилот."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"пристапува до вратата за гориво и портата за полнење на автомобилот"</string>
diff --git a/service/res/values-ml/strings.xml b/service/res/values-ml/strings.xml
index 489e38e..6958ab1 100644
--- a/service/res/values-ml/strings.xml
+++ b/service/res/values-ml/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ഡ്രൈവിംഗ് നിലയിലെ മാറ്റങ്ങൾ ശ്രദ്ധിക്കുക."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Car EVS Service ഉപയോഗിക്കുക"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS വീഡിയോ സ്ട്രീമുകളുടെ വരിക്കാരാകുക"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Car EVS Service സ്‌റ്റാറ്റസ് നിരീക്ഷിക്കുക"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService-ന്റെ ഒരു സ്‌റ്റാറ്റസ് നിരീക്ഷിക്കുക"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS പ്രിവ്യു ആക്റ്റിവിറ്റി അഭ്യർത്ഥിക്കുക"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS പ്രിവ്യു ആക്റ്റിവിറ്റി ലോഞ്ച് ചെയ്യാൻ സിസ്റ്റത്തോട് അഭ്യർത്ഥിക്കുക"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS പ്രിവ്യു ആക്റ്റിവിറ്റി നിയന്ത്രിക്കുക"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"സിസ്റ്റത്തിന്റെ EVS പ്രിവ്യു ആക്റ്റിവിറ്റി നിയന്ത്രിക്കുക"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS ക്യാമറ ഉപയോഗിക്കുക"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS ക്യാമറാ സ്ട്രീമുകളുടെ വരിക്കാരാകുക"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS സേവനത്തിന്റെ സ്‌റ്റാറ്റസ് നിരീക്ഷിക്കുക"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS സേവനത്തിന്റെ സ്‌റ്റാറ്റസ് മാറ്റങ്ങൾ ശ്രദ്ധിക്കുക"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"കാറിൻ്റെ എഞ്ചിൻ വിശദാംശങ്ങൾ ആക്‌സസ് ചെയ്യുക"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"നിങ്ങളുടെ കാറിൻ്റെ വിശദമായ എഞ്ചിൻ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യുക."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"കാറിൻ്റെ ഇന്ധന വാതിലും ചാർജ് പോർട്ടും ആക്‌സസ് ചെയ്യുക"</string>
diff --git a/service/res/values-mn/strings.xml b/service/res/values-mn/strings.xml
index adffa3f..077e6f1 100644
--- a/service/res/values-mn/strings.xml
+++ b/service/res/values-mn/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Жолоодлогын төлөвийн өөрчлөлтийг сонсох."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Car EVS Service-г ашиглах"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS видео дамжуулалтыг захиалах"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Car EVS Service-н төлөвийг хянах"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService-н төлөвийг хянах"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS урьдчилан үзэх үйл ажиллагааны хүсэлт тавих"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Системд EVS урьдчилан үзэх үйл ажиллагааг эхлүүлэх хүсэлт тавих"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS урьдчилан үзэх үйл ажиллагааг хянах"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Системийн EVS урьдчилан үзэх үйл ажиллагааг хянах"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS камерыг ашиглах"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS камер дамжуулалтыг захиалах"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS үйлчилгээний төлөвийг хянах"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS үйлчилгээний төлөвийн өөрчлөлтийг сонсох"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"машины хөдөлгүүрийн дэлгэрэнгүй мэдээлэлд хандах"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Таны машины хөдөлгүүрийн дэлгэрэнгүй мэдээлэлд хандах."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"машины шатахууны савны таг болон цэнэглэх оролтод хандах"</string>
diff --git a/service/res/values-mr/strings.xml b/service/res/values-mr/strings.xml
index 598e9d5..ecf0111 100644
--- a/service/res/values-mr/strings.xml
+++ b/service/res/values-mr/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ड्रायव्हिंगच्या स्थितीतील बदल ऐका."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"कार EVS सेवा वापरा"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS व्हिडिओ स्ट्रीमचे सदस्य व्हा"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"कार EVS सेवेच्या स्थितीचे परीक्षण करा"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService च्या स्थितीचे परीक्षण करा"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS पूर्वावलोकन अ‍ॅक्टिव्हिटीची विनंती करा"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"सिस्टमला EVS पूर्वावलोकन अ‍ॅक्टिव्हिटी लाँच करण्याची विनंती करा"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS पूर्वावलोकन अ‍ॅक्टिव्हिटी नियंत्रित करा"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"सिस्टमची EVS पूर्वावलोकन अ‍ॅक्टिव्हिटी नियंत्रित करा"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS कॅमेरा वापरा"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS कॅमेरा स्ट्रीमचे सदस्य व्हा"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS सेवेच्या स्थितीचे निरीक्षण करा"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS सेवेच्या स्थितीमधील बदल ऐका"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"कारच्या इंजिनची तपशीलवार माहिती अ‍ॅक्सेस करा"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"तुमच्या कारच्या इंजिनची तपशीलवार माहिती अ‍ॅक्सेस करा."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"कारचा इंधन भरण्याचा दरवाजा आणि चार्ज पोर्ट अ‍ॅक्सेस करा"</string>
diff --git a/service/res/values-ms/strings.xml b/service/res/values-ms/strings.xml
index 644c1a4..dc6cdf3 100644
--- a/service/res/values-ms/strings.xml
+++ b/service/res/values-ms/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Dengar Perubahan keadaan pemanduan."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Gunakan Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Langgan strim video EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Pantau status Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Pantau status CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Minta aktiviti pratonton EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Minta sistem untuk melancarkan aktiviti pratonton EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kawal aktiviti pratonton EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kawal aktiviti pratonton EVS bagi sistem"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Gunakan kamera EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Langgan strim kamera EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Pantau status perkhidmatan EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Dengar perubahan status perkhidmatan EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"akses perincian enjin kereta anda"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Akses maklumat terperinci enjin kereta anda."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"akses penutup tangki bahan api dan port pengecasan kereta"</string>
diff --git a/service/res/values-my/strings.xml b/service/res/values-my/strings.xml
index 4dac308..38711d4 100644
--- a/service/res/values-my/strings.xml
+++ b/service/res/values-my/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"\'ယာဉ်မောင်းနှင်မှုဆိုင်ရာ\' အခြေအနေ ပြောင်းလဲမှုများကို စောင့်ကြည့်ပါမည်။"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"‘ကား EVS ဝန်ဆောင်မှု’ ကို သုံးရန်"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ဗီဒီယိုတိုက်ရိုက်ထုတ်လွှင့်ခြင်းများရယူရန်အတွက် စာရင်းသွင်းရန်"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"‘ကား EVS ဝန်ဆောင်မှု’ အခြေအနေကို စောင့်ကြည့်ရန်"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService အခြေအနေကို စောင့်ကြည့်ရန်"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS အစမ်းလုပ်ဆောင်ချက်ကို တောင်းဆိုနိုင်သည်"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS အစမ်းလုပ်ဆောင်ချက်စတင်ရန် စနစ်ကို တောင်းဆိုနိုင်သည်"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS အစမ်းလုပ်ဆောင်ချက်ကို ထိန်းချုပ်နိုင်သည်"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"စနစ်၏ EVS အစမ်းလုပ်ဆောင်ချက်ကို ထိန်းချုပ်နိုင်သည်"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS ကင်မရာကို အသုံးပြုနိုင်သည်"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS ကင်မရာ ထုတ်လွှင့်မှုများအတွက် စာရင်းသွင်းနိုင်သည်"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS ဝန်ဆောင်မှု၏ အခြေအနေကို စောင့်ကြည့်နိုင်သည်"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS ဝန်ဆောင်မှု အခြေအနေအပြောင်းအလဲများကို နားထောင်နိုင်သည်"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"ကား၏ အင်ဂျင်အသေးစိတ်ကို ရယူပါမည်"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"သင့်ကား၏ အသေးစိတ် အင်ဂျင်အချက်အလက်ကို ရယူပါမည်။"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"ကား၏ ဆီတိုင်ကီတံခါးပေါက်နှင့် အားသွင်းသည့်အပေါက်ကို အသုံးပြုပါမည်"</string>
diff --git a/service/res/values-nb/strings.xml b/service/res/values-nb/strings.xml
index e2863a3..8815c68 100644
--- a/service/res/values-nb/strings.xml
+++ b/service/res/values-nb/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Lytt etter endringer i kjøretilstanden."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Bruk Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Abonner på EVS-videodatastrømmer"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Overvåk status for Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Overvåk en status i CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"be om EVS-forhåndsvisningsaktiviteten"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"be systemet om å starte EVS-forhåndsvisningsaktiviteten"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"kontrollere EVS-forhåndsvisningsaktiviteten"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"kontrollere systemets EVS-forhåndsvisningsaktivitet"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"bruke EVS-kameraet"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"abonnere på EVS-kamerastrømmer"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"holde øye med EVS-tjenestens status"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"lytte til EVS-tjenestens statusendringer"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"få informasjon om bilmotoren"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Tilgang til detaljert informasjon om bilmotoren."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"få tilgang til tanklokket og ladeporten på bilen"</string>
diff --git a/service/res/values-ne/strings.xml b/service/res/values-ne/strings.xml
index c3ef77d..adb1532 100644
--- a/service/res/values-ne/strings.xml
+++ b/service/res/values-ne/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ड्राइभिङको स्थितिमा हुने परिवर्तनहरू सुन्ने।"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"कार EVS सेवा प्रयोग गर्नुहोस्"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS भिडियो स्ट्रिमको सदस्यता लिनुहोस्"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"कार EVS सेवाको स्थिति निगरानी गर्नुहोस्"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService को स्थिति निगरानी गर्नुहोस्"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS प्रिभ्यू गतिविधि अनुरोध गर्ने"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"प्रणालीलाई EVS प्रिभ्यू गतिविधि सुरु गर्न अनुरोध गर्ने"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS प्रिभ्यू गतिविधि नियन्त्रण गर्ने"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"प्रणालीको EVS प्रिभ्यू गतिविधि नियन्त्रण गर्ने"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS क्यामेरा प्रयोग गर्ने"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS क्यामेरा स्ट्रिमको सदस्यता लिने"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS सेवाको स्थिति अनुगमन गर्ने"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS सेवाको स्थितिमा भएका परिवर्तनबारे सूचना प्राप्त गर्ने"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"कारको इन्जिनको विस्तृत जानकारीमाथि पहुँच राख्ने"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"तपाईंको कारको इन्जिनको विस्तृत जानकारीमाथि पहुँच राख्ने।"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"कारको इन्धन हाल्ने ट्याङ्कीको बिर्को तथा चार्ज गर्ने पोर्टमाथि पहुँच राख्ने"</string>
diff --git a/service/res/values-nl/strings.xml b/service/res/values-nl/strings.xml
index 2c98420..c2e2f5c 100644
--- a/service/res/values-nl/strings.xml
+++ b/service/res/values-nl/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Luisteren naar wijzigingen van rijstand."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"EVS-autoservice gebruiken"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Abonneren op EVS-videostreams"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Status van EVS-autoservice monitoren"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"De status van een EVS-autoservice monitoren"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"De EVS-voorbeeldactiviteit aanvragen"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Het systeem vragen de EVS-voorbeeldactiviteit te starten"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"De EVS-voorbeeldactiviteit beheren"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"De EVS-voorbeeldactiviteit van het systeem beheren"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"De EVS-camera gebruiken"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Abonneren op EVS-camerastreams"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"De status van de EVS-service monitoren"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Luisteren naar de statuswijzigingen van de EVS-service"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"toegang tot gedetailleerde informatie over motor van auto"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Toegang tot gedetailleerde informatie over motor van auto."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"toegang tot tankklep en oplaadpoort van auto"</string>
diff --git a/service/res/values-or/strings.xml b/service/res/values-or/strings.xml
index 94bc53d..4574131 100644
--- a/service/res/values-or/strings.xml
+++ b/service/res/values-or/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ଡ୍ରାଇଭିଂ ଷ୍ଟେଟ୍‌ରେ ହେଉଥିବା ପରିବର୍ତ୍ତନକୁ ଶୁଣନ୍ତୁ।"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"କାର EVS ସେବାକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ଭିଡିଓ ଷ୍ଟ୍ରିମଗୁଡ଼ିକର ସଦସ୍ୟତା ନିଅନ୍ତୁ"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"କାର EVS ସେବାର ସ୍ଥିତିକୁ ନିରୀକ୍ଷଣ କରନ୍ତୁ"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsServiceର ଏକ ସ୍ଥିତିକୁ ନିରୀକ୍ଷଣ କରନ୍ତୁ"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS ପ୍ରିଭ୍ୟୁ କାର୍ଯ୍ୟକଳାପ ପାଇଁ ଅନୁରୋଧ କରନ୍ତୁ"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS ପ୍ରିଭ୍ୟୁ କାର୍ଯ୍ୟକଳାପ ଲଞ୍ଚ କରିବାକୁ ସିଷ୍ଟମକୁ ଅନୁରୋଧ କରନ୍ତୁ"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS ପ୍ରିଭ୍ୟୁ କାର୍ଯ୍ୟକଳାପକୁ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"ସିଷ୍ଟମର EVS ପ୍ରିଭ୍ୟୁ କାର୍ଯ୍ୟକଳାପକୁ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS କ୍ୟାମେରା ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS କ୍ୟାମେରା ଷ୍ଟ୍ରିମଗୁଡ଼ିକର ସଦସ୍ୟତା ନିଅନ୍ତୁ"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS ସେବାର ସ୍ଥିତିକୁ ନିରୀକ୍ଷଣ କରନ୍ତୁ"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS ସେବାର ସ୍ଥିତି ପରିବର୍ତ୍ତନଗୁଡ଼ିକୁ ଶୁଣନ୍ତୁ"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"କାର୍\'ର ଇଞ୍ଜିନ୍ ବିବରଣୀକୁ ଆକ୍‍‍ସେସ୍ କରନ୍ତୁ"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"ଆପଣଙ୍କ କାର୍\'ର ବିସ୍ତୃତ ଇଞ୍ଜିନ୍ ସୂଚନାକୁ ଆକ୍‍‍ସେସ୍ କରନ୍ତୁ।"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"କାର୍\'ର ଫୁଏଲ୍ ଡୋର୍ ଏବଂ ଚାର୍ଜ ପୋର୍ଟକୁ ଆକ୍‍‍ସେସ୍ କରନ୍ତୁ।"</string>
diff --git a/service/res/values-pa/strings.xml b/service/res/values-pa/strings.xml
index c269132..1442080 100644
--- a/service/res/values-pa/strings.xml
+++ b/service/res/values-pa/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ਗੱਡੀ ਚਲਾਉਣ ਦੀ ਸਥਿਤੀ ਵਿੱਚ ਹੋਣ ਵਾਲੀਆਂ ਤਬਦੀਲੀਆਂ ਨੂੰ ਜਾਣਨਾ।"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"ਕਾਰ ਦੀ EVS ਸੇਵਾ ਵਰਤੋ"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ਵੀਡੀਓ ਸਟ੍ਰੀਮਾਂ ਦੇ ਗਾਹਕ ਬਣੋ"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"ਕਾਰ ਦੀ EVS ਸੇਵਾ ਸਥਿਤੀ ਦਾ ਨਿਰੀਖਣ ਕਰੋ"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService ਦੀ ਸਥਿਤੀ ਦਾ ਨਿਰੀਖਣ ਕਰੋ"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS ਪੂਰਵ-ਝਲਕ ਸਰਗਰਮੀ ਲਈ ਬੇਨਤੀ ਕਰੋ"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS ਪੂਰਵ-ਝਲਕ ਸਰਗਰਮੀ ਨੂੰ ਲਾਂਚ ਕਰਨ ਲਈ ਸਿਸਟਮ ਨੂੰ ਬੇਨਤੀ ਕਰੋ"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS ਪੂਰਵ-ਝਲਕ ਸਰਗਰਮੀ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"ਸਿਸਟਮ ਦੀ EVS ਪੂਰਵ-ਝਲਕ ਸਰਗਰਮੀ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS ਕੈਮਰਾ ਵਰਤੋ"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS ਕੈਮਰਾ ਸਟ੍ਰੀਮਾਂ ਦੇ ਗਾਹਕ ਬਣੋ"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS ਸੇਵਾ ਦੀ ਸਥਿਤੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰੋ"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS ਸੇਵਾ ਦੀ ਸਥਿਤੀ ਸੰਬੰਧੀ ਤਬਦੀਲੀਆਂ ਨੂੰ ਸੁਣੋ"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"ਕਾਰ ਦੇ ਇੰਜਣ ਦੀ ਪੂਰੀ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"ਤੁਹਾਡੀ ਕਾਰ ਦੇ ਇੰਜਣ ਦੀ ਵੇਰਵੇ ਸਹਿਤ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ।"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"ਕਾਰ ਦੀ ਈਂਧਣ ਵਾਲੀ ਜਗ੍ਹਾ ਅਤੇ ਚਾਰਜ ਪੋਰਟ ਤੱਕ ਪਹੁੰਚ"</string>
diff --git a/service/res/values-pl/strings.xml b/service/res/values-pl/strings.xml
index 8112978..75a4393 100644
--- a/service/res/values-pl/strings.xml
+++ b/service/res/values-pl/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Nasłuchiwanie zmian podczas jazdy samochodem."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Używaj usługi EVS w samochodzie"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Subskrybuj strumienie wideo z EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitoruj stan usługi EVS w samochodzie"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitoruj stan usługi CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Wysyłaj prośbę o podgląd EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Wysyłaj do systemu żądanie uruchomienia podglądu EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Steruj podglądem EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Steruj podglądem EVS w systemie"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Używaj kamery EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Subskrybuj strumienie z kamer EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitoruj stan usługi EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Wykrywaj zmiany stanu usługi EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"dostęp do szczegółowych informacji na temat silnika"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Dostęp do szczegółowych informacji o silniku."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"dostęp do drzwiczek wlewu paliwa i portu ładowania samochodu"</string>
diff --git a/service/res/values-pt-rPT/strings.xml b/service/res/values-pt-rPT/strings.xml
index be9687a..b7371e6 100644
--- a/service/res/values-pt-rPT/strings.xml
+++ b/service/res/values-pt-rPT/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Ouvir as alterações ao estado de condução."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Utilizar o Serviço de EVS do carro"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Subscrever streams de vídeo de EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitorizar o estado do Serviço de EVS do carro"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitorizar um estado do CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Solicitar a atividade de pré-visualização de EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Solicitar ao sistema o lançamento da atividade de pré-visualização de EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Controlar a atividade de pré-visualização de EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Controlar a atividade de pré-visualização de EVS do sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Utilizar a câmara de EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Subscrever as streams da câmara de EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitorizar o estado do serviço de EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Ouvir as alterações de estado do serviço de EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"aceder ao motor detalhado do automóvel"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Aceder às informações detalhadas do motor do automóvel."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"aceder à porta de carregamento e à tampa do depósito de combustível do automóvel"</string>
diff --git a/service/res/values-pt/strings.xml b/service/res/values-pt/strings.xml
index adb559b..75fa00c 100644
--- a/service/res/values-pt/strings.xml
+++ b/service/res/values-pt/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Ouvir quando o estado de condução for alterado."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Usar Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Assinar streams de vídeo do sistema de visualização estendida (EVS, na sigla em inglês)"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitorar o status de Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitorar o status de CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Solicitar a atividade de visualização de EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Solicitar que o sistema inicie a atividade de visualização de EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Controlar a atividade de visualização de EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Controlar a atividade de visualização de EVS do sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Usar a câmera EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Assinar streams da câmera EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitorar o status do serviço EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Detectar mudanças de status do serviço EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"acessar detalhes do motor do carro"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Acessar informações detalhadas do motor do carro."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"acessar as entradas de combustível e carregamento do carro"</string>
diff --git a/service/res/values-ro/strings.xml b/service/res/values-ro/strings.xml
index 756cbc1..15ae8ae 100644
--- a/service/res/values-ro/strings.xml
+++ b/service/res/values-ro/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Ascultă modificările stării La volan."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Folosiți serviciul EVS al mașinii"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Abonați-vă la streamurile video EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Monitorizați starea de serviciu EVS a mașinii"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Monitorizați o stare pentru CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Solicitați activitatea de previzualizare EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Solicitați sistemului să lanseze activitatea de previzualizare EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Gestionați activitatea de previzualizare EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Gestionați activitatea de previzualizare EVS a sistemului"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Folosiți camera EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Abonați-vă la streamurile camerei EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitorizați starea serviciului EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Urmăriți modificările de stare ale serviciului EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"Accesează informațiile detaliate despre motorul mașinii"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Accesează informațiile detaliate despre motorul mașinii"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"Accesează ușa de alimentare a mașinii și portul de încărcare"</string>
diff --git a/service/res/values-ru/strings.xml b/service/res/values-ru/strings.xml
index d9d33ab..12bc582 100644
--- a/service/res/values-ru/strings.xml
+++ b/service/res/values-ru/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Отслеживание изменений режима \"За рулем\"."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Использовать Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Подписаться на видеотрансляции EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Отслеживать статус Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Отслеживать статус CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Запрос просмотра действий EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Запрос на запуск просмотра действий EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Управление просмотром действий EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Управление просмотром действий системы EVS"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Использование камеры EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Подписка на видеотрансляции EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Отслеживание статуса сервиса EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Прослушивание информации об изменении статуса сервиса EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"доступ к подробным данным о двигателе"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Доступ к подробным данным о двигателе."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"доступ к лючку топливного бака и порту зарядки"</string>
diff --git a/service/res/values-si/strings.xml b/service/res/values-si/strings.xml
index 3124d63..8fa7e68 100644
--- a/service/res/values-si/strings.xml
+++ b/service/res/values-si/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"රිය පැදවීම් තත්ත්ව වෙනස්කම්වලට සවන් දෙන්න."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"මෝටර් රථ EVS සේවාව භාවිත කරන්න"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS වීඩියෝ ප්‍රවාහ වෙත දායක වන්න"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"මෝටර් රථ EVS සේවා තත්ත්වය නිරීක්ෂණය කරන්න"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService හි තත්ත්වය නිරීක්ෂණය කරන්න"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS පෙරදසුන් ක්‍රියාකාරකම ඉල්ලන්න"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS පෙරදසුන් ක්‍රියාකාරකම දියත් කිරීමට පද්ධතියෙන් ඉල්ලන්න"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS පෙරදසුන් ක්‍රියාකාරකම පාලනය කරන්න"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"පද්ධතියෙහි EVS පෙරදසුන් ක්‍රියාකාරකම පාලනය කරන්න"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"‍‍‍‍‍‍‍‍EVS කැමරාව භාවිත කරන්න"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS කැමරා ප්‍රවාහ වෙත දායක වන්න"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS සේවාවේ තත්ත්වය නිරීක්ෂණය කරන්න"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS සේවාවේ තත්ත්ව වෙනස්වීම්වලට සවන් දෙන්න"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"මෝටර් රථයේ එන්ජින් විස්තරවලට ප්‍රවේශ වන්න"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"ඔබේ මෝටර් රථයේ විස්තරාත්මක එන්ජින් තොරතුරුවලට ප්‍රවේශ වන්න."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"මෝටර් රථයේ ඉන්ධන දොර සහ ආරෝපණ කවුළුවට ප්‍රවේශ වන්න"</string>
diff --git a/service/res/values-sk/strings.xml b/service/res/values-sk/strings.xml
index 1dff40c..50cfa76 100644
--- a/service/res/values-sk/strings.xml
+++ b/service/res/values-sk/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Počúvanie zmien stavu jazdy."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Používanie služby Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Prihlásenie na odber videostreamov EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Sledovanie stavu v službe Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Sledovanie stavu v službe CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Odosielanie žiadostí o aktivitu ukážky EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Odosielanie žiadostí systému o spustenie aktivity ukážky EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Ovládanie aktivity ukážky EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Ovládanie aktivity ukážky EVS systému"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Používanie kamery EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Prihlásenie sa na odber prenosov kamery EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Monitorovanie stavu služby EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Príjem zmien stavu služby EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"získať prístup k podrobnostiam o motore auta"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Získajte prístup k podrobným informáciám o motore auta."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"získať prístup k dvierkam palivovej nádrže a nabíjaciemu portu"</string>
diff --git a/service/res/values-sl/strings.xml b/service/res/values-sl/strings.xml
index 96ea63d..611c7e9 100644
--- a/service/res/values-sl/strings.xml
+++ b/service/res/values-sl/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Poslušanje sprememb voznih stanj."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Uporaba storitve EVS v avtomobilu"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Naročanje na videotoke storitve EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Spremljanje storitve EVS v avtomobilu"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Spremljanje stanja storitve CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Zahtevanje dejavnosti predogleda storitve EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Zahtevanje zagona dejavnosti predogleda storitve EVS od sistema"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Nadziranje dejavnosti predogleda storitve EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Nadziranje dejavnosti predogleda storitve EVS sistema"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Uporaba kamere storitve EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Naročanje na toke kamere storitve EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Nadziranje stanja storitve EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Poslušanje sprememb stanja storitve EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"dostop do podrobnih podatkov o motorju avtomobila"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Dostop do podrobnih podatkov o motorju avtomobila."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"dostop do pokrova rezervoarja in polnilnih vrat avtomobila"</string>
diff --git a/service/res/values-sq/strings.xml b/service/res/values-sq/strings.xml
index cbba61c..6099665 100644
--- a/service/res/values-sq/strings.xml
+++ b/service/res/values-sq/strings.xml
@@ -97,8 +97,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Dëgjo ndryshimet e gjendjes së lëvizjes me makinë."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Të përdorin shërbimin EVS të makinës"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Të abonohen në transmetimet me video të sistemit EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Të monitorojnë statusin e shërbimit EVS të makinës"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Të monitorojnë një status të CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Të kërkojnë aktivitetin e pamjes paraprake nëpërmjet shërbimit EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Të kërkojnë që sistemi të hapë aktivitetin e pamjes paraprake nëpërmjet shërbimit EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Të kontrollojnë aktivitetin e pamjes paraprake nëpërmjet shërbimit EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Të kontrollojnë aktivitetin e pamjes paraprake të sistemit nëpërmjet shërbimit EVS"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Të përdorin kamerën nëpërmjet shërbimit EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Të abonohen te transmetimet e kamerave nëpërmjet shërbimit EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Të monitorojnë statusin e shërbimit EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Të dëgjojnë ndryshimet e statusit të shërbimit EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"qasu te informacionet e detajuara të motorit të makinës"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Qasje në informacionet e detajuara të motorit të makinës."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"qasu te porta e karburantit të makinës dhe te porta e karikimit"</string>
diff --git a/service/res/values-sr/strings.xml b/service/res/values-sr/strings.xml
index d93e8d6..cab0182 100644
--- a/service/res/values-sr/strings.xml
+++ b/service/res/values-sr/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Слушање промене статуса вожње."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Коришћење услуге EVS за аутомобил"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Праћење видео стримове EVS-а"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Праћење статуса услуге EVS за аутомобил"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Праћење статуса који се односи на CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Захтев за EVS активности приказа"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Захтев да систем покрене EVS активности приказа"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Контрола EVS активности приказа"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Контрола EVS активности приказа за систем"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Коришћење EVS камере"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Коришћење EVS стримова камера"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Праћење статуса EVS услуге"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Праћење промена статуса услуге EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"приступ детаљним подацима о мотору аутомобила"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Приступ детаљним подацима о мотору аутомобила."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"приступ поклопцу резервоара за гориво и порту за пуњење"</string>
diff --git a/service/res/values-sv/strings.xml b/service/res/values-sv/strings.xml
index c9aac4b..ef1bbc5 100644
--- a/service/res/values-sv/strings.xml
+++ b/service/res/values-sv/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Reagera på ändringar av bilkörningsläget."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Använd Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Prenumerera på EVS-videoströmmar"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Bevaka status för Car EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Bevaka status för CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Begära EVS-förhandsgranskningsaktivitet"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Begära att systemet ska starta EVS-förhandsgranskningsaktivitet"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Styra EVS-förhandsgranskningsaktivitet"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Styra systemets EVS-förhandsgranskningsaktivitet"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Använda EVS-kameran"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Prenumerera på EVS-kameraströmmar"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Bevaka EVS-tjänstens status"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Bevaka statusförändringar för EVS-tjänsten"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"åtkomst till detaljerad motorinformation för bilen"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Åtkomst till detaljerad information om bilens motor."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"åtkomst till bilens tanklucka och laddningsport"</string>
diff --git a/service/res/values-sw/strings.xml b/service/res/values-sw/strings.xml
index 71793bb..e56616e 100644
--- a/service/res/values-sw/strings.xml
+++ b/service/res/values-sw/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Kusikiliza mabadiliko katika hali ya Kuendesha gari."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Tumia Huduma ya EVS ya Gari"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Jisajili kwa video za kutiririsha za EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Fuatilia hali ya Huduma ya EVS ya Gari"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Fuatilia hali ya CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Kuomba shughuli za kukagua EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Kuomba mfumo uanzishe shughuli za kukagua EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kudhibiti shughuli za kukagua EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kudhibiti shughuli za kukagua EVS kwenye mfumo"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Kutumia kamera ya EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Kujisajili kwenye mitiririko ya kamera ya EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Kufuatilia hali ya huduma ya EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Kufuatilia mabadiliko ya hali ya huduma ya EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"kufikia maelezo ya usafi wa injini ya gari"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Kufikia maelezo ya kina ya injini ya gari lako."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"kufikia kifuniko cha sehemu ya kuwekea mafuta ya gari na mlango wa kuchaji"</string>
diff --git a/service/res/values-ta/strings.xml b/service/res/values-ta/strings.xml
index 042e268..931ffd9 100644
--- a/service/res/values-ta/strings.xml
+++ b/service/res/values-ta/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"காரை இயக்கும் நிலையில் ஏற்படும் மாற்றங்களை அறிய வேண்டும்."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"காரின் EVS சேவையைப் பயன்படுத்தும்"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS வீடியோ ஸ்ட்ரீம்களுக்குக் குழு சேரும்"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"காரின் EVS சேவை நிலையைக் கண்காணிக்கும்"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"காரின் EVS சேவை நிலையைக் கண்காணிக்கும்"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS மாதிரிக்காட்சி செயல்பாட்டைக் கோரும்"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS மாதிரிக்காட்சி செயல்பாட்டைத் தொடங்குமாறு சிஸ்டத்தைக் கோரும்"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS மாதிரிக்காட்சி செயல்பாட்டைக் கட்டுப்படுத்தும்"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"சிஸ்டத்தின் EVS மாதிரிக்காட்சி செயல்பாட்டைக் கட்டுப்படுத்தும்"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS கேமராவைப் பயன்படுத்தும்"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS கேமரா ஸ்ட்ரீம்களுக்குக் குழு சேரும்"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS சேவையின் நிலையைக் கண்காணிக்கும்"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS சேவையின் நிலை மாற்றங்களைக் கவனிக்கும்"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"காரின் இன்ஜினைப் பற்றிய விவரங்களை அணுக வேண்டும்"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"காரின் இன்ஜின் குறித்த முழுமையான தகவலை அணுக வேண்டும்."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"காரின் எரிபொருள் மூடியையும் சார்ஜ் போர்ட்டையும் அணுக வேண்டும்"</string>
diff --git a/service/res/values-te/strings.xml b/service/res/values-te/strings.xml
index 3e82f57..7099686 100644
--- a/service/res/values-te/strings.xml
+++ b/service/res/values-te/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"డ్రైవింగ్ స్థితి మార్పులను వినగలవు."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"కార్ EVS సర్వీస్‌ను ఉపయోగించండి"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS వీడియో ప్రసారాలకు సబ్‌స్క్రయిబ్ చేయండి"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"కార్ EVS సర్వీస్ స్టేటస్‌ను పర్యవేక్షించండి"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService స్టేటస్‌ను పర్యవేక్షించండి"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS ప్రివ్యూ యాక్టివిటీని రిక్వెస్ట్ చేయండి"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS ప్రివ్యూ యాక్టివిటీని లాంచ్ చేయడానికి సిస్టమ్‌ను రిక్వెస్ట్ చేయండి"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS ప్రివ్యూ యాక్టివిటీని కంట్రోల్ చేయండి"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"సిస్టమ్‌కు సంబంధించిన EVS ప్రివ్యూ యాక్టివిటీని కంట్రోల్ చేయండి"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS కెమెరాను ఉపయోగించండి"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS కెమెరా ప్రసారాలకు సబ్‌స్క్రయిబ్ చేయండి"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS సర్వీస్ తాలూకు స్టేటస్‌ను పర్యవేక్షించండి"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS సర్వీస్‌కు సంబంధించిన స్టేటస్ మార్పులను వినండి"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"కారు ఇంజిన్ వివరాలను యాక్సెస్ చేయగలవు"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"మీ కారు యొక్క సమగ్ర ఇంజిన్ సమాచారాన్ని యాక్సెస్ చేయగలవు."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"కారు ఇంధన డోర్ మరియు ఛార్జ్ పోర్ట్‌ను యాక్సెస్ చేయగలవు"</string>
diff --git a/service/res/values-th/strings.xml b/service/res/values-th/strings.xml
index d7552ed..8bd6876 100644
--- a/service/res/values-th/strings.xml
+++ b/service/res/values-th/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"ฟังการเปลี่ยนแปลงสถานะการขับรถ"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"ใช้บริการ EVS ในรถยนต์"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"สมัครใช้บริการสตรีมวิดีโอ EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"ตรวจสอบสถานะบริการ EVS ในรถยนต์"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"ตรวจสอบสถานะของ CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"ขอดูกิจกรรมการแสดงตัวอย่าง EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"ขอให้ระบบเปิดกิจกรรมการแสดงตัวอย่าง EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"ควบคุมกิจกรรมการแสดงตัวอย่าง EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"ควบคุมกิจกรรมการแสดงตัวอย่าง EVS ของระบบ"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"ใช้กล้อง EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"สมัครใช้บริการสตรีมกล้อง EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"ตรวจสอบสถานะบริการ EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"ฟังการเปลี่ยนแปลงสถานะบริการ EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"เข้าถึงรายละเอียดเครื่องยนต์ของรถ"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"เข้าถึงข้อมูลเครื่องยนต์ของรถโดยละเอียด"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"เข้าถึงฝาถังน้ำมันและพอร์ตชาร์จ"</string>
diff --git a/service/res/values-tl/strings.xml b/service/res/values-tl/strings.xml
index d4c21d7..7e1a9dc 100644
--- a/service/res/values-tl/strings.xml
+++ b/service/res/values-tl/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Makinig sa mga Mga pagbabago ng status ng pagmamaneho."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Gamitin ang Serbisyo sa EVS na Kotse"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Mag-subscribe sa mga video stream ng EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Subaybayan ang status ng Serbisyo sa EVS na Kotse"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Magsubaybay ng status ng CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Hilingin ang aktibidad ng pag-preview ng EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Hilingin sa system na ilunsad ang aktibidad ng pag-preview ng EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kontrolin ang aktibidad ng pag-preview ng EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kontrolin ang aktibidad ng pag-preview ng EVS ng system"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Gamitin ang camera ng EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Mag-subscribe sa mga stream ng camera ng EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Subaybayan ang status ng serbisyo ng EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Pakinggan ang mga pagbabago sa status ng serbisyo ng EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"i-access ang mga detalye ng makina ng sasakyan"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"I-access ang detalyadong impormasyon sa makina ng iyong sasakyan."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"i-access ang takip ng gasolina at charge port ng sasakyan"</string>
diff --git a/service/res/values-tr/strings.xml b/service/res/values-tr/strings.xml
index 65af936..d741315 100644
--- a/service/res/values-tr/strings.xml
+++ b/service/res/values-tr/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Araç kullanma durumundaki değişiklikleri dinleme."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Araç EVS Hizmetini kullan"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS video akışına abone ol"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Araç EVS Hizmet durumunu izle"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService durumunu izle"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS önizleme etkinliği talep etme"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Sistemden EVS önizleme etkinliği başlatmasını isteme"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS önizleme etkinliğini kontrol etme"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Sistemin Genişletilmiş Görüş Sistemi (EVS) önizleme etkinliğini kontrol etme"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS kamerasını kullanma"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS kamera yayınlarını kullanabilme"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS hizmetinin durumunu izleme"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS hizmetinin durum değişikliklerini izleme"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"aracın motoruyla ilgili ayrıntılara erişim"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Aracınızın ayrıntılı motor bilgilerine erişim."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"aracın yakıt kapağına ve şarj bağlantı noktasına erişim"</string>
diff --git a/service/res/values-uk/strings.xml b/service/res/values-uk/strings.xml
index 7a089a8..bbed5e8 100644
--- a/service/res/values-uk/strings.xml
+++ b/service/res/values-uk/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Відстеження змін стану кермування."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Використовувати сервіс Car EVS"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Підписуватися на відеопотоки сервісу EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Стежити за статусом сервісу Car EVS"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Стежити за статусом сервісу CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Надсилати запити на попередній перегляд EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Надсилати системі запити запускати попередній перегляд EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Контролювати попередній перегляд EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Контролювати попередній перегляд EVS у системі"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Використовувати камеру EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Підписуватися на потоки з камер EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Стежити за статусом сервісу EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Відстежувати зміни статусу сервісу EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"доступ до детальної інформації про двигун автомобіля"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Доступ до детальної інформації про двигун автомобіля."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"доступ до даних про кришку паливного бака чи порт заряджання автомобіля"</string>
diff --git a/service/res/values-ur/strings.xml b/service/res/values-ur/strings.xml
index a3e89c2..3c2ac8e 100644
--- a/service/res/values-ur/strings.xml
+++ b/service/res/values-ur/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"کار چلانے کے دوران کی تبدیلیوں کے بارے میں سنیں۔"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"کار کی EVS سروس استعمال کریں"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS ویڈیو اسٹریمز کو سبسکرائب کریں"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"کار کی EVS سروس کے اسٹیٹس کو مانیٹر کریں"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService کے اسٹیٹس کی نگرانی کریں"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS پیش منظر کی سرگرمی کی درخواست کریں"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"EVS پیش منظر کی سرگرمی کو شروع کرنے کیلئے سسٹم سے درخواست کریں"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS پیش منظر کی سرگرمی کو کنٹرول کریں"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"سسٹم کی EVS پیش منظر کی سرگرمی کنٹرول کریں"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS کیمرا استعمال کریں"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS کیمرے کی سلسلہ بندیوں کو سبسکرائب کریں"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS سروس کے اسٹیٹس کو مانیٹر کریں"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS سروس کے اسٹیٹس کی تبدیلیوں کو سنیں"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"کار کے انجن کی تفصیلات تک رسائی حاصل کریں"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"اپنی کار کے انجن کی تفصیلی معلومات تک رسائی حاصل کریں۔"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"کار کے ایندھن کے دروازے اور چارج پورٹ تک رسائی حاصل کریں"</string>
diff --git a/service/res/values-uz/strings.xml b/service/res/values-uz/strings.xml
index 25a7e8c..92d3528 100644
--- a/service/res/values-uz/strings.xml
+++ b/service/res/values-uz/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Avtomobilda rejimining oʻzgarishini kuzatish."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Avtomobil EVS xizmatidan foydalanish"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"EVS video strimingiga obuna boʻlish"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Avtomoil EVS xizmati holatini nazorat qilish"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"CarEvsService holatini nazorat qilish"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"EVS nazar solish harakati talabini yuborish"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Tizimda EVS nazar solish harakatini ishga tushirish talabini yuborish"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"EVS nazar solish harakatlarini boshqarish"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Tizimning EVS nazar solish harakatlarini boshqarish"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"EVS kamerasidan foydalanish"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"EVS kamera strimlariga obuna boʻlish"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"EVS xizmati holatini nazorat qilish"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"EVS xizmati holatidagi oʻzgarishlarni kuzatish"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"avtomobil motori haqidagi batafsil axborotga kirish"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Avtomobilning motori haqidagi batafsil axborotga kirish."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"avtomobilning yonilgʻi darajasi va quvvatlash porti haqidagi axborotga kirish"</string>
diff --git a/service/res/values-vi/strings.xml b/service/res/values-vi/strings.xml
index 83ea162..0851457 100644
--- a/service/res/values-vi/strings.xml
+++ b/service/res/values-vi/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Nghe những thay đổi về trạng thái Lái xe."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Sử dụng dịch vụ CarEvsService"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Theo dõi luồng video của EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Theo dõi trạng thái CarEvsService"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Theo dõi trạng thái CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Yêu cầu hoạt động xem trước qua EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Yêu cầu hệ thống triển khai hoạt động xem trước qua EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Kiểm soát hoạt động xem trước qua EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Kiểm soát hoạt động xem trước của hệ thống qua EVS"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Sử dụng camera qua EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Đăng ký xem video của camera phát trực tuyến qua EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Theo dõi sự thay đổi trạng thái của dịch vụ EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Theo dõi sự thay đổi trạng thái của dịch vụ EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"truy cập vào thông tin chi tiết về động cơ ô tô"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Truy cập vào thông tin chi tiết về động cơ trên ô tô của bạn."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"truy cập vào cổng sạc và cổng nhiên liệu của ô tô"</string>
diff --git a/service/res/values-zh-rCN/strings.xml b/service/res/values-zh-rCN/strings.xml
index ff5a377..d79368b 100644
--- a/service/res/values-zh-rCN/strings.xml
+++ b/service/res/values-zh-rCN/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"监听驾车状态变化。"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"使用汽车 EVS 服务"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"订阅 EVS 视频串流"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"监控汽车 EVS 服务状态"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"监控 CarEvsService 的状态"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"请求 EVS 预览活动"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"请求系统启动 EVS 预览活动"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"控制 EVS 预览活动"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"控制系统的 EVS 预览活动"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"使用 EVS 摄像机"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"订阅 EVS 摄像机数据流"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"监控 EVS 服务的状态"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"监听 EVS 服务的状态变化"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"访问汽车的引擎详情"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"访问汽车的详细引擎信息。"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"访问汽车的油箱盖和充电端口信息"</string>
diff --git a/service/res/values-zh-rHK/strings.xml b/service/res/values-zh-rHK/strings.xml
index 201defa..70727f7 100644
--- a/service/res/values-zh-rHK/strings.xml
+++ b/service/res/values-zh-rHK/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"聽取駕駛狀態變動。"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"使用 Car EVS Service"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"訂閱電動車影片串流"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"監控 Car EVS Service 狀態"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"監控 CarEvsService 狀態"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"要求 EVS 預覽活動"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"要求系統啟動 EVS 預覽活動"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"控制 EVS 預覽活動"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"控制系統的 EVS 預覽活動"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"使用 EVS 攝影機"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"訂閱 EVS 攝影機串流"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"監察 EVS 服務的狀態"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"留意 EVS 服務狀態變更"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"存取汽車引擎詳情"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"存取汽車引擎詳情。"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"存取汽車油箱蓋及充電埠"</string>
diff --git a/service/res/values-zh-rTW/strings.xml b/service/res/values-zh-rTW/strings.xml
index 8952ecd..af77102 100644
--- a/service/res/values-zh-rTW/strings.xml
+++ b/service/res/values-zh-rTW/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"監聽駕駛狀態變更。"</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"使用車輛 EVS 服務"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"訂閱 EVS 視訊串流"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"監控車輛 EVS 服務狀態"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"監控 CarEvsService 狀態"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"要求 EVS 預覽活動"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"要求系統啟動 EVS 預覽活動"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"控管 EVS 預覽活動"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"控管系統的 EVS 預覽活動"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"使用 EVS 攝影機"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"訂閱 EVS 攝影機串流畫面"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"監控 EVS 服務狀態"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"注意 EVS 服務狀態變更"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"存取車輛的引擎詳細資料"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"存取車輛的詳細引擎資訊。"</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"存取車輛的油孔蓋和充電口"</string>
diff --git a/service/res/values-zu/strings.xml b/service/res/values-zu/strings.xml
index a2716ad..7d79009 100644
--- a/service/res/values-zu/strings.xml
+++ b/service/res/values-zu/strings.xml
@@ -95,8 +95,14 @@
     <string name="car_permission_desc_driving_state" msgid="2684025262811635737">"Lale izinguquko zesimo sokushayela."</string>
     <string name="car_permission_label_use_evs_service" msgid="1729276125209310607">"Sebenzisa Isevisi Yemoto ye-EVS"</string>
     <string name="car_permission_desc_use_evs_service" msgid="2374737642186632816">"Bhalisa ekudlalweni kwevidiyo kwe-EVS"</string>
-    <string name="car_permission_label_monitor_evs_status" msgid="8586151402220417700">"Qapha isimo Sesevisi Yemoto ye-EVS Service"</string>
-    <string name="car_permission_desc_monitor_evs_status" msgid="9211849809250999081">"Qapha isimo se-CarEvsService"</string>
+    <string name="car_permission_label_request_evs_activity" msgid="3906551972883482883">"Cela umsebenzi wokubuka kuqala kwe-EVS"</string>
+    <string name="car_permission_desc_request_evs_activity" msgid="4582768053649138488">"Cela isistimu iqalise umsebenzi wokubuka kuqala kwe-EVS"</string>
+    <string name="car_permission_label_control_evs_activity" msgid="2030069860204405679">"Lawula umsebenzi wokubuka kuqala kwe-EVS"</string>
+    <string name="car_permission_desc_control_evs_activity" msgid="691646545916976346">"Lawula ukubuka kuqala komsebenzi we-EVS yesistimu"</string>
+    <string name="car_permission_label_use_evs_camera" msgid="3607720208623955067">"Sebenzisa ikhamera ye-EVS"</string>
+    <string name="car_permission_desc_use_evs_camera" msgid="1625845902221003985">"Bhalisa ekusakazeni kwekhamera ye-EVS"</string>
+    <string name="car_permission_label_monitor_evs_status" msgid="2091521314159379622">"Qapha isimo sesevisi ye-EVS"</string>
+    <string name="car_permission_desc_monitor_evs_status" msgid="2764278897143573535">"Lalela isimo sezinguquko zesevisi ye-EVS"</string>
     <string name="car_permission_label_car_engine_detailed" msgid="8911992719173587337">"finyelela injini yemoto enemininingwane"</string>
     <string name="car_permission_desc_car_engine_detailed" msgid="1746863362811347700">"Finyelela ulwazi lwenjini olunemininingwane lwemoto yakho."</string>
     <string name="car_permission_label_car_energy_ports" msgid="8548990315169219454">"iinyelela umnyango kaphethiloli nembobo yokushaja"</string>
diff --git a/service/src/com/android/car/AppFocusService.java b/service/src/com/android/car/AppFocusService.java
index 674d7ff..477529d 100644
--- a/service/src/com/android/car/AppFocusService.java
+++ b/service/src/com/android/car/AppFocusService.java
@@ -208,7 +208,9 @@
                 // ignore as listener doesn't own focus.
                 return;
             }
-            if (mFocusOwners.contains(appType)) {
+            // Because this code will run as part of unit tests on older platform, we can't use
+            // APIs such as {@link SparseArray#contains} that are added with API 30.
+            if (mFocusOwners.indexOfKey(appType) >= 0) {
                 mFocusOwners.remove(appType);
                 mActiveAppTypes.remove(appType);
                 info.removeOwnedAppType(appType);
@@ -278,7 +280,9 @@
      */
     public boolean isFocusOwner(int uid, int pid, int appType) {
         synchronized (mLock) {
-            if (mFocusOwners.contains(appType)) {
+            // Because this code will run as part of unit tests on older platform, we can't use
+            // APIs such as {@link SparseArray#contains} that are added with API 30.
+            if (mFocusOwners.indexOfKey(appType) >= 0) {
                 OwnershipClientInfo clientInfo = mFocusOwners.get(appType);
                 return clientInfo.getUid() == uid && clientInfo.getPid() == pid;
             }
diff --git a/service/src/com/android/car/CarOccupantZoneService.java b/service/src/com/android/car/CarOccupantZoneService.java
index a2bb991..7ba6929 100644
--- a/service/src/com/android/car/CarOccupantZoneService.java
+++ b/service/src/com/android/car/CarOccupantZoneService.java
@@ -48,8 +48,6 @@
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.IntArray;
-import android.util.Log;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.view.Display;
@@ -192,9 +190,7 @@
 
     @VisibleForTesting
     final UserLifecycleListener mUserLifecycleListener = event -> {
-        if (Log.isLoggable(CarLog.TAG_MEDIA, Log.DEBUG)) {
-            Slog.d(CarLog.TAG_MEDIA, "onEvent(" + event + ")");
-        }
+        Slogf.d(TAG, "onEvent(%s)", event);
         if (CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING == event.getEventType()) {
             handleUserChange();
         }
@@ -296,17 +292,17 @@
                     for (int i = 0; i < mActiveOccupantConfigs.size(); ++i) {
                         OccupantConfig config = mActiveOccupantConfigs.valueAt(i);
                         if (config.userId == userId && zoneId != mActiveOccupantConfigs.keyAt(i)) {
-                            Slog.w(TAG, "cannot assign user to two different zone simultaneously");
+                            Slogf.w(TAG, "cannot assign user to two different zone simultaneously");
                             return false;
                         }
                     }
                     OccupantConfig zoneConfig = mActiveOccupantConfigs.get(zoneId);
                     if (zoneConfig == null) {
-                        Slog.w(TAG, "cannot find the zone(" + zoneId + ")");
+                        Slogf.w(TAG, "cannot find the zone(%d)", zoneId);
                         return false;
                     }
                     if (zoneConfig.userId != UserHandle.USER_NULL && zoneConfig.userId != userId) {
-                        Slog.w(TAG, "other user already occupies the zone(" + zoneId + ")");
+                        Slogf.w(TAG, "other user already occupies the zone(%d)", zoneId);
                         return false;
                     }
                     zoneConfig.userId = userId;
@@ -620,8 +616,8 @@
                     return mActiveOccupantConfigs.keyAt(i);
                 }
             }
-            Slog.w(TAG, "Could not find occupantZoneId for userId" + userId
-                    + " returning invalid occupant zone id " + OccupantZoneInfo.INVALID_ZONE_ID);
+            Slogf.w(TAG, "Could not find occupantZoneId for userId%d returning invalid "
+                    + "occupant zone id %d", userId, OccupantZoneInfo.INVALID_ZONE_ID);
             return OccupantZoneInfo.INVALID_ZONE_ID;
         }
     }
@@ -695,11 +691,11 @@
             if (!mProfileUsers.contains(userId) && userId != UserHandle.USER_NULL) {
                 // current user can change while this call is happening, so return false rather
                 // than throwing exception
-                Slog.w(TAG, "Invalid profile user id:" + userId);
+                Slogf.w(TAG, "Invalid profile user id: %d", userId);
                 return false;
             }
             if (!mUserManager.isUserRunning(userId)) {
-                Slog.w(TAG, "User is not running:" + userId);
+                Slogf.w(TAG, "User%d is not running.", userId);
                 return false;
             }
             OccupantConfig config = mActiveOccupantConfigs.get(occupantZoneId);
@@ -707,8 +703,8 @@
                 throw new IllegalArgumentException("Invalid occupantZoneId:" + occupantZoneId);
             }
             if (config.userId == userId && userId != UserHandle.USER_NULL) {
-                Slog.w(TAG, "assignProfileUserToOccupantZone zone:"
-                        + occupantZoneId + " already set to user:" + userId);
+                Slogf.w(TAG, "assignProfileUserToOccupantZone zone:%d already set to user:%",
+                        occupantZoneId, userId);
                 return true;
             }
             if (userId == UserHandle.USER_NULL) {
@@ -785,7 +781,7 @@
         try {
             helper.setPassengerDisplays(passengerDisplayIds);
         } catch (RemoteException e) {
-            Slog.e(TAG, "ICarServiceHelper.setPassengerDisplays failed");
+            Slogf.e(TAG, "ICarServiceHelper.setPassengerDisplays failed", e);
         }
     }
 
@@ -794,16 +790,16 @@
         ArrayList<ComponentName> componentNames = null;
         if (components == null || components.length == 0) {
             enableSourcePreferred = false;
-            Slog.i(TAG, "CarLaunchParamsModifier: disable source-preferred");
+            Slogf.i(TAG, "CarLaunchParamsModifier: disable source-preferred");
         } else if (components.length == 1 && components[0].equals(ALL_COMPONENTS)) {
             enableSourcePreferred = true;
-            Slog.i(TAG, "CarLaunchParamsModifier: enable source-preferred for all Components");
+            Slogf.i(TAG, "CarLaunchParamsModifier: enable source-preferred for all Components");
         } else {
             componentNames = new ArrayList<>((components.length));
             for (String item : components) {
                 ComponentName name = ComponentName.unflattenFromString(item);
                 if (name == null) {
-                    Slog.e(TAG, "CarLaunchParamsModifier: Wrong ComponentName=" + item);
+                    Slogf.e(TAG, "CarLaunchParamsModifier: Wrong ComponentName=" + item);
                     return;
                 }
                 componentNames.add(name);
@@ -815,7 +811,7 @@
             mEnableSourcePreferred = enableSourcePreferred;
             mSourcePreferredComponents = componentNames;
         } catch (RemoteException e) {
-            Slog.e(TAG, "ICarServiceHelper.setSourcePreferredComponents failed");
+            Slogf.e(TAG, "ICarServiceHelper.setSourcePreferredComponents failed");
         }
     }
 
@@ -854,7 +850,7 @@
                 helper.setDisplayAllowlistForUser(userId, allowlists.valueAt(i).toArray());
             }
         } catch (RemoteException e) {
-            Slog.e(TAG, "ICarServiceHelper.setDisplayAllowlistForUser failed");
+            Slogf.e(TAG, "ICarServiceHelper.setDisplayAllowlistForUser failed", e);
         }
     }
 
@@ -975,7 +971,7 @@
         if (!hasDriver) {
             maxZoneId++;
             mDriverZoneId = maxZoneId;
-            Slog.w(TAG, "No driver zone, add one:" + mDriverZoneId);
+            Slogf.w(TAG, "No driver zone, add one:%d", mDriverZoneId);
             OccupantZoneInfo info = new OccupantZoneInfo(mDriverZoneId,
                     CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER, getDriverSeat());
             mOccupantsConfig.put(mDriverZoneId, info);
@@ -1099,7 +1095,7 @@
         for (Display display : mDisplayManager.getDisplays()) {
             DisplayConfig displayConfig = findDisplayConfigForDisplayLocked(display);
             if (displayConfig == null) {
-                Slogf.w(TAG, "Display id: %d does not have configurations",
+                Slogf.w(TAG, "Display id:%d does not have configurations",
                         display.getDisplayId());
                 continue;
             }
@@ -1115,7 +1111,7 @@
         }
         if (!hasDefaultDisplayConfig) {
             // Can reach here if default display has no port / no config
-            Slog.w(TAG, "Default display not assigned, will assign to driver zone");
+            Slogf.w(TAG, "Default display not assigned, will assign to driver zone");
             addDisplayInfoToOccupantZoneLocked(mDriverZoneId, new DisplayInfo(
                     mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY),
                     CarOccupantZoneManager.DISPLAY_TYPE_MAIN));
@@ -1149,8 +1145,8 @@
             OccupantConfig config = mActiveOccupantConfigs.valueAt(i);
             // mProfileUsers empty if not supported
             if (mProfileUsers.contains(config.userId)) {
-                Slog.i(TAG, "Profile user:" + config.userId
-                        + " already assigned for occupant zone:" + zoneId);
+                Slogf.i(TAG, "Profile user:%d already assigned for occupant zone:%d",
+                        config.userId, zoneId);
             } else {
                 config.userId = driverUserId;
             }
diff --git a/service/src/com/android/car/CarShellCommand.java b/service/src/com/android/car/CarShellCommand.java
index ffa071e..6867ca5 100644
--- a/service/src/com/android/car/CarShellCommand.java
+++ b/service/src/com/android/car/CarShellCommand.java
@@ -236,6 +236,8 @@
                 PERMISSION_CAR_CONTROL_AUDIO_VOLUME);
         USER_BUILD_COMMAND_TO_PERMISSION_MAP.put(COMMAND_SET_GROUP_VOLUME,
                 PERMISSION_CAR_CONTROL_AUDIO_VOLUME);
+        USER_BUILD_COMMAND_TO_PERMISSION_MAP.put(COMMAND_INJECT_KEY,
+                android.Manifest.permission.INJECT_EVENTS);
     }
 
     private static final String PARAM_DAY_MODE = "day";
@@ -1030,9 +1032,14 @@
     private void injectKeyEvent(int action, int keyCode, int display) {
         long currentTime = SystemClock.uptimeMillis();
         if (action == KeyEvent.ACTION_DOWN) mKeyDownTime = currentTime;
-        mCarInputService.onKeyEvent(
-                new KeyEvent(/* downTime= */ mKeyDownTime, /* eventTime= */ currentTime,
-                        action, keyCode, /* repeat= */ 0), display);
+        long token = Binder.clearCallingIdentity();
+        try {
+            mCarInputService.injectKeyEvent(
+                    new KeyEvent(/* downTime= */ mKeyDownTime, /* eventTime= */ currentTime,
+                            action, keyCode, /* repeat= */ 0), display);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     private void injectRotary(String[] args, IndentingPrintWriter writer) {
diff --git a/service/src/com/android/car/admin/CarDevicePolicyService.java b/service/src/com/android/car/admin/CarDevicePolicyService.java
index db7fe83..4425936 100644
--- a/service/src/com/android/car/admin/CarDevicePolicyService.java
+++ b/service/src/com/android/car/admin/CarDevicePolicyService.java
@@ -25,6 +25,8 @@
 import android.car.admin.ICarDevicePolicyService;
 import android.car.user.UserCreationResult;
 import android.car.user.UserRemovalResult;
+import android.car.user.UserStartResult;
+import android.car.user.UserStopResult;
 import android.content.pm.UserInfo;
 import android.os.UserManager;
 import android.sysprop.CarProperties;
@@ -102,6 +104,17 @@
     }
 
     @Override
+    public void startUserInBackground(@UserIdInt int userId,
+            AndroidFuture<UserStartResult> receiver) {
+        mCarUserService.startUserInBackground(userId, receiver);
+    }
+
+    @Override
+    public void stopUser(@UserIdInt int userId, AndroidFuture<UserStopResult> receiver) {
+        mCarUserService.stopUser(userId, receiver);
+    }
+
+    @Override
     public void dump(@NonNull IndentingPrintWriter writer) {
         checkHasDumpPermissionGranted("dump()");
 
diff --git a/service/src/com/android/car/cluster/ClusterHomeService.java b/service/src/com/android/car/cluster/ClusterHomeService.java
index 388b594..1cdc406 100644
--- a/service/src/com/android/car/cluster/ClusterHomeService.java
+++ b/service/src/com/android/car/cluster/ClusterHomeService.java
@@ -37,6 +37,7 @@
 import android.content.pm.PackageManager;
 import android.graphics.Insets;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.os.RemoteCallbackList;
@@ -44,8 +45,6 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Slog;
 import android.view.Display;
 
 import com.android.car.CarLog;
@@ -54,6 +53,7 @@
 import com.android.car.R;
 import com.android.car.am.FixedActivityService;
 import com.android.car.hal.ClusterHalService;
+import com.android.server.utils.Slogf;
 
 /**
  * Service responsible for interactions between ClusterOS and ClusterHome.
@@ -65,8 +65,6 @@
     private static final int DEFAULT_MIN_UPDATE_INTERVAL_MILLIS = 1000;
     private static final String NAV_STATE_PROTO_BUNDLE_KEY = "navstate2";
 
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-
     private final Context mContext;
     private final ClusterHalService mClusterHalService;
     private final ClusterNavigationService mClusterNavigationService;
@@ -79,8 +77,7 @@
     private int mClusterDisplayId = Display.INVALID_DISPLAY;
 
     private int mOnOff = DISPLAY_OFF;
-    private int mWidth;
-    private int mHeight;
+    private Rect mBounds = new Rect();
     private Insets mInsets = Insets.NONE;
     private int mUiType = ClusterHomeManager.UI_TYPE_CLUSTER_HOME;
     private Intent mLastIntent;
@@ -104,14 +101,14 @@
 
     @Override
     public void init() {
-        if (DBG) Slog.d(TAG, "initClusterHomeService");
+        Slogf.d(TAG, "initClusterHomeService");
         if (TextUtils.isEmpty(mClusterHomeActivity.getPackageName())
                 || TextUtils.isEmpty(mClusterHomeActivity.getClassName())) {
-            Slog.i(TAG, "Improper ClusterHomeActivity: " + mClusterHomeActivity);
+            Slogf.i(TAG, "Improper ClusterHomeActivity: %s", mClusterHomeActivity);
             return;
         }
         if (!mClusterHalService.isCoreSupported()) {
-            Slog.e(TAG, "No Cluster HAL properties");
+            Slogf.e(TAG, "No Cluster HAL properties");
             return;
         }
 
@@ -127,7 +124,7 @@
         int clusterDisplayId = mOccupantZoneService.getDisplayIdForDriver(
                 CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER);
         if (clusterDisplayId == Display.INVALID_DISPLAY) {
-            Slog.i(TAG, "No cluster display is defined");
+            Slogf.i(TAG, "No cluster display is defined");
         }
         if (clusterDisplayId == mClusterDisplayId) {
             return;  // Skip if the cluster display isn't changed.
@@ -137,18 +134,15 @@
             return;
         }
 
-        // Initialize mWidth/mHeight only once.
-        if (mWidth == 0 && mHeight == 0) {
+        // Initialize mBounds only once.
+        if (mBounds.right == 0 && mBounds.bottom == 0 && mBounds.left == 0 && mBounds.top == 0) {
             DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
             Display clusterDisplay = displayManager.getDisplay(clusterDisplayId);
             Point size = new Point();
             clusterDisplay.getRealSize(size);
-            mWidth = size.x;
-            mHeight = size.y;
-            if (DBG) {
-                Slog.d(TAG, "Found cluster displayId=" + clusterDisplayId
-                        + ", width=" + mWidth + ", height=" + mHeight);
-            }
+            mBounds.right = size.x;
+            mBounds.bottom = size.y;
+            Slogf.d(TAG, "Found cluster displayId=%d, bounds=%s", clusterDisplayId, mBounds);
         }
 
         ActivityOptions activityOptions = ActivityOptions.makeBasic()
@@ -169,7 +163,7 @@
 
     @Override
     public void release() {
-        if (DBG) Slog.d(TAG, "releaseClusterHomeService");
+        Slogf.d(TAG, "releaseClusterHomeService");
         mOccupantZoneService.unregisterCallback(mOccupantZoneCallback);
         mClusterHalService.setCallback(null);
         mClusterNavigationService.setClusterServiceCallback(null);
@@ -184,7 +178,7 @@
     // ClusterHalEventListener starts
     @Override
     public void onSwitchUi(int uiType) {
-        if (DBG) Slog.d(TAG, "onSwitchUi: uiType=" + uiType);
+        Slogf.d(TAG, "onSwitchUi: uiType=%d", uiType);
         int changes = 0;
         if (mUiType != uiType) {
             mUiType = uiType;
@@ -204,20 +198,15 @@
     }
 
     @Override
-    public void onDisplayState(int onOff, int width, int height, Insets insets) {
-        if (DBG) {
-            Slog.d(TAG, "onDisplayState: onOff=" + onOff + ", width=" + width
-                    + ", height=" + height + ", insets=" + insets);
-        }
+    public void onDisplayState(int onOff, Rect bounds, Insets insets) {
+        Slogf.d(TAG, "onDisplayState: onOff=%d, bounds=%s, insets=%s", onOff, bounds, insets);
         int changes = 0;
         if (onOff != DONT_CARE && mOnOff != onOff) {
             mOnOff = onOff;
             changes |= ClusterHomeManager.CONFIG_DISPLAY_ON_OFF;
         }
-        if (width != DONT_CARE && height != DONT_CARE
-                && (mWidth != width || mHeight != height)) {
-            mWidth = width;
-            mHeight = height;
+        if (bounds != null && !mBounds.equals(bounds)) {
+            mBounds = bounds;
             changes |= ClusterHomeManager.CONFIG_DISPLAY_SIZE;
         }
         if (insets != null && !mInsets.equals(insets)) {
@@ -257,7 +246,7 @@
         mClientCallbacks.finishBroadcast();
 
         if (!mClusterHalService.isNavigationStateSupported()) {
-            if (DBG) Slog.d(TAG, "No Cluster NavigationState HAL property");
+            Slogf.d(TAG, "No Cluster NavigationState HAL property");
             return;
         }
         mClusterHalService.sendNavigationState(protoBytes);
@@ -277,17 +266,17 @@
     // IClusterHomeService starts
     @Override
     public void reportState(int uiTypeMain, int uiTypeSub, byte[] uiAvailability) {
-        if (DBG) Slog.d(TAG, "reportState: main=" + uiTypeMain + ", sub=" + uiTypeSub);
+        Slogf.d(TAG, "reportState: main=%d, sub=%d", uiTypeMain, uiTypeSub);
         enforcePermission(Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL);
         if (!mServiceEnabled) throw new IllegalStateException("Service is not enabled");
 
-        mClusterHalService.reportState(mOnOff, mWidth, mHeight, mInsets,
+        mClusterHalService.reportState(mOnOff, mBounds, mInsets,
                 uiTypeMain, uiTypeSub, uiAvailability);
     }
 
     @Override
     public void requestDisplay(int uiType) {
-        if (DBG) Slog.d(TAG, "requestDisplay: uiType=" + uiType);
+        Slogf.d(TAG, "requestDisplay: uiType=%d", uiType);
         enforcePermission(Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL);
         if (!mServiceEnabled) throw new IllegalStateException("Service is not enabled");
 
@@ -300,7 +289,7 @@
         enforcePermission(Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL);
         if (!mServiceEnabled) throw new IllegalStateException("Service is not enabled");
         if (mClusterDisplayId == Display.INVALID_DISPLAY) {
-            Slog.e(TAG, "Cluster display is not ready.");
+            Slogf.e(TAG, "Cluster display is not ready.");
             return false;
         }
 
@@ -316,7 +305,7 @@
         enforcePermission(Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL);
         if (!mServiceEnabled) throw new IllegalStateException("Service is not enabled");
         if (mClusterDisplayId == Display.INVALID_DISPLAY) {
-            Slog.e(TAG, "Cluster display is not ready.");
+            Slogf.e(TAG, "Cluster display is not ready.");
             return;
         }
 
@@ -341,7 +330,7 @@
 
     @Override
     public ClusterState getClusterState() {
-        if (DBG) Slog.d(TAG, "getClusterState");
+        Slogf.d(TAG, "getClusterState");
         enforcePermission(Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL);
         if (!mServiceEnabled) throw new IllegalStateException("Service is not enabled");
         return createClusterState();
@@ -358,8 +347,7 @@
     private ClusterState createClusterState() {
         ClusterState state = new ClusterState();
         state.on = mOnOff == DISPLAY_ON;
-        state.width = mWidth;
-        state.height = mHeight;
+        state.bounds = mBounds;
         state.insets = mInsets;
         state.uiType = mUiType;
         return state;
diff --git a/service/src/com/android/car/hal/ClusterHalService.java b/service/src/com/android/car/hal/ClusterHalService.java
index c37d817..325b30d 100644
--- a/service/src/com/android/car/hal/ClusterHalService.java
+++ b/service/src/com/android/car/hal/ClusterHalService.java
@@ -24,15 +24,15 @@
 
 import android.annotation.NonNull;
 import android.graphics.Insets;
+import android.graphics.Rect;
 import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig;
 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.util.IntArray;
-import android.util.Log;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -56,19 +56,22 @@
     public interface ClusterHalEventCallback {
         /**
          * Called when CLUSTER_SWITCH_UI message is received.
+         *
          * @param uiType uiType ClusterOS wants to switch to
          */
         void onSwitchUi(int uiType);
 
         /**
          * Called when CLUSTER_DISPLAY_STATE message is received.
-         * @param onOff 0 - off, 1 - on
-         * @param width width in pixel
-         * @param height height in pixel
+         *
+         * @param onOff  0 - off, 1 - on
+         * @param bounds the area to render the cluster Activity in pixel
          * @param insets Insets of the cluster display
          */
-        void onDisplayState(int onOff, int width, int height, Insets insets);
-    };
+        void onDisplayState(int onOff, Rect bounds, Insets insets);
+    }
+
+    ;
 
     private static final int[] SUPPORTED_PROPERTIES = new int[]{
             CLUSTER_SWITCH_UI,
@@ -106,17 +109,17 @@
 
     @Override
     public void init() {
-        if (DBG) Log.d(TAG, "initClusterHalService");
+        Slogf.d(TAG, "initClusterHalService");
         if (!isCoreSupported()) return;
 
-        for (int property: SUBSCRIBABLE_PROPERTIES) {
+        for (int property : SUBSCRIBABLE_PROPERTIES) {
             mHal.subscribeProperty(this, property);
         }
     }
 
     @Override
     public void release() {
-        if (DBG) Log.d(TAG, "releaseClusterHalService");
+        Slogf.d(TAG, "releaseClusterHalService");
         synchronized (mLock) {
             mCallback = null;
         }
@@ -152,10 +155,8 @@
             }
         }
         mIsNavigationStateSupported = supportedProperties.indexOf(CLUSTER_NAVIGATION_STATE) >= 0;
-        if (DBG) {
-            Log.d(TAG, "takeProperties: coreSupported=" + mIsCoreSupported
-                    + ", navigationStateSupported=" + mIsNavigationStateSupported);
-        }
+        Slogf.d(TAG, "takeProperties: coreSupported=%s, navigationStateSupported=%s",
+                mIsCoreSupported, mIsNavigationStateSupported);
     }
 
     public boolean isCoreSupported() {
@@ -168,7 +169,7 @@
 
     @Override
     public void onHalEvents(List<VehiclePropValue> values) {
-        if (DBG) Log.d(TAG, "handleHalEvents(): " + values);
+        Slogf.d(TAG, "handleHalEvents(): %s", values);
         ClusterHalEventCallback callback;
         synchronized (mLock) {
             callback = mCallback;
@@ -183,22 +184,22 @@
                     break;
                 case CLUSTER_DISPLAY_STATE:
                     int onOff = value.value.int32Values.get(0);
-                    int width = DONT_CARE;
-                    int height = DONT_CARE;
-                    if (hasNoDontCare(value.value.int32Values, 1, 2, "width/height")) {
-                        width = value.value.int32Values.get(1);
-                        height = value.value.int32Values.get(2);
+                    Rect bounds = null;
+                    if (hasNoDontCare(value.value.int32Values, 1, 4, "bounds")) {
+                        bounds = new Rect(
+                                value.value.int32Values.get(1), value.value.int32Values.get(2),
+                                value.value.int32Values.get(3), value.value.int32Values.get(4));
                     }
                     Insets insets = null;
-                    if (hasNoDontCare(value.value.int32Values, 3, 4, "insets")) {
+                    if (hasNoDontCare(value.value.int32Values, 5, 4, "insets")) {
                         insets = Insets.of(
-                                value.value.int32Values.get(3), value.value.int32Values.get(4),
-                                value.value.int32Values.get(5), value.value.int32Values.get(6));
+                                value.value.int32Values.get(5), value.value.int32Values.get(6),
+                                value.value.int32Values.get(7), value.value.int32Values.get(8));
                     }
-                    callback.onDisplayState(onOff, width, height, insets);
+                    callback.onDisplayState(onOff, bounds, insets);
                     break;
                 default:
-                    Slog.w(TAG, "received unsupported event from HAL: " + value);
+                    Slogf.w(TAG, "received unsupported event from HAL: %s", value);
             }
         }
     }
@@ -211,28 +212,30 @@
         }
         if (count == 0) return true;
         if (count != length) {
-            Slog.w(TAG, "Don't care should be set in the whole " + fieldName);
+            Slogf.w(TAG, "Don't care should be set in the whole %s.", fieldName);
         }
         return false;
     }
 
     /**
      * Reports the current display state and ClusterUI state.
-     * @param onOff 0 - off, 1 - on
-     * @param width width in pixel
-     * @param height height in pixel
-     * @param insets Insets of the cluster display
-     * @param uiTypeMain uiType that ClusterHome tries to show in main area
-     * @param uiTypeSub uiType that ClusterHome tries to show in sub area
+     *
+     * @param onOff          0 - off, 1 - on
+     * @param bounds         the area to render the cluster Activity in pixel
+     * @param insets         Insets of the cluster display
+     * @param uiTypeMain     uiType that ClusterHome tries to show in main area
+     * @param uiTypeSub      uiType that ClusterHome tries to show in sub area
      * @param uiAvailability the byte array to represent the availability of ClusterUI.
      */
-    public void reportState(int onOff, int width, int height, Insets insets,
+    public void reportState(int onOff, Rect bounds, Insets insets,
             int uiTypeMain, int uiTypeSub, byte[] uiAvailability) {
         if (!isCoreSupported()) return;
         VehiclePropValue request = createVehiclePropValue(CLUSTER_REPORT_STATE);
         request.value.int32Values.add(onOff);
-        request.value.int32Values.add(width);
-        request.value.int32Values.add(height);
+        request.value.int32Values.add(bounds.left);
+        request.value.int32Values.add(bounds.top);
+        request.value.int32Values.add(bounds.right);
+        request.value.int32Values.add(bounds.bottom);
         request.value.int32Values.add(insets.left);
         request.value.int32Values.add(insets.top);
         request.value.int32Values.add(insets.right);
@@ -245,6 +248,7 @@
 
     /**
      * Requests to turn the cluster display on to show some ClusterUI.
+     *
      * @param uiType uiType that ClusterHome tries to show in main area
      */
     public void requestDisplay(int uiType) {
@@ -257,6 +261,7 @@
 
     /**
      * Informs the current navigation state.
+     *
      * @param navigateState the serialized message of {@code NavigationStateProto}
      */
     public void sendNavigationState(byte[] navigateState) {
@@ -270,13 +275,13 @@
         try {
             mHal.set(request);
         } catch (ServiceSpecificException e) {
-            Slog.e(TAG, "Failed to send request: " + request, e);
+            Slogf.e(TAG, "Failed to send request: " + request, e);
         }
     }
 
     private static void fillByteList(ArrayList<Byte> byteList, byte[] bytesArray) {
         byteList.ensureCapacity(bytesArray.length);
-        for (byte b: bytesArray) {
+        for (byte b : bytesArray) {
             byteList.add(b);
         }
     }
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index 685a7ce..5439236 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -44,6 +44,8 @@
 import android.car.user.UserCreationResult;
 import android.car.user.UserIdentificationAssociationResponse;
 import android.car.user.UserRemovalResult;
+import android.car.user.UserStartResult;
+import android.car.user.UserStopResult;
 import android.car.user.UserSwitchResult;
 import android.car.userlib.HalCallback;
 import android.car.userlib.UserHalHelper;
@@ -110,6 +112,7 @@
 import com.android.internal.util.FunctionalUtils;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.UserIcons;
+import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -964,10 +967,10 @@
             sendUserSwitchResult(receiver, UserSwitchResult.STATUS_NOT_SWITCHABLE);
             return;
         }
-        mHandler.post(()-> switchUserInternal(targetUser, timeoutMs, receiver));
+        mHandler.post(() -> handleSwitchUser(targetUser, timeoutMs, receiver));
     }
 
-    private void switchUserInternal(@NonNull UserInfo targetUser, int timeoutMs,
+    private void handleSwitchUser(@NonNull UserInfo targetUser, int timeoutMs,
             @NonNull AndroidFuture<UserSwitchResult> receiver) {
         int currentUser = ActivityManager.getCurrentUser();
         int targetUserId = targetUser.id;
@@ -1129,10 +1132,10 @@
                         + " can only remove itself");
             }
         }
-        mHandler.post(()-> removeUserInternal(userId, hasCallerRestrictions, receiver));
+        mHandler.post(() -> handleRemoveUser(userId, hasCallerRestrictions, receiver));
     }
 
-    private void removeUserInternal(@UserIdInt int userId, boolean hasCallerRestrictions,
+    private void handleRemoveUser(@UserIdInt int userId, boolean hasCallerRestrictions,
             AndroidFuture<UserRemovalResult> receiver) {
         UserInfo userInfo = mUserManager.getUserInfo(userId);
         if (userInfo == null) {
@@ -1301,12 +1304,12 @@
         EventLog.writeEvent(EventLogTags.CAR_USER_SVC_CREATE_USER_REQ,
                 UserHelperLite.safeName(name), userType, flags, timeoutMs,
                 hasCallerRestrictions ? 1 : 0);
-        mHandler.post(() -> createUserInternal(name, userType, flags, timeoutMs, receiver,
+        mHandler.post(() -> handleCreateUser(name, userType, flags, timeoutMs, receiver,
                 hasCallerRestrictions));
 
     }
 
-    private void createUserInternal(@Nullable String name, @NonNull String userType,
+    private void handleCreateUser(@Nullable String name, @NonNull String userType,
             @UserInfoFlag int flags, int timeoutMs,
             @NonNull AndroidFuture<UserCreationResult> receiver,
             boolean hasCallerRestrictions) {
@@ -1840,6 +1843,53 @@
     }
 
     /**
+     * Starts the specified user in the background.
+     *
+     * @param userId user to start in background
+     * @param receiver to post results
+     */
+    public void startUserInBackground(@UserIdInt int userId,
+            @NonNull AndroidFuture<UserStartResult> receiver) {
+        mHandler.post(() -> handleStartUserInBackground(userId, receiver));
+    }
+
+    private void handleStartUserInBackground(@UserIdInt int userId,
+            @NonNull AndroidFuture<UserStartResult> receiver) {
+        // If the requested user is the current user, do nothing and return success.
+        if (ActivityManager.getCurrentUser() == userId) {
+            sendUserStartResult(UserStartResult.STATUS_SUCCESSFUL_USER_IS_CURRENT_USER, receiver);
+            return;
+        }
+        // If requested user does not exist, return error.
+        if (mUserManager.getUserInfo(userId) == null) {
+            Slogf.w(TAG, "User %d does not exist", userId);
+            sendUserStartResult(UserStartResult.STATUS_USER_DOES_NOT_EXIST, receiver);
+            return;
+        }
+
+        try {
+            if (!mAm.startUserInBackground(userId)) {
+                Slogf.w(TAG, "Failed to start user %d in background", userId);
+                sendUserStartResult(UserStartResult.STATUS_ANDROID_FAILURE, receiver);
+                return;
+            }
+        } catch (RemoteException e) {
+            Slogf.w(TAG, e, "Failed to start user %d in background", userId);
+        }
+
+        // TODO(b/181331178): We are not updating mBackgroundUsersToRestart or
+        // mBackgroundUsersRestartedHere, which were only used for the garage mode. Consider
+        // renaming them to make it more clear.
+        sendUserStartResult(UserStartResult.STATUS_SUCCESSFUL, receiver);
+    }
+
+    private void sendUserStartResult(@UserStartResult.Status int result,
+            @NonNull AndroidFuture<UserStartResult> receiver) {
+        // TODO(b/181331178): Add event log calls.
+        receiver.complete(new UserStartResult(result));
+    }
+
+    /**
      * Starts all background users that were active in system.
      *
      * @return list of background users started successfully.
@@ -1891,36 +1941,67 @@
     }
 
     /**
-     * Stops all background users that were active in system.
+     * Stops the specified background user.
+     *
+     * @param userId user to stop
+     * @param receiver to post results
+     */
+    public void stopUser(@UserIdInt int userId, @NonNull AndroidFuture<UserStopResult> receiver) {
+        mHandler.post(() -> handleStopUser(userId, receiver));
+    }
+
+    private void handleStopUser(
+            @UserIdInt int userId, @NonNull AndroidFuture<UserStopResult> receiver) {
+        @UserStopResult.Status int userStopStatus = stopBackgroundUserInternal(userId);
+        sendUserStopResult(userStopStatus, receiver);
+    }
+
+    private void sendUserStopResult(@UserStopResult.Status int result,
+            @NonNull AndroidFuture<UserStopResult> receiver) {
+        // TODO(b/181331178): Add event log calls.
+        receiver.complete(new UserStopResult(result));
+    }
+
+    private @UserStopResult.Status int stopBackgroundUserInternal(@UserIdInt int userId) {
+        try {
+            int r = mAm.stopUserWithDelayedLocking(userId, true, null);
+            switch(r) {
+                case ActivityManager.USER_OP_SUCCESS:
+                    return UserStopResult.STATUS_SUCCESSFUL;
+                case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
+                    Slogf.w(TAG, "Cannot stop the system user: %d", userId);
+                    return UserStopResult.STATUS_FAILURE_SYSTEM_USER;
+                case ActivityManager.USER_OP_IS_CURRENT:
+                    Slogf.w(TAG, "Cannot stop the current user: %d", userId);
+                    return UserStopResult.STATUS_FAILURE_CURRENT_USER;
+                case ActivityManager.USER_OP_UNKNOWN_USER:
+                    Slogf.w(TAG, "Cannot stop the user that does not exist: %d", userId);
+                    return UserStopResult.STATUS_USER_DOES_NOT_EXIST;
+                default:
+                    Slogf.w(TAG, "stopUser failed, user: %d, err: %d", userId, r);
+            }
+        } catch (RemoteException e) {
+            // ignore the exception
+            Slogf.w(TAG, e, "error while stopping user: %d", userId);
+        }
+        return UserStopResult.STATUS_ANDROID_FAILURE;
+    }
+
+    /**
+     * Stops a background user.
      *
      * @return whether stopping succeeds.
      */
     public boolean stopBackgroundUser(@UserIdInt int userId) {
-        if (userId == UserHandle.USER_SYSTEM) {
-            return false;
-        }
-        if (userId == ActivityManager.getCurrentUser()) {
-            Slog.i(TAG, "stopBackgroundUser, already a FG user:" + userId);
-            return false;
-        }
-        try {
-            int r = mAm.stopUserWithDelayedLocking(userId, true, null);
-            if (r == ActivityManager.USER_OP_SUCCESS) {
-                synchronized (mLockUser) {
-                    Integer user = userId;
-                    mBackgroundUsersRestartedHere.remove(user);
-                }
-            } else if (r == ActivityManager.USER_OP_IS_CURRENT) {
-                return false;
-            } else {
-                Slog.i(TAG, "stopBackgroundUser failed, user:" + userId + " err:" + r);
-                return false;
+        @UserStopResult.Status int userStopStatus = stopBackgroundUserInternal(userId);
+        if (UserStopResult.isSuccess(userStopStatus)) {
+            // Remove the stopped user from the mBackgroundUserRestartedHere list.
+            synchronized (mLockUser) {
+                mBackgroundUsersRestartedHere.remove(Integer.valueOf(userId));
             }
-        } catch (RemoteException e) {
-            // ignore
-            Slog.w(TAG, "error while stopping user", e);
+            return true;
         }
-        return true;
+        return false;
     }
 
     /**
diff --git a/service/src/com/android/car/watchdog/CarWatchdogService.java b/service/src/com/android/car/watchdog/CarWatchdogService.java
index 8b650ed..0b26e0a 100644
--- a/service/src/com/android/car/watchdog/CarWatchdogService.java
+++ b/service/src/com/android/car/watchdog/CarWatchdogService.java
@@ -63,8 +63,8 @@
  * Service to implement CarWatchdogManager API.
  */
 public final class CarWatchdogService extends ICarWatchdogService.Stub implements CarServiceBase {
-    private static final boolean DEBUG = false; // STOPSHIP if true
-    private static final String TAG = CarLog.tagFor(CarWatchdogService.class);
+    static final boolean DEBUG = false; // STOPSHIP if true
+    static final String TAG = CarLog.tagFor(CarWatchdogService.class);
 
     private final Context mContext;
     private final ICarWatchdogServiceForSystemImpl mWatchdogServiceForSystem;
@@ -85,9 +85,9 @@
         mCarWatchdogDaemonHelper = new CarWatchdogDaemonHelper(TAG_WATCHDOG);
         mWatchdogServiceForSystem = new ICarWatchdogServiceForSystemImpl(this);
         mWatchdogProcessHandler = new WatchdogProcessHandler(mWatchdogServiceForSystem,
-                mCarWatchdogDaemonHelper, DEBUG);
+                mCarWatchdogDaemonHelper);
         mWatchdogPerfHandler = new WatchdogPerfHandler(mContext, mCarWatchdogDaemonHelper,
-                mPackageInfoHandler, DEBUG);
+                mPackageInfoHandler);
     }
 
     @Override
diff --git a/service/src/com/android/car/watchdog/PackageInfoHandler.java b/service/src/com/android/car/watchdog/PackageInfoHandler.java
index c2b3323..f04f2b9 100644
--- a/service/src/com/android/car/watchdog/PackageInfoHandler.java
+++ b/service/src/com/android/car/watchdog/PackageInfoHandler.java
@@ -45,6 +45,8 @@
     /* Cache of uid to package name mapping. */
     @GuardedBy("mLock")
     private final SparseArray<String> mPackageNamesByUid = new SparseArray<>();
+    @GuardedBy("mLock")
+    private List<String> mVendorPackagePrefixes = new ArrayList<>();
 
     public PackageInfoHandler(PackageManager packageManager) {
         mPackageManager = packageManager;
@@ -93,25 +95,31 @@
      */
     public List<PackageInfo> getPackageInfosForUids(int[] uids,
             List<String> vendorPackagePrefixes) {
+        synchronized (mLock) {
+            /*
+             * Vendor package prefixes don't change frequently because it changes only when the
+             * vendor configuration is updated. Thus caching this locally during this call should
+             * keep the cache up-to-date because the daemon issues this call frequently.
+             */
+            mVendorPackagePrefixes = vendorPackagePrefixes;
+        }
         SparseArray<String> packageNamesByUid = getPackageNamesForUids(uids);
         ArrayList<PackageInfo> packageInfos = new ArrayList<>(packageNamesByUid.size());
         for (int i = 0; i < packageNamesByUid.size(); ++i) {
             packageInfos.add(getPackageInfo(packageNamesByUid.keyAt(i),
-                    packageNamesByUid.valueAt(i), vendorPackagePrefixes));
+                    packageNamesByUid.valueAt(i)));
         }
         return packageInfos;
     }
 
-    private PackageInfo getPackageInfo(
-            int uid, String packageName, List<String> vendorPackagePrefixes) {
+    private PackageInfo getPackageInfo(int uid, String packageName) {
         PackageInfo packageInfo = new PackageInfo();
         packageInfo.packageIdentifier = new PackageIdentifier();
         packageInfo.packageIdentifier.uid = uid;
         packageInfo.packageIdentifier.name = packageName;
         packageInfo.sharedUidPackages = new ArrayList<>();
         packageInfo.componentType = ComponentType.UNKNOWN;
-        // TODO(b/170741935): Identify application category type using the package names. Vendor
-        //  should define the mappings from package name to the application category type.
+        /* Application category type mapping is handled on the daemon side. */
         packageInfo.appCategoryType = ApplicationCategoryType.OTHERS;
         int userId = UserHandle.getUserId(uid);
         int appId = UserHandle.getAppId(uid);
@@ -126,14 +134,13 @@
             boolean seenVendor = false;
             boolean seenSystem = false;
             boolean seenThirdParty = false;
-            /**
+            /*
              * A shared UID has multiple packages associated with it and these packages may be
              * mapped to different component types. Thus map the shared UID to the most restrictive
              * component type.
              */
             for (int i = 0; i < sharedUidPackages.length; ++i) {
-                int componentType = getPackageComponentType(userId, sharedUidPackages[i],
-                        vendorPackagePrefixes);
+                int componentType = getPackageComponentType(userId, sharedUidPackages[i]);
                 switch(componentType) {
                     case ComponentType.VENDOR:
                         seenVendor = true;
@@ -159,35 +166,41 @@
             }
         } else {
             packageInfo.componentType = getPackageComponentType(
-                    userId, packageName, vendorPackagePrefixes);
+                    userId, packageName);
         }
         return packageInfo;
     }
 
-    private int getPackageComponentType(
-            int userId, String packageName, List<String> vendorPackagePrefixes) {
+    private int getPackageComponentType(int userId, String packageName) {
         try {
             ApplicationInfo info = mPackageManager.getApplicationInfoAsUser(packageName,
                     /* flags= */ 0, userId);
-            if ((info.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0
-                    || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0
-                    || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
-                return ComponentType.VENDOR;
-            }
-            if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0
-                    || (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
-                    || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0
-                    || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
-                for (String prefix : vendorPackagePrefixes) {
+            return getComponentType(packageName, info);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slogf.e(TAG, "Package '%s' not found for user %d: %s", packageName, userId, e);
+        }
+        return ComponentType.UNKNOWN;
+    }
+
+    /** Returns the component type for the given package and its application info. */
+    public int getComponentType(String packageName, ApplicationInfo info) {
+        if ((info.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0
+                || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0
+                || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
+            return ComponentType.VENDOR;
+        }
+        if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0
+                || (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
+                || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0
+                || (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
+            synchronized (mLock) {
+                for (String prefix : mVendorPackagePrefixes) {
                     if (packageName.startsWith(prefix)) {
                         return ComponentType.VENDOR;
                     }
                 }
-                return ComponentType.SYSTEM;
             }
-        } catch (PackageManager.NameNotFoundException e) {
-            Slogf.e(TAG, "Package '%s' not found for user %d: %s", packageName, userId, e);
-            return ComponentType.UNKNOWN;
+            return ComponentType.SYSTEM;
         }
         return ComponentType.THIRD_PARTY;
     }
diff --git a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
index 37fbbb3..80dcb82 100644
--- a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
+++ b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
@@ -34,11 +34,18 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityThread;
 import android.automotive.watchdog.ResourceType;
+import android.automotive.watchdog.internal.ApplicationCategoryType;
+import android.automotive.watchdog.internal.ComponentType;
 import android.automotive.watchdog.internal.PackageIdentifier;
 import android.automotive.watchdog.internal.PackageIoOveruseStats;
+import android.automotive.watchdog.internal.PackageMetadata;
 import android.automotive.watchdog.internal.PackageResourceOveruseAction;
+import android.automotive.watchdog.internal.PerStateIoOveruseThreshold;
+import android.automotive.watchdog.internal.ResourceSpecificConfiguration;
 import android.car.watchdog.CarWatchdogManager;
 import android.car.watchdog.IResourceOveruseListener;
+import android.car.watchdog.IoOveruseAlertThreshold;
+import android.car.watchdog.IoOveruseConfiguration;
 import android.car.watchdog.IoOveruseStats;
 import android.car.watchdog.PackageKillableState;
 import android.car.watchdog.PackageKillableState.KillableState;
@@ -48,18 +55,21 @@
 import android.car.watchdoglib.CarWatchdogDaemonHelper;
 import android.content.Context;
 import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.SparseArray;
 
-import com.android.car.CarLog;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
@@ -78,9 +88,10 @@
  * Handles system resource performance monitoring module.
  */
 public final class WatchdogPerfHandler {
-    private static final String TAG = CarLog.tagFor(CarWatchdogService.class);
+    public static final String INTERNAL_APPLICATION_CATEGORY_TYPE_MAPS = "MAPS";
+    public static final String INTERNAL_APPLICATION_CATEGORY_TYPE_MEDIA = "MEDIA";
+    public static final String INTERNAL_APPLICATION_CATEGORY_TYPE_UNKNOWN = "UNKNOWN";
 
-    private final boolean mIsDebugEnabled;
     private final Context mContext;
     private final CarWatchdogDaemonHelper mCarWatchdogDaemonHelper;
     private final PackageInfoHandler mPackageInfoHandler;
@@ -102,10 +113,15 @@
             new SparseArray<>();
     @GuardedBy("mLock")
     private ZonedDateTime mLastStatsReportUTC;
+    /* Set of safe-to-kill system and vendor packages. */
+    @GuardedBy("mLock")
+    public final Set<String> mSafeToKillPackages = new ArraySet<>();
+    /* Default killable state for packages when not updated by the user. */
+    @GuardedBy("mLock")
+    public final Set<String> mDefaultNotKillablePackages = new ArraySet<>();
 
     public WatchdogPerfHandler(Context context, CarWatchdogDaemonHelper daemonHelper,
-            PackageInfoHandler packageInfoHandler, boolean isDebugEnabled) {
-        mIsDebugEnabled = isDebugEnabled;
+            PackageInfoHandler packageInfoHandler) {
         mContext = context;
         mCarWatchdogDaemonHelper = daemonHelper;
         mPackageInfoHandler = packageInfoHandler;
@@ -119,31 +135,31 @@
          * TODO(b/183947162): Opt-in to receive package change broadcast and handle package enabled
          *  state changes.
          *
-         * TODO(b/170741935): Read the current day's I/O overuse stats from database and push them
+         * TODO(b/185287136): Persist in-memory data:
+         *  1. Read the current day's I/O overuse stats from database and push them
          *  to the daemon.
+         *  2. Fetch the safe-to-kill from daemon on initialization and update mSafeToKillPackages.
          */
         synchronized (mLock) {
             checkAndHandleDateChangeLocked();
         }
-        if (mIsDebugEnabled) {
-            Slogf.d(TAG, "WatchdogPerfHandler is initialized");
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "WatchdogPerfHandler is initialized");
         }
     }
 
     /** Releases the handler */
     public void release() {
-        /*
-         * TODO(b/170741935): Write daily usage to SQLite DB storage.
-         */
-        if (mIsDebugEnabled) {
-            Slogf.d(TAG, "WatchdogPerfHandler is released");
+        /* TODO(b/185287136): Write daily usage to SQLite DB storage. */
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "WatchdogPerfHandler is released");
         }
     }
 
     /** Dumps its state. */
     public void dump(IndentingPrintWriter writer) {
-        /**
-         * TODO(b/170741935): Implement this method.
+        /*
+         * TODO(b/183436216): Implement this method.
          */
     }
 
@@ -156,9 +172,29 @@
                 "Must provide valid resource overuse flag");
         Preconditions.checkArgument((maxStatsPeriod > 0),
                 "Must provide valid maximum stats period");
-        // TODO(b/170741935): Implement this method.
-        return new ResourceOveruseStats.Builder("",
-                UserHandle.getUserHandleForUid(Binder.getCallingUid())).build();
+        // When more resource stats are added, make this as optional.
+        Preconditions.checkArgument((resourceOveruseFlag & FLAG_RESOURCE_OVERUSE_IO) != 0,
+                "Must provide resource I/O overuse flag");
+        int callingUid = Binder.getCallingUid();
+        int callingUserId = UserHandle.getUserId(callingUid);
+        UserHandle callingUserHandle = UserHandle.of(callingUserId);
+        String callingPackageName =
+                mPackageInfoHandler.getPackageNamesForUids(new int[]{callingUid})
+                        .get(callingUid, null);
+        if (callingPackageName == null) {
+            Slogf.w(CarWatchdogService.TAG, "Failed to fetch package info for uid %d", callingUid);
+            return new ResourceOveruseStats.Builder("", callingUserHandle).build();
+        }
+        ResourceOveruseStats.Builder statsBuilder =
+                new ResourceOveruseStats.Builder(callingPackageName, callingUserHandle);
+        statsBuilder.setIoOveruseStats(getIoOveruseStats(callingUserId, callingPackageName,
+                /* minimumBytesWritten= */ 0, maxStatsPeriod));
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Returning all resource overuse stats for calling uid "
+                            + "%d [user %d and package '%s']", callingUid, callingUserId,
+                    callingPackageName);
+        }
+        return statsBuilder.build();
     }
 
     /** Returns resource overuse stats for all packages. */
@@ -171,8 +207,24 @@
                 "Must provide valid resource overuse flag");
         Preconditions.checkArgument((maxStatsPeriod > 0),
                 "Must provide valid maximum stats period");
-        // TODO(b/170741935): Implement this method.
-        return new ArrayList<>();
+        // When more resource types are added, make this as optional.
+        Preconditions.checkArgument((resourceOveruseFlag & FLAG_RESOURCE_OVERUSE_IO) != 0,
+                "Must provide resource I/O overuse flag");
+        long minimumBytesWritten = getMinimumBytesWritten(minimumStatsFlag);
+        List<ResourceOveruseStats> allStats = new ArrayList<>();
+        for (PackageResourceUsage usage : mUsageByUserPackage.values()) {
+            ResourceOveruseStats.Builder statsBuilder = usage.getResourceOveruseStatsBuilder();
+            IoOveruseStats ioOveruseStats = getIoOveruseStats(usage.userId, usage.packageName,
+                    minimumBytesWritten, maxStatsPeriod);
+            if (ioOveruseStats == null) {
+                continue;
+            }
+            allStats.add(statsBuilder.setIoOveruseStats(ioOveruseStats).build());
+        }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Returning all resource overuse stats");
+        }
+        return allStats;
     }
 
     /** Returns resource overuse stats for the specified user package. */
@@ -183,12 +235,25 @@
             @CarWatchdogManager.StatsPeriod int maxStatsPeriod) {
         Objects.requireNonNull(packageName, "Package name must be non-null");
         Objects.requireNonNull(userHandle, "User handle must be non-null");
+        Preconditions.checkArgument((userHandle != UserHandle.ALL),
+                "Must provide the user handle for a specific user");
         Preconditions.checkArgument((resourceOveruseFlag > 0),
                 "Must provide valid resource overuse flag");
         Preconditions.checkArgument((maxStatsPeriod > 0),
                 "Must provide valid maximum stats period");
-        // TODO(b/170741935): Implement this method.
-        return new ResourceOveruseStats.Builder("", userHandle).build();
+        // When more resource types are added, make this as optional.
+        Preconditions.checkArgument((resourceOveruseFlag & FLAG_RESOURCE_OVERUSE_IO) != 0,
+                "Must provide resource I/O overuse flag");
+        ResourceOveruseStats.Builder statsBuilder =
+                new ResourceOveruseStats.Builder(packageName, userHandle);
+        statsBuilder.setIoOveruseStats(getIoOveruseStats(userHandle.getIdentifier(), packageName,
+                /* minimumBytesWritten= */ 0, maxStatsPeriod));
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG,
+                    "Returning resource overuse stats for user %d, package '%s'",
+                    userHandle.getIdentifier(), packageName);
+        }
+        return statsBuilder.build();
     }
 
     /** Adds the resource overuse listener. */
@@ -238,18 +303,107 @@
             boolean isKillable) {
         Objects.requireNonNull(packageName, "Package name must be non-null");
         Objects.requireNonNull(userHandle, "User handle must be non-null");
-        /*
-         * TODO(b/170741935): Add/remove the package from the user do-no-kill list.
-         *  If the {@code userHandle == UserHandle.ALL}, update the settings for all users.
-         */
+        if (userHandle == UserHandle.ALL) {
+            synchronized (mLock) {
+                for (PackageResourceUsage usage : mUsageByUserPackage.values()) {
+                    if (!usage.packageName.equals(packageName)) {
+                        continue;
+                    }
+                    if (!usage.setKillableState(isKillable)) {
+                        Slogf.e(CarWatchdogService.TAG,
+                                "Cannot set killable state for package '%s'", packageName);
+                        throw new IllegalArgumentException(
+                                "Package killable state is not updatable");
+                    }
+                }
+                if (!isKillable) {
+                    mDefaultNotKillablePackages.add(packageName);
+                } else {
+                    mDefaultNotKillablePackages.remove(packageName);
+                }
+            }
+            if (CarWatchdogService.DEBUG) {
+                Slogf.d(CarWatchdogService.TAG,
+                        "Successfully set killable package state for all users");
+            }
+            return;
+        }
+        int userId = userHandle.getIdentifier();
+        String key = getUserPackageUniqueId(userId, packageName);
+        synchronized (mLock) {
+            /*
+             * When the queried package is not cached in {@link mUsageByUserPackage}, the set API
+             * will update the killable state even when the package should never be killed.
+             * But the get API will return the correct killable state. This behavior is tolerable
+             * because in production the set API should be called only after the get API.
+             * For instance, when this case happens by mistake and the package overuses resource
+             * between the set and the get API calls, the daemon will provide correct killable
+             * state when pushing the latest stats. Ergo, the invalid killable state doesn't have
+             * any effect.
+             */
+            PackageResourceUsage usage = mUsageByUserPackage.getOrDefault(key,
+                    new PackageResourceUsage(userId, packageName));
+            if (!usage.setKillableState(isKillable)) {
+                Slogf.e(CarWatchdogService.TAG,
+                        "User %d cannot set killable state for package '%s'",
+                        userHandle.getIdentifier(), packageName);
+                throw new IllegalArgumentException("Package killable state is not updatable");
+            }
+            mUsageByUserPackage.put(key, usage);
+        }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Successfully set killable package state for user %d",
+                    userId);
+        }
     }
 
     /** Returns the list of package killable states on resource overuse for the user. */
     @NonNull
     public List<PackageKillableState> getPackageKillableStatesAsUser(UserHandle userHandle) {
         Objects.requireNonNull(userHandle, "User handle must be non-null");
-        // TODO(b/170741935): Implement this method.
-        return new ArrayList<>();
+        PackageManager pm = mContext.getPackageManager();
+        if (userHandle != UserHandle.ALL) {
+            if (CarWatchdogService.DEBUG) {
+                Slogf.d(CarWatchdogService.TAG, "Returning all package killable states for user %d",
+                        userHandle.getIdentifier());
+            }
+            return getPackageKillableStatesForUserId(userHandle.getIdentifier(), pm);
+        }
+        List<PackageKillableState> packageKillableStates = new ArrayList<>();
+        UserManager userManager = UserManager.get(mContext);
+        List<UserInfo> userInfos = userManager.getAliveUsers();
+        for (UserInfo userInfo : userInfos) {
+            packageKillableStates.addAll(getPackageKillableStatesForUserId(userInfo.id, pm));
+        }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Returning all package killable states for all users");
+        }
+        return packageKillableStates;
+    }
+
+    private List<PackageKillableState> getPackageKillableStatesForUserId(int userId,
+            PackageManager pm) {
+        List<PackageInfo> packageInfos = pm.getInstalledPackagesAsUser(/* flags= */0, userId);
+        List<PackageKillableState> states = new ArrayList<>();
+        synchronized (mLock) {
+            for (int i = 0; i < packageInfos.size(); ++i) {
+                PackageInfo packageInfo = packageInfos.get(i);
+                String key = getUserPackageUniqueId(userId, packageInfo.packageName);
+                PackageResourceUsage usage = mUsageByUserPackage.getOrDefault(key,
+                        new PackageResourceUsage(userId, packageInfo.packageName));
+                int killableState = usage.syncAndFetchKillableStateLocked(
+                        mPackageInfoHandler.getComponentType(packageInfo.packageName,
+                                packageInfo.applicationInfo));
+                mUsageByUserPackage.put(key, usage);
+                states.add(
+                        new PackageKillableState(packageInfo.packageName, userId, killableState));
+            }
+        }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG,
+                    "Returning the package killable states for a user package");
+        }
+        return states;
     }
 
     /** Sets the given resource overuse configurations. */
@@ -257,11 +411,18 @@
             List<ResourceOveruseConfiguration> configurations,
             @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag) {
         Objects.requireNonNull(configurations, "Configurations must be non-null");
+        Preconditions.checkArgument((configurations.size() > 0),
+                "Must provide at least one configuration");
         Preconditions.checkArgument((resourceOveruseFlag > 0),
                 "Must provide valid resource overuse flag");
         Set<Integer> seenComponentTypes = new ArraySet<>();
+        List<android.automotive.watchdog.internal.ResourceOveruseConfiguration> internalConfigs =
+                new ArrayList<>();
         for (ResourceOveruseConfiguration config : configurations) {
             int componentType = config.getComponentType();
+            if (toComponentTypeStr(componentType).equals("UNKNOWN")) {
+                throw new IllegalArgumentException("Invalid component type in the configuration");
+            }
             if (seenComponentTypes.contains(componentType)) {
                 throw new IllegalArgumentException(
                         "Cannot provide duplicate configurations for the same component type");
@@ -271,8 +432,24 @@
                 throw new IllegalArgumentException("Must provide I/O overuse configuration");
             }
             seenComponentTypes.add(config.getComponentType());
+            internalConfigs.add(toInternalResourceOveruseConfiguration(config,
+                    resourceOveruseFlag));
         }
-        // TODO(b/170741935): Implement this method.
+
+        // TODO(b/186119640): Add retry logic when daemon is not available.
+        try {
+            mCarWatchdogDaemonHelper.updateResourceOveruseConfigurations(internalConfigs);
+        } catch (IllegalArgumentException e) {
+            Slogf.w(CarWatchdogService.TAG, "Failed to set resource overuse configurations: %s", e);
+            throw e;
+        } catch (RemoteException | RuntimeException e) {
+            Slogf.w(CarWatchdogService.TAG, "Failed to set resource overuse configurations: %s", e);
+            throw new IllegalStateException(e);
+        }
+        /* TODO(b/185287136): Fetch safe-to-kill list from daemon and update mSafeToKillPackages. */
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Set the resource overuse configuration successfully");
+        }
     }
 
     /** Returns the available resource overuse configurations. */
@@ -281,8 +458,25 @@
             @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag) {
         Preconditions.checkArgument((resourceOveruseFlag > 0),
                 "Must provide valid resource overuse flag");
-        // TODO(b/170741935): Implement this method.
-        return new ArrayList<>();
+        List<android.automotive.watchdog.internal.ResourceOveruseConfiguration> internalConfigs =
+                new ArrayList<>();
+        // TODO(b/186119640): Add retry logic when daemon is not available.
+        try {
+            internalConfigs = mCarWatchdogDaemonHelper.getResourceOveruseConfigurations();
+        } catch (RemoteException | RuntimeException e) {
+            Slogf.w(CarWatchdogService.TAG, "Failed to fetch resource overuse configurations: %s",
+                    e);
+            throw new IllegalStateException(e);
+        }
+        List<ResourceOveruseConfiguration> configs = new ArrayList<>();
+        for (android.automotive.watchdog.internal.ResourceOveruseConfiguration internalConfig
+                : internalConfigs) {
+            configs.add(toResourceOveruseConfiguration(internalConfig, resourceOveruseFlag));
+        }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Returning the resource overuse configuration");
+        }
+        return configs;
     }
 
     /** Processes the latest I/O overuse stats */
@@ -308,9 +502,12 @@
                      * and only the daemon is aware of such packages. Thus the flag is used to
                      * indicate which packages should be notified.
                      */
-                    notifyResourceOveruseStatsLocked(stats.uid,
-                            usage.getResourceOveruseStatsWithIo());
+                    ResourceOveruseStats resourceOveruseStats =
+                            usage.getResourceOveruseStatsBuilder().setIoOveruseStats(
+                                    usage.getIoOveruseStats()).build();
+                    notifyResourceOveruseStatsLocked(stats.uid, resourceOveruseStats);
                 }
+
                 if (!usage.ioUsage.exceedsThreshold()) {
                     continue;
                 }
@@ -326,7 +523,6 @@
                  * #2 The package has no recurring overuse behavior and the user opted to not
                  *    kill the package so honor the user's decision.
                  */
-                String userPackageId = getUserPackageUniqueId(userId, packageName);
                 int killableState = usage.getKillableState();
                 if (killableState == KILLABLE_STATE_NEVER) {
                     mOveruseActionsByUserPackage.add(overuseAction);
@@ -363,8 +559,8 @@
                         usage.oldEnabledState = oldEnabledState;
                     }
                 } catch (RemoteException e) {
-                    Slogf.e(TAG, "Failed to disable application enabled setting for user %d, "
-                            + "package '%s'", userId, packageName);
+                    Slogf.e(CarWatchdogService.TAG, "Failed to disable application enabled setting "
+                            + "for user %d, package '%s'", userId, packageName);
                 }
                 mOveruseActionsByUserPackage.add(overuseAction);
             }
@@ -373,6 +569,9 @@
                         WatchdogPerfHandler::notifyActionsTakenOnOveruse, this));
             }
         }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Processed latest I/O overuse stats");
+        }
     }
 
     /** Notify daemon about the actions take on resource overuse */
@@ -387,9 +586,13 @@
         }
         try {
             mCarWatchdogDaemonHelper.actionTakenOnResourceOveruse(actions);
-        } catch (RemoteException e) {
-            Slogf.w(TAG, "Failed to notify car watchdog daemon of actions taken on "
-                    + "resource overuse: %s", e);
+        } catch (RemoteException | RuntimeException e) {
+            Slogf.w(CarWatchdogService.TAG, "Failed to notify car watchdog daemon of actions taken "
+                    + "on resource overuse: %s", e);
+        }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG,
+                    "Notified car watchdog daemon of actions taken on resource overuse");
         }
     }
 
@@ -401,7 +604,7 @@
             try {
                 listenerInfo.listener.onOveruse(resourceOveruseStats);
             } catch (RemoteException e) {
-                Slogf.e(TAG,
+                Slogf.e(CarWatchdogService.TAG,
                         "Failed to notify listener(uid %d, package '%s') on resource overuse: %s",
                         uid, resourceOveruseStats, e);
             }
@@ -415,11 +618,15 @@
             try {
                 systemListenerInfo.listener.onOveruse(resourceOveruseStats);
             } catch (RemoteException e) {
-                Slogf.e(TAG, "Failed to notify system listener(uid %d, pid: %d) of resource "
-                                + "overuse by package(uid %d, package '%s'): %s",
+                Slogf.e(CarWatchdogService.TAG, "Failed to notify system listener(uid %d, pid: %d) "
+                                + "of resource overuse by package(uid %d, package '%s'): %s",
                         systemListenerInfo.uid, systemListenerInfo.pid, uid, packageName, e);
             }
         }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG,
+                    "Notified resource overuse stats to listening applications");
+        }
     }
 
     private void checkAndHandleDateChangeLocked() {
@@ -443,7 +650,7 @@
                             usage.oldEnabledState,
                             /* flags= */ 0, usage.userId, mContext.getPackageName());
                 } catch (RemoteException e) {
-                    Slogf.e(TAG,
+                    Slogf.e(CarWatchdogService.TAG,
                             "Failed to reset enabled setting for disabled package '%s', user %d",
                             usage.packageName, usage.userId);
                 }
@@ -451,6 +658,9 @@
             /* TODO(b/170741935): Stash the old usage into SQLite DB storage. */
             usage.ioUsage.clear();
         }
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "Handled date change successfully");
+        }
     }
 
     private PackageResourceUsage cacheAndFetchUsageLocked(@UserIdInt int userId, String packageName,
@@ -458,19 +668,39 @@
         String key = getUserPackageUniqueId(userId, packageName);
         PackageResourceUsage usage = mUsageByUserPackage.getOrDefault(key,
                 new PackageResourceUsage(userId, packageName));
-        usage.update(internalStats);
+        usage.updateLocked(internalStats);
         mUsageByUserPackage.put(key, usage);
         return usage;
     }
 
     private boolean isRecurringOveruseLocked(PackageResourceUsage ioUsage) {
         /*
-         * TODO(b/170741935): Look up I/O overuse history and determine whether or not the package
+         * TODO(b/185287136): Look up I/O overuse history and determine whether or not the package
          *  has recurring I/O overuse behavior.
          */
         return false;
     }
 
+    private IoOveruseStats getIoOveruseStats(int userId, String packageName,
+            long minimumBytesWritten, @CarWatchdogManager.StatsPeriod int maxStatsPeriod) {
+        String key = getUserPackageUniqueId(userId, packageName);
+        PackageResourceUsage usage = mUsageByUserPackage.get(key);
+        if (usage == null) {
+            return null;
+        }
+        IoOveruseStats stats = usage.getIoOveruseStats();
+        long totalBytesWritten = stats != null ? stats.getTotalBytesWritten() : 0;
+        /*
+         * TODO(b/185431129): When maxStatsPeriod > current day, populate the historical stats
+         *  from the local database. Also handle the case where the package doesn't have current
+         *  day stats but has historical stats.
+         */
+        if (totalBytesWritten < minimumBytesWritten) {
+            return null;
+        }
+        return stats;
+    }
+
     private void addResourceOveruseListenerLocked(
             @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag,
             @NonNull IResourceOveruseListener listener,
@@ -495,20 +725,21 @@
         try {
             listenerInfo.linkToDeath();
         } catch (RemoteException e) {
-            Slogf.w(TAG, "Cannot add %s: linkToDeath to listener failed", listenerType);
+            Slogf.w(CarWatchdogService.TAG, "Cannot add %s: linkToDeath to listener failed",
+                    listenerType);
             return;
         }
 
         if (existingListenerInfo != null) {
-            Slogf.w(TAG, "Overwriting existing %s: pid %d, uid: %d", listenerType,
-                    existingListenerInfo.pid, existingListenerInfo.uid);
+            Slogf.w(CarWatchdogService.TAG, "Overwriting existing %s: pid %d, uid: %d",
+                    listenerType, existingListenerInfo.pid, existingListenerInfo.uid);
             existingListenerInfo.unlinkToDeath();
         }
 
 
         listenerInfosByUid.put(callingUid, listenerInfo);
-        if (mIsDebugEnabled) {
-            Slogf.d(TAG, "The %s (pid: %d, uid: %d) is added", listenerType,
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "The %s (pid: %d, uid: %d) is added", listenerType,
                     callingPid, callingUid);
         }
     }
@@ -522,14 +753,15 @@
 
         ResourceOveruseListenerInfo listenerInfo = listenerInfosByUid.get(callingUid, null);
         if (listenerInfo == null || listenerInfo.listener != listener) {
-            Slogf.w(TAG, "Cannot remove the %s: it has not been registered before", listenerType);
+            Slogf.w(CarWatchdogService.TAG,
+                    "Cannot remove the %s: it has not been registered before", listenerType);
             return;
         }
         listenerInfo.unlinkToDeath();
         listenerInfosByUid.remove(callingUid);
-        if (mIsDebugEnabled) {
-            Slogf.d(TAG, "The %s (pid: %d, uid: %d) is removed", listenerType, listenerInfo.pid,
-                    listenerInfo.uid);
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "The %s (pid: %d, uid: %d) is removed", listenerType,
+                    listenerInfo.pid, listenerInfo.uid);
         }
     }
 
@@ -561,9 +793,8 @@
 
     private static PerStateBytes toPerStateBytes(
             android.automotive.watchdog.PerStateBytes internalPerStateBytes) {
-        PerStateBytes perStateBytes = new PerStateBytes(internalPerStateBytes.foregroundBytes,
+        return new PerStateBytes(internalPerStateBytes.foregroundBytes,
                 internalPerStateBytes.backgroundBytes, internalPerStateBytes.garageModeBytes);
-        return perStateBytes;
     }
 
     private static long totalPerStateBytes(
@@ -575,7 +806,231 @@
                 internalPerStateBytes.backgroundBytes), internalPerStateBytes.garageModeBytes);
     }
 
-    private static final class PackageResourceUsage {
+    private static long getMinimumBytesWritten(
+            @CarWatchdogManager.MinimumStatsFlag int minimumStatsIoFlag) {
+        switch (minimumStatsIoFlag) {
+            case 0:
+                return 0;
+            case CarWatchdogManager.FLAG_MINIMUM_STATS_IO_1_MB:
+                return 1024 * 1024;
+            case CarWatchdogManager.FLAG_MINIMUM_STATS_IO_100_MB:
+                return 100 * 1024 * 1024;
+            case CarWatchdogManager.FLAG_MINIMUM_STATS_IO_1_GB:
+                return 1024 * 1024 * 1024;
+            default:
+                throw new IllegalArgumentException(
+                        "Must provide valid minimum stats flag for I/O resource");
+        }
+    }
+
+    private static android.automotive.watchdog.internal.ResourceOveruseConfiguration
+            toInternalResourceOveruseConfiguration(ResourceOveruseConfiguration config,
+            @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag) {
+        android.automotive.watchdog.internal.ResourceOveruseConfiguration internalConfig =
+                new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+        internalConfig.componentType = config.getComponentType();
+        internalConfig.safeToKillPackages = config.getSafeToKillPackages();
+        internalConfig.vendorPackagePrefixes = config.getVendorPackagePrefixes();
+        internalConfig.packageMetadata = new ArrayList<>();
+        for (Map.Entry<String, String> entry : config.getPackagesToAppCategoryTypes().entrySet()) {
+            if (entry.getKey().isEmpty()) {
+                continue;
+            }
+            PackageMetadata metadata = new PackageMetadata();
+            metadata.packageName = entry.getKey();
+            switch(entry.getValue()) {
+                case ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MAPS:
+                    metadata.appCategoryType = ApplicationCategoryType.MAPS;
+                    break;
+                case ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MEDIA:
+                    metadata.appCategoryType = ApplicationCategoryType.MEDIA;
+                    break;
+                default:
+                    continue;
+            }
+            internalConfig.packageMetadata.add(metadata);
+        }
+        internalConfig.resourceSpecificConfigurations = new ArrayList<>();
+        if ((resourceOveruseFlag & FLAG_RESOURCE_OVERUSE_IO) != 0
+                && config.getIoOveruseConfiguration() != null) {
+            internalConfig.resourceSpecificConfigurations.add(
+                    toResourceSpecificConfiguration(config.getComponentType(),
+                            config.getIoOveruseConfiguration()));
+        }
+        return internalConfig;
+    }
+
+    private static ResourceSpecificConfiguration
+            toResourceSpecificConfiguration(int componentType, IoOveruseConfiguration config) {
+        android.automotive.watchdog.internal.IoOveruseConfiguration internalConfig =
+                new android.automotive.watchdog.internal.IoOveruseConfiguration();
+        internalConfig.componentLevelThresholds = toPerStateIoOveruseThreshold(
+                toComponentTypeStr(componentType), config.getComponentLevelThresholds());
+        internalConfig.packageSpecificThresholds = toPerStateIoOveruseThresholds(
+                config.getPackageSpecificThresholds());
+        internalConfig.categorySpecificThresholds = toPerStateIoOveruseThresholds(
+                config.getAppCategorySpecificThresholds());
+        for (PerStateIoOveruseThreshold threshold : internalConfig.categorySpecificThresholds) {
+            switch(threshold.name) {
+                case ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MAPS:
+                    threshold.name = INTERNAL_APPLICATION_CATEGORY_TYPE_MAPS;
+                    break;
+                case ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MEDIA:
+                    threshold.name = INTERNAL_APPLICATION_CATEGORY_TYPE_MEDIA;
+                    break;
+                default:
+                    threshold.name = INTERNAL_APPLICATION_CATEGORY_TYPE_UNKNOWN;
+            }
+        }
+        internalConfig.systemWideThresholds = toInternalIoOveruseAlertThresholds(
+                config.getSystemWideThresholds());
+
+        ResourceSpecificConfiguration resourceSpecificConfig = new ResourceSpecificConfiguration();
+        resourceSpecificConfig.setIoOveruseConfiguration(internalConfig);
+        return resourceSpecificConfig;
+    }
+
+    @VisibleForTesting
+    static String toComponentTypeStr(int componentType) {
+        switch(componentType) {
+            case ComponentType.SYSTEM:
+                return "SYSTEM";
+            case ComponentType.VENDOR:
+                return "VENDOR";
+            case ComponentType.THIRD_PARTY:
+                return "THIRD_PARTY";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    private static List<PerStateIoOveruseThreshold> toPerStateIoOveruseThresholds(
+            Map<String, PerStateBytes> thresholds) {
+        List<PerStateIoOveruseThreshold> internalThresholds = new ArrayList<>();
+        for (Map.Entry<String, PerStateBytes> entry : thresholds.entrySet()) {
+            if (!entry.getKey().isEmpty()) {
+                internalThresholds.add(toPerStateIoOveruseThreshold(entry.getKey(),
+                        entry.getValue()));
+            }
+        }
+        return internalThresholds;
+    }
+
+    private static PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(String name,
+            PerStateBytes perStateBytes) {
+        PerStateIoOveruseThreshold threshold = new PerStateIoOveruseThreshold();
+        threshold.name = name;
+        threshold.perStateWriteBytes = new android.automotive.watchdog.PerStateBytes();
+        threshold.perStateWriteBytes.foregroundBytes = perStateBytes.getForegroundModeBytes();
+        threshold.perStateWriteBytes.backgroundBytes = perStateBytes.getBackgroundModeBytes();
+        threshold.perStateWriteBytes.garageModeBytes = perStateBytes.getGarageModeBytes();
+        return threshold;
+    }
+
+    private static List<android.automotive.watchdog.internal.IoOveruseAlertThreshold>
+            toInternalIoOveruseAlertThresholds(List<IoOveruseAlertThreshold> thresholds) {
+        List<android.automotive.watchdog.internal.IoOveruseAlertThreshold> internalThresholds =
+                new ArrayList<>();
+        for (IoOveruseAlertThreshold threshold : thresholds) {
+            if (threshold.getDurationInSeconds() == 0
+                    || threshold.getWrittenBytesPerSecond() == 0) {
+                continue;
+            }
+            android.automotive.watchdog.internal.IoOveruseAlertThreshold internalThreshold =
+                    new android.automotive.watchdog.internal.IoOveruseAlertThreshold();
+            internalThreshold.durationInSeconds = threshold.getDurationInSeconds();
+            internalThreshold.writtenBytesPerSecond = threshold.getWrittenBytesPerSecond();
+            internalThresholds.add(internalThreshold);
+        }
+        return internalThresholds;
+    }
+
+    private static ResourceOveruseConfiguration toResourceOveruseConfiguration(
+            android.automotive.watchdog.internal.ResourceOveruseConfiguration internalConfig,
+            @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag) {
+        Map<String, String> packagesToAppCategoryTypes = new ArrayMap<>();
+        for (PackageMetadata metadata : internalConfig.packageMetadata) {
+            String categoryTypeStr;
+            switch (metadata.appCategoryType) {
+                case ApplicationCategoryType.MAPS:
+                    categoryTypeStr = ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MAPS;
+                    break;
+                case ApplicationCategoryType.MEDIA:
+                    categoryTypeStr = ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MEDIA;
+                    break;
+                default:
+                    continue;
+            }
+            packagesToAppCategoryTypes.put(metadata.packageName, categoryTypeStr);
+        }
+        ResourceOveruseConfiguration.Builder configBuilder =
+                new ResourceOveruseConfiguration.Builder(
+                internalConfig.componentType,
+                internalConfig.safeToKillPackages,
+                internalConfig.vendorPackagePrefixes,
+                packagesToAppCategoryTypes);
+        for (ResourceSpecificConfiguration resourceSpecificConfig :
+                internalConfig.resourceSpecificConfigurations) {
+            if (resourceSpecificConfig.getTag()
+                    == ResourceSpecificConfiguration.ioOveruseConfiguration
+                    && (resourceOveruseFlag & FLAG_RESOURCE_OVERUSE_IO) != 0) {
+                configBuilder.setIoOveruseConfiguration(toIoOveruseConfiguration(
+                        resourceSpecificConfig.getIoOveruseConfiguration()));
+            }
+        }
+        return configBuilder.build();
+    }
+
+    private static IoOveruseConfiguration toIoOveruseConfiguration(
+            android.automotive.watchdog.internal.IoOveruseConfiguration internalConfig) {
+        PerStateBytes componentLevelThresholds =
+                toPerStateBytes(internalConfig.componentLevelThresholds.perStateWriteBytes);
+        Map<String, PerStateBytes> packageSpecificThresholds =
+                toPerStateBytesMap(internalConfig.packageSpecificThresholds);
+        Map<String, PerStateBytes> appCategorySpecificThresholds =
+                toPerStateBytesMap(internalConfig.categorySpecificThresholds);
+        replaceKey(appCategorySpecificThresholds, INTERNAL_APPLICATION_CATEGORY_TYPE_MAPS,
+                ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MAPS);
+        replaceKey(appCategorySpecificThresholds, INTERNAL_APPLICATION_CATEGORY_TYPE_MEDIA,
+                ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MEDIA);
+        List<IoOveruseAlertThreshold> systemWideThresholds =
+                toIoOveruseAlertThresholds(internalConfig.systemWideThresholds);
+
+        IoOveruseConfiguration.Builder configBuilder = new IoOveruseConfiguration.Builder(
+                componentLevelThresholds, packageSpecificThresholds, appCategorySpecificThresholds,
+                systemWideThresholds);
+        return configBuilder.build();
+    }
+
+    private static Map<String, PerStateBytes> toPerStateBytesMap(
+            List<PerStateIoOveruseThreshold> thresholds) {
+        Map<String, PerStateBytes> thresholdsMap = new ArrayMap<>();
+        for (PerStateIoOveruseThreshold threshold : thresholds) {
+            thresholdsMap.put(threshold.name, toPerStateBytes(threshold.perStateWriteBytes));
+        }
+        return thresholdsMap;
+    }
+
+    private static List<IoOveruseAlertThreshold> toIoOveruseAlertThresholds(
+            List<android.automotive.watchdog.internal.IoOveruseAlertThreshold> internalThresholds) {
+        List<IoOveruseAlertThreshold> thresholds = new ArrayList<>();
+        for (android.automotive.watchdog.internal.IoOveruseAlertThreshold internalThreshold
+                : internalThresholds) {
+            thresholds.add(new IoOveruseAlertThreshold(internalThreshold.durationInSeconds,
+                    internalThreshold.writtenBytesPerSecond));
+        }
+        return thresholds;
+    }
+
+    private static void replaceKey(Map<String, PerStateBytes> map, String oldKey, String newKey) {
+        PerStateBytes perStateBytes = map.get(oldKey);
+        if (perStateBytes != null) {
+            map.put(newKey, perStateBytes);
+            map.remove(oldKey);
+        }
+    }
+
+    private final class PackageResourceUsage {
         public final String packageName;
         public @UserIdInt final int userId;
         public final PackageIoUsage ioUsage;
@@ -583,15 +1038,17 @@
 
         private @KillableState int mKillableState;
 
+        /** Must be called only after acquiring {@link mLock} */
         PackageResourceUsage(@UserIdInt int userId, String packageName) {
             this.packageName = packageName;
             this.userId = userId;
             this.ioUsage = new PackageIoUsage();
             this.oldEnabledState = -1;
-            this.mKillableState = KILLABLE_STATE_YES;
+            this.mKillableState = mDefaultNotKillablePackages.contains(packageName)
+                    ? KILLABLE_STATE_NO : KILLABLE_STATE_YES;
         }
 
-        public void update(android.automotive.watchdog.IoOveruseStats internalStats) {
+        public void updateLocked(android.automotive.watchdog.IoOveruseStats internalStats) {
             if (!internalStats.killableOnOveruse) {
                 /*
                  * Killable value specified in the internal stats is provided by the native daemon.
@@ -600,20 +1057,28 @@
                  * vendor services and doesn't reflect the user choices. Thus if the internal stats
                  * specify the application is not killable, the application is not safe-to-kill.
                  */
-                this.mKillableState = KILLABLE_STATE_NEVER;
+                mKillableState = KILLABLE_STATE_NEVER;
+            } else if (mKillableState == KILLABLE_STATE_NEVER) {
+                /*
+                 * This case happens when a previously unsafe to kill system/vendor package was
+                 * recently marked as safe-to-kill so update the old state to the default value.
+                 */
+                mKillableState = mDefaultNotKillablePackages.contains(packageName)
+                        ? KILLABLE_STATE_NO : KILLABLE_STATE_YES;
             }
             ioUsage.update(internalStats);
         }
 
-        public ResourceOveruseStats getResourceOveruseStatsWithIo() {
-            IoOveruseStats ioOveruseStats = null;
-            if (ioUsage.hasUsage()) {
-                ioOveruseStats = ioUsage.getStatsBuilder().setKillableOnOveruse(
-                        mKillableState != PackageKillableState.KILLABLE_STATE_NEVER).build();
-            }
+        public ResourceOveruseStats.Builder getResourceOveruseStatsBuilder() {
+            return new ResourceOveruseStats.Builder(packageName, UserHandle.of(userId));
+        }
 
-            return new ResourceOveruseStats.Builder(packageName, UserHandle.of(userId))
-                    .setIoOveruseStats(ioOveruseStats).build();
+        public IoOveruseStats getIoOveruseStats() {
+            if (!ioUsage.hasUsage()) {
+                return null;
+            }
+            return ioUsage.getStatsBuilder().setKillableOnOveruse(
+                        mKillableState != KILLABLE_STATE_NEVER).build();
         }
 
         public @KillableState int getKillableState() {
@@ -621,12 +1086,30 @@
         }
 
         public boolean setKillableState(boolean isKillable) {
-            if (mKillableState == PackageKillableState.KILLABLE_STATE_NEVER) {
+            if (mKillableState == KILLABLE_STATE_NEVER) {
                 return false;
             }
             mKillableState = isKillable ? KILLABLE_STATE_YES : KILLABLE_STATE_NO;
             return true;
         }
+
+        public int syncAndFetchKillableStateLocked(int myComponentType) {
+            /*
+             * The killable state goes out-of-sync:
+             * 1. When the on-device safe-to-kill list is recently updated and the user package
+             * didn't have any resource usage so the native daemon didn't update the killable state.
+             * 2. When a package has no resource usage and is initialized outside of processing the
+             * latest resource usage stats.
+             */
+            if (myComponentType != ComponentType.THIRD_PARTY
+                    && !mSafeToKillPackages.contains(packageName)) {
+                mKillableState = KILLABLE_STATE_NEVER;
+            } else if (mKillableState == KILLABLE_STATE_NEVER) {
+                mKillableState = mDefaultNotKillablePackages.contains(packageName)
+                        ? KILLABLE_STATE_NO : KILLABLE_STATE_YES;
+            }
+            return mKillableState;
+        }
     }
 
     private static final class PackageIoUsage {
@@ -697,7 +1180,7 @@
 
         @Override
         public void binderDied() {
-            Slogf.w(TAG, "Resource overuse listener%s (pid: %d) died",
+            Slogf.w(CarWatchdogService.TAG, "Resource overuse listener%s (pid: %d) died",
                     isListenerForSystem ? " for system" : "", pid);
             onResourceOveruseListenerDeath(uid, isListenerForSystem);
             unlinkToDeath();
diff --git a/service/src/com/android/car/watchdog/WatchdogProcessHandler.java b/service/src/com/android/car/watchdog/WatchdogProcessHandler.java
index 59e76c7..2754755 100644
--- a/service/src/com/android/car/watchdog/WatchdogProcessHandler.java
+++ b/service/src/com/android/car/watchdog/WatchdogProcessHandler.java
@@ -37,7 +37,6 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
-import com.android.car.CarLog;
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.utils.Slogf;
 
@@ -47,11 +46,9 @@
  * Handles clients' health status checking and reporting the statuses to the watchdog daemon.
  */
 public final class WatchdogProcessHandler {
-    private static final String TAG = CarLog.tagFor(CarWatchdogService.class);
     private static final int[] ALL_TIMEOUTS =
             { TIMEOUT_CRITICAL, TIMEOUT_MODERATE, TIMEOUT_NORMAL };
 
-    private final boolean mIsDebugEnabled;
     private final ICarWatchdogServiceForSystem mWatchdogServiceForSystem;
     private final CarWatchdogDaemonHelper mCarWatchdogDaemonHelper;
     private final Handler mMainHandler = new Handler(Looper.getMainLooper());
@@ -85,8 +82,7 @@
     private final SparseBooleanArray mStoppedUser = new SparseBooleanArray();
 
     public WatchdogProcessHandler(ICarWatchdogServiceForSystem serviceImpl,
-            CarWatchdogDaemonHelper daemonHelper, boolean isDebugEnabled) {
-        mIsDebugEnabled = isDebugEnabled;
+            CarWatchdogDaemonHelper daemonHelper) {
         mWatchdogServiceForSystem = serviceImpl;
         mCarWatchdogDaemonHelper = daemonHelper;
     }
@@ -98,8 +94,8 @@
             mPingedClientMap.put(timeout, new SparseArray<ClientInfo>());
             mClientCheckInProgress.put(timeout, false);
         }
-        if (mIsDebugEnabled) {
-            Slogf.d(TAG, "WatchdogProcessHandler is initialized");
+        if (CarWatchdogService.DEBUG) {
+            Slogf.d(CarWatchdogService.TAG, "WatchdogProcessHandler is initialized");
         }
     }
 
@@ -136,14 +132,15 @@
         synchronized (mLock) {
             ArrayList<ClientInfo> clients = mClientMap.get(timeout);
             if (clients == null) {
-                Slogf.w(TAG, "Cannot register the client: invalid timeout");
+                Slogf.w(CarWatchdogService.TAG, "Cannot register the client: invalid timeout");
                 return;
             }
             IBinder binder = client.asBinder();
             for (int i = 0; i < clients.size(); i++) {
                 ClientInfo clientInfo = clients.get(i);
                 if (binder == clientInfo.client.asBinder()) {
-                    Slogf.w(TAG, "Cannot register the client: the client(pid: %d) has been already "
+                    Slogf.w(CarWatchdogService.TAG,
+                            "Cannot register the client: the client(pid: %d) has been already "
                             + "registered", clientInfo.pid);
                     return;
                 }
@@ -154,12 +151,13 @@
             try {
                 clientInfo.linkToDeath();
             } catch (RemoteException e) {
-                Slogf.w(TAG, "Cannot register the client: linkToDeath to the client failed");
+                Slogf.w(CarWatchdogService.TAG,
+                        "Cannot register the client: linkToDeath to the client failed");
                 return;
             }
             clients.add(clientInfo);
-            if (mIsDebugEnabled) {
-                Slogf.d(TAG, "Client(pid: %d) is registered", pid);
+            if (CarWatchdogService.DEBUG) {
+                Slogf.d(CarWatchdogService.TAG, "Client(pid: %d) is registered", pid);
             }
         }
     }
@@ -177,14 +175,16 @@
                     }
                     clientInfo.unlinkToDeath();
                     clients.remove(i);
-                    if (mIsDebugEnabled) {
-                        Slogf.d(TAG, "Client(pid: %d) is unregistered", clientInfo.pid);
+                    if (CarWatchdogService.DEBUG) {
+                        Slogf.d(CarWatchdogService.TAG, "Client(pid: %d) is unregistered",
+                                clientInfo.pid);
                     }
                     return;
                 }
             }
         }
-        Slogf.w(TAG, "Cannot unregister the client: the client has not been registered before");
+        Slogf.w(CarWatchdogService.TAG,
+                "Cannot unregister the client: the client has not been registered before");
         return;
     }
 
@@ -297,8 +297,8 @@
             try {
                 clientInfo.client.onCheckHealthStatus(clientInfo.sessionId, timeout);
             } catch (RemoteException e) {
-                Slogf.w(TAG, "Sending a ping message to client(pid: %d) failed: %s", clientInfo.pid,
-                        e);
+                Slogf.w(CarWatchdogService.TAG,
+                        "Sending a ping message to client(pid: %d) failed: %s", clientInfo.pid, e);
                 synchronized (mLock) {
                     pingedClients.remove(clientInfo.sessionId);
                 }
@@ -348,7 +348,8 @@
             try {
                 clientInfo.client.onPrepareProcessTermination();
             } catch (RemoteException e) {
-                Slogf.w(TAG, "Notifying onPrepareProcessTermination to client(pid: %d) failed: %s",
+                Slogf.w(CarWatchdogService.TAG,
+                        "Notifying onPrepareProcessTermination to client(pid: %d) failed: %s",
                         clientInfo.pid, e);
             }
         }
@@ -357,7 +358,8 @@
             mCarWatchdogDaemonHelper.tellCarWatchdogServiceAlive(
                     mWatchdogServiceForSystem, clientsNotResponding, sessionId);
         } catch (RemoteException | RuntimeException e) {
-            Slogf.w(TAG, "Cannot respond to car watchdog daemon (sessionId=%d): %s", sessionId, e);
+            Slogf.w(CarWatchdogService.TAG,
+                    "Cannot respond to car watchdog daemon (sessionId=%d): %s", sessionId, e);
         }
     }
 
@@ -380,7 +382,7 @@
             case TIMEOUT_NORMAL:
                 return "normal";
             default:
-                Slogf.w(TAG, "Unknown timeout value");
+                Slogf.w(CarWatchdogService.TAG, "Unknown timeout value");
                 return "unknown";
         }
     }
@@ -394,7 +396,7 @@
             case TIMEOUT_NORMAL:
                 return 10000L;
             default:
-                Slogf.w(TAG, "Unknown timeout value");
+                Slogf.w(CarWatchdogService.TAG, "Unknown timeout value");
                 return 10000L;
         }
     }
@@ -416,7 +418,7 @@
 
         @Override
         public void binderDied() {
-            Slogf.w(TAG, "Client(pid: %d) died", pid);
+            Slogf.w(CarWatchdogService.TAG, "Client(pid: %d) died", pid);
             onClientDeath(client, timeout);
         }
 
diff --git a/tests/CarEvsCameraPreviewApp/Android.bp b/tests/CarEvsCameraPreviewApp/Android.bp
index eb5f704..99f0505 100644
--- a/tests/CarEvsCameraPreviewApp/Android.bp
+++ b/tests/CarEvsCameraPreviewApp/Android.bp
@@ -13,6 +13,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_app {
     name: "CarEvsCameraPreviewApp",
 
diff --git a/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/jni/Android.bp b/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/jni/Android.bp
index 59cdedc..d06620a 100644
--- a/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/jni/Android.bp
+++ b/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/jni/Android.bp
@@ -14,6 +14,10 @@
 //
 //
 //#################################
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_library_shared {
     name: "libcarevsglrenderer_jni",
 
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/bluetooth_devices.xml b/tests/EmbeddedKitchenSinkApp/res/layout/bluetooth_devices.xml
new file mode 100644
index 0000000..c856233
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/bluetooth_devices.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:columnCount = "2">
+    <TextView
+      android:id="@+id/bluetooth_device"
+      android:layout_height="wrap_content"
+      android:layout_width="wrap_content"/>
+    <Button
+      android:id="@+id/bluetooth_pick_device"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:text="@string/bluetooth_pick_device"/>
+    <TableLayout
+      android:id="@+id/PairedDeviceTable"
+      android:layout_width="409dp"
+      android:layout_height="190dp"
+      tools:layout_editor_absoluteX="1dp"
+      tools:layout_editor_absoluteY="1dp"/>
+</GridLayout>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
index acbc2ad..01748a6 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
@@ -47,6 +47,7 @@
 import com.google.android.car.kitchensink.assistant.CarAssistantFragment;
 import com.google.android.car.kitchensink.audio.AudioTestFragment;
 import com.google.android.car.kitchensink.audio.CarAudioInputTestFragment;
+import com.google.android.car.kitchensink.bluetooth.BluetoothDeviceFragment;
 import com.google.android.car.kitchensink.bluetooth.BluetoothHeadsetFragment;
 import com.google.android.car.kitchensink.bluetooth.MapMceTestFragment;
 import com.google.android.car.kitchensink.carboard.KeyboardTestFragment;
@@ -173,6 +174,7 @@
             new FragmentMenuEntry("assistant", CarAssistantFragment.class),
             new FragmentMenuEntry("audio", AudioTestFragment.class),
             new FragmentMenuEntry("Audio Input", CarAudioInputTestFragment.class),
+            new FragmentMenuEntry("BT device", BluetoothDeviceFragment.class),
             new FragmentMenuEntry("BT headset", BluetoothHeadsetFragment.class),
             new FragmentMenuEntry("BT messaging", MapMceTestFragment.class),
             new FragmentMenuEntry("carapi", CarApiTestFragment.class),
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/BluetoothDeviceFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/BluetoothDeviceFragment.java
new file mode 100644
index 0000000..c1de700
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/BluetoothDeviceFragment.java
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+package com.google.android.car.kitchensink.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothDevicePicker;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.google.android.car.kitchensink.R;
+
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+public class BluetoothDeviceFragment extends Fragment {
+    private static final String TAG = "CAR.BLUETOOTH.KS";
+    BluetoothAdapter mBluetoothAdapter;
+    BluetoothDevice mPickedDevice;
+    Executor mExecutor;
+    BluetoothDeviceTypeChecker mDeviceTypeChecker;
+
+    TextView mPickedDeviceText;
+    Button mDevicePicker;
+    TableLayout mTableLayout;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.bluetooth_devices, container, false);
+        mDeviceTypeChecker = new BluetoothDeviceTypeChecker(getContext(), true);
+        mDevicePicker = v.findViewById(R.id.bluetooth_pick_device);
+        mTableLayout = v.findViewById(R.id.PairedDeviceTable);
+        mExecutor = new ThreadPerTaskExecutor();
+
+        // Pick a bluetooth device
+        mDevicePicker.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                launchDevicePicker();
+            }
+        });
+
+        return v;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        checkAllDevices();
+    }
+
+    void launchDevicePicker() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothDevicePicker.ACTION_DEVICE_SELECTED);
+        getContext().registerReceiver(mPickerReceiver, filter);
+
+        Intent intent = new Intent(BluetoothDevicePicker.ACTION_LAUNCH);
+        intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        getContext().startActivity(intent);
+    }
+
+    void checkAllDevices() {
+        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (bluetoothAdapter == null) {
+            Log.w(TAG, "Bluetooth Adapter not available");
+            return;
+        }
+        mTableLayout.removeAllViews();
+        Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
+        Context context = getContext();
+        for (BluetoothDevice device : bondedDevices) {
+            TableRow row = new TableRow(context);
+            TextView deviceName = new TextView(context);
+            deviceName.setText(device.getName());
+            TextView deviceType = new TextView(context);
+            deviceType.setText(Boolean.toString(mDeviceTypeChecker.isIapDevice(device)));
+            row.addView(deviceName);
+            row.addView(deviceType);
+            mTableLayout.addView(row);
+        }
+    }
+
+    private void addDeviceToTable(BluetoothDevice device, String value) {
+        getActivity().runOnUiThread(new Runnable() {
+            public void run() {
+                Context context = getContext();
+                TableRow row = new TableRow(context);
+                TextView deviceName = new TextView(context);
+                TextView deviceValue = new TextView(context);
+                deviceName.setText(device.getName());
+                deviceValue.setText(value);
+                row.addView(deviceName);
+                row.addView(deviceValue);
+                mTableLayout.addView(row);
+            }
+        });
+    }
+
+    private final BroadcastReceiver mPickerReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            Log.v(TAG, "mPickerReceiver got " + action);
+
+            if (BluetoothDevicePicker.ACTION_DEVICE_SELECTED.equals(action)) {
+                final BluetoothDevice device =
+                        intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                Log.v(TAG, "mPickerReceiver got " + device);
+                if (device == null) {
+                    Toast.makeText(getContext(), "No device selected", Toast.LENGTH_SHORT).show();
+                    return;
+                }
+                mExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        addDeviceToTable(device,
+                                Boolean.toString(mDeviceTypeChecker.isIapDevice(device)));
+                        Log.w(TAG, "Is iAP" + mDeviceTypeChecker.isIapDevice(device));
+                    }
+                });
+                Log.w(TAG, "Dispatched");
+                getContext().unregisterReceiver(mPickerReceiver);
+            }
+        }
+    };
+
+    private class ThreadPerTaskExecutor implements Executor {
+        public void execute(Runnable r) {
+            new Thread(r).start();
+        }
+    }
+}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/BluetoothDeviceTypeChecker.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/BluetoothDeviceTypeChecker.java
new file mode 100644
index 0000000..1523634
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/BluetoothDeviceTypeChecker.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+package com.google.android.car.kitchensink.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+public class BluetoothDeviceTypeChecker {
+    private static final ParcelUuid IAP_UUID =
+            ParcelUuid.fromString("00000000-deca-fade-deca-deafdecacafe");
+    private static final int MAX_SECONDS_TO_BLOCK = 10;
+    private static final String TAG = "BluetoothDeviceTypeChecker";
+
+    private final Context mContext;
+    private final boolean mAllowBlocking;
+    private final Object mLock = new Object();
+
+    CompletableFuture<ParcelUuid[]> mDeviceUUidsFuture;
+    BluetoothDevice mBluetoothDevice;
+
+    /**
+     * BluetoothDeviceTypeChecker
+     * Class designed to fetch and check UUID records for matches based on either cached or live
+     * records.  Live records are fetched if allowBlocking is enabled and there is nothing in the
+     * cache.  Paired devices should always have records in the cache if the BluetoothAdapter is on.
+     *
+     * @param context The context on which to receive updates if live records are necessary
+     * @param allowBlocking If cached SDP records are not available allow methods to block in a
+     *                     best effort of acquiring them.
+     */
+    public BluetoothDeviceTypeChecker(Context context, boolean allowBlocking) {
+        mContext = context;
+        if (mContext != null) {
+            mAllowBlocking = allowBlocking;
+        } else {
+            mAllowBlocking = false;
+        }
+    }
+
+    /**
+     * isIapDevice
+     * Check if device is indicating support for iAP
+     * @param device
+     * @return
+     */
+    public boolean isIapDevice(BluetoothDevice device) {
+        return deviceContainsUuid(device, IAP_UUID);
+    }
+
+    /**
+     * deviceContainsUuid
+     * Check if device contains a specific UUID record
+     * @param device to perform a lookup on
+     * @param uuid to check in the records
+     * @return
+     */
+    public boolean deviceContainsUuid(BluetoothDevice device, ParcelUuid uuid) {
+        if (device == null) return false;
+        if (uuid == null) return false;
+
+        synchronized (mLock) {
+            mBluetoothDevice = device;
+            ParcelUuid[] uuidsArray = device.getUuids();
+            if (mAllowBlocking && (uuidsArray == null || uuidsArray.length == 0)) {
+                uuidsArray = blockingFetchUuids(device);
+            }
+            if (uuidsArray == null || uuidsArray.length == 0) {
+                return false;
+            }
+            for (int i = 0; i < uuidsArray.length; i++) {
+                if (uuid.equals(uuidsArray[i])) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /*
+    Perform a blocking fetch of the UUIDs on specified BluetoothDevice
+     */
+    private ParcelUuid[] blockingFetchUuids(BluetoothDevice device) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothDevice.ACTION_UUID);
+        mContext.registerReceiver(mUuidReceiver, filter);
+        mDeviceUUidsFuture = new CompletableFuture<>();
+        if (!device.fetchUuidsWithSdp()) {
+            Log.w(TAG, "fetching UUIDs failed.");
+            mContext.unregisterReceiver(mUuidReceiver);
+            return new ParcelUuid[0];
+        }
+        try {
+            return mDeviceUUidsFuture.get(MAX_SECONDS_TO_BLOCK, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            mContext.unregisterReceiver(mUuidReceiver);
+            return new ParcelUuid[0];
+        }
+    }
+
+    /*
+    Broadcast receiver on which to receive updates to Bluetooth UUID records.
+     */
+    private BroadcastReceiver mUuidReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            BluetoothDevice device =
+                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            if (mBluetoothDevice.equals(device)
+                    && BluetoothDevice.ACTION_UUID.equals(intent.getAction())) {
+                mDeviceUUidsFuture.complete(device.getUuids());
+                mContext.unregisterReceiver(this);
+            }
+        }
+    };
+}
diff --git a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
index 2fb64d4..abafdf6 100644
--- a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
@@ -112,6 +112,23 @@
                     | VehicleArea.GLOBAL;
     private static final Integer[] FAKE_INT_ARRAY_VALUE = {1, 2};
 
+    private static final int INT_ARRAY_PROP_STATUS_ERROR =
+            0x1104 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.INT32_VEC
+                    | VehicleArea.GLOBAL;
+
+    private static final int BOOLEAN_PROP_STATUS_ERROR =
+            0x1105 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.BOOLEAN
+                    | VehicleArea.GLOBAL;
+    private static final boolean FAKE_BOOLEAN_PROPERTY_VALUE = true;
+    private static final int FLOAT_PROP_STATUS_UNAVAILABLE =
+            0x1106 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.FLOAT
+                    | VehicleArea.GLOBAL;
+    private static final float FAKE_FLOAT_PROPERTY_VALUE = 3f;
+    private static final int INT_PROP_STATUS_UNAVAILABLE =
+            0x1107 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.INT32
+                    | VehicleArea.GLOBAL;
+    private static final int FAKE_INT_PROPERTY_VALUE = 3;
+
     // Vendor properties for testing exceptions.
     private static final int PROP_CAUSE_STATUS_CODE_TRY_AGAIN =
             0x1201 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.INT32 | VehicleArea.GLOBAL;
@@ -161,8 +178,10 @@
     private void setUpTargetSdk() {
         if (mTestName.getMethodName().endsWith("InQ")) {
             getContext().getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.Q;
-        } else if (mTestName.getMethodName().endsWith("InR")) {
+        } else if (mTestName.getMethodName().endsWith("AfterQ")) {
             getContext().getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.R;
+        } else if (mTestName.getMethodName().endsWith("AfterR")) {
+            getContext().getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.S;
         }
     }
 
@@ -192,6 +211,10 @@
                 case CUSTOM_SEAT_INT_PROP_1:
                 case CUSTOM_SEAT_INT_PROP_2:
                 case CUSTOM_GLOBAL_INT_ARRAY_PROP:
+                case INT_ARRAY_PROP_STATUS_ERROR:
+                case BOOLEAN_PROP_STATUS_ERROR:
+                case INT_PROP_STATUS_UNAVAILABLE:
+                case FLOAT_PROP_STATUS_UNAVAILABLE:
                 case VehiclePropertyIds.INFO_VIN:
                     break;
                 default:
@@ -235,6 +258,64 @@
     }
 
     /**
+     * Test {@link CarPropertyManager#getIntArrayProperty(int, int)} when vhal returns a value with
+     * error status.
+     */
+    @Test
+    public void testGetIntArrayPropertyWithErrorStatusAfterR() {
+        Truth.assertThat(getContext().getApplicationInfo().targetSdkVersion)
+                .isGreaterThan(Build.VERSION_CODES.R);
+        mManager.setProperty(Integer[].class, INT_ARRAY_PROP_STATUS_ERROR,
+                VehicleArea.GLOBAL, FAKE_INT_ARRAY_VALUE);
+        assertThrows(CarInternalErrorException.class,
+                () -> mManager.getIntArrayProperty(INT_ARRAY_PROP_STATUS_ERROR,
+                        VehicleArea.GLOBAL));
+    }
+
+    /**
+     * Test {@link CarPropertyManager#getIntProperty(int, int)} when vhal returns a value with
+     * unavailable status.
+     */
+    @Test
+    public void testGetIntPropertyWithUnavailableStatusAfterR() {
+        Truth.assertThat(getContext().getApplicationInfo().targetSdkVersion)
+                .isGreaterThan(Build.VERSION_CODES.R);
+        mManager.setProperty(Integer.class, INT_PROP_STATUS_UNAVAILABLE,
+                VehicleArea.GLOBAL, FAKE_INT_PROPERTY_VALUE);
+        assertThrows(PropertyNotAvailableException.class,
+                () -> mManager.getIntProperty(INT_PROP_STATUS_UNAVAILABLE, VehicleArea.GLOBAL));
+
+    }
+
+    /**
+     * Test {@link CarPropertyManager#getBooleanProperty(int, int)} when vhal returns a value with
+     * error status.
+     */
+    @Test
+    public void testGetBooleanPropertyWithErrorStatusAfterR() {
+        Truth.assertThat(getContext().getApplicationInfo().targetSdkVersion)
+                .isGreaterThan(Build.VERSION_CODES.R);
+        mManager.setProperty(Boolean.class, BOOLEAN_PROP_STATUS_ERROR,
+                VehicleArea.GLOBAL, FAKE_BOOLEAN_PROPERTY_VALUE);
+        assertThrows(CarInternalErrorException.class,
+                () -> mManager.getBooleanProperty(BOOLEAN_PROP_STATUS_ERROR, VehicleArea.GLOBAL));
+    }
+
+    /**
+     * Test {@link CarPropertyManager#getFloatProperty(int, int)} when vhal returns a value with
+     * unavailable status.
+     */
+    @Test
+    public void testGetFloatPropertyWithUnavailableStatusAfterR() {
+        Truth.assertThat(getContext().getApplicationInfo().targetSdkVersion)
+                .isGreaterThan(Build.VERSION_CODES.R);
+        mManager.setProperty(Float.class, FLOAT_PROP_STATUS_UNAVAILABLE,
+                VehicleArea.GLOBAL, FAKE_FLOAT_PROPERTY_VALUE);
+        assertThrows(PropertyNotAvailableException.class,
+                () -> mManager.getFloatProperty(FLOAT_PROP_STATUS_UNAVAILABLE, VehicleArea.GLOBAL));
+    }
+
+    /**
      * Test {@link CarPropertyManager#getProperty(Class, int, int)}
      */
     @Test
@@ -373,9 +454,9 @@
     }
 
     @Test
-    public void testSetterExceptionsInR() {
+    public void testSetterExceptionsAfterQ() {
         Truth.assertThat(getContext().getApplicationInfo().targetSdkVersion)
-                .isEqualTo(Build.VERSION_CODES.R);
+                .isGreaterThan(Build.VERSION_CODES.Q);
 
         assertThrows(PropertyAccessDeniedSecurityException.class,
                 ()->mManager.setProperty(Integer.class, PROP_CAUSE_STATUS_CODE_ACCESS_DENIED,
@@ -402,39 +483,74 @@
         assertThrows(IllegalStateException.class,
                 ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_ACCESS_DENIED,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(IllegalStateException.class,
+                ()->mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_ACCESS_DENIED,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
         assertThrows(IllegalArgumentException.class,
                 ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_INVALID_ARG,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(IllegalArgumentException.class,
+                ()->mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_INVALID_ARG,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
         assertThrows(IllegalStateException.class,
                 ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
         assertThrows(IllegalStateException.class,
+                ()->mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
+        assertThrows(IllegalStateException.class,
                 ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_INTERNAL_ERROR,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(IllegalStateException.class,
+                ()->mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_INTERNAL_ERROR,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
         Truth.assertThat(mManager.getProperty(PROP_CAUSE_STATUS_CODE_TRY_AGAIN,
                 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL)).isNull();
     }
 
     @Test
-    public void testGetterExceptionsInR() {
+    public void testGetterExceptionsAfterQ() {
         Truth.assertThat(getContext().getApplicationInfo().targetSdkVersion)
-                .isEqualTo(Build.VERSION_CODES.R);
+                .isAtLeast(Build.VERSION_CODES.R);
 
         assertThrows(PropertyAccessDeniedSecurityException.class,
                 () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_ACCESS_DENIED,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(PropertyAccessDeniedSecurityException.class,
+                () -> mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_ACCESS_DENIED,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
         assertThrows(IllegalArgumentException.class,
                 () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_INVALID_ARG,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(IllegalArgumentException.class,
+                () -> mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_INVALID_ARG,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
         assertThrows(PropertyNotAvailableAndRetryException.class,
                 () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_TRY_AGAIN,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(PropertyNotAvailableAndRetryException.class,
+                () -> mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_TRY_AGAIN,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
         assertThrows(PropertyNotAvailableException.class,
                 () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(PropertyNotAvailableException.class,
+                () -> mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+
         assertThrows(CarInternalErrorException.class,
                 () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_INTERNAL_ERROR,
                         VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
+        assertThrows(CarInternalErrorException.class,
+                () -> mManager.getIntProperty(PROP_CAUSE_STATUS_CODE_INTERNAL_ERROR,
+                        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
     }
 
     @Test
@@ -616,6 +732,11 @@
         addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_3, handler).setConfigArray(CONFIG_ARRAY_3);
         addProperty(CUSTOM_GLOBAL_INT_ARRAY_PROP, handler);
 
+        addProperty(INT_ARRAY_PROP_STATUS_ERROR, handler);
+        addProperty(INT_PROP_STATUS_UNAVAILABLE, handler);
+        addProperty(FLOAT_PROP_STATUS_UNAVAILABLE, handler);
+        addProperty(BOOLEAN_PROP_STATUS_ERROR, handler);
+
         VehiclePropValue tempValue = new VehiclePropValue();
         tempValue.value.floatValues.add(INIT_TEMP_VALUE);
         tempValue.prop = VehiclePropertyIds.HVAC_TEMPERATURE_SET;
@@ -640,7 +761,7 @@
         @Override
         public synchronized void onPropertySet(VehiclePropValue value) {
             // Simulate HalClient.set() behavior.
-            int statusCode = mapPropertyToStatusCode(value.prop);
+            int statusCode = mapPropertyToVhalStatusCode(value.prop);
             if (statusCode == VehicleHalStatusCode.STATUS_INVALID_ARG) {
                 throw new IllegalArgumentException();
             }
@@ -655,17 +776,23 @@
         @Override
         public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
             // Simulate HalClient.get() behavior.
-            int statusCode = mapPropertyToStatusCode(value.prop);
-            if (statusCode == VehicleHalStatusCode.STATUS_INVALID_ARG) {
+            int vhalStatusCode = mapPropertyToVhalStatusCode(value.prop);
+            if (vhalStatusCode == VehicleHalStatusCode.STATUS_INVALID_ARG) {
                 throw new IllegalArgumentException();
             }
 
-            if (statusCode != VehicleHalStatusCode.STATUS_OK) {
-                throw new ServiceSpecificException(statusCode);
+            if (vhalStatusCode != VehicleHalStatusCode.STATUS_OK) {
+                throw new ServiceSpecificException(vhalStatusCode);
             }
 
+            int propertyStatus = mapPropertyToCarPropertyStatusCode(value.prop);
             VehiclePropValue currentValue = mMap.get(value.prop);
-            return currentValue != null ? currentValue : value;
+            if (currentValue == null) {
+                return value;
+            } else {
+                currentValue.status = propertyStatus;
+            }
+            return currentValue;
         }
 
         @Override
@@ -684,7 +811,7 @@
         return VehiclePropertyIds.toString(propertyId) + " (" + propertyId + ")";
     }
 
-    private static int mapPropertyToStatusCode(int propId) {
+    private static int mapPropertyToVhalStatusCode(int propId) {
         switch (propId) {
             case PROP_CAUSE_STATUS_CODE_TRY_AGAIN:
                 return VehicleHalStatusCode.STATUS_TRY_AGAIN;
@@ -701,6 +828,19 @@
         }
     }
 
+    private static int mapPropertyToCarPropertyStatusCode(int propId) {
+        switch (propId) {
+            case INT_ARRAY_PROP_STATUS_ERROR:
+            case BOOLEAN_PROP_STATUS_ERROR:
+                return CarPropertyValue.STATUS_ERROR;
+            case INT_PROP_STATUS_UNAVAILABLE:
+            case FLOAT_PROP_STATUS_UNAVAILABLE:
+                return CarPropertyValue.STATUS_UNAVAILABLE;
+            default:
+                return CarPropertyValue.STATUS_AVAILABLE;
+        }
+    }
+
     private static class TestErrorCallback implements CarPropertyManager.CarPropertyEventCallback {
 
         private static final String CALLBACK_TAG = "ErrorEventTest";
diff --git a/tests/carservice_test/src/com/android/car/cluster/ClusterHomeManagerTest.java b/tests/carservice_test/src/com/android/car/cluster/ClusterHomeManagerTest.java
index c0e20f2d..611efd4 100644
--- a/tests/carservice_test/src/com/android/car/cluster/ClusterHomeManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/cluster/ClusterHomeManagerTest.java
@@ -68,8 +68,10 @@
     private static final int UI_TYPE_2 = 2;
     private static final byte[] UI_AVAILABILITY = new byte[] {(byte) 1, (byte) 0, (byte) 1};
 
-    private static final int WIDTH = 800;
-    private static final int HEIGHT = 600;
+    private static final int BOUNDS_LEFT = 0;
+    private static final int BOUNDS_TOP = 1;
+    private static final int BOUNDS_RIGHT = 800;
+    private static final int BOUNDS_BOTTOM = 601;
     private static final int INSET_LEFT = 20;
     private static final int INSET_TOP = 10;
     private static final int INSET_RIGHT = 780;
@@ -189,13 +191,16 @@
     @Test
     public void testClusterState() throws InterruptedException {
         getMockedVehicleHal().injectEvent(createDisplayStateEvent(
-                DISPLAY_ON, WIDTH, HEIGHT, INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM));
+                DISPLAY_ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM,
+                INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM));
         mCallbackReceived.await(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
 
         assertThat(mState).isNotNull();
         assertThat(mState.on).isEqualTo(true);
-        assertThat(mState.width).isEqualTo(WIDTH);
-        assertThat(mState.height).isEqualTo(HEIGHT);
+        assertThat(mState.bounds.left).isEqualTo(BOUNDS_LEFT);
+        assertThat(mState.bounds.top).isEqualTo(BOUNDS_TOP);
+        assertThat(mState.bounds.right).isEqualTo(BOUNDS_RIGHT);
+        assertThat(mState.bounds.bottom).isEqualTo(BOUNDS_BOTTOM);
         assertThat(mState.insets.left).isEqualTo(INSET_LEFT);
         assertThat(mState.insets.top).isEqualTo(INSET_TOP);
         assertThat(mState.insets.right).isEqualTo(INSET_RIGHT);
@@ -208,8 +213,7 @@
         assertThat(state2).isNotNull();
         // The class generated from aidl doesn't have the proper equals() method yet.
         assertThat(state2.on).isEqualTo(mState.on);
-        assertThat(state2.width).isEqualTo(mState.width);
-        assertThat(state2.height).isEqualTo(mState.height);
+        assertThat(state2.bounds).isEqualTo(mState.bounds);
         assertThat(state2.insets).isEqualTo(mState.insets);
     }
 
@@ -220,7 +224,7 @@
 
         VehiclePropValue value = mPropertyHandler.peek(VehicleProperty.CLUSTER_REPORT_STATE);
         assertThat(value.prop).isEqualTo(VehicleProperty.CLUSTER_REPORT_STATE);
-        assertThat(value.value.int32Values.subList(7, 9)).containsExactly(UI_TYPE_1, UI_TYPE_2);
+        assertThat(value.value.int32Values.subList(9, 11)).containsExactly(UI_TYPE_1, UI_TYPE_2);
         assertThat(value.value.bytes).containsExactly(
                 (Byte) UI_AVAILABILITY[0], (Byte) UI_AVAILABILITY[1], (Byte) UI_AVAILABILITY[2]);
     }
@@ -334,17 +338,20 @@
         return event;
     }
 
-    private static VehiclePropValue createDisplayStateEvent(int onOff, int width, int height,
-            int left, int top, int right, int bottom) {
+    private static VehiclePropValue createDisplayStateEvent(int onOff,
+            int boundsLeft, int boundsTop, int boundsRight, int boundsBottom,
+            int insetsLeft, int insetsTop, int insetSRight, int insetSBottom) {
         VehiclePropValue event = new VehiclePropValue();
         event.prop = CLUSTER_DISPLAY_STATE;
         event.value.int32Values.add(onOff);
-        event.value.int32Values.add(width);
-        event.value.int32Values.add(height);
-        event.value.int32Values.add(left);
-        event.value.int32Values.add(top);
-        event.value.int32Values.add(right);
-        event.value.int32Values.add(bottom);
+        event.value.int32Values.add(boundsLeft);
+        event.value.int32Values.add(boundsTop);
+        event.value.int32Values.add(boundsRight);
+        event.value.int32Values.add(boundsBottom);
+        event.value.int32Values.add(insetsLeft);
+        event.value.int32Values.add(insetsTop);
+        event.value.int32Values.add(insetSRight);
+        event.value.int32Values.add(insetSBottom);
         return event;
     }
 }
diff --git a/tests/carservice_unit_test/src/android/car/test/mocks/JavaMockitoHelperTest.java b/tests/carservice_unit_test/src/android/car/test/mocks/JavaMockitoHelperTest.java
new file mode 100644
index 0000000..f83deee
--- /dev/null
+++ b/tests/carservice_unit_test/src/android/car/test/mocks/JavaMockitoHelperTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package android.car.test.mocks;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public final class JavaMockitoHelperTest {
+
+    private static final long TIMEOUT_MS = 1_000L;
+
+    @Test
+    public void testAwait_Semaphore() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(1);
+
+        JavaMockitoHelper.await(semaphore, TIMEOUT_MS);
+
+        assertThat(semaphore.availablePermits()).isEqualTo(0);
+    }
+
+    @Test
+    public void testAwait_CountDownLatch() throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        new Thread(() -> latch.countDown(), "testAwait_CountDownLatch").start();
+
+        JavaMockitoHelper.await(latch, TIMEOUT_MS);
+
+        assertThat(latch.getCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testSilentAwait_notCalled() {
+        CountDownLatch latch = new CountDownLatch(1);
+
+        assertThat(JavaMockitoHelper.silentAwait(latch, 5L)).isFalse();
+        assertThat(latch.getCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void testSilentAwait_called() {
+        CountDownLatch latch = new CountDownLatch(1);
+        new Thread(() -> latch.countDown(), "testSilentAwait_called").start();
+
+        assertThat(JavaMockitoHelper.silentAwait(latch, TIMEOUT_MS)).isTrue();
+        assertThat(latch.getCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetResult() throws InterruptedException, ExecutionException, TimeoutException {
+        Future<String> future = mock(Future.class);
+        when(future.get(anyLong(), any())).thenReturn("done");
+
+        assertThat(JavaMockitoHelper.getResult(future)).isEqualTo("done");
+    }
+
+    @Test
+    public void testGetResult_withCustomTimeout()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        Future<String> future = mock(Future.class);
+        when(future.get(anyLong(), any(TimeUnit.class))).thenReturn("done");
+
+        assertThat(JavaMockitoHelper.getResult(future, TIMEOUT_MS)).isEqualTo("done");
+        verify(future).get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+    }
+}
diff --git a/tests/carservice_unit_test/src/android/car/test/util/SyncAnswerTest.java b/tests/carservice_unit_test/src/android/car/test/mocks/SyncAnswerTest.java
similarity index 97%
rename from tests/carservice_unit_test/src/android/car/test/util/SyncAnswerTest.java
rename to tests/carservice_unit_test/src/android/car/test/mocks/SyncAnswerTest.java
index 2e26e7e..4847588 100644
--- a/tests/carservice_unit_test/src/android/car/test/util/SyncAnswerTest.java
+++ b/tests/carservice_unit_test/src/android/car/test/mocks/SyncAnswerTest.java
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
-package android.car.test.util;
+package android.car.test.mocks;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
-import android.car.test.mocks.SyncAnswer;
-
 import org.junit.Before;
 import org.junit.Test;
 
diff --git a/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java b/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java
index d682969..92dfb9a 100644
--- a/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java
+++ b/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java
@@ -20,11 +20,15 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
+import android.automotive.watchdog.internal.ComponentType;
 import android.automotive.watchdog.internal.ICarWatchdog;
 import android.automotive.watchdog.internal.ICarWatchdogMonitor;
 import android.automotive.watchdog.internal.ICarWatchdogServiceForSystem;
@@ -32,6 +36,7 @@
 import android.automotive.watchdog.internal.PackageIoOveruseStats;
 import android.automotive.watchdog.internal.PackageResourceOveruseAction;
 import android.automotive.watchdog.internal.PowerCycle;
+import android.automotive.watchdog.internal.ResourceOveruseConfiguration;
 import android.automotive.watchdog.internal.StateType;
 import android.os.Binder;
 import android.os.IBinder;
@@ -47,6 +52,7 @@
 import org.mockito.quality.Strictness;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -154,6 +160,31 @@
     }
 
     @Test
+    public void testIndirectCall_updateResourceOveruseConfigurations() throws Exception {
+        ResourceOveruseConfiguration config = new ResourceOveruseConfiguration();
+        config.componentType = ComponentType.SYSTEM;
+        List<ResourceOveruseConfiguration> configs = new ArrayList<>(Collections.singleton(config));
+
+        mCarWatchdogDaemonHelper.updateResourceOveruseConfigurations(configs);
+
+        verify(mFakeCarWatchdog).updateResourceOveruseConfigurations(eq(configs));
+    }
+
+    @Test
+    public void testIndirectCall_getResourceOveruseConfigurations() throws Exception {
+        ResourceOveruseConfiguration config = new ResourceOveruseConfiguration();
+        config.componentType = ComponentType.SYSTEM;
+        List<ResourceOveruseConfiguration> expected =
+                new ArrayList<>(Collections.singleton(config));
+        when(mFakeCarWatchdog.getResourceOveruseConfigurations()).thenReturn(expected);
+
+        List<ResourceOveruseConfiguration> actual =
+                mCarWatchdogDaemonHelper.getResourceOveruseConfigurations();
+
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
     public void testIndirectCall_actionTakenOnResourceOveruse() throws Exception {
         List<PackageResourceOveruseAction> actions = new ArrayList<>();
 
diff --git a/tests/carservice_unit_test/src/com/android/car/admin/CarDevicePolicyServiceTest.java b/tests/carservice_unit_test/src/com/android/car/admin/CarDevicePolicyServiceTest.java
index da1eb72..ed37a9b 100644
--- a/tests/carservice_unit_test/src/com/android/car/admin/CarDevicePolicyServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/admin/CarDevicePolicyServiceTest.java
@@ -26,6 +26,8 @@
 import android.car.test.mocks.AbstractExtendedMockitoTestCase;
 import android.car.user.UserCreationResult;
 import android.car.user.UserRemovalResult;
+import android.car.user.UserStartResult;
+import android.car.user.UserStopResult;
 import android.content.pm.UserInfo;
 import android.content.pm.UserInfo.UserInfoFlag;
 import android.os.UserManager;
@@ -44,11 +46,13 @@
 
     private CarDevicePolicyService mService;
 
-    private AndroidFuture<UserRemovalResult> mUserRemovalResult =
-            new AndroidFuture<UserRemovalResult>();
+    private AndroidFuture<UserRemovalResult> mUserRemovalResult = new AndroidFuture<>();
 
-    private AndroidFuture<UserCreationResult> mUserCreationResult =
-            new AndroidFuture<UserCreationResult>();
+    private AndroidFuture<UserCreationResult> mUserCreationResult = new AndroidFuture<>();
+
+    private AndroidFuture<UserStartResult> mUserStartResult = new AndroidFuture<>();
+
+    private AndroidFuture<UserStopResult> mUserStopResult = new AndroidFuture<>();
 
     @Before
     public void setFixtures() {
@@ -104,4 +108,18 @@
         verify(mCarUserService).createUser(eq("name"), eq(userType), eq(flags),
                 /* timeoutMs= */ anyInt(), eq(mUserCreationResult));
     }
+
+    @Test
+    public void testStartUserInBackground() {
+        mService.startUserInBackground(42, mUserStartResult);
+
+        verify(mCarUserService).startUserInBackground(42, mUserStartResult);
+    }
+
+    @Test
+    public void testStopUser() {
+        mService.stopUser(42, mUserStopResult);
+
+        verify(mCarUserService).stopUser(42, mUserStopResult);
+    }
 }
diff --git a/tests/carservice_unit_test/src/com/android/car/hal/ClusterHalServiceTest.java b/tests/carservice_unit_test/src/com/android/car/hal/ClusterHalServiceTest.java
index 21d99a8..5b47294 100644
--- a/tests/carservice_unit_test/src/com/android/car/hal/ClusterHalServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/hal/ClusterHalServiceTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.graphics.Insets;
+import android.graphics.Rect;
 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
 
 import com.android.car.hal.ClusterHalService.ClusterHalEventCallback;
@@ -55,8 +56,10 @@
     private static final int UI_TYPE_2 = 2;
     private static final byte[] UI_AVAILABILITY = new byte[] {(byte) 1, (byte) 1, (byte) 0};
 
-    private static final int WIDTH = 800;
-    private static final int HEIGHT = 600;
+    private static final int BOUNDS_LEFT = 0;
+    private static final int BOUNDS_TOP = 1;
+    private static final int BOUNDS_RIGHT = 800;
+    private static final int BOUNDS_BOTTOM = 601;
     private static final int INSET_LEFT = 20;
     private static final int INSET_TOP = 10;
     private static final int INSET_RIGHT = 780;
@@ -71,8 +74,7 @@
 
     int mUiType = NOT_ASSIGNED;
     int mOnOff = NOT_ASSIGNED;
-    int mWidth = NOT_ASSIGNED;
-    int mHeight = NOT_ASSIGNED;
+    Rect mBounds = null;
     Insets mInsets = null;
 
     private final ClusterHalEventCallback mHalEventListener = new ClusterHalEventCallback() {
@@ -80,10 +82,9 @@
             mUiType = uiType;
         }
 
-        public void onDisplayState(int onOff, int width, int height, Insets insets) {
+        public void onDisplayState(int onOff, Rect bounds, Insets insets) {
             mOnOff = onOff;
-            mWidth = width;
-            mHeight = height;
+            mBounds = bounds;
             mInsets = insets;
         }
     };
@@ -162,17 +163,20 @@
         return event;
     }
 
-    private static VehiclePropValue createDisplayStateEvent(int onOff, int width, int height,
-            int left, int top, int right, int bottom) {
+    private static VehiclePropValue createDisplayStateEvent(int onOff,
+            int boundsLeft, int boundsTop, int boundsRight, int boundsBottom,
+            int insetsLeft, int insetsTop, int insetSRight, int insetSBottom) {
         VehiclePropValue event = new VehiclePropValue();
         event.prop = CLUSTER_DISPLAY_STATE;
         event.value.int32Values.add(onOff);
-        event.value.int32Values.add(width);
-        event.value.int32Values.add(height);
-        event.value.int32Values.add(left);
-        event.value.int32Values.add(top);
-        event.value.int32Values.add(right);
-        event.value.int32Values.add(bottom);
+        event.value.int32Values.add(boundsLeft);
+        event.value.int32Values.add(boundsTop);
+        event.value.int32Values.add(boundsRight);
+        event.value.int32Values.add(boundsBottom);
+        event.value.int32Values.add(insetsLeft);
+        event.value.int32Values.add(insetsTop);
+        event.value.int32Values.add(insetSRight);
+        event.value.int32Values.add(insetSBottom);
         return event;
     }
 
@@ -207,12 +211,14 @@
     @Test
     public void testOnDisplayState() {
         mClusterHalService.onHalEvents(Arrays.asList(
-                createDisplayStateEvent(ON, WIDTH, HEIGHT,
+                createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM,
                         INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM)));
 
         assertThat(mOnOff).isEqualTo(ON);
-        assertThat(mWidth).isEqualTo(WIDTH);
-        assertThat(mHeight).isEqualTo(HEIGHT);
+        assertThat(mBounds.left).isEqualTo(BOUNDS_LEFT);
+        assertThat(mBounds.top).isEqualTo(BOUNDS_TOP);
+        assertThat(mBounds.right).isEqualTo(BOUNDS_RIGHT);
+        assertThat(mBounds.bottom).isEqualTo(BOUNDS_BOTTOM);
         assertThat(mInsets.left).isEqualTo(INSET_LEFT);
         assertThat(mInsets.top).isEqualTo(INSET_TOP);
         assertThat(mInsets.right).isEqualTo(INSET_RIGHT);
@@ -220,14 +226,13 @@
     }
 
     @Test
-    public void testOnDisplayState_DontAcceptPartialDontCare_Height() {
+    public void testOnDisplayState_DontAcceptPartialDontCare_Bounds() {
         mClusterHalService.onHalEvents(Arrays.asList(
-                createDisplayStateEvent(ON, WIDTH, DONT_CARE,
+                createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, DONT_CARE,
                         INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM)));
 
         assertThat(mOnOff).isEqualTo(ON);
-        assertThat(mWidth).isEqualTo(NOT_ASSIGNED);
-        assertThat(mHeight).isEqualTo(NOT_ASSIGNED);
+        assertThat(mBounds).isNull();
         assertThat(mInsets.left).isEqualTo(INSET_LEFT);
         assertThat(mInsets.top).isEqualTo(INSET_TOP);
         assertThat(mInsets.right).isEqualTo(INSET_RIGHT);
@@ -237,12 +242,14 @@
     @Test
     public void testOnDisplayState_DontAcceptPartialDontCare_Inset() {
         mClusterHalService.onHalEvents(Arrays.asList(
-                createDisplayStateEvent(ON, WIDTH, HEIGHT,
+                createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM,
                         INSET_LEFT, INSET_TOP, INSET_RIGHT, DONT_CARE)));
 
         assertThat(mOnOff).isEqualTo(ON);
-        assertThat(mWidth).isEqualTo(WIDTH);
-        assertThat(mHeight).isEqualTo(HEIGHT);
+        assertThat(mBounds.left).isEqualTo(BOUNDS_LEFT);
+        assertThat(mBounds.top).isEqualTo(BOUNDS_TOP);
+        assertThat(mBounds.right).isEqualTo(BOUNDS_RIGHT);
+        assertThat(mBounds.bottom).isEqualTo(BOUNDS_BOTTOM);
         assertThat(mInsets).isNull();
     }
 
@@ -251,12 +258,11 @@
         mClusterHalService.setCallback(null);
 
         mClusterHalService.onHalEvents(Arrays.asList(
-                createDisplayStateEvent(ON, WIDTH, HEIGHT,
+                createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM,
                         INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM)));
 
         assertThat(mOnOff).isEqualTo(NOT_ASSIGNED);
-        assertThat(mWidth).isEqualTo(NOT_ASSIGNED);
-        assertThat(mHeight).isEqualTo(NOT_ASSIGNED);
+        assertThat(mBounds).isNull();
         assertThat(mInsets).isNull();
     }
 
@@ -265,25 +271,26 @@
         mClusterHalService.takeProperties(Arrays.asList());
 
         mClusterHalService.onHalEvents(Arrays.asList(
-                createDisplayStateEvent(ON, WIDTH, HEIGHT,
+                createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM,
                         INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM)));
 
         assertThat(mOnOff).isEqualTo(NOT_ASSIGNED);
-        assertThat(mWidth).isEqualTo(NOT_ASSIGNED);
-        assertThat(mHeight).isEqualTo(NOT_ASSIGNED);
+        assertThat(mBounds).isNull();
         assertThat(mInsets).isNull();
     }
 
     @Test
     public void testReportState() {
-        mClusterHalService.reportState(ON, WIDTH, HEIGHT,
+        mClusterHalService.reportState(
+                ON, new Rect(BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM),
                 Insets.of(INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM),
                 UI_TYPE_1, UI_TYPE_2, UI_AVAILABILITY);
 
         verify(mVehicleHal).set(mPropCaptor.capture());
         VehiclePropValue prop = mPropCaptor.getValue();
         assertThat(prop.prop).isEqualTo(CLUSTER_REPORT_STATE);
-        assertThat(prop.value.int32Values).containsExactly(ON, WIDTH, HEIGHT,
+        assertThat(prop.value.int32Values).containsExactly(
+                ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM,
                 INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM, UI_TYPE_1, UI_TYPE_2);
         assertThat(prop.value.bytes).containsExactly(
                 (Byte) UI_AVAILABILITY[0], (Byte) UI_AVAILABILITY[1], (Byte) UI_AVAILABILITY[2]);
@@ -293,7 +300,8 @@
     public void testReportState_noProperties() {
         mClusterHalService.takeProperties(Arrays.asList());
 
-        mClusterHalService.reportState(ON, WIDTH, HEIGHT,
+        mClusterHalService.reportState(
+                ON, new Rect(BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM),
                 Insets.of(INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM),
                 UI_TYPE_1, UI_TYPE_2, UI_AVAILABILITY);
 
diff --git a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
index adafb57..4620c81 100644
--- a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
@@ -72,6 +72,8 @@
 import android.car.user.UserCreationResult;
 import android.car.user.UserIdentificationAssociationResponse;
 import android.car.user.UserRemovalResult;
+import android.car.user.UserStartResult;
+import android.car.user.UserStopResult;
 import android.car.user.UserSwitchResult;
 import android.car.userlib.HalCallback;
 import android.car.userlib.HalCallback.HalCallbackStatus;
@@ -528,9 +530,9 @@
         UserInfo user2Info = new UserInfo(user2, "user2", NO_USER_INFO_FLAGS);
         UserInfo user3Info = new UserInfo(user3, "user3", NO_USER_INFO_FLAGS);
 
-        doReturn(user1Info).when(mMockedUserManager).getUserInfo(user1);
-        doReturn(user2Info).when(mMockedUserManager).getUserInfo(user2);
-        doReturn(user3Info).when(mMockedUserManager).getUserInfo(user3);
+        when(mMockedUserManager.getUserInfo(user1)).thenReturn(user1Info);
+        when(mMockedUserManager.getUserInfo(user2)).thenReturn(user2Info);
+        when(mMockedUserManager.getUserInfo(user3)).thenReturn(user3Info);
 
         mockGetCurrentUser(user1);
         sendUserUnlockedEvent(UserHandle.USER_SYSTEM);
@@ -540,40 +542,108 @@
         sendUserUnlockedEvent(user1);
         mockGetCurrentUser(user3);
         sendUserUnlockedEvent(user3);
+        mockStopUserWithDelayedLocking(user3, ActivityManager.USER_OP_IS_CURRENT);
 
-        assertEquals(new Integer[]{user3, user2},
-                mCarUserService.getBackgroundUsersToRestart().toArray());
+        assertThat(mCarUserService.getBackgroundUsersToRestart()).containsExactly(user2, user3);
 
-        doReturn(true).when(mMockedIActivityManager).startUserInBackground(user2);
-        doReturn(true).when(mMockedIActivityManager).unlockUser(user2,
-                null, null, null);
-        assertEquals(new Integer[]{user2},
-                mCarUserService.startAllBackgroundUsers().toArray());
+        when(mMockedIActivityManager.startUserInBackground(user2)).thenReturn(true);
+        when(mMockedIActivityManager.unlockUser(user2, null, null, null)).thenReturn(true);
+        assertThat(mCarUserService.startAllBackgroundUsers()).containsExactly(user2);
         sendUserUnlockedEvent(user2);
-        assertEquals(new Integer[]{user3, user2},
-                mCarUserService.getBackgroundUsersToRestart().toArray());
+        assertThat(mCarUserService.getBackgroundUsersToRestart()).containsExactly(user2, user3);
 
-        doReturn(ActivityManager.USER_OP_SUCCESS).when(mMockedIActivityManager).stopUser(user2,
-                true, null);
+        when(mMockedIActivityManager.stopUser(user2, true, null))
+                .thenReturn(ActivityManager.USER_OP_SUCCESS);
         // should not stop the current fg user
-        assertFalse(mCarUserService.stopBackgroundUser(user3));
-        assertTrue(mCarUserService.stopBackgroundUser(user2));
-        assertEquals(new Integer[]{user3, user2},
-                mCarUserService.getBackgroundUsersToRestart().toArray());
-        assertEquals(new Integer[]{user3, user2},
-                mCarUserService.getBackgroundUsersToRestart().toArray());
+        assertThat(mCarUserService.stopBackgroundUser(user3)).isFalse();
+        assertThat(mCarUserService.stopBackgroundUser(user2)).isTrue();
+        assertThat(mCarUserService.getBackgroundUsersToRestart()).containsExactly(user2, user3);
+        assertThat(mCarUserService.getBackgroundUsersToRestart()).containsExactly(user2, user3);
     }
 
     @Test
-    public void testStopBackgroundUserForSystemUser() {
-        assertFalse(mCarUserService.stopBackgroundUser(UserHandle.USER_SYSTEM));
+    public void testStopUser_success() throws Exception {
+        int userId = 101;
+        UserInfo userInfo = new UserInfo(userId, "user101", NO_USER_INFO_FLAGS);
+        mockStopUserWithDelayedLocking(userId, ActivityManager.USER_OP_SUCCESS);
+
+        AndroidFuture<UserStopResult> userStopResult = new AndroidFuture<>();
+        mCarUserService.stopUser(userId, userStopResult);
+
+        assertThat(getResult(userStopResult).getStatus())
+                .isEqualTo(UserStopResult.STATUS_SUCCESSFUL);
+        assertThat(getResult(userStopResult).isSuccess()).isTrue();
     }
 
     @Test
-    public void testStopBackgroundUserForFgUser() throws RemoteException {
-        int user1 = 101;
-        mockGetCurrentUser(user1);
-        assertFalse(mCarUserService.stopBackgroundUser(UserHandle.USER_SYSTEM));
+    public void testStopUser_fail() throws Exception {
+        int userId = 101;
+        UserInfo userInfo = new UserInfo(userId, "user101", NO_USER_INFO_FLAGS);
+        mockStopUserWithDelayedLockingThrowsRemoteException(userId);
+
+        AndroidFuture<UserStopResult> userStopResult = new AndroidFuture<>();
+        mCarUserService.stopUser(userId, userStopResult);
+
+        assertThat(getResult(userStopResult).getStatus())
+                .isEqualTo(UserStopResult.STATUS_ANDROID_FAILURE);
+        assertThat(getResult(userStopResult).isSuccess()).isFalse();
+    }
+
+    @Test
+    public void testStopUser_userDoesNotExist() throws Exception {
+        int userId = 101;
+        UserInfo userInfo = new UserInfo(userId, "user101", NO_USER_INFO_FLAGS);
+        mockStopUserWithDelayedLocking(userId, ActivityManager.USER_OP_UNKNOWN_USER);
+
+        AndroidFuture<UserStopResult> userStopResult = new AndroidFuture<>();
+        mCarUserService.stopUser(userId, userStopResult);
+
+        assertThat(getResult(userStopResult).getStatus())
+                .isEqualTo(UserStopResult.STATUS_USER_DOES_NOT_EXIST);
+        assertThat(getResult(userStopResult).isSuccess()).isFalse();
+    }
+
+    @Test
+    public void testStopUser_systemUser() throws Exception {
+        mockStopUserWithDelayedLocking(
+                UserHandle.USER_SYSTEM, ActivityManager.USER_OP_ERROR_IS_SYSTEM);
+
+        AndroidFuture<UserStopResult> userStopResult = new AndroidFuture<>();
+        mCarUserService.stopUser(UserHandle.USER_SYSTEM, userStopResult);
+
+        assertThat(getResult(userStopResult).getStatus())
+                .isEqualTo(UserStopResult.STATUS_FAILURE_SYSTEM_USER);
+        assertThat(getResult(userStopResult).isSuccess()).isFalse();
+    }
+
+    @Test
+    public void testStopUser_currentUser() throws Exception {
+        int userId = 101;
+        UserInfo userInfo = new UserInfo(userId, "user101", NO_USER_INFO_FLAGS);
+        mockStopUserWithDelayedLocking(userId, ActivityManager.USER_OP_IS_CURRENT);
+
+        AndroidFuture<UserStopResult> userStopResult = new AndroidFuture<>();
+        mCarUserService.stopUser(userId, userStopResult);
+
+        assertThat(getResult(userStopResult).getStatus())
+                .isEqualTo(UserStopResult.STATUS_FAILURE_CURRENT_USER);
+        assertThat(getResult(userStopResult).isSuccess()).isFalse();
+    }
+
+    @Test
+    public void testStopBackgroundUserForSystemUser() throws Exception {
+        mockStopUserWithDelayedLocking(
+                UserHandle.USER_SYSTEM, ActivityManager.USER_OP_ERROR_IS_SYSTEM);
+
+        assertThat(mCarUserService.stopBackgroundUser(UserHandle.USER_SYSTEM)).isFalse();
+    }
+
+    @Test
+    public void testStopBackgroundUserForFgUser() throws Exception {
+        int userId = 101;
+        mockStopUserWithDelayedLocking(userId, ActivityManager.USER_OP_IS_CURRENT);
+
+        assertThat(mCarUserService.stopBackgroundUser(userId)).isFalse();
     }
 
     @Test
@@ -1775,6 +1845,69 @@
     }
 
     @Test
+    public void testStartUserInBackground_success() throws Exception {
+        int userId = 101;
+        UserInfo userInfo = new UserInfo(userId, "user1", NO_USER_INFO_FLAGS);
+        mockCurrentUser(mRegularUser);
+        mockUmGetUserInfo(mMockedUserManager, userInfo);
+        mockAmStartUserInBackground(userId, true);
+
+        AndroidFuture<UserStartResult> userStartResult = new AndroidFuture<>();
+        mCarUserService.startUserInBackground(userId, userStartResult);
+
+        assertThat(getResult(userStartResult).getStatus())
+                .isEqualTo(UserStartResult.STATUS_SUCCESSFUL);
+        assertThat(getResult(userStartResult).isSuccess()).isTrue();
+    }
+
+    @Test
+    public void testStartUserInBackground_fail() throws Exception {
+        int userId = 101;
+        UserInfo userInfo = new UserInfo(userId, "user1", NO_USER_INFO_FLAGS);
+        mockCurrentUser(mRegularUser);
+        mockUmGetUserInfo(mMockedUserManager, userInfo);
+        mockAmStartUserInBackground(userId, false);
+
+        AndroidFuture<UserStartResult> userStartResult = new AndroidFuture<>();
+        mCarUserService.startUserInBackground(userId, userStartResult);
+
+        assertThat(getResult(userStartResult).getStatus())
+                .isEqualTo(UserStartResult.STATUS_ANDROID_FAILURE);
+        assertThat(getResult(userStartResult).isSuccess()).isFalse();
+    }
+
+    @Test
+    public void testStartUserInBackground_currentUser() throws Exception {
+        int userId = 101;
+        UserInfo userInfo = new UserInfo(userId, "user1", NO_USER_INFO_FLAGS);
+        mockGetCurrentUser(userId);
+        mockUmGetUserInfo(mMockedUserManager, userInfo);
+        mockAmStartUserInBackground(userId, true);
+
+        AndroidFuture<UserStartResult> userStartResult = new AndroidFuture<>();
+        mCarUserService.startUserInBackground(userId, userStartResult);
+
+        assertThat(getResult(userStartResult).getStatus())
+                .isEqualTo(UserStartResult.STATUS_SUCCESSFUL_USER_IS_CURRENT_USER);
+        assertThat(getResult(userStartResult).isSuccess()).isTrue();
+    }
+
+    @Test
+    public void testStartUserInBackground_userDoesNotExist() throws Exception {
+        int userId = 101;
+        mockCurrentUser(mRegularUser);
+        when(mMockedUserManager.getUserInfo(userId)).thenReturn(null);
+        mockAmStartUserInBackground(userId, true);
+
+        AndroidFuture<UserStartResult> userStartResult = new AndroidFuture<>();
+        mCarUserService.startUserInBackground(userId, userStartResult);
+
+        assertThat(getResult(userStartResult).getStatus())
+                .isEqualTo(UserStartResult.STATUS_USER_DOES_NOT_EXIST);
+        assertThat(getResult(userStartResult).isSuccess()).isFalse();
+    }
+
+    @Test
     public void testIsHalSupported() throws Exception {
         when(mUserHal.isSupported()).thenReturn(true);
         assertThat(mCarUserService.isUserHalSupported()).isTrue();
@@ -2286,6 +2419,11 @@
         mockGetCurrentUser(user.id);
     }
 
+    private void mockAmStartUserInBackground(@UserIdInt int userId, boolean result)
+            throws Exception {
+        when(mMockedIActivityManager.startUserInBackground(userId)).thenReturn(result);
+    }
+
     private void mockAmSwitchUser(@NonNull UserInfo user, boolean result) throws Exception {
         when(mMockedIActivityManager.switchUser(user.id)).thenReturn(result);
     }
@@ -2318,6 +2456,18 @@
                 /* listener= */ null);
     }
 
+    private void mockStopUserWithDelayedLocking(@UserIdInt int userId, int result)
+            throws Exception {
+        when(mMockedIActivityManager.stopUserWithDelayedLocking(userId, true, null))
+                .thenReturn(result);
+    }
+
+    private void mockStopUserWithDelayedLockingThrowsRemoteException(@UserIdInt int userId)
+            throws Exception {
+        when(mMockedIActivityManager.stopUserWithDelayedLocking(userId, true, null))
+                .thenThrow(new RemoteException());
+    }
+
     private void mockHalGetInitialInfo(@UserIdInt int currentUserId,
             @NonNull InitialUserInfoResponse response) {
         UsersInfo usersInfo = newUsersInfo(currentUserId);
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
index fa4c30f..cdb3452 100644
--- a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
@@ -18,6 +18,7 @@
 
 import static android.automotive.watchdog.internal.ResourceOveruseActionType.KILLED;
 import static android.automotive.watchdog.internal.ResourceOveruseActionType.NOT_KILLED;
+import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetAliveUsers;
 import static android.car.test.mocks.AndroidMockitoHelper.mockUmGetAllUsers;
 import static android.car.watchdog.CarWatchdogManager.TIMEOUT_CRITICAL;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
@@ -51,13 +52,21 @@
 import android.automotive.watchdog.internal.PackageIdentifier;
 import android.automotive.watchdog.internal.PackageInfo;
 import android.automotive.watchdog.internal.PackageIoOveruseStats;
+import android.automotive.watchdog.internal.PackageMetadata;
 import android.automotive.watchdog.internal.PackageResourceOveruseAction;
+import android.automotive.watchdog.internal.PerStateIoOveruseThreshold;
+import android.automotive.watchdog.internal.ResourceSpecificConfiguration;
 import android.automotive.watchdog.internal.UidType;
 import android.car.test.mocks.AbstractExtendedMockitoTestCase;
 import android.car.watchdog.CarWatchdogManager;
 import android.car.watchdog.ICarWatchdogServiceCallback;
 import android.car.watchdog.IResourceOveruseListener;
+import android.car.watchdog.IoOveruseAlertThreshold;
+import android.car.watchdog.IoOveruseConfiguration;
 import android.car.watchdog.IoOveruseStats;
+import android.car.watchdog.PackageKillableState;
+import android.car.watchdog.PerStateBytes;
+import android.car.watchdog.ResourceOveruseConfiguration;
 import android.car.watchdog.ResourceOveruseStats;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -66,13 +75,16 @@
 import android.content.pm.UserInfo;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.SparseArray;
-import android.util.SparseBooleanArray;
+
+import com.android.internal.util.function.TriConsumer;
 
 import com.google.common.truth.Correspondence;
 
@@ -89,6 +101,8 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * <p>This class contains unit tests for the {@link CarWatchdogService}.
@@ -102,9 +116,9 @@
 
     @Mock private Context mMockContext;
     @Mock private PackageManager mMockPackageManager;
-    @Mock private UserManager mUserManager;
-    @Mock private IBinder mBinder;
-    @Mock private ICarWatchdog mCarWatchdogDaemon;
+    @Mock private UserManager mMockUserManager;
+    @Mock private IBinder mMockBinder;
+    @Mock private ICarWatchdog mMockCarWatchdogDaemon;
 
     private CarWatchdogService mCarWatchdogService;
     private ICarWatchdogServiceForSystem mWatchdogServiceForSystemImpl;
@@ -135,7 +149,7 @@
     @Test
     public void testCarWatchdogServiceHealthCheck() throws Exception {
         mWatchdogServiceForSystemImpl.checkIfAlive(123456, TIMEOUT_CRITICAL);
-        verify(mCarWatchdogDaemon,
+        verify(mMockCarWatchdogDaemon,
                 timeout(MAX_WAIT_TIME_MS)).tellCarWatchdogServiceAlive(
                         eq(mWatchdogServiceForSystemImpl), any(int[].class), eq(123456));
     }
@@ -178,6 +192,204 @@
     }
 
     @Test
+    public void testGetResourceOveruseStats() throws Exception {
+        SparseArray<String> packageNamesByUid = new SparseArray<>();
+        packageNamesByUid.put(Binder.getCallingUid(), mMockContext.getPackageName());
+        injectUidToPackageNameMapping(packageNamesByUid);
+
+        List<PackageIoOveruseStats> packageIoOveruseStats = new ArrayList<>(
+                Collections.singletonList(
+                    constructPackageIoOveruseStats(
+                            Binder.getCallingUid(), /* shouldNotify= */false,
+                            constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                    /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                                    /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                    /* totalOveruses= */2)))
+        );
+        mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
+
+        ResourceOveruseStats expectedStats =
+                constructResourceOveruseStats(packageNamesByUid.keyAt(0),
+                        packageNamesByUid.valueAt(0), packageIoOveruseStats.get(0).ioOveruseStats);
+
+        ResourceOveruseStats actualStats = mCarWatchdogService.getResourceOveruseStats(
+                CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                CarWatchdogManager.STATS_PERIOD_CURRENT_DAY);
+
+        assertWithMessage("Expected: " + expectedStats.toString() + "\nActual: "
+                + actualStats.toString())
+                .that(ResourceOveruseStatsSubject.isEquals(actualStats, expectedStats)).isTrue();
+    }
+
+    @Test
+    public void testFailsGetResourceOveruseStatsWithInvalidArgs() throws Exception {
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getResourceOveruseStats(/* resourceOveruseFlag= */0,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getResourceOveruseStats(
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, /* maxStatsPeriod= */0));
+    }
+
+    @Test
+    public void testGetAllResourceOveruseStatsWithNoMinimum() throws Exception {
+        SparseArray<String> packageNamesByUid = new SparseArray<>();
+        packageNamesByUid.put(1103456, "third_party_package");
+        packageNamesByUid.put(1201278, "vendor_package.critical");
+        injectUidToPackageNameMapping(packageNamesByUid);
+
+        List<PackageIoOveruseStats> packageIoOveruseStats = new ArrayList<>(Arrays.asList(
+                constructPackageIoOveruseStats(packageNamesByUid.keyAt(0), /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */true,
+                                /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2)),
+                constructPackageIoOveruseStats(packageNamesByUid.keyAt(1), /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                /* remainingWriteBytes= */constructPerStateBytes(450, 120, 340),
+                                /* writtenBytes= */constructPerStateBytes(5000, 6000, 9000),
+                                /* totalOveruses= */2))));
+        mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
+
+        List<ResourceOveruseStats> expectedStats = new ArrayList<>(Arrays.asList(
+                constructResourceOveruseStats(packageNamesByUid.keyAt(0),
+                        packageNamesByUid.valueAt(0), packageIoOveruseStats.get(0).ioOveruseStats),
+                constructResourceOveruseStats(packageNamesByUid.keyAt(1),
+                        packageNamesByUid.valueAt(1), packageIoOveruseStats.get(1).ioOveruseStats))
+        );
+
+        List<ResourceOveruseStats> actualStats = mCarWatchdogService.getAllResourceOveruseStats(
+                CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, /* minimumStatsFlag= */0,
+                CarWatchdogManager.STATS_PERIOD_CURRENT_DAY);
+
+        ResourceOveruseStatsSubject.assertThat(actualStats)
+                .containsExactlyElementsIn(expectedStats);
+    }
+
+    @Test
+    public void testFailsGetAllResourceOveruseStatsWithInvalidArgs() throws Exception {
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getAllResourceOveruseStats(0, /* minimumStatsFlag= */0,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getAllResourceOveruseStats(
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                        CarWatchdogManager.FLAG_MINIMUM_STATS_IO_1_MB
+                                | CarWatchdogManager.FLAG_MINIMUM_STATS_IO_100_MB,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getAllResourceOveruseStats(
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, /* minimumStatsFlag= */1 << 5,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getAllResourceOveruseStats(
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, /* minimumStatsFlag= */0,
+                        /* maxStatsPeriod= */0));
+    }
+
+    @Test
+    public void testGetAllResourceOveruseStatsWithMinimum() throws Exception {
+        SparseArray<String> packageNamesByUid = new SparseArray<>();
+        packageNamesByUid.put(1103456, "third_party_package");
+        packageNamesByUid.put(1201278, "vendor_package.critical");
+        injectUidToPackageNameMapping(packageNamesByUid);
+
+        List<PackageIoOveruseStats> packageIoOveruseStats = new ArrayList<>(Arrays.asList(
+                constructPackageIoOveruseStats(packageNamesByUid.keyAt(0), /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */true,
+                                /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2)),
+                constructPackageIoOveruseStats(packageNamesByUid.keyAt(1), /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                /* remainingWriteBytes= */constructPerStateBytes(450, 120, 340),
+                                /* writtenBytes= */constructPerStateBytes(7000000, 6000, 9000),
+                                /* totalOveruses= */2))));
+        mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
+
+        List<ResourceOveruseStats> expectedStats = new ArrayList<>(Arrays.asList(
+                constructResourceOveruseStats(packageNamesByUid.keyAt(1),
+                        packageNamesByUid.valueAt(1), packageIoOveruseStats.get(1).ioOveruseStats))
+        );
+
+        List<ResourceOveruseStats> actualStats = mCarWatchdogService.getAllResourceOveruseStats(
+                CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                CarWatchdogManager.FLAG_MINIMUM_STATS_IO_1_MB,
+                CarWatchdogManager.STATS_PERIOD_CURRENT_DAY);
+
+        ResourceOveruseStatsSubject.assertThat(actualStats)
+                .containsExactlyElementsIn(expectedStats);
+    }
+
+    @Test
+    public void testGetResourceOveruseStatsForUserPackage() throws Exception {
+        SparseArray<String> packageNamesByUid = new SparseArray<>();
+        packageNamesByUid.put(1103456, "third_party_package");
+        packageNamesByUid.put(1201278, "vendor_package.critical");
+        injectUidToPackageNameMapping(packageNamesByUid);
+
+        List<PackageIoOveruseStats> packageIoOveruseStats = new ArrayList<>(Arrays.asList(
+                constructPackageIoOveruseStats(packageNamesByUid.keyAt(0), /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */true,
+                                /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2)),
+                constructPackageIoOveruseStats(packageNamesByUid.keyAt(1), /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                /* remainingWriteBytes= */constructPerStateBytes(450, 120, 340),
+                                /* writtenBytes= */constructPerStateBytes(500, 600, 900),
+                                /* totalOveruses= */2))));
+        mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
+
+        ResourceOveruseStats expectedStats =
+                constructResourceOveruseStats(packageNamesByUid.keyAt(1),
+                        packageNamesByUid.valueAt(1), packageIoOveruseStats.get(1).ioOveruseStats);
+
+        ResourceOveruseStats actualStats =
+                mCarWatchdogService.getResourceOveruseStatsForUserPackage(
+                        "vendor_package.critical", new UserHandle(12),
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY);
+
+        assertWithMessage("Expected: " + expectedStats.toString() + "\nActual: "
+                + actualStats.toString())
+                .that(ResourceOveruseStatsSubject.isEquals(actualStats, expectedStats)).isTrue();
+    }
+
+    @Test
+    public void testFailsGetResourceOveruseStatsForUserPackageWithInvalidArgs() throws Exception {
+        assertThrows(NullPointerException.class,
+                () -> mCarWatchdogService.getResourceOveruseStatsForUserPackage(
+                        /* packageName= */null, new UserHandle(10),
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(NullPointerException.class,
+                () -> mCarWatchdogService.getResourceOveruseStatsForUserPackage("some.package",
+                        /* userHandle= */null, CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getResourceOveruseStatsForUserPackage("some.package",
+                        UserHandle.ALL, CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getResourceOveruseStatsForUserPackage("some.package",
+                        new UserHandle(10), /* resourceOveruseFlag= */0,
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getResourceOveruseStatsForUserPackage("some.package",
+                        new UserHandle(10), CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                        /* maxStatsPeriod= */0));
+    }
+
+    @Test
     public void testAddResourceOveruseListenerThrowsWithInvalidFlag() throws Exception {
         IResourceOveruseListener mockListener = createMockResourceOveruseListener();
         assertThrows(IllegalArgumentException.class, () -> {
@@ -203,8 +415,9 @@
                 Collections.singletonList(constructPackageIoOveruseStats(
                         callingUid, /* shouldNotify= */true,
                         constructInternalIoOveruseStats(/* killableOnOveruse= */true,
-                                constructPerStateBytes(20, 20, 20),
-                                constructPerStateBytes(100, 200, 300), /* totalOveruses= */2))));
+                                /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2))));
 
         mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
 
@@ -246,8 +459,9 @@
                 Collections.singletonList(constructPackageIoOveruseStats(
                         callingUid, /* shouldNotify= */true,
                         constructInternalIoOveruseStats(/* killableOnOveruse= */true,
-                                constructPerStateBytes(20, 20, 20),
-                                constructPerStateBytes(100, 200, 300), /* totalOveruses= */2))));
+                                /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2))));
 
         mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
 
@@ -264,6 +478,308 @@
     }
 
     @Test
+    public void testSetKillablePackageAsUserWithPackageStats() throws Exception {
+        mockUmGetAliveUsers(mMockUserManager, 11, 12);
+        injectPackageInfos(new ArrayList<>(Arrays.asList("third_party_package",
+                "vendor_package.critical")));
+
+        SparseArray<String> packageNamesByUid = new SparseArray<>();
+        packageNamesByUid.put(1103456, "third_party_package");
+        packageNamesByUid.put(1101278, "vendor_package.critical");
+        injectIoOveruseStatsForPackages(packageNamesByUid,
+                new ArraySet<>(Collections.singletonList("third_party_package")));
+
+        UserHandle userHandle = new UserHandle(11);
+
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", userHandle,
+                /* isKillable= */ true);
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        userHandle, /* isKillable= */ true));
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(userHandle)).containsExactly(
+                        new PackageKillableState("third_party_package", 11,
+                                PackageKillableState.KILLABLE_STATE_YES),
+                        new PackageKillableState("vendor_package.critical", 11,
+                                PackageKillableState.KILLABLE_STATE_NEVER));
+
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", userHandle,
+                /* isKillable= */ false);
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        userHandle, /* isKillable= */ false));
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(userHandle)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_NO),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+    }
+
+    @Test
+    public void testSetKillablePackageAsUserWithNoPackageStats() throws Exception {
+        mockUmGetAliveUsers(mMockUserManager, 11, 12);
+        injectPackageInfos(new ArrayList<>(Arrays.asList("third_party_package",
+                "vendor_package.critical")));
+
+        UserHandle userHandle = new UserHandle(11);
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", userHandle,
+                /* isKillable= */ true);
+        mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        userHandle, /* isKillable= */ true);
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(userHandle)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", userHandle,
+                /* isKillable= */ false);
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        userHandle, /* isKillable= */ false));
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(userHandle)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_NO),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+    }
+
+    @Test
+    public void testSetKillablePackageAsUserForAllUsersWithPackageStats() throws Exception {
+        mockUmGetAliveUsers(mMockUserManager, 11, 12);
+        injectPackageInfos(new ArrayList<>(Arrays.asList("third_party_package",
+                "vendor_package.critical")));
+
+        SparseArray<String> packageNamesByUid = new SparseArray<>();
+        packageNamesByUid.put(1103456, "third_party_package");
+        packageNamesByUid.put(1101278, "vendor_package.critical");
+        injectIoOveruseStatsForPackages(packageNamesByUid,
+                new ArraySet<>(Collections.singletonList("third_party_package")));
+
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", UserHandle.ALL,
+                /* isKillable= */ true);
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        UserHandle.ALL, /* isKillable= */ true));
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER),
+                new PackageKillableState("third_party_package", 12,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 12,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", UserHandle.ALL,
+                /* isKillable= */ false);
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        UserHandle.ALL, /* isKillable= */ false));
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_NO),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER),
+                new PackageKillableState("third_party_package", 12,
+                        PackageKillableState.KILLABLE_STATE_NO),
+                new PackageKillableState("vendor_package.critical", 12,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+    }
+
+    @Test
+    public void testSetKillablePackageAsUserForAllUsersWithNoPackageStats() throws Exception {
+        mockUmGetAliveUsers(mMockUserManager, 11, 12);
+        injectPackageInfos(new ArrayList<>(Arrays.asList("third_party_package",
+                "vendor_package.critical")));
+
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", UserHandle.ALL,
+                /* isKillable= */ true);
+        mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        UserHandle.ALL, /* isKillable= */ true);
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER),
+                new PackageKillableState("third_party_package", 12,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 12,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+
+        mCarWatchdogService.setKillablePackageAsUser("third_party_package", UserHandle.ALL,
+                /* isKillable= */ false);
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
+                        UserHandle.ALL, /* isKillable= */ false));
+
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_NO),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER),
+                new PackageKillableState("third_party_package", 12,
+                        PackageKillableState.KILLABLE_STATE_NO),
+                new PackageKillableState("vendor_package.critical", 12,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+    }
+
+    @Test
+    public void testGetPackageKillableStatesAsUser() throws Exception {
+        mockUmGetAliveUsers(mMockUserManager, 11, 12);
+        injectPackageInfos(new ArrayList<>(Arrays.asList("third_party_package",
+                "vendor_package.critical")));
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(new UserHandle(11)))
+                .containsExactly(
+                        new PackageKillableState("third_party_package", 11,
+                                PackageKillableState.KILLABLE_STATE_YES),
+                        new PackageKillableState("vendor_package.critical", 11,
+                                PackageKillableState.KILLABLE_STATE_NEVER));
+    }
+
+    @Test
+    public void testGetPackageKillableStatesAsUserForAllUsers() throws Exception {
+        mockUmGetAliveUsers(mMockUserManager, 11, 12);
+        injectPackageInfos(new ArrayList<>(Arrays.asList("third_party_package",
+                "vendor_package.critical")));
+        PackageKillableStateSubject.assertThat(
+                mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL)).containsExactly(
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER),
+                new PackageKillableState("third_party_package", 12,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 12,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
+    }
+
+    @Test
+    public void testSetResourceOveruseConfigurations() throws Exception {
+        List<ResourceOveruseConfiguration> resourceOveruseConfigs = new ArrayList<>(Arrays.asList(
+                sampleResourceOveruseConfigurationBuilder(ComponentType.SYSTEM,
+                        sampleIoOveruseConfigurationBuilder(ComponentType.SYSTEM).build()).build(),
+                sampleResourceOveruseConfigurationBuilder(ComponentType.VENDOR,
+                        sampleIoOveruseConfigurationBuilder(ComponentType.VENDOR).build()).build(),
+                sampleResourceOveruseConfigurationBuilder(ComponentType.THIRD_PARTY,
+                        sampleIoOveruseConfigurationBuilder(ComponentType.THIRD_PARTY).build())
+                        .build()));
+
+        mCarWatchdogService.setResourceOveruseConfigurations(resourceOveruseConfigs,
+                CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO);
+
+        List<android.automotive.watchdog.internal.ResourceOveruseConfiguration>
+                actualConfigs = captureOnSetResourceOveruseConfigurations();
+
+        List<android.automotive.watchdog.internal.ResourceOveruseConfiguration>
+                expectedConfigs = new ArrayList<>(Arrays.asList(
+                sampleInternalResourceOveruseConfiguration(ComponentType.SYSTEM,
+                        sampleInternalIoOveruseConfiguration(ComponentType.SYSTEM)),
+                sampleInternalResourceOveruseConfiguration(ComponentType.VENDOR,
+                        sampleInternalIoOveruseConfiguration(ComponentType.VENDOR)),
+                sampleInternalResourceOveruseConfiguration(ComponentType.THIRD_PARTY,
+                        sampleInternalIoOveruseConfiguration(ComponentType.THIRD_PARTY))));
+
+        InternalResourceOveruseConfigurationSubject.assertThat(actualConfigs)
+                .containsExactlyElementsIn(expectedConfigs);
+    }
+
+    @Test
+    public void testFailsSetResourceOveruseConfigurationsOnInvalidArgs() throws Exception {
+        assertThrows(NullPointerException.class,
+                () -> mCarWatchdogService.setResourceOveruseConfigurations(null,
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setResourceOveruseConfigurations(new ArrayList<>(),
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO));
+
+        List<ResourceOveruseConfiguration> resourceOveruseConfigs = new ArrayList<>(
+                Collections.singletonList(
+                        sampleResourceOveruseConfigurationBuilder(ComponentType.SYSTEM,
+                                sampleIoOveruseConfigurationBuilder(ComponentType.SYSTEM).build())
+                                .build()));
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setResourceOveruseConfigurations(resourceOveruseConfigs,
+                        0));
+    }
+
+    @Test
+    public void testFailsSetResourceOveruseConfigurationsOnDuplicateComponents() throws Exception {
+        ResourceOveruseConfiguration config =
+                sampleResourceOveruseConfigurationBuilder(ComponentType.SYSTEM,
+                sampleIoOveruseConfigurationBuilder(ComponentType.SYSTEM).build()).build();
+        List<ResourceOveruseConfiguration> resourceOveruseConfigs = new ArrayList<>(Arrays.asList(
+                config, config));
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setResourceOveruseConfigurations(resourceOveruseConfigs,
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO));
+    }
+
+    @Test
+    public void testFailsSetResourceOveruseConfigurationsOnNullIoOveruseConfiguration()
+            throws Exception {
+        List<ResourceOveruseConfiguration> resourceOveruseConfigs = new ArrayList<>(
+                Collections.singletonList(
+                        sampleResourceOveruseConfigurationBuilder(ComponentType.SYSTEM,
+                                null).build()));
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.setResourceOveruseConfigurations(resourceOveruseConfigs,
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO));
+    }
+
+    @Test
+    public void testGetResourceOveruseConfigurations() throws Exception {
+        List<android.automotive.watchdog.internal.ResourceOveruseConfiguration>
+                internalResourceOveruseConfigs = new ArrayList<>(Arrays.asList(
+                sampleInternalResourceOveruseConfiguration(ComponentType.SYSTEM,
+                        sampleInternalIoOveruseConfiguration(ComponentType.SYSTEM)),
+                sampleInternalResourceOveruseConfiguration(ComponentType.VENDOR,
+                        sampleInternalIoOveruseConfiguration(ComponentType.VENDOR)),
+                sampleInternalResourceOveruseConfiguration(ComponentType.THIRD_PARTY,
+                        sampleInternalIoOveruseConfiguration(ComponentType.THIRD_PARTY))));
+        doReturn(internalResourceOveruseConfigs).when(mMockCarWatchdogDaemon)
+                .getResourceOveruseConfigurations();
+
+        List<ResourceOveruseConfiguration> actualConfigs =
+                mCarWatchdogService.getResourceOveruseConfigurations(
+                        CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO);
+
+        List<ResourceOveruseConfiguration> expectedConfigs = new ArrayList<>(Arrays.asList(
+                sampleResourceOveruseConfigurationBuilder(ComponentType.SYSTEM,
+                        sampleIoOveruseConfigurationBuilder(ComponentType.SYSTEM).build()).build(),
+                sampleResourceOveruseConfigurationBuilder(ComponentType.VENDOR,
+                        sampleIoOveruseConfigurationBuilder(ComponentType.VENDOR).build()).build(),
+                sampleResourceOveruseConfigurationBuilder(ComponentType.THIRD_PARTY,
+                        sampleIoOveruseConfigurationBuilder(ComponentType.THIRD_PARTY).build())
+                        .build()));
+
+        ResourceOveruseConfigurationSubject.assertThat(actualConfigs)
+                .containsExactlyElementsIn(expectedConfigs);
+    }
+
+    @Test
+    public void testFailsGetResourceOveruseConfigurationsOnInvalidArgs() throws Exception {
+        assertThrows(IllegalArgumentException.class,
+                () -> mCarWatchdogService.getResourceOveruseConfigurations(0));
+    }
+
+    @Test
     public void testLatestIoOveruseStats() throws Exception {
         int criticalSysPkgUid = Binder.getCallingUid();
         int nonCriticalSysPkgUid = getUid(1056);
@@ -275,12 +791,6 @@
         packageNamesByUid.put(nonCriticalSysPkgUid, "non_critical.system.package");
         packageNamesByUid.put(nonCriticalVndrPkgUid, "non_critical.vendor.package");
         packageNamesByUid.put(thirdPartyPkgUid, "third_party.package");
-
-        SparseBooleanArray killableOnOveruseByUid = new SparseBooleanArray();
-        killableOnOveruseByUid.put(criticalSysPkgUid, false);
-        killableOnOveruseByUid.put(nonCriticalSysPkgUid, true);
-        killableOnOveruseByUid.put(nonCriticalVndrPkgUid, true);
-        killableOnOveruseByUid.put(thirdPartyPkgUid, true);
         injectUidToPackageNameMapping(packageNamesByUid);
 
         IResourceOveruseListener mockSystemListener = createMockResourceOveruseListener();
@@ -298,28 +808,28 @@
         List<PackageIoOveruseStats> packageIoOveruseStats = new ArrayList<>(Arrays.asList(
                 /* Overuse occurred but cannot be killed/disabled. */
                 constructPackageIoOveruseStats(criticalSysPkgUid, /* shouldNotify= */true,
-                        constructInternalIoOveruseStats(
-                                killableOnOveruseByUid.get(criticalSysPkgUid),
-                                constructPerStateBytes(0, 0, 0),
-                                constructPerStateBytes(100, 200, 300), /* totalOveruses= */2)),
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                /* remainingWriteBytes= */constructPerStateBytes(0, 0, 0),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2)),
                 /* No overuse occurred but should be notified. */
                 constructPackageIoOveruseStats(nonCriticalSysPkgUid, /* shouldNotify= */true,
-                        constructInternalIoOveruseStats(
-                                killableOnOveruseByUid.get(nonCriticalSysPkgUid),
-                                constructPerStateBytes(20, 30, 40),
-                                constructPerStateBytes(100, 200, 300), /* totalOveruses= */2)),
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */true,
+                                /* remainingWriteBytes= */constructPerStateBytes(20, 30, 40),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2)),
                 /* Neither overuse occurred nor be notified. */
                 constructPackageIoOveruseStats(nonCriticalVndrPkgUid, /* shouldNotify= */false,
-                        constructInternalIoOveruseStats(
-                                killableOnOveruseByUid.get(nonCriticalVndrPkgUid),
-                                constructPerStateBytes(200, 300, 400),
-                                constructPerStateBytes(100, 200, 300), /* totalOveruses= */2)),
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */true,
+                                /* remainingWriteBytes= */constructPerStateBytes(200, 300, 400),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2)),
                 /* Overuse occurred and can be killed/disabled. */
                 constructPackageIoOveruseStats(thirdPartyPkgUid, /* shouldNotify= */true,
-                        constructInternalIoOveruseStats(
-                                killableOnOveruseByUid.get(thirdPartyPkgUid),
-                                constructPerStateBytes(0, 0, 0),
-                                constructPerStateBytes(100, 200, 300), /* totalOveruses= */2))));
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */true,
+                                /* remainingWriteBytes= */constructPerStateBytes(0, 0, 0),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2))));
 
         mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
 
@@ -327,19 +837,16 @@
 
         expectedStats.add(constructResourceOveruseStats(criticalSysPkgUid,
                 packageNamesByUid.get(criticalSysPkgUid),
-                killableOnOveruseByUid.get(criticalSysPkgUid),
                 packageIoOveruseStats.get(0).ioOveruseStats));
 
         verifyOnOveruseCalled(expectedStats, mockListener);
 
         expectedStats.add(constructResourceOveruseStats(nonCriticalSysPkgUid,
                 packageNamesByUid.get(nonCriticalSysPkgUid),
-                killableOnOveruseByUid.get(nonCriticalSysPkgUid),
                 packageIoOveruseStats.get(1).ioOveruseStats));
 
         expectedStats.add(constructResourceOveruseStats(thirdPartyPkgUid,
                 packageNamesByUid.get(thirdPartyPkgUid),
-                killableOnOveruseByUid.get(thirdPartyPkgUid),
                 packageIoOveruseStats.get(3).ioOveruseStats));
 
         verifyOnOveruseCalled(expectedStats, mockSystemListener);
@@ -499,19 +1006,19 @@
     }
 
     private void mockWatchdogDaemon() {
-        doReturn(mBinder).when(() -> ServiceManager.getService(CAR_WATCHDOG_DAEMON_INTERFACE));
-        when(mBinder.queryLocalInterface(anyString())).thenReturn(mCarWatchdogDaemon);
+        doReturn(mMockBinder).when(() -> ServiceManager.getService(CAR_WATCHDOG_DAEMON_INTERFACE));
+        when(mMockBinder.queryLocalInterface(anyString())).thenReturn(mMockCarWatchdogDaemon);
     }
 
     private void setupUsers() {
-        when(mMockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        mockUmGetAllUsers(mUserManager, new UserInfo[0]);
+        when(mMockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
+        mockUmGetAllUsers(mMockUserManager, new UserInfo[0]);
     }
 
     private ICarWatchdogServiceForSystem registerCarWatchdogService() throws Exception {
         ArgumentCaptor<ICarWatchdogServiceForSystem> watchdogServiceForSystemImplCaptor =
                 ArgumentCaptor.forClass(ICarWatchdogServiceForSystem.class);
-        verify(mCarWatchdogDaemon).registerCarWatchdogService(
+        verify(mMockCarWatchdogDaemon).registerCarWatchdogService(
                 watchdogServiceForSystemImplCaptor.capture());
         return watchdogServiceForSystemImplCaptor.getValue();
     }
@@ -520,15 +1027,24 @@
         mCarWatchdogService.registerClient(client, TIMEOUT_CRITICAL);
         mWatchdogServiceForSystemImpl.checkIfAlive(123456, TIMEOUT_CRITICAL);
         ArgumentCaptor<int[]> notRespondingClients = ArgumentCaptor.forClass(int[].class);
-        verify(mCarWatchdogDaemon, timeout(MAX_WAIT_TIME_MS)).tellCarWatchdogServiceAlive(
+        verify(mMockCarWatchdogDaemon, timeout(MAX_WAIT_TIME_MS)).tellCarWatchdogServiceAlive(
                 eq(mWatchdogServiceForSystemImpl), notRespondingClients.capture(), eq(123456));
         assertThat(notRespondingClients.getValue().length).isEqualTo(0);
         mWatchdogServiceForSystemImpl.checkIfAlive(987654, TIMEOUT_CRITICAL);
-        verify(mCarWatchdogDaemon, timeout(MAX_WAIT_TIME_MS)).tellCarWatchdogServiceAlive(
+        verify(mMockCarWatchdogDaemon, timeout(MAX_WAIT_TIME_MS)).tellCarWatchdogServiceAlive(
                 eq(mWatchdogServiceForSystemImpl), notRespondingClients.capture(), eq(987654));
         assertThat(notRespondingClients.getValue().length).isEqualTo(badClientCount);
     }
 
+    private List<android.automotive.watchdog.internal.ResourceOveruseConfiguration>
+            captureOnSetResourceOveruseConfigurations() throws Exception {
+        ArgumentCaptor<List<android.automotive.watchdog.internal.ResourceOveruseConfiguration>>
+                resourceOveruseConfigurationsCaptor = ArgumentCaptor.forClass(List.class);
+        verify(mMockCarWatchdogDaemon).updateResourceOveruseConfigurations(
+                resourceOveruseConfigurationsCaptor.capture());
+        return resourceOveruseConfigurationsCaptor.getValue();
+    }
+
     private void injectUidToPackageNameMapping(SparseArray<String> packageNamesByUid) {
         doAnswer(args -> {
             int[] uids = args.getArgument(0);
@@ -540,6 +1056,49 @@
         }).when(mMockPackageManager).getNamesForUids(any());
     }
 
+    private void injectIoOveruseStatsForPackages(SparseArray<String> packageNamesByUid,
+            Set<String> killablePackages) throws RemoteException {
+        injectUidToPackageNameMapping(packageNamesByUid);
+        List<PackageIoOveruseStats> packageIoOveruseStats = new ArrayList<>();
+        for (int i = 0; i < packageNamesByUid.size(); ++i) {
+            String packageName = packageNamesByUid.valueAt(i);
+            int uid = packageNamesByUid.keyAt(i);
+            packageIoOveruseStats.add(constructPackageIoOveruseStats(uid,
+                    false,
+                    constructInternalIoOveruseStats(killablePackages.contains(packageName),
+                            /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                            /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                            /* totalOveruses= */2)));
+        }
+        mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
+    }
+
+    private void injectPackageInfos(List<String> packageNames) {
+        List<android.content.pm.PackageInfo> packageInfos = new ArrayList<>();
+        TriConsumer<String, Integer, Integer> addPackageInfo =
+                (packageName, flags, privateFlags) -> {
+                    android.content.pm.PackageInfo packageInfo =
+                            new android.content.pm.PackageInfo();
+                    packageInfo.packageName = packageName;
+                    packageInfo.applicationInfo = new ApplicationInfo();
+                    packageInfo.applicationInfo.flags = flags;
+                    packageInfo.applicationInfo.privateFlags = privateFlags;
+                    packageInfos.add(packageInfo);
+                };
+        for (String packageName : packageNames) {
+            if (packageName.startsWith("system")) {
+                addPackageInfo.accept(packageName, ApplicationInfo.FLAG_SYSTEM, 0);
+            } else if (packageName.startsWith("vendor")) {
+                addPackageInfo.accept(packageName, ApplicationInfo.FLAG_SYSTEM,
+                        ApplicationInfo.PRIVATE_FLAG_OEM);
+            } else {
+                addPackageInfo.accept(packageName, 0, 0);
+            }
+        }
+        doReturn(packageInfos).when(mMockPackageManager).getInstalledPackagesAsUser(
+                eq(0), anyInt());
+    }
+
     private void mockApplicationEnabledSettingAccessors(IPackageManager pm) throws Exception {
         doReturn(COMPONENT_ENABLED_STATE_ENABLED).when(pm)
                 .getApplicationEnabledSetting(anyString(), eq(UserHandle.myUserId()));
@@ -553,7 +1112,7 @@
         ArgumentCaptor<List<PackageResourceOveruseAction>> resourceOveruseActionsCaptor =
                 ArgumentCaptor.forClass((Class) List.class);
 
-        verify(mCarWatchdogDaemon, timeout(MAX_WAIT_TIME_MS)).actionTakenOnResourceOveruse(
+        verify(mMockCarWatchdogDaemon, timeout(MAX_WAIT_TIME_MS)).actionTakenOnResourceOveruse(
                 resourceOveruseActionsCaptor.capture());
         List<PackageResourceOveruseAction> actual = resourceOveruseActionsCaptor.getValue();
 
@@ -586,6 +1145,118 @@
         return UserHandle.getUid(UserHandle.myUserId(), appId);
     }
 
+    private static ResourceOveruseConfiguration.Builder sampleResourceOveruseConfigurationBuilder(
+            int componentType, IoOveruseConfiguration ioOveruseConfig) {
+        String prefix = WatchdogPerfHandler.toComponentTypeStr(componentType);
+        List<String> safeToKill = new ArrayList<>(Arrays.asList(
+                prefix + "_package.A", prefix + "_pkg.B"));
+        List<String> vendorPrefixes = new ArrayList<>(Arrays.asList(
+                prefix + "_package", prefix + "_pkg"));
+        Map<String, String> pkgToAppCategory = new ArrayMap<>();
+        pkgToAppCategory.put(prefix + "_package.A", "android.car.watchdog.app.category.MEDIA");
+        ResourceOveruseConfiguration.Builder configBuilder =
+                new ResourceOveruseConfiguration.Builder(componentType, safeToKill,
+                        vendorPrefixes, pkgToAppCategory);
+        configBuilder.setIoOveruseConfiguration(ioOveruseConfig);
+        return configBuilder;
+    }
+
+    private static IoOveruseConfiguration.Builder sampleIoOveruseConfigurationBuilder(
+            int componentType) {
+        String prefix = WatchdogPerfHandler.toComponentTypeStr(componentType);
+        PerStateBytes componentLevelThresholds = new PerStateBytes(
+                /* foregroundModeBytes= */10, /* backgroundModeBytes= */20,
+                /* garageModeBytes= */30);
+        Map<String, PerStateBytes> packageSpecificThresholds = new ArrayMap<>();
+        packageSpecificThresholds.put(prefix + "_package.A", new PerStateBytes(
+                /* foregroundModeBytes= */40, /* backgroundModeBytes= */50,
+                /* garageModeBytes= */60));
+
+        Map<String, PerStateBytes> appCategorySpecificThresholds = new ArrayMap<>();
+        appCategorySpecificThresholds.put(
+                ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MEDIA,
+                new PerStateBytes(/* foregroundModeBytes= */100, /* backgroundModeBytes= */200,
+                        /* garageModeBytes= */300));
+        appCategorySpecificThresholds.put(
+                ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MAPS,
+                new PerStateBytes(/* foregroundModeBytes= */1100, /* backgroundModeBytes= */2200,
+                        /* garageModeBytes= */3300));
+
+        List<IoOveruseAlertThreshold> systemWideThresholds = new ArrayList<>(
+                Collections.singletonList(new IoOveruseAlertThreshold(/* durationInSeconds= */10,
+                        /* writtenBytesPerSecond= */200)));
+
+        return new IoOveruseConfiguration.Builder(componentLevelThresholds,
+                packageSpecificThresholds, appCategorySpecificThresholds, systemWideThresholds);
+    }
+
+    private static android.automotive.watchdog.internal.ResourceOveruseConfiguration
+            sampleInternalResourceOveruseConfiguration(int componentType,
+            android.automotive.watchdog.internal.IoOveruseConfiguration ioOveruseConfig) {
+        String prefix = WatchdogPerfHandler.toComponentTypeStr(componentType);
+        android.automotive.watchdog.internal.ResourceOveruseConfiguration config =
+                new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+        config.componentType = componentType;
+        config.safeToKillPackages = new ArrayList<>(Arrays.asList(
+                prefix + "_package.A", prefix + "_pkg.B"));
+        config.vendorPackagePrefixes = new ArrayList<>(Arrays.asList(
+                prefix + "_package", prefix + "_pkg"));
+
+        PackageMetadata metadata = new PackageMetadata();
+        metadata.packageName = prefix + "_package.A";
+        metadata.appCategoryType = ApplicationCategoryType.MEDIA;
+        config.packageMetadata = new ArrayList<>(Collections.singletonList(metadata));
+
+        ResourceSpecificConfiguration resourceSpecificConfig = new ResourceSpecificConfiguration();
+        resourceSpecificConfig.setIoOveruseConfiguration(ioOveruseConfig);
+        config.resourceSpecificConfigurations = new ArrayList<>(
+                Collections.singletonList(resourceSpecificConfig));
+
+        return config;
+    }
+
+    private static android.automotive.watchdog.internal.IoOveruseConfiguration
+            sampleInternalIoOveruseConfiguration(int componentType) {
+        String prefix = WatchdogPerfHandler.toComponentTypeStr(componentType);
+        android.automotive.watchdog.internal.IoOveruseConfiguration config =
+                new android.automotive.watchdog.internal.IoOveruseConfiguration();
+        config.componentLevelThresholds = constructPerStateIoOveruseThreshold(prefix,
+                /* fgBytes= */10, /* bgBytes= */20, /* gmBytes= */30);
+        config.packageSpecificThresholds = new ArrayList<>(Collections.singletonList(
+                constructPerStateIoOveruseThreshold(prefix + "_package.A", /* fgBytes= */40,
+                        /* bgBytes= */50, /* gmBytes= */60)));
+        config.categorySpecificThresholds = new ArrayList<>(Arrays.asList(
+                constructPerStateIoOveruseThreshold(
+                        WatchdogPerfHandler.INTERNAL_APPLICATION_CATEGORY_TYPE_MEDIA,
+                        /* fgBytes= */100, /* bgBytes= */200, /* gmBytes= */300),
+                constructPerStateIoOveruseThreshold(
+                        WatchdogPerfHandler.INTERNAL_APPLICATION_CATEGORY_TYPE_MAPS,
+                        /* fgBytes= */1100, /* bgBytes= */2200, /* gmBytes= */3300)));
+        config.systemWideThresholds = new ArrayList<>(Collections.singletonList(
+                constructInternalIoOveruseAlertThreshold(/* duration= */10, /* writeBPS= */200)));
+        return config;
+    }
+
+    private static PerStateIoOveruseThreshold constructPerStateIoOveruseThreshold(String name,
+            long fgBytes, long bgBytes, long gmBytes) {
+        PerStateIoOveruseThreshold threshold = new PerStateIoOveruseThreshold();
+        threshold.name = name;
+        threshold.perStateWriteBytes = new android.automotive.watchdog.PerStateBytes();
+        threshold.perStateWriteBytes.foregroundBytes = fgBytes;
+        threshold.perStateWriteBytes.backgroundBytes = bgBytes;
+        threshold.perStateWriteBytes.garageModeBytes = gmBytes;
+        return threshold;
+    }
+
+    private static android.automotive.watchdog.internal.IoOveruseAlertThreshold
+            constructInternalIoOveruseAlertThreshold(long duration, long writeBPS) {
+        android.automotive.watchdog.internal.IoOveruseAlertThreshold threshold =
+                new android.automotive.watchdog.internal.IoOveruseAlertThreshold();
+        threshold.durationInSeconds = duration;
+        threshold.writtenBytesPerSecond = writeBPS;
+        return threshold;
+    }
+
     private static PackageIoOveruseStats constructPackageIoOveruseStats(int uid,
             boolean shouldNotify, android.automotive.watchdog.IoOveruseStats ioOveruseStats) {
         PackageIoOveruseStats stats = new PackageIoOveruseStats();
@@ -596,11 +1267,10 @@
     }
 
     private static ResourceOveruseStats constructResourceOveruseStats(int uid, String packageName,
-            boolean killableOnOveruse,
             android.automotive.watchdog.IoOveruseStats internalIoOveruseStats) {
         IoOveruseStats ioOveruseStats =
                 WatchdogPerfHandler.toIoOveruseStatsBuilder(internalIoOveruseStats)
-                        .setKillableOnOveruse(killableOnOveruse).build();
+                        .setKillableOnOveruse(internalIoOveruseStats.killableOnOveruse).build();
 
         return new ResourceOveruseStats.Builder(packageName, UserHandle.getUserHandleForUid(uid))
                 .setIoOveruseStats(ioOveruseStats).build();
@@ -629,7 +1299,7 @@
         return perStateBytes;
     }
 
-    public static PackageResourceOveruseAction constructPackageResourceOveruseAction(
+    private static PackageResourceOveruseAction constructPackageResourceOveruseAction(
             String packageName, int uid, int[] resourceTypes, int resourceOveruseActionType) {
         PackageResourceOveruseAction action = new PackageResourceOveruseAction();
         action.packageIdentifier = new PackageIdentifier();
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/InternalIoOveruseConfigurationSubject.java b/tests/carservice_unit_test/src/com/android/car/watchdog/InternalIoOveruseConfigurationSubject.java
new file mode 100644
index 0000000..47ad645
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/InternalIoOveruseConfigurationSubject.java
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+package com.android.car.watchdog;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import android.annotation.Nullable;
+import android.automotive.watchdog.PerStateBytes;
+import android.automotive.watchdog.internal.IoOveruseAlertThreshold;
+import android.automotive.watchdog.internal.IoOveruseConfiguration;
+import android.automotive.watchdog.internal.PerStateIoOveruseThreshold;
+
+import com.google.common.truth.Correspondence;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.common.truth.Truth;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public final class InternalIoOveruseConfigurationSubject extends Subject {
+    // Boiler-plate Subject.Factory for InternalIoOveruseConfigurationSubject
+    private static final Subject.Factory<
+            com.android.car.watchdog.InternalIoOveruseConfigurationSubject,
+            Iterable<IoOveruseConfiguration>> Io_OVERUSE_CONFIG_SUBJECT_FACTORY =
+            com.android.car.watchdog.InternalIoOveruseConfigurationSubject::new;
+
+    private final Iterable<IoOveruseConfiguration> mActual;
+
+    // User-defined entry point
+    public static InternalIoOveruseConfigurationSubject assertThat(
+            @Nullable Iterable<IoOveruseConfiguration> stats) {
+        return assertAbout(Io_OVERUSE_CONFIG_SUBJECT_FACTORY).that(stats);
+    }
+
+    public static Subject.Factory<InternalIoOveruseConfigurationSubject,
+            Iterable<IoOveruseConfiguration>> resourceOveruseStats() {
+        return Io_OVERUSE_CONFIG_SUBJECT_FACTORY;
+    }
+
+    public void containsExactly(IoOveruseConfiguration... stats) {
+        containsExactlyElementsIn(Arrays.asList(stats));
+    }
+
+    public void containsExactlyElementsIn(Iterable<IoOveruseConfiguration> expected) {
+        Truth.assertWithMessage("Expected: " + expected.toString() + "\nActual: "
+                + mActual.toString()).that(mActual)
+                .comparingElementsUsing(Correspondence.from(
+                        InternalIoOveruseConfigurationSubject::isEquals, "is equal to"))
+                .containsExactlyElementsIn(expected);
+    }
+
+    public static boolean isEquals(IoOveruseConfiguration actual,
+            IoOveruseConfiguration expected) {
+        if (actual == null || expected == null) {
+            return (actual == null) && (expected == null);
+        }
+        return actual.componentLevelThresholds.name == expected.componentLevelThresholds.name
+                && isPerStateBytesEquals(actual.componentLevelThresholds.perStateWriteBytes,
+                    expected.componentLevelThresholds.perStateWriteBytes)
+                && isPerStateThresholdEquals(actual.packageSpecificThresholds,
+                    expected.packageSpecificThresholds)
+                && isPerStateThresholdEquals(actual.categorySpecificThresholds,
+                    expected.categorySpecificThresholds)
+                && isAlertThresholdEquals(actual.systemWideThresholds,
+                    expected.systemWideThresholds);
+    }
+
+    public static StringBuilder toStringBuilder(StringBuilder builder,
+            IoOveruseConfiguration config) {
+        builder.append("{Component-level thresholds: ")
+                .append(toString(config.componentLevelThresholds))
+                .append(", Package specific thresholds: [")
+                .append(config.packageSpecificThresholds.stream()
+                        .map(InternalIoOveruseConfigurationSubject::toString)
+                        .collect(Collectors.joining(", ")))
+                .append("], Category specific thresholds: [")
+                .append(config.categorySpecificThresholds.stream()
+                        .map(InternalIoOveruseConfigurationSubject::toString)
+                        .collect(Collectors.joining(", ")))
+                .append("], System wide thresholds: [")
+                .append(config.systemWideThresholds.stream()
+                        .map(InternalIoOveruseConfigurationSubject::toString)
+                        .collect(Collectors.joining(", ")))
+                .append("]}");
+        return builder;
+    }
+
+    public static String toString(PerStateIoOveruseThreshold threshold) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{Name: ").append(threshold.name).append(", WriteBytes: {fgBytes: ")
+                .append(threshold.perStateWriteBytes.foregroundBytes).append(", bgBytes: ")
+                .append(threshold.perStateWriteBytes.backgroundBytes).append(", gmBytes: ")
+                .append(threshold.perStateWriteBytes.garageModeBytes).append("}}");
+        return builder.toString();
+    }
+
+    public static String toString(IoOveruseAlertThreshold threshold) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{durationInSeconds: ").append(threshold.durationInSeconds)
+                .append(", writtenBytesPerSecond: ").append(threshold.writtenBytesPerSecond)
+                .append("}");
+        return builder.toString();
+    }
+
+    private InternalIoOveruseConfigurationSubject(FailureMetadata failureMetadata,
+            @Nullable Iterable<IoOveruseConfiguration> iterableSubject) {
+        super(failureMetadata, iterableSubject);
+        this.mActual = iterableSubject;
+    }
+
+    private static boolean isPerStateThresholdEquals(List<PerStateIoOveruseThreshold> actual,
+            List<PerStateIoOveruseThreshold> expected) {
+        Set<String> actualStr = toPerStateThresholdStrings(actual);
+        Set<String> expectedStr = toPerStateThresholdStrings(expected);
+        return actualStr.equals(expectedStr);
+    }
+
+    private static boolean isAlertThresholdEquals(List<IoOveruseAlertThreshold> actual,
+            List<IoOveruseAlertThreshold> expected) {
+        Set<String> actualStr = toAlertThresholdStrings(actual);
+        Set<String> expectedStr = toAlertThresholdStrings(expected);
+        return actualStr.equals(expectedStr);
+    }
+
+    private static boolean isPerStateBytesEquals(PerStateBytes acutal, PerStateBytes expected) {
+        return acutal.foregroundBytes == expected.foregroundBytes
+                && acutal.backgroundBytes == expected.backgroundBytes
+                && acutal.garageModeBytes == expected.garageModeBytes;
+    }
+
+    private static Set<String> toPerStateThresholdStrings(
+            List<PerStateIoOveruseThreshold> thresholds) {
+        return thresholds.stream().map(x -> String.format("%s:{%d,%d,%d}", x.name,
+                x.perStateWriteBytes.foregroundBytes, x.perStateWriteBytes.backgroundBytes,
+                x.perStateWriteBytes.garageModeBytes))
+                .collect(Collectors.toSet());
+    }
+
+    private static Set<String> toAlertThresholdStrings(
+            List<IoOveruseAlertThreshold> thresholds) {
+        return thresholds.stream().map(x -> String.format("%d:%d", x.durationInSeconds,
+                x.writtenBytesPerSecond)).collect(Collectors.toSet());
+    }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/InternalResourceOveruseConfigurationSubject.java b/tests/carservice_unit_test/src/com/android/car/watchdog/InternalResourceOveruseConfigurationSubject.java
new file mode 100644
index 0000000..d324efe
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/InternalResourceOveruseConfigurationSubject.java
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+package com.android.car.watchdog;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import android.annotation.Nullable;
+import android.automotive.watchdog.internal.PackageMetadata;
+import android.automotive.watchdog.internal.ResourceOveruseConfiguration;
+import android.automotive.watchdog.internal.ResourceSpecificConfiguration;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.truth.Correspondence;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.common.truth.Truth;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public final class InternalResourceOveruseConfigurationSubject extends Subject {
+    // Boiler-plate Subject.Factory for InternalResourceOveruseConfigurationSubject
+    private static final Subject.Factory<
+            com.android.car.watchdog.InternalResourceOveruseConfigurationSubject,
+            Iterable<ResourceOveruseConfiguration>> RESOURCE_OVERUSE_CONFIG_SUBJECT_FACTORY =
+            com.android.car.watchdog.InternalResourceOveruseConfigurationSubject::new;
+
+    private static final Correspondence<List<PackageMetadata>, List<PackageMetadata>>
+            METADATA_LIST_CORRESPONDENCE = Correspondence.from(
+                    InternalResourceOveruseConfigurationSubject::isPackageMetadataEquals,
+            "is equal to");
+
+    private static final Correspondence<List<ResourceSpecificConfiguration>,
+            List<ResourceSpecificConfiguration>>
+            RESOURCE_SPECIFIC_CONFIG_LIST_CORRESPONDENCE = Correspondence.from(
+            InternalResourceOveruseConfigurationSubject::isResourceSpecificConfigEquals,
+            "is equal to");
+
+    private final Iterable<ResourceOveruseConfiguration> mActual;
+
+    // User-defined entry point
+    public static InternalResourceOveruseConfigurationSubject assertThat(
+            @Nullable Iterable<ResourceOveruseConfiguration> stats) {
+        return assertAbout(RESOURCE_OVERUSE_CONFIG_SUBJECT_FACTORY).that(stats);
+    }
+
+    public static Subject.Factory<InternalResourceOveruseConfigurationSubject,
+            Iterable<ResourceOveruseConfiguration>> resourceOveruseStats() {
+        return RESOURCE_OVERUSE_CONFIG_SUBJECT_FACTORY;
+    }
+
+    public void containsExactly(ResourceOveruseConfiguration... stats) {
+        containsExactlyElementsIn(Arrays.asList(stats));
+    }
+
+    public void containsExactlyElementsIn(Iterable<ResourceOveruseConfiguration> expected) {
+        Truth.assertWithMessage("Expected: " + toString(expected) + "\nActual: "
+                + toString(mActual)).that(mActual)
+                .comparingElementsUsing(Correspondence.from(
+                        InternalResourceOveruseConfigurationSubject::isEquals, "is equal to"))
+                .containsExactlyElementsIn(expected);
+    }
+
+    public static boolean isPackageMetadataEquals(List<PackageMetadata> actual,
+            List<PackageMetadata> expected) {
+        Set<String> actualStr = toMetadataStrings(actual);
+        Set<String> expectedStr = toMetadataStrings(expected);
+        return actualStr.equals(expectedStr);
+    }
+
+    public static boolean isResourceSpecificConfigEquals(List<ResourceSpecificConfiguration> actual,
+            List<ResourceSpecificConfiguration> expected) {
+        if (actual.size() != expected.size()) {
+            return false;
+        }
+        if (actual.size() == 0) {
+            return true;
+        }
+        /*
+         * When more resource types are added make this comparison more generic. Because the
+         * resource overuse configuration should contain only one I/O overuse configuration, the
+         * comparison only checks for first I/O overuse configuration.
+         */
+        ResourceSpecificConfiguration actualElement = actual.get(0);
+        ResourceSpecificConfiguration expectedElement = expected.get(0);
+        if (actualElement.getTag() != expectedElement.getTag()) {
+            return false;
+        }
+        if (actualElement.getTag() != ResourceSpecificConfiguration.ioOveruseConfiguration) {
+            return false;
+        }
+        return InternalIoOveruseConfigurationSubject.isEquals(
+                actualElement.getIoOveruseConfiguration(),
+                expectedElement.getIoOveruseConfiguration());
+    }
+
+    public static boolean isEquals(ResourceOveruseConfiguration actual,
+            ResourceOveruseConfiguration expected) {
+        if (actual == null || expected == null) {
+            return (actual == null) && (expected == null);
+        }
+        return actual.componentType == expected.componentType
+                && ImmutableSet.copyOf(actual.safeToKillPackages).equals(
+                        ImmutableSet.copyOf(expected.safeToKillPackages))
+                && ImmutableSet.copyOf(actual.vendorPackagePrefixes).equals(
+                        ImmutableSet.copyOf(expected.vendorPackagePrefixes))
+                && METADATA_LIST_CORRESPONDENCE.compare(actual.packageMetadata,
+                        expected.packageMetadata)
+                && RESOURCE_SPECIFIC_CONFIG_LIST_CORRESPONDENCE.compare(
+                        actual.resourceSpecificConfigurations,
+                        expected.resourceSpecificConfigurations);
+    }
+
+    private InternalResourceOveruseConfigurationSubject(FailureMetadata failureMetadata,
+            @Nullable Iterable<ResourceOveruseConfiguration> iterableSubject) {
+        super(failureMetadata, iterableSubject);
+        this.mActual = iterableSubject;
+    }
+
+    private static Set<String> toMetadataStrings(List<PackageMetadata> metadata) {
+        return metadata.stream().map(x -> String.format("%s:%d", x.packageName, x.appCategoryType))
+                .collect(Collectors.toSet());
+    }
+
+    private static String toString(
+            Iterable<ResourceOveruseConfiguration> configs) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("[");
+        for (ResourceOveruseConfiguration config : configs) {
+            toStringBuilder(builder, config).append(", ");
+        }
+        builder.append("]");
+        return builder.toString();
+    }
+
+    private static StringBuilder toStringBuilder(StringBuilder builder,
+            ResourceOveruseConfiguration config) {
+        builder.append("{Component type: ").append(config.componentType)
+                .append(", Safe-to-kill packages: [")
+                .append(config.safeToKillPackages.stream().map(Object::toString)
+                        .collect(Collectors.joining(", ")))
+                .append("], Vendor package prefixes: [")
+                .append(config.vendorPackagePrefixes.stream().map(Object::toString)
+                        .collect(Collectors.joining(", ")))
+                .append("], Package Metadata: [")
+                .append(config.packageMetadata.stream()
+                        .map(InternalResourceOveruseConfigurationSubject::toPackageMetadataString)
+                        .collect(Collectors.joining(", ")))
+                .append("], Resource specific configurations: [")
+                .append(config.resourceSpecificConfigurations.stream()
+                        .map(InternalResourceOveruseConfigurationSubject
+                                ::toResourceOveruseConfigString).collect(Collectors.joining(", ")))
+                .append("]}");
+        return builder;
+    }
+
+    private static String toResourceOveruseConfigString(ResourceSpecificConfiguration config) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{Tag: ").append(config.getTag()).append(", Value: ");
+        if (config.getTag() == ResourceSpecificConfiguration.ioOveruseConfiguration) {
+            InternalIoOveruseConfigurationSubject.toStringBuilder(builder,
+                    config.getIoOveruseConfiguration());
+        } else {
+            builder.append("UNKNOWN");
+        }
+        return builder.toString();
+    }
+
+    private static String toPackageMetadataString(PackageMetadata metadata) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{Name: ").append(metadata.packageName).append(", App category type: ")
+                .append(metadata.appCategoryType).append("}");
+        return builder.toString();
+    }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/IoOveruseConfigurationSubject.java b/tests/carservice_unit_test/src/com/android/car/watchdog/IoOveruseConfigurationSubject.java
new file mode 100644
index 0000000..3629898
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/IoOveruseConfigurationSubject.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+package com.android.car.watchdog;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import android.annotation.Nullable;
+import android.car.watchdog.IoOveruseAlertThreshold;
+import android.car.watchdog.IoOveruseConfiguration;
+import android.car.watchdog.PerStateBytes;
+
+import com.google.common.base.Equivalence;
+import com.google.common.collect.Maps;
+import com.google.common.truth.Correspondence;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.common.truth.Truth;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public final class IoOveruseConfigurationSubject extends Subject {
+    // Boiler-plate Subject.Factory for IoOveruseConfigurationSubject
+    private static final Subject.Factory<
+            com.android.car.watchdog.IoOveruseConfigurationSubject,
+            Iterable<IoOveruseConfiguration>> Io_OVERUSE_CONFIG_SUBJECT_FACTORY =
+            com.android.car.watchdog.IoOveruseConfigurationSubject::new;
+
+    private static final Equivalence<PerStateBytes> PER_STATE_BYTES_EQUIVALENCE =
+            new Equivalence<PerStateBytes>() {
+                @Override
+                protected boolean doEquivalent(PerStateBytes actual, PerStateBytes expected) {
+                    return isPerStateBytesEquals(actual, expected);
+                }
+
+                @Override
+                protected int doHash(PerStateBytes perStateBytes) {
+                    return (int) ((perStateBytes.getForegroundModeBytes() * 10 ^ 4)
+                            + (perStateBytes.getBackgroundModeBytes() * 10 ^ 3)
+                            + perStateBytes.getGarageModeBytes());
+                }
+            };
+
+    private final Iterable<IoOveruseConfiguration> mActual;
+
+    // User-defined entry point
+    public static IoOveruseConfigurationSubject assertThat(
+            @Nullable Iterable<IoOveruseConfiguration> stats) {
+        return assertAbout(Io_OVERUSE_CONFIG_SUBJECT_FACTORY).that(stats);
+    }
+
+    public static Subject.Factory<IoOveruseConfigurationSubject,
+            Iterable<IoOveruseConfiguration>> resourceOveruseStats() {
+        return Io_OVERUSE_CONFIG_SUBJECT_FACTORY;
+    }
+
+    public void containsExactly(IoOveruseConfiguration... stats) {
+        containsExactlyElementsIn(Arrays.asList(stats));
+    }
+
+    public void containsExactlyElementsIn(Iterable<IoOveruseConfiguration> expected) {
+        Truth.assertThat(mActual)
+                .comparingElementsUsing(Correspondence.from(
+                        IoOveruseConfigurationSubject::isEquals, "is equal to"))
+                .containsExactlyElementsIn(expected);
+    }
+
+    public static boolean isEquals(IoOveruseConfiguration actual,
+            IoOveruseConfiguration expected) {
+        if (actual == null || expected == null) {
+            return (actual == null) && (expected == null);
+        }
+
+        return isPerStateBytesEquals(actual.getComponentLevelThresholds(),
+                expected.getComponentLevelThresholds())
+                && Maps.difference(actual.getPackageSpecificThresholds(),
+                expected.getPackageSpecificThresholds(), PER_STATE_BYTES_EQUIVALENCE).areEqual()
+                && Maps.difference(actual.getAppCategorySpecificThresholds(),
+                expected.getAppCategorySpecificThresholds(), PER_STATE_BYTES_EQUIVALENCE).areEqual()
+                && isAlertThresholdEquals(actual.getSystemWideThresholds(),
+                expected.getSystemWideThresholds());
+    }
+
+    private IoOveruseConfigurationSubject(FailureMetadata failureMetadata,
+            @Nullable Iterable<IoOveruseConfiguration> iterableSubject) {
+        super(failureMetadata, iterableSubject);
+        this.mActual = iterableSubject;
+    }
+
+    private static boolean isPerStateBytesEquals(PerStateBytes actual, PerStateBytes expected) {
+        return actual.getForegroundModeBytes() == expected.getForegroundModeBytes()
+                && actual.getBackgroundModeBytes() == expected.getBackgroundModeBytes()
+                && actual.getGarageModeBytes() == expected.getGarageModeBytes();
+    }
+
+    private static boolean isAlertThresholdEquals(List<IoOveruseAlertThreshold> actual,
+            List<IoOveruseAlertThreshold> expected) {
+        Set<String> actualStr = toAlertThresholdStrings(actual);
+        Set<String> expectedStr = toAlertThresholdStrings(expected);
+        return actualStr.equals(expectedStr);
+    }
+
+    private static Set<String> toAlertThresholdStrings(List<IoOveruseAlertThreshold> thresholds) {
+        return thresholds.stream().map(x -> String.format("%d:%d", x.getDurationInSeconds(),
+                x.getWrittenBytesPerSecond())).collect(Collectors.toSet());
+    }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/PackageKillableStateSubject.java b/tests/carservice_unit_test/src/com/android/car/watchdog/PackageKillableStateSubject.java
new file mode 100644
index 0000000..953d1df
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/PackageKillableStateSubject.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package com.android.car.watchdog;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import android.annotation.Nullable;
+import android.car.watchdog.PackageKillableState;
+
+import com.google.common.truth.Correspondence;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.common.truth.Truth;
+
+import java.util.Arrays;
+
+public final class PackageKillableStateSubject extends Subject {
+    // Boiler-plate Subject.Factory for PackageKillableStateSubject
+    private static final Subject.Factory<
+            com.android.car.watchdog.PackageKillableStateSubject,
+            Iterable<PackageKillableState>> PACKAGE_KILLABLE_STATE_SUBJECT_FACTORY =
+            com.android.car.watchdog.PackageKillableStateSubject::new;
+
+    private final Iterable<PackageKillableState> mActual;
+
+    // User-defined entry point
+    public static PackageKillableStateSubject assertThat(
+            @Nullable Iterable<PackageKillableState> stats) {
+        return assertAbout(PACKAGE_KILLABLE_STATE_SUBJECT_FACTORY).that(stats);
+    }
+
+    public static Subject.Factory<PackageKillableStateSubject,
+            Iterable<PackageKillableState>> resourceOveruseStats() {
+        return PACKAGE_KILLABLE_STATE_SUBJECT_FACTORY;
+    }
+
+    public void containsExactly(PackageKillableState... stats) {
+        containsExactlyElementsIn(Arrays.asList(stats));
+    }
+
+    public void containsExactlyElementsIn(Iterable<PackageKillableState> expected) {
+        Truth.assertThat(mActual)
+                .comparingElementsUsing(Correspondence.from(
+                        PackageKillableStateSubject::isEquals, "is equal to"))
+                .containsExactlyElementsIn(expected);
+    }
+
+    public static boolean isEquals(PackageKillableState actual,
+            PackageKillableState expected) {
+        if (actual == null || expected == null) {
+            return (actual == null) && (expected == null);
+        }
+        return actual.getPackageName().equals(expected.getPackageName())
+                && actual.getUserId() == expected.getUserId()
+                && actual.getKillableState() == expected.getKillableState();
+    }
+
+    private PackageKillableStateSubject(FailureMetadata failureMetadata,
+            @Nullable Iterable<PackageKillableState> iterableSubject) {
+        super(failureMetadata, iterableSubject);
+        this.mActual = iterableSubject;
+    }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/ResourceOveruseConfigurationSubject.java b/tests/carservice_unit_test/src/com/android/car/watchdog/ResourceOveruseConfigurationSubject.java
new file mode 100644
index 0000000..5bfdf17
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/ResourceOveruseConfigurationSubject.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+package com.android.car.watchdog;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import android.annotation.Nullable;
+import android.car.watchdog.ResourceOveruseConfiguration;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.truth.Correspondence;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.common.truth.Truth;
+
+import java.util.Arrays;
+
+public final class ResourceOveruseConfigurationSubject extends Subject {
+    // Boiler-plate Subject.Factory for ResourceOveruseConfigurationSubject
+    private static final Subject.Factory<
+            com.android.car.watchdog.ResourceOveruseConfigurationSubject,
+            Iterable<ResourceOveruseConfiguration>> RESOURCE_OVERUSE_CONFIG_SUBJECT_FACTORY =
+            com.android.car.watchdog.ResourceOveruseConfigurationSubject::new;
+
+    private final Iterable<ResourceOveruseConfiguration> mActual;
+
+    // User-defined entry point
+    public static ResourceOveruseConfigurationSubject assertThat(
+            @Nullable Iterable<ResourceOveruseConfiguration> stats) {
+        return assertAbout(RESOURCE_OVERUSE_CONFIG_SUBJECT_FACTORY).that(stats);
+    }
+
+    public static Subject.Factory<ResourceOveruseConfigurationSubject,
+            Iterable<ResourceOveruseConfiguration>> resourceOveruseStats() {
+        return RESOURCE_OVERUSE_CONFIG_SUBJECT_FACTORY;
+    }
+
+    public void containsExactly(ResourceOveruseConfiguration... stats) {
+        containsExactlyElementsIn(Arrays.asList(stats));
+    }
+
+    public void containsExactlyElementsIn(Iterable<ResourceOveruseConfiguration> expected) {
+        Truth.assertThat(mActual)
+                .comparingElementsUsing(Correspondence.from(
+                        ResourceOveruseConfigurationSubject::isEquals, "is equal to"))
+                .containsExactlyElementsIn(expected);
+    }
+
+    public static boolean isEquals(ResourceOveruseConfiguration actual,
+            ResourceOveruseConfiguration expected) {
+        if (actual == null || expected == null) {
+            return (actual == null) && (expected == null);
+        }
+        return actual.getComponentType() == expected.getComponentType()
+                && ImmutableSet.copyOf(actual.getSafeToKillPackages()).equals(
+                ImmutableSet.copyOf(expected.getSafeToKillPackages()))
+                && ImmutableSet.copyOf(actual.getVendorPackagePrefixes()).equals(
+                ImmutableSet.copyOf(expected.getVendorPackagePrefixes()))
+                && Maps.difference(actual.getPackagesToAppCategoryTypes(),
+                expected.getPackagesToAppCategoryTypes()).areEqual()
+                && IoOveruseConfigurationSubject.isEquals(actual.getIoOveruseConfiguration(),
+                    expected.getIoOveruseConfiguration());
+    }
+
+    private ResourceOveruseConfigurationSubject(FailureMetadata failureMetadata,
+            @Nullable Iterable<ResourceOveruseConfiguration> iterableSubject) {
+        super(failureMetadata, iterableSubject);
+        this.mActual = iterableSubject;
+    }
+}