Merge "Update UserRestriction defaults to use framework mechanisms"
diff --git a/FrameworkPackageStubs/AndroidManifest.xml b/FrameworkPackageStubs/AndroidManifest.xml
index e1ad903..c88ffdb 100644
--- a/FrameworkPackageStubs/AndroidManifest.xml
+++ b/FrameworkPackageStubs/AndroidManifest.xml
@@ -55,6 +55,15 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.dir/audio"/>
             </intent-filter>
+            <intent-filter android:priority="-1">
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="content" />
+                <data android:scheme="file" />
+                <data android:mimeType="video/*" />
+                <data android:mimeType="image/*" />
+            </intent-filter>
         </activity>
 
         <!-- Settings package stubs -->
diff --git a/car-lib/api/current.txt b/car-lib/api/current.txt
index c1c0e63..bab3b88 100644
--- a/car-lib/api/current.txt
+++ b/car-lib/api/current.txt
@@ -533,7 +533,9 @@
 package android.car.hardware.property {
 
   public class CarPropertyManager {
+    method public int getAreaId(int, int);
     method public boolean getBooleanProperty(int, int);
+    method @Nullable public android.car.hardware.CarPropertyConfig<?> getCarPropertyConfig(int);
     method public float getFloatProperty(int, int);
     method @NonNull public int[] getIntArrayProperty(int, int);
     method public int getIntProperty(int, int);
diff --git a/car-lib/src/android/car/Car.java b/car-lib/src/android/car/Car.java
index f3fb100..3bf0f5d 100644
--- a/car-lib/src/android/car/Car.java
+++ b/car-lib/src/android/car/Car.java
@@ -61,6 +61,7 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.TransactionTooLargeException;
 import android.os.UserHandle;
 import android.util.Log;
 
@@ -1462,7 +1463,12 @@
 
     /** @hide */
     void handleRemoteExceptionFromCarService(RemoteException e) {
-        Log.w(TAG_CAR, "Car service has crashed", e);
+        if (e instanceof TransactionTooLargeException) {
+            Log.w(TAG_CAR, "Car service threw TransactionTooLargeException", e);
+            throw new CarTransactionException(e, "Car service threw TransactionTooLargException");
+        } else {
+            Log.w(TAG_CAR, "Car service has crashed", e);
+        }
     }
 
 
@@ -1498,10 +1504,18 @@
 
     /** @hide */
     public static  void handleRemoteExceptionFromCarService(Service service, RemoteException e) {
-        Log.w(TAG_CAR,
-                "Car service has crashed, client:" + service.getPackageName() + ","
-                        + service.getClass().getSimpleName(), e);
-        service.stopSelf();
+        if (e instanceof TransactionTooLargeException) {
+            Log.w(TAG_CAR, "Car service threw TransactionTooLargeException, client:"
+                    + service.getPackageName() + ","
+                    + service.getClass().getSimpleName(), e);
+            throw new CarTransactionException(e, "Car service threw TransactionTooLargeException, "
+                + "client: %s, %s", service.getPackageName(), service.getClass().getSimpleName());
+        } else {
+            Log.w(TAG_CAR, "Car service has crashed, client:"
+                    + service.getPackageName() + ","
+                    + service.getClass().getSimpleName(), e);
+            service.stopSelf();
+        }
     }
 
     @Nullable
diff --git a/car-lib/src/android/car/CarTransactionException.java b/car-lib/src/android/car/CarTransactionException.java
new file mode 100644
index 0000000..c0e7e2f
--- /dev/null
+++ b/car-lib/src/android/car/CarTransactionException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 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;
+
+/**
+ * Runtime exception thrown when a transaction-level binder exception has occurred.
+ *
+ * This allows clients to log or recover transaction errors as appropriate.
+ *
+ * @hide
+ */
+public class CarTransactionException extends UnsupportedOperationException {
+    CarTransactionException(Throwable cause, String msg, Object... args) {
+        super(String.format(msg, args), cause);
+    }
+}
+
diff --git a/car-lib/src/android/car/hardware/property/CarPropertyManager.java b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
index e3651da..9419d6d 100644
--- a/car-lib/src/android/car/hardware/property/CarPropertyManager.java
+++ b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
@@ -23,6 +23,7 @@
 import android.annotation.Nullable;
 import android.car.Car;
 import android.car.CarManagerBase;
+import android.car.VehicleAreaType;
 import android.car.hardware.CarPropertyConfig;
 import android.car.hardware.CarPropertyValue;
 import android.os.Handler;
@@ -317,6 +318,47 @@
     }
 
     /**
+     * Get CarPropertyConfig by property Id.
+     *
+     * @param propId Property ID
+     * @return {@link CarPropertyConfig} for the selected property.
+     * Null if the property is not available.
+     */
+    @Nullable
+    public CarPropertyConfig<?> getCarPropertyConfig(int propId) {
+        return  mConfigMap.get(propId);
+    }
+
+    /**
+     * Returns areaId contains the seletcted area for the property.
+     *
+     * @param propId Property ID
+     * @param area Area enum such as Enums in {@link android.car.VehicleAreaSeat}.
+     * @throws IllegalArgumentException if the property is not available in the vehicle for
+     * the selected area.
+     * @return AreaId contains the selected area for the property.
+     */
+    public int getAreaId(int propId, int area) {
+        CarPropertyConfig<?> propConfig = getCarPropertyConfig(propId);
+        if (propConfig == null) {
+            throw new IllegalArgumentException("The property propId: 0x" + toHexString(propId)
+                    + " is not available");
+        }
+        // For the global property, areaId is 0
+        if (propConfig.isGlobalProperty()) {
+            return VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
+        }
+        for (int areaId : propConfig.getAreaIds()) {
+            if ((area & areaId) == area) {
+                return areaId;
+            }
+        }
+
+        throw new IllegalArgumentException("The property propId: 0x" + toHexString(propId)
+                + " is not available at the area: 0x" + toHexString(area));
+    }
+
+    /**
      * Return read permission string for given property ID.
      *
      * @param propId Property ID to query
diff --git a/car-lib/src/android/car/settings/CarSettings.java b/car-lib/src/android/car/settings/CarSettings.java
index 888ccad..cd31a50 100644
--- a/car-lib/src/android/car/settings/CarSettings.java
+++ b/car-lib/src/android/car/settings/CarSettings.java
@@ -54,22 +54,6 @@
                 "android.car.GARAGE_MODE_MAINTENANCE_WINDOW";
 
         /**
-         * Key for default user id to boot into.
-         *
-         * @hide
-         */
-        public static final String DEFAULT_USER_ID_TO_BOOT_INTO =
-                "android.car.DEFAULT_BOOT_INTO_USER_ID";
-
-        /**
-         * Key for user id that is last logged in to.
-         *
-         * @hide
-         */
-        public static final String LAST_ACTIVE_USER_ID =
-                "android.car.LAST_ACTIVE_USER_ID";
-
-        /**
          * Whether default restrictions for users have been set.
          *
          * @hide
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-af/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-af/strings.xml
index cf04334..abf8fd2 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-af/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-af/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Bestuurder"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"kry benaderde ligging net op die voorgrond"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-am/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-am/strings.xml
index 4afdf25..0f190c4 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-am/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-am/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ነጂ"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"ከፊት ለፊት ብቻ ግምታዊ አካባቢን ድረስ"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ar/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ar/strings.xml
index 874ff29..aa51d5d 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ar/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ar/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"السائق"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"الوصول إلى الموقع الجغرافي التقريبي في الواجهة الأمامية فقط"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-az/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-az/strings.xml
index 67b565b..3e2ccc1 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-az/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-az/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Sürücü"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"yalnız ön planda təqribi məkana daxil olun"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-b+sr+Latn/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-b+sr+Latn/strings.xml
index 5f857c2..a20c58e 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-b+sr+Latn/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-b+sr+Latn/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Vozač"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"pristup približnoj lokaciji samo u prvom planu"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-be/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-be/strings.xml
index 7cc0826..d6e8de4 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-be/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-be/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Вадзіцель"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"доступ да прыблізнага месцазнаходжання толькі ў асноўным рэжыме"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-bg/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-bg/strings.xml
index ad2abf6..7a2fd23 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-bg/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-bg/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Шофьор"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"достъп до приблизителното местоположение само на преден план"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-bn/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-bn/strings.xml
index cb6d8a6..e9725c8 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-bn/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-bn/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ড্রাইভার"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"শুধুমাত্র অ্যাপটি খোলা থাকলে আপনার আনুমানিক লোকেশন অ্যাক্সেস করা"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-bs/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-bs/strings.xml
index 5f857c2..a20c58e 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-bs/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-bs/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Vozač"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"pristup približnoj lokaciji samo u prvom planu"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ca/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ca/strings.xml
index 130c869..8d24e22 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ca/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ca/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Conductor"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"accedeix a la ubicació aproximada només en primer pla"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-cs/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-cs/strings.xml
index 40d9e58..2432df2 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-cs/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-cs/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Řidič"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"přístup k přibližné poloze jen na popředí"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml
index 25c544c..4f95061 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-da/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Chauffør"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"få kun adgang til omtrentlig placering i forgrunden"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-de/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-de/strings.xml
index 6a1deea..9febde6 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-de/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-de/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Fahrer"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"Nur bei Ausführung im Vordergrund auf den ungefähren Standort zugreifen"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-el/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-el/strings.xml
index 4c317af..fcfe739 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-el/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-el/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Οδηγός"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"πρόσβαση στην κατά προσέγγιση τοποθεσία μόνο στο προσκήνιο"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-en-rAU/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-en-rAU/strings.xml
index a4a3e1a..85c4908 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-en-rAU/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-en-rAU/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Driver"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"access approximate location only in the foreground"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-en-rCA/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-en-rCA/strings.xml
index a4a3e1a..85c4908 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-en-rCA/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-en-rCA/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Driver"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"access approximate location only in the foreground"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-en-rGB/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-en-rGB/strings.xml
index a4a3e1a..85c4908 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-en-rGB/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-en-rGB/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Driver"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"access approximate location only in the foreground"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-en-rIN/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-en-rIN/strings.xml
index a4a3e1a..85c4908 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-en-rIN/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-en-rIN/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Driver"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"access approximate location only in the foreground"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-en-rXC/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-en-rXC/strings.xml
index 725d577..7778984 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-en-rXC/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-en-rXC/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‎Driver‎‏‎‎‏‎"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎access approximate location only in the foreground‎‏‎‎‏‎"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-es-rUS/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-es-rUS/strings.xml
index 130c869..5666331 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-es-rUS/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-es-rUS/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Conductor"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"acceder a la ubicación aproximada solo en primer plano"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-es/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-es/strings.xml
index 130c869..3e3ad48 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-es/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-es/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Conductor"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"acceder a la ubicación aproximada solo al estar en primer plano"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-et/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-et/strings.xml
index 4cffa81..27ae02b 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-et/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-et/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Sõitja"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"juurdepääs ligikaudsele asukohale ainult esiplaanil"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-eu/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-eu/strings.xml
index 14ccb8e..f7e62cf 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-eu/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-eu/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Gidaria"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"atzitu gutxi gorabeherako kokapena aurreko planoan bakarrik"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-fa/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-fa/strings.xml
index 19c4ff9..4d257d6 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-fa/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-fa/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"راننده"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"دسترسی به مکان تقریبی فقط در پیش‌زمینه"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-fi/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-fi/strings.xml
index 07853e1..b2d5135 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-fi/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-fi/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Kuljettaja"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"käyttää likimääräistä sijaintia vain etualalla"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-fr-rCA/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-fr-rCA/strings.xml
index 3cfdaf3..2ac4be7 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-fr-rCA/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-fr-rCA/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Conducteur"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"accéder à votre position approximative seulement en avant-plan"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-fr/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-fr/strings.xml
index 3cfdaf3..81af986 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-fr/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-fr/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Conducteur"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"accéder à la position approximative au premier plan uniquement"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-gl/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-gl/strings.xml
index fa09574..3754442 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-gl/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-gl/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Condutor"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"acceder á localización aproximada só en primeiro plano"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-gu/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-gu/strings.xml
index 62dd43e..5c6ff84 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-gu/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-gu/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ડ્રાઇવર"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"ફૉરગ્રાઉન્ડમાં ફક્ત અંદાજિત સ્થાન ઍક્સેસ કરો"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-hi/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-hi/strings.xml
index fbe93e1..003478d 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-hi/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-hi/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ड्राइवर"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"अनुमानित जगह की जानकारी सिर्फ़ तब ऐक्सेस करें, जब ऐप्लिकेशन स्क्रीन पर खुला हो"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-hr/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-hr/strings.xml
index 5f857c2..4cffd31 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-hr/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-hr/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Vozač"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"pristupiti približnoj lokaciji samo u prednjem planu"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-hu/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-hu/strings.xml
index 83dc49a..52b7760 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-hu/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-hu/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Sofőr"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"megközelítőleges helyadatokhoz való hozzáférés csak előtérben"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-hy/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-hy/strings.xml
index cbaa105..68df140 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-hy/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-hy/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Վարորդ"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"տեղադրության մոտավոր տվյալների հասանելիություն միայն ֆոնային ռեժիմում"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-in/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-in/strings.xml
index 89fa52e..21c21a8 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-in/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-in/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Pengemudi"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"akses perkiraan lokasi hanya saat di latar depan"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-is/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-is/strings.xml
index 38bba6e..1eb3776 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-is/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-is/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Ökumaður"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"aðgangur að áætlaðri staðsetningu aðeins í forgrunni"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-it/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-it/strings.xml
index c9491dd..c704544 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-it/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-it/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Autista"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"Accesso alla posizione approssimativa solo in primo piano"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ja/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ja/strings.xml
index 7872368..eb41c01 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ja/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ja/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ドライバー"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"フォアグラウンドでのみおおよその位置情報を取得"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ka/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ka/strings.xml
index 55879f3..4d26423 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ka/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ka/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"მძღოლი"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"მიახლოებით მდებარეობაზე წვდომა მხოლოდ წინა პლანზე"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-kk/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-kk/strings.xml
index 68714f3..b12a6d5 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-kk/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-kk/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Көлік жүргізуші"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"болжалды орналасқан жер туралы ақпаратқа тек ашық экранда кіру"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-km/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-km/strings.xml
index f2d19e7..4975540 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-km/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-km/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"អ្នក​បើកបរ"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"ចូលប្រើ​ទីតាំង​ប្រហាក់ប្រហែល​តែនៅផ្ទៃ​ខាងមុខប៉ុណ្ណោះ"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-kn/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-kn/strings.xml
index 1812f01..27e9a9e 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-kn/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-kn/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ಡ್ರೈವರ್"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"ಮುನ್ನೆಲೆಯಲ್ಲಿ ಮಾತ್ರ ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ko/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ko/strings.xml
index 6fb8bbd..20facb1 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ko/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ko/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"운전자"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"포그라운드에서만 대략적인 위치에 액세스"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ky/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ky/strings.xml
index a961e34..1a43c49 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ky/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ky/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Айдоочу"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"болжолдуу аныкталган жайгашкан жерге активдүү режимде гана кирүүгө уруксат берүү"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-lo/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-lo/strings.xml
index a2e075b..877a259 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-lo/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-lo/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ຄົນຂັບລົດ"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"ເຂົ້າເຖິງສະຖານທີ່ໂດຍປະມານເມື່ອຢູ່ໃນພື້ນໜ້າເທົ່ານັ້ນ"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-lt/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-lt/strings.xml
index 20d10d8..134230f 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-lt/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-lt/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Vairuotojas"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"pasiekti apytikslę vietovę, tik kai programa veikia priekiniame plane"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-lv/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-lv/strings.xml
index f8a9b63..3cc5c88 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-lv/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-lv/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Vadītājs"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"piekļuve aptuvenai atrašanās vietai, tikai darbojoties priekšplānā"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-mk/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-mk/strings.xml
index ea97216..3b1eda7 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-mk/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-mk/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Возач"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"пристап до приближната локација само во преден план"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ml/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ml/strings.xml
index e09eaeb..95298dd 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ml/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ml/strings.xml
@@ -18,4 +18,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ഡ്രൈവർ"</string>
+    <!-- no translation found for permlab_accessCoarseLocation (2494909511737161237) -->
+    <skip />
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-mn/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-mn/strings.xml
index 5a1682e..dd1d6a2 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-mn/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-mn/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Жолооч"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"ойролцоо байршилд зөвхөн дэлгэц дээр хандах"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-mr/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-mr/strings.xml
index de33088..a0619ec 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-mr/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-mr/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ड्रायव्हर"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"फक्त फोअरग्राउंडमध्ये अंदाजे स्थान अ‍ॅक्सेस करा"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ms/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ms/strings.xml
index 837f538..7f22021 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ms/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ms/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Pemandu"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"akses lokasi anggaran hanya di latar depan"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-my/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-my/strings.xml
index 5c96457..aea1568 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-my/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-my/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ယာဉ်မောင်းသူ"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"မျက်နှာစာတွင်သာ ခန့်မှန်းခြေ တည်နေရာ အသုံးပြုခြင်း"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-nb/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-nb/strings.xml
index 139517b..6e0de84 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-nb/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-nb/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Sjåfør"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"bare tilgang til omtrentlig posisjon i forgrunnen"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-nl/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-nl/strings.xml
index c634d43..873fb01 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-nl/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-nl/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Chauffeur"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"alleen toegang tot geschatte locatie op de voorgrond"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-or/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-or/strings.xml
index 04f5336..964683f 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-or/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-or/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ଡ୍ରାଇଭର୍"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"କେବଳ ଫୋର୍‌ଗ୍ରାଉଣ୍ଡରେ ହାରାହାରି ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-pa/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-pa/strings.xml
index 354b580..16541d3 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-pa/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-pa/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ਡਰਾਈਵਰ"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"ਸਿਰਫ਼ ਫੋਰਗ੍ਰਾਊਂਡ ਵਿੱਚ ਅਨੁਮਾਨਿਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-pl/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-pl/strings.xml
index 315bf44..d0ff092 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-pl/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-pl/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Kierowca"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"dostęp do przybliżonej lokalizacji tylko na pierwszym planie"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-pt-rPT/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-pt-rPT/strings.xml
index fa09574..984000a 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-pt-rPT/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-pt-rPT/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Condutor"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"apenas aceder à localização aproximada em primeiro plano"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-pt/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-pt/strings.xml
index af84856..7ac9eef 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-pt/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-pt/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Motorista"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"acessar local aproximado apenas em primeiro plano"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ro/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ro/strings.xml
index c6ca011..ec78db2 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ro/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ro/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Șofer"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"să acceseze locația aproximativă numai în prim-plan"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ru/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ru/strings.xml
index 87359fb..ed49d76 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ru/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ru/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Водитель"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"Доступ к приблизительному местоположению только в активном режиме"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-si/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-si/strings.xml
index a2aa811..fcba27e 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-si/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-si/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"රියදුරු"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"පෙරබිම තුළ පමණක් ආසන්න ස්ථානයට ප්‍රවේශය"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-sk/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-sk/strings.xml
index 94a4723..c9a990d 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-sk/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-sk/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Vodič"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"prístup k približnej polohe iba v popredí"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-sl/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-sl/strings.xml
index 9f75529..918dda4 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-sl/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-sl/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Voznik"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"dostop do približne lokacije samo, ko deluje v ospredju"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-sq/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-sq/strings.xml
index 4e6cd54..e4192e7 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-sq/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-sq/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Drejtuesi"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"qasu në vendndodhjen e përafërt vetëm në plan të parë"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-sr/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-sr/strings.xml
index ea97216..8cce889 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-sr/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-sr/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Возач"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"приступ приближној локацији само у првом плану"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-sv/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-sv/strings.xml
index 12d2369..b5b4f63 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-sv/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-sv/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Förare"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"endast åtkomst till ungefärlig plats i förgrunden"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-sw/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-sw/strings.xml
index 90924e1..765973c 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-sw/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-sw/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Dereva"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"kufikia mahali palipokadiriwa ikiwa tu programu imefunguliwa kwenye skrini"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ta/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ta/strings.xml
index 47a7058..264f0c1 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ta/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ta/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"கார் உரிமையாளர்"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"முன்புலத்தில் இயங்கும்போது மட்டும் தோராயமான இருப்பிடத்தைக் கண்டறிதல்"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-th/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-th/strings.xml
index c3d4c8c..8fae2ca 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-th/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-th/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ผู้ขับรถ"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"เข้าถึงตำแหน่งโดยประมาณเมื่ออยู่เบื้องหน้าเท่านั้น"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-tl/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-tl/strings.xml
index a4a3e1a..d425a87 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-tl/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-tl/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Driver"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"i-access lang ang tinatantyang lokasyon sa foreground"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-tr/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-tr/strings.xml
index 67b565b..244564e 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-tr/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-tr/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Sürücü"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"yalnızca ön planda yaklaşık konuma erişme"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-uk/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-uk/strings.xml
index 1bc0b22..b46d679 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-uk/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-uk/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Водій"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"отримувати доступ до даних про приблизне місцезнаходження лише в активному режимі"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-ur/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-ur/strings.xml
index f69a738..89fd655 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-ur/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-ur/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"ڈرائیور"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"صرف پیش منظر میں تخمینی مقام تک رسائی"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-uz/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-uz/strings.xml
index 07264f4..9914c10 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-uz/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-uz/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Haydovchi"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"taxminiy joylashuv axborotini olishga faqat old fonda ruxsat"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-vi/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-vi/strings.xml
index ef6b702..41ce1e9 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-vi/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-vi/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Tài xế"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"chỉ truy cập thông tin vị trí gần đúng trong nền trước"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-zh-rCN/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-zh-rCN/strings.xml
index 0347e14..06fe50d 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-zh-rCN/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-zh-rCN/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"司机"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"只有在前台运行时才能获取大致位置信息"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-zh-rHK/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-zh-rHK/strings.xml
index 37aab13..86618d3 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-zh-rHK/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-zh-rHK/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"司機"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"只在前景存取大概位置"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-zh-rTW/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-zh-rTW/strings.xml
index 8ecce72..59f09e1 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-zh-rTW/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-zh-rTW/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"駕駛"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"僅可在前景中取得概略位置"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values-zu/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values-zu/strings.xml
index b5ec2c1..adb9402 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values-zu/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values-zu/strings.xml
@@ -18,4 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="owner_name" msgid="3416113395996003764">"Umshayeli"</string>
+    <string name="permlab_accessCoarseLocation" msgid="2494909511737161237">"finyelela indawo enembile kuphela engaphambili"</string>
 </resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/config.xml b/car_product/overlay/frameworks/base/core/res/res/values/config.xml
index cbd1660..2d28676 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values/config.xml
@@ -97,8 +97,9 @@
 
     <bool name="config_automotiveHideNavBarForKeyboard">true</bool>
 
-    <!-- Turn off Wallpaper service -->
-    <bool name="config_enableWallpaperService">false</bool>
+    <!-- Turn on Wallpaper service -->
+    <!-- Enabled temporarily to watch the dashboard-->
+    <bool name="config_enableWallpaperService">true</bool>
 
     <!-- Default user restrictions for system user 0. -->
     <string-array translatable="false" name="config_defaultFirstUserRestrictions">
diff --git a/computepipe/aidl/Android.bp b/computepipe/aidl/Android.bp
index b70b9b4..a60b2f2 100644
--- a/computepipe/aidl/Android.bp
+++ b/computepipe/aidl/Android.bp
@@ -3,13 +3,19 @@
     vendor_available: true,
     srcs: [
         "android/automotive/computepipe/runner/*.aidl",
-	"android/automotive/computepipe/*.aidl",
+        "android/automotive/computepipe/*.aidl",
+    ],
+    imports: [
+        "vintf-graphics-common",
     ],
     stability: "vintf",
     backend: {
         java: {
             enabled: false,
         },
+        cpp: {
+            enabled: false,
+        },
     },
 }
 
@@ -19,12 +25,15 @@
     imports: ["android.automotive.computepipe.runner"],
     srcs: [
         "android/automotive/computepipe/registry/*.aidl",
-	"android/automotive/computepipe/*.aidl",
+        "android/automotive/computepipe/*.aidl",
     ],
     stability: "vintf",
     backend: {
         java: {
             enabled: false,
         },
+        cpp: {
+            enabled: false,
+        },
     },
 }
diff --git a/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl b/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl
index b76210c..44f7e6b 100644
--- a/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl
+++ b/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl
@@ -16,7 +16,7 @@
 package android.automotive.computepipe.runner;
 
 import android.automotive.computepipe.runner.PacketDescriptorPacketType;
-import android.automotive.computepipe.NativeHandle;
+import android.hardware.graphics.common.HardwareBuffer;
 
 /**
  * Structure that describes the output packet for a specific outputstream
@@ -40,8 +40,10 @@
     /**
      * handle to memory region containing zero copy data
      * This handle can be mapped and data retrieved.
+     * In case of Pixel data the description field will contain the
+     * graphics buffer description.
      */
-    NativeHandle handle;
+    HardwareBuffer handle;
     /**
      * Timestamp of event at source. Timestamp value is milliseconds since epoch.
      */
@@ -51,4 +53,3 @@
      */
     @utf8InCpp String data;
 }
-
diff --git a/computepipe/proto/InputConfig.proto b/computepipe/proto/InputConfig.proto
index f696d57..b061e46 100644
--- a/computepipe/proto/InputConfig.proto
+++ b/computepipe/proto/InputConfig.proto
@@ -32,7 +32,7 @@
    * of InputType. If only one of a certain type is present
    * this should be 0. For VIDEO_FILE this should be 0.
    */
-  optional int32 camId = 6;
+  optional int32 cam_id = 6;
 
   optional int32 config_id = 7;
 }
diff --git a/computepipe/proto/Options.proto b/computepipe/proto/Options.proto
index 94a7927..14d130d 100644
--- a/computepipe/proto/Options.proto
+++ b/computepipe/proto/Options.proto
@@ -11,7 +11,7 @@
   /**
    * input configurations supported by the graph
    */
-  optional InputConfig input_configs = 1;
+  repeated InputConfig input_configs = 1;
 
   /**
    * Offload options supported by the graph
@@ -25,4 +25,9 @@
    * Output streams supported by the graph.
    */
   repeated OutputConfig output_configs = 4;
+
+  /**
+   * Name of the computer vision graph.
+   */
+  optional string graph_name = 5;
 }
diff --git a/computepipe/router/1.0/Android.bp b/computepipe/router/1.0/Android.bp
index d1bad50..dd4b6c0 100644
--- a/computepipe/router/1.0/Android.bp
+++ b/computepipe/router/1.0/Android.bp
@@ -12,33 +12,33 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-
 cc_library {
     name: "android.automotive.computepipe.router@1.0-impl",
-    vendor_available : true,
+    vendor_available: true,
     srcs: [
         "PipeClient.cpp",
-	"PipeRunner.cpp",
-	"PipeRegistration.cpp",
-	"PipeQuery.cpp",
+        "PipeRunner.cpp",
+        "PipeRegistration.cpp",
+        "PipeQuery.cpp",
+        "RemoteState.cpp",
     ],
-    cflags: ["-DLOG_TAG=\"ComputepipeRouter\""]
-    + [
-    	"-Wall",
-	"-Werror",
-	"-Wextra",
-	"-Wno-unused-parameter",
-    ],
+    cflags: ["-DLOG_TAG=\"ComputepipeRouter\""] +
+        [
+            "-Wall",
+            "-Werror",
+            "-Wextra",
+            "-Wno-unused-parameter",
+        ],
     header_libs: [
-      "computepipe_router_headers",
+        "computepipe_router_headers",
     ],
     export_include_dirs: ["include"],
     shared_libs: [
-	"liblog",
+        "liblog",
         "libutils",
-	"libbinder",
-        "android.automotive.computepipe.registry-cpp",
-        "android.automotive.computepipe.runner-cpp",
+        "libbinder_ndk",
+        "android.automotive.computepipe.registry-ndk_platform",
+        "android.automotive.computepipe.runner-ndk_platform",
     ],
 }
 
@@ -48,22 +48,18 @@
         "service.cpp",
         "RouterSvc.cpp",
     ],
-         
     shared_libs: [
         "libcutils",
         "liblog",
         "libutils",
-        "libbinder",
+        "libbinder_ndk",
         "android.automotive.computepipe.router@1.0-impl",
-        "android.automotive.computepipe.registry-cpp",
+        "android.automotive.computepipe.registry-ndk_platform",
     ],
-
     header_libs: [
-      "computepipe_router_headers",
+        "computepipe_router_headers",
     ],
-
     init_rc: ["android.automotive.computepipe.router@1.0.rc"],
-
     cflags: ["-DLOG_TAG=\"ComputepipeRouter\""] + [
         "-DGL_GLEXT_PROTOTYPES",
         "-DEGL_EGLEXT_PROTOTYPES",
@@ -73,5 +69,4 @@
         "-Wunused",
         "-Wunreachable-code",
     ],
-
 }
diff --git a/computepipe/router/1.0/PipeClient.cpp b/computepipe/router/1.0/PipeClient.cpp
index 3896d73..817782a 100644
--- a/computepipe/router/1.0/PipeClient.cpp
+++ b/computepipe/router/1.0/PipeClient.cpp
@@ -16,7 +16,7 @@
 
 #include "PipeClient.h"
 
-#include <binder/ProcessState.h>
+#include <android/binder_ibinder.h>
 
 namespace android {
 namespace automotive {
@@ -25,7 +25,13 @@
 namespace V1_0 {
 namespace implementation {
 
-using namespace android::automotive::computepipe::registry;
+using namespace aidl::android::automotive::computepipe::registry;
+using namespace ndk;
+
+PipeClient::PipeClient(const std::shared_ptr<IClientInfo>& info)
+    : mDeathMonitor(AIBinder_DeathRecipient_new(RemoteMonitor::BinderDiedCallback)),
+      mClientInfo(info) {
+}
 
 uint32_t PipeClient::getClientId() {
     if (mClientInfo == nullptr) {
@@ -38,37 +44,19 @@
 }
 
 bool PipeClient::startClientMonitor() {
-    mClientMonitor = new ClientMonitor();
-    if (!mClientMonitor) {
-        return false;
-    }
-    const sp<IBinder> client = IInterface::asBinder(mClientInfo);
-    if (!client) {
-        return false;
-    }
-    auto res = client->linkToDeath(mClientMonitor);
-    return res == OK;
+    mState = std::make_shared<RemoteState>();
+    auto monitor = new RemoteMonitor(mState);
+    auto status = ScopedAStatus::fromStatus(
+        AIBinder_linkToDeath(mClientInfo->asBinder().get(), mDeathMonitor.get(), monitor));
+    return status.isOk();
 }
 
 bool PipeClient::isAlive() {
-    return mClientMonitor->isAlive();
+    return mState->isAlive();
 }
 
 PipeClient::~PipeClient() {
-    const sp<IBinder> client = IInterface::asBinder(mClientInfo);
-    (void)client->unlinkToDeath(mClientMonitor);
 }
-
-void ClientMonitor::binderDied(const wp<android::IBinder>& /* base */) {
-    std::lock_guard<std::mutex> lock(mStateLock);
-    mAlive = false;
-}
-
-bool ClientMonitor::isAlive() {
-    std::lock_guard<std::mutex> lock(mStateLock);
-    return mAlive;
-}
-
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace router
diff --git a/computepipe/router/1.0/PipeQuery.cpp b/computepipe/router/1.0/PipeQuery.cpp
index 9ea8db1..42e4f0b 100644
--- a/computepipe/router/1.0/PipeQuery.cpp
+++ b/computepipe/router/1.0/PipeQuery.cpp
@@ -25,37 +25,38 @@
 namespace implementation {
 
 using namespace android::automotive::computepipe::router;
-using namespace android::automotive::computepipe::registry;
-using namespace android::automotive::computepipe::runner;
-using namespace android::binder;
+using namespace aidl::android::automotive::computepipe::registry;
+using namespace aidl::android::automotive::computepipe::runner;
+using namespace ndk;
 
-Status PipeQuery::getGraphList(std::vector<std::string>* outNames) {
+ScopedAStatus PipeQuery::getGraphList(std::vector<std::string>* outNames) {
     if (!mRegistry || !outNames) {
-        return Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE);
+        return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
     }
     auto names = mRegistry->getPipeList();
     std::copy(names.begin(), names.end(), std::back_inserter(*outNames));
-    return Status::ok();
+    return ScopedAStatus::ok();
 }
 
-Status PipeQuery::getPipeRunner(const std::string& graphName, const sp<IClientInfo>& info,
-                                sp<IPipeRunner>* outRunner) {
+ScopedAStatus PipeQuery::getPipeRunner(const std::string& graphName,
+                                       const std::shared_ptr<IClientInfo>& info,
+                                       std::shared_ptr<IPipeRunner>* outRunner) {
     *outRunner = nullptr;
     if (!mRegistry) {
-        return Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE);
+        return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
     }
     std::unique_ptr<ClientHandle> clientHandle = std::make_unique<PipeClient>(info);
     auto pipeHandle = mRegistry->getClientPipeHandle(graphName, std::move(clientHandle));
     if (!pipeHandle) {
-        return Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE);
+        return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
     }
     auto pipeRunner = pipeHandle->getInterface();
     *outRunner = pipeRunner->runner;
-    return Status::ok();
+    return ScopedAStatus::ok();
 }
 
-String16 PipeQuery::getIfaceName() {
-    return this->getInterfaceDescriptor();
+const char* PipeQuery::getIfaceName() {
+    return this->descriptor;
 }
 }  // namespace implementation
 }  // namespace V1_0
diff --git a/computepipe/router/1.0/PipeRegistration.cpp b/computepipe/router/1.0/PipeRegistration.cpp
index 1a5eb8e..cff413c 100644
--- a/computepipe/router/1.0/PipeRegistration.cpp
+++ b/computepipe/router/1.0/PipeRegistration.cpp
@@ -22,31 +22,31 @@
 namespace V1_0 {
 namespace implementation {
 
-using namespace android::binder;
 using namespace android::automotive::computepipe;
-using namespace android::automotive::computepipe::runner;
+using namespace aidl::android::automotive::computepipe::runner;
+using namespace ndk;
 // Methods from ::android::automotive::computepipe::registry::V1_0::IPipeRegistration follow.
-Status PipeRegistration::registerPipeRunner(const std::string& graphName,
-                                            const sp<IPipeRunner>& graphRunner) {
+ScopedAStatus PipeRegistration::registerPipeRunner(const std::string& graphName,
+                                                   const std::shared_ptr<IPipeRunner>& graphRunner) {
     if (!mRegistry) {
-        return Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE);
+        return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
     }
     std::unique_ptr<PipeHandle<PipeRunner>> handle = std::make_unique<RunnerHandle>(graphRunner);
     auto err = mRegistry->RegisterPipe(std::move(handle), graphName);
     return convertToBinderStatus(err);
 }
 
-Status PipeRegistration::convertToBinderStatus(Error err) {
+ScopedAStatus PipeRegistration::convertToBinderStatus(Error err) {
     switch (err) {
         case OK:
-            return Status::ok();
+            return ScopedAStatus::ok();
         default:
-            return Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE);
+            return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
     }
 }
 
-String16 PipeRegistration::getIfaceName() {
-    return this->getInterfaceDescriptor();
+const char* PipeRegistration::getIfaceName() {
+    return this->descriptor;
 }
 }  // namespace implementation
 }  // namespace V1_0
diff --git a/computepipe/router/1.0/PipeRunner.cpp b/computepipe/router/1.0/PipeRunner.cpp
index 616e86b..cdf1cb1 100644
--- a/computepipe/router/1.0/PipeRunner.cpp
+++ b/computepipe/router/1.0/PipeRunner.cpp
@@ -16,6 +16,8 @@
 
 #include "PipeRunner.h"
 
+#include <android/binder_ibinder.h>
+
 #include <mutex>
 
 namespace android {
@@ -25,34 +27,27 @@
 namespace V1_0 {
 namespace implementation {
 
-using namespace android::automotive::computepipe::runner;
+using namespace aidl::android::automotive::computepipe::runner;
+using namespace ndk;
 
-PipeRunner::PipeRunner(const sp<IPipeRunner>& graphRunner) : runner(graphRunner) {
+PipeRunner::PipeRunner(const std::shared_ptr<IPipeRunner>& graphRunner) : runner(graphRunner) {
 }
 
-void PipeMonitor::binderDied(const wp<android::IBinder>& /* base */) {
-    mNotifier();
-}
-
-RunnerHandle::RunnerHandle(const sp<IPipeRunner>& r) : PipeHandle(std::make_unique<PipeRunner>(r)) {
+RunnerHandle::RunnerHandle(const std::shared_ptr<IPipeRunner>& r)
+    : PipeHandle(std::make_unique<PipeRunner>(r)),
+      mDeathMonitor(AIBinder_DeathRecipient_new(RemoteMonitor::BinderDiedCallback)) {
 }
 
 bool RunnerHandle::startPipeMonitor() {
-    sp<PipeMonitor> monitor = new PipeMonitor([this]() { this->markDead(); });
-    // We store a weak reference to be able to perform an unlink
-    mPipeMonitor = monitor;
-    sp<IBinder> iface = IInterface::asBinder(mInterface->runner);
-    return iface->linkToDeath(monitor) == OK;
-}
-
-void RunnerHandle::markDead() {
-    std::lock_guard<std::mutex> lock(mStateLock);
-    mAlive = false;
+    mState = std::make_shared<RemoteState>();
+    auto monitor = new RemoteMonitor(mState);
+    auto status = ScopedAStatus::fromStatus(
+        AIBinder_linkToDeath(mInterface->runner->asBinder().get(), mDeathMonitor.get(), monitor));
+    return status.isOk();
 }
 
 bool RunnerHandle::isAlive() {
-    std::lock_guard<std::mutex> lock(mStateLock);
-    return mAlive;
+    return mState->isAlive();
 }
 
 PipeHandle<PipeRunner>* RunnerHandle::clone() const {
@@ -60,8 +55,6 @@
 }
 
 RunnerHandle::~RunnerHandle() {
-    sp<IBinder> iface = IInterface::asBinder(mInterface->runner);
-    iface->unlinkToDeath(mPipeMonitor.promote());
 }
 
 }  // namespace implementation
diff --git a/computepipe/router/1.0/RemoteState.cpp b/computepipe/router/1.0/RemoteState.cpp
new file mode 100644
index 0000000..9d81fb6
--- /dev/null
+++ b/computepipe/router/1.0/RemoteState.cpp
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2019 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 "RemoteState.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace router {
+namespace V1_0 {
+namespace implementation {
+
+void RemoteState::markDead() {
+    std::lock_guard<std::mutex> lock(mStateLock);
+    mAlive = false;
+}
+
+bool RemoteState::isAlive() {
+    std::lock_guard<std::mutex> lock(mStateLock);
+    return mAlive;
+}
+
+void RemoteMonitor::binderDied() {
+    auto state = mState.lock();
+    if (state != nullptr) {
+        state->markDead();
+    }
+}
+
+void RemoteMonitor::BinderDiedCallback(void* cookie) {
+    auto monitor = static_cast<RemoteMonitor*>(cookie);
+    monitor->binderDied();
+}
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace router
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
diff --git a/computepipe/router/1.0/RouterSvc.cpp b/computepipe/router/1.0/RouterSvc.cpp
index 57ef9a0..0b296e6 100644
--- a/computepipe/router/1.0/RouterSvc.cpp
+++ b/computepipe/router/1.0/RouterSvc.cpp
@@ -15,8 +15,11 @@
  */
 #include "RouterSvc.h"
 
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
 #include <binder/IServiceManager.h>
 
+#include "PipeQuery.h"
 #include "PipeRegistration.h"
 #include "Registry.h"
 
@@ -49,15 +52,14 @@
 }
 
 Error RouterSvc::initRegistrationEngine() {
-    mRegisterEngine = new PipeRegistration(mRegistry);
+    mRegisterEngine = ndk::SharedRefBase::make<PipeRegistration>(mRegistry);
     if (!mRegisterEngine) {
         ALOGE("unable to allocate registration engine");
         return NOMEM;
     }
-    std::string name =
-        std::string() + String8(mRegisterEngine->getIfaceName()).c_str() + "/" + kRouterName;
-    auto status = defaultServiceManager()->addService(String16(name.c_str()), mRegisterEngine);
-    if (status != android::OK) {
+    std::string name = std::string() + mRegisterEngine->getIfaceName() + "/" + kRouterName;
+    auto status = AServiceManager_addService(mRegisterEngine->asBinder().get(), name.c_str());
+    if (status != STATUS_OK) {
         ALOGE("unable to add registration service %s", name.c_str());
         return INTERNAL_ERR;
     }
@@ -65,15 +67,14 @@
 }
 
 Error RouterSvc::initQueryEngine() {
-    mQueryEngine = new PipeQuery(mRegistry);
+    mQueryEngine = ndk::SharedRefBase::make<PipeQuery>(mRegistry);
     if (!mQueryEngine) {
         ALOGE("unable to allocate query service");
         return NOMEM;
     }
-    std::string name =
-        std::string() + String8(mQueryEngine->getIfaceName()).c_str() + "/" + kRouterName;
-    auto status = defaultServiceManager()->addService(String16(name.c_str()), mQueryEngine);
-    if (status != android::OK) {
+    std::string name = std::string() + mQueryEngine->getIfaceName() + "/" + kRouterName;
+    auto status = AServiceManager_addService(mQueryEngine->asBinder().get(), name.c_str());
+    if (status != STATUS_OK) {
         ALOGE("unable to add query service %s", name.c_str());
         return INTERNAL_ERR;
     }
diff --git a/computepipe/router/1.0/RouterSvc.h b/computepipe/router/1.0/RouterSvc.h
index 3d19807..08ea59c 100644
--- a/computepipe/router/1.0/RouterSvc.h
+++ b/computepipe/router/1.0/RouterSvc.h
@@ -50,8 +50,8 @@
     router::Error initRegistrationEngine();
 
     std::string mSvcName = "ComputePipeRouter";
-    sp<PipeQuery> mQueryEngine;
-    sp<PipeRegistration> mRegisterEngine;
+    std::shared_ptr<PipeQuery> mQueryEngine;
+    std::shared_ptr<PipeRegistration> mRegisterEngine;
     std::shared_ptr<RouterRegistry> mRegistry;
 };
 }  // namespace implementation
diff --git a/computepipe/router/1.0/include/PipeClient.h b/computepipe/router/1.0/include/PipeClient.h
index ea934ee..03fc8f3 100644
--- a/computepipe/router/1.0/include/PipeClient.h
+++ b/computepipe/router/1.0/include/PipeClient.h
@@ -17,12 +17,15 @@
 #ifndef ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPECLIENT
 #define ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPECLIENT
 
-#include <android/automotive/computepipe/registry/IClientInfo.h>
+#include <aidl/android/automotive/computepipe/registry/IClientInfo.h>
+#include <android/binder_auto_utils.h>
 
 #include <functional>
+#include <memory>
 #include <mutex>
 
 #include "ClientHandle.h"
+#include "RemoteState.h"
 
 namespace android {
 namespace automotive {
@@ -32,39 +35,23 @@
 namespace implementation {
 
 /**
- * Tracks Client Death
- */
-struct ClientMonitor : public IBinder::DeathRecipient {
-  public:
-    /* override method to track client death */
-    virtual void binderDied(const wp<android::IBinder>& base) override;
-    /* query for client death */
-    bool isAlive();
-
-  private:
-    std::function<void()> mHandleCb;
-    bool mAlive = true;
-    std::mutex mStateLock;
-};
-
-/**
  * PipeClient: Encapsulated the IPC interface to the client.
  *
  * Allows for querrying the client state
  */
 class PipeClient : public ClientHandle {
   public:
-    explicit PipeClient(const sp<android::automotive::computepipe::registry::IClientInfo>& info)
-        : mClientInfo(info) {
-    }
+    explicit PipeClient(
+        const std::shared_ptr<aidl::android::automotive::computepipe::registry::IClientInfo>& info);
     bool startClientMonitor() override;
     uint32_t getClientId() override;
     bool isAlive() override;
     ~PipeClient();
 
   private:
-    sp<ClientMonitor> mClientMonitor;
-    sp<android::automotive::computepipe::registry::IClientInfo> mClientInfo;
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathMonitor;
+    std::shared_ptr<RemoteState> mState;
+    const std::shared_ptr<aidl::android::automotive::computepipe::registry::IClientInfo> mClientInfo;
 };
 
 }  // namespace implementation
diff --git a/computepipe/router/1.0/include/PipeQuery.h b/computepipe/router/1.0/include/PipeQuery.h
index ee17bc0..4cf80ac 100644
--- a/computepipe/router/1.0/include/PipeQuery.h
+++ b/computepipe/router/1.0/include/PipeQuery.h
@@ -17,7 +17,9 @@
 #ifndef ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPEQUERY
 #define ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPEQUERY
 
-#include <android/automotive/computepipe/registry/BnPipeQuery.h>
+#include <aidl/android/automotive/computepipe/registry/BnPipeQuery.h>
+
+#include <memory>
 
 #include "PipeRunner.h"
 #include "Registry.h"
@@ -29,16 +31,17 @@
 namespace V1_0 {
 namespace implementation {
 
-class PipeQuery : public android::automotive::computepipe::registry::BnPipeQuery {
+class PipeQuery : public aidl::android::automotive::computepipe::registry::BnPipeQuery {
   public:
     explicit PipeQuery(std::shared_ptr<PipeRegistry<PipeRunner>> r) : mRegistry(r) {
     }
-    binder::Status getGraphList(::std::vector<std::string>* outNames) override;
-    binder::Status getPipeRunner(
+    ndk::ScopedAStatus getGraphList(::std::vector<std::string>* outNames) override;
+    ndk::ScopedAStatus getPipeRunner(
         const std::string& graphName,
-        const sp<::android::automotive::computepipe::registry::IClientInfo>& info,
-        sp<::android::automotive::computepipe::runner::IPipeRunner>* outRunner) override;
-    String16 getIfaceName();
+        const std::shared_ptr<aidl::android::automotive::computepipe::registry::IClientInfo>& info,
+        std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeRunner>* outRunner)
+        override;
+    const char* getIfaceName();
 
   private:
     std::shared_ptr<PipeRegistry<PipeRunner>> mRegistry;
diff --git a/computepipe/router/1.0/include/PipeRegistration.h b/computepipe/router/1.0/include/PipeRegistration.h
index 2258d72..abd5a99 100644
--- a/computepipe/router/1.0/include/PipeRegistration.h
+++ b/computepipe/router/1.0/include/PipeRegistration.h
@@ -16,7 +16,7 @@
 
 #ifndef ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPEREGISTRATION
 #define ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPEREGISTRATION
-#include <android/automotive/computepipe/registry/BnPipeRegistration.h>
+#include <aidl/android/automotive/computepipe/registry/BnPipeRegistration.h>
 
 #include <memory>
 #include <utility>
@@ -31,21 +31,22 @@
 namespace V1_0 {
 namespace implementation {
 
-class PipeRegistration : public android::automotive::computepipe::registry::BnPipeRegistration {
+class PipeRegistration
+    : public aidl::android::automotive::computepipe::registry::BnPipeRegistration {
   public:
     // Method from ::android::automotive::computepipe::registry::V1_0::IPipeRegistration
-    android::binder::Status registerPipeRunner(
+    ndk::ScopedAStatus registerPipeRunner(
         const std::string& graphName,
-        const ::android::sp<::android::automotive::computepipe::runner::IPipeRunner>& graphRunner)
-        override;
+        const std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeRunner>&
+            graphRunner) override;
 
     explicit PipeRegistration(std::shared_ptr<PipeRegistry<PipeRunner>> r) : mRegistry(r) {
     }
-    String16 getIfaceName();
+    const char* getIfaceName();
 
   private:
     // Convert internal registry error codes to PipeStatus
-    android::binder::Status convertToBinderStatus(Error err);
+    ndk::ScopedAStatus convertToBinderStatus(Error err);
     std::shared_ptr<PipeRegistry<PipeRunner>> mRegistry;
 };
 
diff --git a/computepipe/router/1.0/include/PipeRunner.h b/computepipe/router/1.0/include/PipeRunner.h
index 43a777a..d3d0453 100644
--- a/computepipe/router/1.0/include/PipeRunner.h
+++ b/computepipe/router/1.0/include/PipeRunner.h
@@ -16,12 +16,14 @@
 
 #ifndef ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPERUNNER
 #define ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_PIPERUNNER
-#include <android/automotive/computepipe/runner/IPipeRunner.h>
+#include <aidl/android/automotive/computepipe/runner/IPipeRunner.h>
 
 #include <functional>
+#include <memory>
 #include <mutex>
 
 #include "PipeHandle.h"
+#include "RemoteState.h"
 
 namespace android {
 namespace automotive {
@@ -34,12 +36,12 @@
  * Wrapper for IPC handle
  */
 struct PipeRunner {
-    explicit PipeRunner(const sp<android::automotive::computepipe::runner::IPipeRunner>& graphRunner);
-    sp<android::automotive::computepipe::runner::IPipeRunner> runner;
+    explicit PipeRunner(
+        const std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeRunner>&
+            graphRunner);
+    std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeRunner> runner;
 };
 
-class PipeMonitor;
-
 /**
  * Runner Handle to be stored with registry.
  *
@@ -48,7 +50,8 @@
  */
 class RunnerHandle : public android::automotive::computepipe::router::PipeHandle<PipeRunner> {
   public:
-    explicit RunnerHandle(const sp<android::automotive::computepipe::runner::IPipeRunner>& r);
+    explicit RunnerHandle(
+        const std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeRunner>& r);
     /**
      * override registry pipehandle methods
      */
@@ -58,28 +61,8 @@
     ~RunnerHandle();
 
   private:
-    /**
-     * method used by monitor to report death
-     */
-    void markDead();
-    bool mAlive = true;
-    std::mutex mStateLock;
-    // Instance of the monitor for the associated runner
-    wp<PipeMonitor> mPipeMonitor;
-};
-
-/**
- * Monitors binder death notifications to handle death of the graph runner
- * process
- */
-class PipeMonitor : public IBinder::DeathRecipient {
-  public:
-    PipeMonitor(std::function<void()> cb) : mNotifier(cb) {
-    }
-    void binderDied(const wp<android::IBinder>& base) override;
-
-  private:
-    std::function<void()> mNotifier;
+    std::shared_ptr<RemoteState> mState;
+    ndk::ScopedAIBinder_DeathRecipient mDeathMonitor;
 };
 
 }  // namespace implementation
diff --git a/computepipe/router/1.0/include/RemoteState.h b/computepipe/router/1.0/include/RemoteState.h
new file mode 100644
index 0000000..6fa34df
--- /dev/null
+++ b/computepipe/router/1.0/include/RemoteState.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019 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 ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_REMOTESTATE
+#define ANDROID_AUTOMOTIVE_COMPUTEPIPE_ROUTER_V1_0_REMOTESTATE
+
+#include <utils/RefBase.h>
+
+#include <memory>
+#include <mutex>
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace router {
+namespace V1_0 {
+namespace implementation {
+
+/**
+ * Wrapper for the Runner State machine
+ */
+class RemoteState {
+  public:
+    RemoteState() = default;
+    void markDead();
+    bool isAlive();
+
+  private:
+    std::mutex mStateLock;
+    bool mAlive = true;
+};
+
+/**
+ * Monitor for tracking remote state
+ */
+class RemoteMonitor : public RefBase {
+  public:
+    explicit RemoteMonitor(const std::weak_ptr<RemoteState>& s) : mState(s) {
+    }
+    static void BinderDiedCallback(void* cookie);
+    void binderDied();
+
+  private:
+    std::weak_ptr<RemoteState> mState;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace router
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
+#endif
diff --git a/computepipe/router/1.0/service.cpp b/computepipe/router/1.0/service.cpp
index c671d0f..6135836 100644
--- a/computepipe/router/1.0/service.cpp
+++ b/computepipe/router/1.0/service.cpp
@@ -1,5 +1,4 @@
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
+#include <android/binder_process.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
@@ -29,9 +28,9 @@
         ALOGE("Bad Args");
         exit(2);
     }
-    android::ProcessState::self()->startThreadPool();
+    ABinderProcess_startThreadPool();
     std::thread registrationThread(startService);
-    android::IPCThreadState::self()->joinThreadPool();
+    ABinderProcess_joinThreadPool();
     ALOGE("Router thread joined IPC pool");
     return 1;
 }
diff --git a/computepipe/runner/Android.bp b/computepipe/runner/Android.bp
index 0007512..33684e7 100644
--- a/computepipe/runner/Android.bp
+++ b/computepipe/runner/Android.bp
@@ -18,5 +18,8 @@
     static_libs: [
          "libcomputepipeprotos",
     ],
-    visibility:["//packages/services/Car/computepipe/runner:__subpackages__"],
+    visibility:[
+        "//packages/services/Car/computepipe/runner:__subpackages__",
+	"//packages/services/Car/computepipe/tests:__subpackages__",
+    ],
 }
diff --git a/computepipe/runner/stream_manager/Android.bp b/computepipe/runner/stream_manager/Android.bp
new file mode 100644
index 0000000..70d98c5
--- /dev/null
+++ b/computepipe/runner/stream_manager/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 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.
+
+cc_library {
+    name: "libcomputepipe_stream_manager",
+    srcs: [
+        "Factory.cpp",
+	"SemanticManager.cpp",
+    ],
+    export_include_dirs: ["include"],
+    visibility: [
+        "//packages/services/Car/computepipe/runner:__subpackages__",
+        "//packages/services/Car/computepipe/tests:__subpackages__",
+    ],
+    header_libs: [
+        "computepipe_runner_includes",
+    ],
+    static_libs: [
+         "libcomputepipeprotos",
+    ],
+    include_dirs: [
+        "packages/services/Car/computepipe",
+    ],
+}
diff --git a/computepipe/runner/stream_manager/Factory.cpp b/computepipe/runner/stream_manager/Factory.cpp
new file mode 100644
index 0000000..27fc442
--- /dev/null
+++ b/computepipe/runner/stream_manager/Factory.cpp
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 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 "OutputConfig.pb.h"
+#include "SemanticManager.h"
+#include "StreamManager.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner {
+namespace stream_manager {
+
+std::unique_ptr<StreamManager> StreamManagerFactory::getStreamManager(
+    const proto::OutputConfig& config) {
+    if (!config.has_type()) {
+        return nullptr;
+    }
+    switch (config.type()) {
+        case proto::PacketType::SEMANTIC_DATA:
+            return std::make_unique<SemanticManager>(config.stream_name(), config.type());
+        default:
+            return nullptr;
+    }
+    return nullptr;
+}
+
+}  // namespace stream_manager
+}  // namespace runner
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
diff --git a/computepipe/runner/stream_manager/SemanticManager.cpp b/computepipe/runner/stream_manager/SemanticManager.cpp
new file mode 100644
index 0000000..e9482d2
--- /dev/null
+++ b/computepipe/runner/stream_manager/SemanticManager.cpp
@@ -0,0 +1,133 @@
+#include "SemanticManager.h"
+
+#include <cstdlib>
+
+#include "types/Status.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner {
+namespace stream_manager {
+
+proto::PacketType SemanticHandle::getType() {
+    return mType;
+}
+
+uint64_t SemanticHandle::getTimeStamp() {
+    return mTimestamp;
+}
+
+uint32_t SemanticHandle::getSize() {
+    return mSize;
+}
+
+const char* SemanticHandle::getData() {
+    return mData;
+}
+
+native_handle_t SemanticHandle::getNativeHandle() {
+    native_handle_t temp;
+    temp.numFds = 0;
+    temp.numInts = 0;
+    return temp;
+}
+
+Status SemanticHandle::setMemInfo(const char* data, uint32_t size, uint64_t timestamp,
+                                  const proto::PacketType& type) {
+    if (data == nullptr || size == 0 || size > kMaxSemanticDataSize) {
+        return INVALID_ARGUMENT;
+    }
+    mData = (char*)malloc(size);
+    if (!mData) {
+        return NO_MEMORY;
+    }
+    memcpy(mData, data, size);
+    mType = type;
+    mTimestamp = timestamp;
+    mSize = size;
+    return SUCCESS;
+}
+
+/* Destroy local copy */
+SemanticHandle::~SemanticHandle() {
+    free(mData);
+}
+
+Status SemanticManager::setIpcDispatchCallback(
+    std::function<Status(const std::shared_ptr<MemHandle>)>& cb) {
+    mDispatchCallback = cb;
+    std::lock_guard<std::mutex> lock(mStateLock);
+    mState = RESET;
+    return SUCCESS;
+}
+
+// TODO: b/146495240 Add support for batching
+Status SemanticManager::setMaxInFlightPackets(uint32_t /* maxPackets */) {
+    if (!mDispatchCallback) {
+        return ILLEGAL_STATE;
+    }
+    mState = CONFIG_DONE;
+    return SUCCESS;
+}
+
+Status SemanticManager::start() {
+    std::lock_guard<std::mutex> lock(mStateLock);
+    if (mState != CONFIG_DONE) {
+        return ILLEGAL_STATE;
+    }
+    mState = RUNNING;
+    return SUCCESS;
+}
+
+Status SemanticManager::stop(bool /* flush */) {
+    std::lock_guard<std::mutex> lock(mStateLock);
+    if (mState != RUNNING) {
+        return ILLEGAL_STATE;
+    }
+    /*
+     * We skip directly to config_done as there is no outstanding cleanup
+     * required
+     */
+    mState = CONFIG_DONE;
+    return SUCCESS;
+}
+
+Status SemanticManager::cleanup() {
+    std::lock_guard<std::mutex> lock(mStateLock);
+    mState = RESET;
+    return SUCCESS;
+}
+
+Status SemanticManager::freePacket(const std::shared_ptr<MemHandle>& /* handle */) {
+    return SUCCESS;
+}
+
+Status SemanticManager::queuePacket(const char* data, const uint32_t size, uint64_t timestamp) {
+    std::lock_guard<std::mutex> lock(mStateLock);
+    // We drop the packet since we have received the stop notifications.
+    if (mState != RUNNING) {
+        return SUCCESS;
+    }
+    // Invalid state.
+    if (mDispatchCallback == nullptr) {
+        return INTERNAL_ERROR;
+    }
+    auto memHandle = std::make_shared<SemanticHandle>();
+    auto status = memHandle->setMemInfo(data, size, timestamp, mType);
+    if (status != SUCCESS) {
+        return status;
+    }
+    mDispatchCallback(memHandle);
+    return SUCCESS;
+}
+
+SemanticManager::SemanticManager(std::string name, const proto::PacketType& type)
+    : StreamManager(name, type) {
+}
+
+}  // namespace stream_manager
+}  // namespace runner
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
diff --git a/computepipe/runner/stream_manager/SemanticManager.h b/computepipe/runner/stream_manager/SemanticManager.h
new file mode 100644
index 0000000..8a7cf94
--- /dev/null
+++ b/computepipe/runner/stream_manager/SemanticManager.h
@@ -0,0 +1,81 @@
+// Copyright (C) 2019 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 COMPUTEPIPE_RUNNER_STREAM_MANAGER_SEMANTIC_MANAGER_H
+#define COMPUTEPIPE_RUNNER_STREAM_MANAGER_SEMANTIC_MANAGER_H
+
+#include <mutex>
+
+#include "OutputConfig.pb.h"
+#include "StreamManager.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner {
+namespace stream_manager {
+
+class SemanticHandle : public MemHandle {
+  public:
+    static constexpr uint32_t kMaxSemanticDataSize = 1024;
+    proto::PacketType getType() override;
+    /* Retrieve packet time stamp */
+    uint64_t getTimeStamp() override;
+    /* Get size */
+    uint32_t getSize() override;
+    /* Get data, raw pointer. Only implemented for copy semantics */
+    const char* getData() override;
+    /* Get native handle. data with zero copy semantics */
+    native_handle_t getNativeHandle() override;
+    /* set info for the memory. Make a copy */
+    Status setMemInfo(const char* data, uint32_t size, uint64_t timestamp,
+                      const proto::PacketType& type);
+    /* Destroy local copy */
+    ~SemanticHandle();
+
+  private:
+    char* mData = nullptr;
+    uint32_t mSize;
+    uint64_t mTimestamp;
+    proto::PacketType mType;
+};
+
+class SemanticManager : public StreamManager {
+  public:
+    Status setIpcDispatchCallback(
+        std::function<Status(const std::shared_ptr<MemHandle>)>& cb) override;
+    /* Set Max in flight packets based on client specification */
+    Status setMaxInFlightPackets(uint32_t maxPackets) override;
+    /* Start stream manager */
+    Status start() override;
+    /* Stop stream manager */
+    Status stop(bool flush) override;
+    /* initiate cleanup. Forget maxinflightPackets */
+    Status cleanup() override;
+    /* Free previously dispatched packet. Once client has confirmed usage */
+    Status freePacket(const std::shared_ptr<MemHandle>& memhandle) override;
+    /* Queue packet produced by graph stream */
+    Status queuePacket(const char* data, const uint32_t size, uint64_t timestamp) override;
+    explicit SemanticManager(std::string name, const proto::PacketType& type);
+
+  private:
+    std::mutex mStateLock;
+    std::function<Status(const std::shared_ptr<MemHandle>&)> mDispatchCallback = nullptr;
+};
+}  // namespace stream_manager
+}  // namespace runner
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
+#endif
diff --git a/computepipe/runner/stream_manager/include/StreamManager.h b/computepipe/runner/stream_manager/include/StreamManager.h
new file mode 100644
index 0000000..e6aaad2
--- /dev/null
+++ b/computepipe/runner/stream_manager/include/StreamManager.h
@@ -0,0 +1,105 @@
+// Copyright (C) 2019 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 COMPUTEPIPE_RUNNER_STREAM_MANAGER_H
+#define COMPUTEPIPE_RUNNER_STREAM_MANAGER_H
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "MemHandle.h"
+#include "OutputConfig.pb.h"
+#include "types/Status.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner {
+namespace stream_manager {
+
+/**
+ * Manager the operations of an output stream from the graph.
+ * Should be constructed using the StreamManagerFactory.
+ * The manager instance for a given stream depends on the streams
+ * description specified in OuputConfig.
+ */
+
+class StreamManager {
+  public:
+    enum State {
+        /* State on construction. */
+        RESET = 0,
+        /* State once inflight packets set */
+        CONFIG_DONE = 1,
+        /* State once packets are */
+        RUNNING = 2,
+        /**
+         * State once stop issued
+         * Returns to config done, once all in flight packets handled.
+         */
+        STOPPED = 3,
+    };
+    /* Constructor for StreamManager Base class */
+    explicit StreamManager(std::string streamName, const proto::PacketType& type)
+        : mName(streamName), mType(type) {
+    }
+    /**
+     * IPC dispatch routine invoked by Stream manager, to send output packet to client.
+     * Callback must be set before any client specific configs are applied.
+     */
+    virtual Status setIpcDispatchCallback(std::function<Status(std::shared_ptr<MemHandle>)>& cb) = 0;
+    /* Retrieves the current state */
+    State getState() {
+        return mState;
+    }
+    /* Sets max in flight packets based on client specification */
+    virtual Status setMaxInFlightPackets(uint32_t maxPackets) = 0;
+    /* Starts stream manager */
+    virtual Status start() = 0;
+    /* Stops stream manager */
+    virtual Status stop(bool flush) = 0;
+    /* Initiates cleanup. Forgets maxinflightPackets */
+    virtual Status cleanup() = 0;
+    /* Frees previously dispatched packet. Once client has confirmed usage */
+    virtual Status freePacket(const std::shared_ptr<MemHandle>& memhandle) = 0;
+    /* Queue's packet produced by graph stream */
+    virtual Status queuePacket(const char* data, const uint32_t size, uint64_t timestamp) = 0;
+    /* Destructor */
+    virtual ~StreamManager() = default;
+
+  protected:
+    std::string mName;
+    proto::PacketType mType;
+    State mState = RESET;
+};
+
+/**
+ * Factory for generating stream manager instances
+ */
+class StreamManagerFactory {
+  public:
+    std::unique_ptr<StreamManager> getStreamManager(const proto::OutputConfig& config);
+    StreamManagerFactory(const StreamManagerFactory&) = delete;
+    StreamManagerFactory& operator=(const StreamManagerFactory&) = delete;
+    StreamManagerFactory() = default;
+};
+
+}  // namespace stream_manager
+}  // namespace runner
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
+
+#endif
diff --git a/computepipe/runner/utils/Android.bp b/computepipe/runner/utils/Android.bp
index b820de0..74c6656 100644
--- a/computepipe/runner/utils/Android.bp
+++ b/computepipe/runner/utils/Android.bp
@@ -35,11 +35,14 @@
         "liblog",
         "libutils",
         "android.automotive.computepipe.runner-ndk_platform",
+        "android.automotive.computepipe.registry-ndk_platform",
         "libprotobuf-cpp-lite",
     ],
 
     visibility:["//packages/services/Car/computepipe/runner:__subpackages__"],
     srcs: [
+        "InterfaceImpl.cc",
+        "PipeOptionsConverter.cc",
         "RunnerInterface.cc",
     ],
 }
diff --git a/computepipe/runner/utils/DebuggerInterface.cc b/computepipe/runner/utils/DebuggerInterface.cc
new file mode 100644
index 0000000..66556da
--- /dev/null
+++ b/computepipe/runner/utils/DebuggerInterface.cc
@@ -0,0 +1,13 @@
+// Copyright (C) 2019 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.
diff --git a/computepipe/runner/utils/InterfaceImpl.cc b/computepipe/runner/utils/InterfaceImpl.cc
new file mode 100644
index 0000000..245e59b
--- /dev/null
+++ b/computepipe/runner/utils/InterfaceImpl.cc
@@ -0,0 +1,234 @@
+// Copyright (C) 2019 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.c
+
+#define LOG_TAG "RunnerIpcInterface"
+
+#include "InterfaceImpl.h"
+
+#include <android-base/logging.h>
+#include "PacketDescriptor.pb.h"
+#include "PipeOptionsConverter.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner_utils {
+namespace {
+
+using ::aidl::android::automotive::computepipe::runner::IPipeStateCallback;
+using ::aidl::android::automotive::computepipe::runner::IPipeStream;
+using ::aidl::android::automotive::computepipe::runner::PipeDescriptor;
+using ::aidl::android::automotive::computepipe::runner::PipeState;
+using ::ndk::ScopedAStatus;
+
+ScopedAStatus ToNdkStatus(Status status) {
+    switch (status) {
+        case SUCCESS:
+            return ScopedAStatus::ok();
+        case INTERNAL_ERROR:
+            return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+        case INVALID_ARGUMENT:
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        case FATAL_ERROR:
+        default:
+            return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+    }
+}
+
+PipeState ToAidlState(GraphState state) {
+    switch (state) {
+        case RESET:
+            return PipeState::RESET;
+        case CONFIG_DONE:
+            return PipeState::CONFIG_DONE;
+        case RUNNING:
+            return PipeState::RUNNING;
+        case DONE:
+            return PipeState::DONE;
+        case ERR_HALT:
+        default:
+            return PipeState::ERR_HALT;
+    }
+}
+
+void deathNotifier(void* cookie) {
+    InterfaceImpl* iface = static_cast<InterfaceImpl*>(cookie);
+    iface->clientDied();
+}
+
+}  // namespace
+
+// Thread-safe function to deliver new packets to client.
+Status InterfaceImpl::newPacketNotification(int32_t streamId,
+                                            const std::shared_ptr<MemHandle>& packetHandle) {
+    // TODO(146464279) implement.
+    (void)packetHandle;
+    return Status::SUCCESS;
+}
+
+Status InterfaceImpl::stateUpdateNotification(const GraphState newState) {
+    (void)mClientStateChangeCallback->handleState(ToAidlState(newState));
+    return Status::SUCCESS;
+}
+
+ScopedAStatus InterfaceImpl::getPipeDescriptor(PipeDescriptor* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    *_aidl_return = OptionsToPipeDesciptor(mGraphOptions);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus InterfaceImpl::setPipeInputSource(int32_t configId) {
+    if (!isClientInitDone()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    proto::ConfigurationCommand configurationCommand;
+    configurationCommand.mutable_set_input_source()->set_source_id(configId);
+
+    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);
+    return ToNdkStatus(status);
+}
+
+ScopedAStatus InterfaceImpl::setPipeOffloadOptions(int32_t configId) {
+    if (!isClientInitDone()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    proto::ConfigurationCommand configurationCommand;
+    configurationCommand.mutable_set_offload_offload()->set_offload_option_id(configId);
+
+    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);
+    return ToNdkStatus(status);
+}
+
+ScopedAStatus InterfaceImpl::setPipeTermination(int32_t configId) {
+    if (!isClientInitDone()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    proto::ConfigurationCommand configurationCommand;
+    configurationCommand.mutable_set_termination_option()->set_termination_option_id(configId);
+
+    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);
+    return ToNdkStatus(status);
+}
+
+ScopedAStatus InterfaceImpl::init(const std::shared_ptr<IPipeStateCallback>& stateCb) {
+    if (isClientInitDone()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(&deathNotifier);
+    AIBinder_linkToDeath(stateCb->asBinder().get(), recipient, this);
+
+    mClientStateChangeCallback = stateCb;
+    return ScopedAStatus::ok();
+}
+
+bool InterfaceImpl::isClientInitDone() {
+    if (mClientStateChangeCallback == nullptr) {
+        return false;
+    }
+    return true;
+}
+
+void InterfaceImpl::clientDied() {
+    LOG(INFO) << "Client has died";
+    releaseRunner();
+}
+
+ScopedAStatus InterfaceImpl::setPipeOutputConfig(int32_t streamId, int32_t maxInFlightCount,
+                                                 const std::shared_ptr<IPipeStream>& handler) {
+    if (!isClientInitDone()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    if (mPacketHandlers.find(streamId) != mPacketHandlers.end()) {
+        LOG(INFO) << "Handler for stream id " << streamId
+                  << " has already"
+                     " been registered.";
+        return ToNdkStatus(INVALID_ARGUMENT);
+    }
+
+    mPacketHandlers.insert(std::pair<int, std::shared_ptr<IPipeStream>>(streamId, handler));
+
+    proto::ConfigurationCommand configurationCommand;
+    configurationCommand.mutable_set_output_stream()->set_stream_id(streamId);
+    configurationCommand.mutable_set_output_stream()->set_max_inflight_packets_count(
+        maxInFlightCount);
+    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);
+
+    if (status != SUCCESS) {
+        LOG(INFO) << "Failed to register handler for stream id " << streamId;
+        mPacketHandlers.erase(streamId);
+    }
+    return ToNdkStatus(status);
+}
+
+ScopedAStatus InterfaceImpl::applyPipeConfigs() {
+    if (!isClientInitDone()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    proto::ControlCommand controlCommand;
+    *controlCommand.mutable_apply_configs() = proto::ApplyConfigs();
+
+    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);
+    return ToNdkStatus(status);
+}
+
+ScopedAStatus InterfaceImpl::startPipe() {
+    proto::ControlCommand controlCommand;
+    *controlCommand.mutable_start_graph() = proto::StartGraph();
+
+    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);
+    return ToNdkStatus(status);
+}
+
+ScopedAStatus InterfaceImpl::stopPipe() {
+    proto::ControlCommand controlCommand;
+    *controlCommand.mutable_stop_graph() = proto::StopGraph();
+
+    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);
+    return ToNdkStatus(status);
+}
+
+ScopedAStatus InterfaceImpl::doneWithPacket(int32_t id) {
+    // TODO(146464279) implement.
+    return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InterfaceImpl::getPipeDebugger(
+    std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeDebugger>* _aidl_return) {
+    // TODO(146464281) implement.
+    return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus InterfaceImpl::releaseRunner() {
+    proto::ControlCommand controlCommand;
+    *controlCommand.mutable_death_notification() = proto::DeathNotification();
+
+    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);
+
+    mClientStateChangeCallback = nullptr;
+    mPacketHandlers.clear();
+    return ToNdkStatus(status);
+}
+
+}  // namespace runner_utils
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
diff --git a/computepipe/runner/utils/InterfaceImpl.h b/computepipe/runner/utils/InterfaceImpl.h
new file mode 100644
index 0000000..26684c2
--- /dev/null
+++ b/computepipe/runner/utils/InterfaceImpl.h
@@ -0,0 +1,97 @@
+// Copyright (C) 2019 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 COMPUTEPIPE_RUNNER_UTILS_INTERFACEIMPL_H_
+#define COMPUTEPIPE_RUNNER_UTILS_INTERFACEIMPL_H_
+#include <aidl/android/automotive/computepipe/runner/BnPipeRunner.h>
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "RunnerInterfaceCallbacks.h"
+#include "MemHandle.h"
+#include "types/GraphState.h"
+#include "types/Status.h"
+
+#include "Options.pb.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner_utils {
+
+// RunnerInterface registers an IPipeRunner interface with computepipe router.
+// RunnerInterface handles binder IPC calls and invokes appropriate callbacks.
+class InterfaceImpl : public aidl::android::automotive::computepipe::runner::BnPipeRunner {
+  public:
+    explicit InterfaceImpl(const proto::Options graphOptions,
+                           const RunnerInterfaceCallbacks& runnerInterfaceCallbacks)
+        : mGraphOptions(graphOptions), mRunnerInterfaceCallbacks(runnerInterfaceCallbacks) {
+    }
+
+    ~InterfaceImpl() {
+    }
+
+    Status newPacketNotification(int32_t streamId, const std::shared_ptr<MemHandle>& packetHandle);
+
+    Status stateUpdateNotification(const GraphState newState);
+
+    // Methods from android::automotive::computepipe::runner::BnPipeRunner
+    ndk::ScopedAStatus init(
+        const std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStateCallback>&
+            stateCb) override;
+    ndk::ScopedAStatus getPipeDescriptor(
+        aidl::android::automotive::computepipe::runner::PipeDescriptor* _aidl_return) override;
+    ndk::ScopedAStatus setPipeInputSource(int32_t configId) override;
+    ndk::ScopedAStatus setPipeOffloadOptions(int32_t configId) override;
+    ndk::ScopedAStatus setPipeTermination(int32_t configId) override;
+    ndk::ScopedAStatus setPipeOutputConfig(
+        int32_t streamId, int32_t maxInFlightCount,
+        const std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStream>& handler)
+        override;
+    ndk::ScopedAStatus applyPipeConfigs() override;
+    ndk::ScopedAStatus startPipe() override;
+    ndk::ScopedAStatus stopPipe() override;
+    ndk::ScopedAStatus doneWithPacket(int32_t id) override;
+
+    ndk::ScopedAStatus getPipeDebugger(
+        std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeDebugger>* _aidl_return)
+        override;
+
+    ndk::ScopedAStatus releaseRunner() override;
+
+    void clientDied();
+
+  private:
+    const proto::Options mGraphOptions;
+    const RunnerInterfaceCallbacks& mRunnerInterfaceCallbacks;
+
+    bool isClientInitDone();
+
+    // If value of mClientStateChangeCallback is null pointer, client has not
+    // invoked init.
+    std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStateCallback>
+        mClientStateChangeCallback = nullptr;
+
+    std::map<int, std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStream>>
+        mPacketHandlers;
+};
+
+}  // namespace runner_utils
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
+
+#endif  // COMPUTEPIPE_RUNNER_UTILS_INTERFACEIMPL_H_
diff --git a/computepipe/runner/utils/PipeOptionsConverter.cc b/computepipe/runner/utils/PipeOptionsConverter.cc
new file mode 100644
index 0000000..e117251
--- /dev/null
+++ b/computepipe/runner/utils/PipeOptionsConverter.cc
@@ -0,0 +1,172 @@
+// Copyright (C) 2019 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 "PipeOptionsConverter.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner_utils {
+
+using ::aidl::android::automotive::computepipe::runner::PipeDescriptor;
+using ::aidl::android::automotive::computepipe::runner::PipeInputConfig;
+using ::aidl::android::automotive::computepipe::runner::PipeInputConfigFormatType;
+using ::aidl::android::automotive::computepipe::runner::PipeInputConfigInputType;
+using ::aidl::android::automotive::computepipe::runner::PipeOffloadConfig;
+using ::aidl::android::automotive::computepipe::runner::PipeOffloadConfigOffloadType;
+using ::aidl::android::automotive::computepipe::runner::PipeOutputConfig;
+using ::aidl::android::automotive::computepipe::runner::PipeOutputConfigPacketType;
+using ::aidl::android::automotive::computepipe::runner::PipeTerminationConfig;
+using ::aidl::android::automotive::computepipe::runner::PipeTerminationConfigTerminationType;
+
+namespace {
+
+PipeInputConfigInputType ConvertInputType(proto::InputConfig_InputType type) {
+    switch (type) {
+        case proto::InputConfig_InputType_DRIVER_VIEW_CAMERA:
+            return PipeInputConfigInputType::DRIVER_VIEW_CAMERA;
+        case proto::InputConfig_InputType_OCCUPANT_VIEW_CAMERA:
+            return PipeInputConfigInputType::OCCUPANT_VIEW_CAMERA;
+        case proto::InputConfig_InputType_EXTERNAL_CAMERA:
+            return PipeInputConfigInputType::EXTERNAL_CAMERA;
+        case proto::InputConfig_InputType_SURROUND_VIEW_CAMERA:
+            return PipeInputConfigInputType::SURROUND_VIEW_CAMERA;
+        case proto::InputConfig_InputType_VIDEO_FILE:
+            return PipeInputConfigInputType::VIDEO_FILE;
+    }
+}
+
+PipeInputConfigFormatType ConvertInputFormat(proto::InputConfig_FormatType type) {
+    switch (type) {
+        case proto::InputConfig_FormatType_RGB:
+            return PipeInputConfigFormatType::RGB;
+        case proto::InputConfig_FormatType_NIR:
+            return PipeInputConfigFormatType::NIR;
+        case proto::InputConfig_FormatType_NIR_DEPTH:
+            return PipeInputConfigFormatType::NIR_DEPTH;
+    }
+}
+
+PipeOffloadConfigOffloadType ConvertOffloadType(proto::OffloadOption_OffloadType type) {
+    switch (type) {
+        case proto::OffloadOption_OffloadType_CPU:
+            return PipeOffloadConfigOffloadType::CPU;
+        case proto::OffloadOption_OffloadType_GPU:
+            return PipeOffloadConfigOffloadType::GPU;
+        case proto::OffloadOption_OffloadType_NEURAL_ENGINE:
+            return PipeOffloadConfigOffloadType::NEURAL_ENGINE;
+        case proto::OffloadOption_OffloadType_CV_ENGINE:
+            return PipeOffloadConfigOffloadType::CV_ENGINE;
+    }
+}
+
+PipeOutputConfigPacketType ConvertOutputType(proto::PacketType type) {
+    switch (type) {
+        case proto::PacketType::SEMANTIC_DATA:
+            return PipeOutputConfigPacketType::SEMANTIC_DATA;
+        case proto::PacketType::PIXEL_DATA:
+            return PipeOutputConfigPacketType::PIXEL_DATA;
+        case proto::PacketType::PIXEL_ZERO_COPY_DATA:
+            return PipeOutputConfigPacketType::PIXEL_ZERO_COPY_DATA;
+    }
+}
+
+PipeTerminationConfigTerminationType ConvertTerminationType(
+    proto::TerminationOption_TerminationType type) {
+    switch (type) {
+        case proto::TerminationOption_TerminationType_CLIENT_STOP:
+            return PipeTerminationConfigTerminationType::CLIENT_STOP;
+        case proto::TerminationOption_TerminationType_MIN_PACKET_COUNT:
+            return PipeTerminationConfigTerminationType::MIN_PACKET_COUNT;
+        case proto::TerminationOption_TerminationType_MAX_RUN_TIME:
+            return PipeTerminationConfigTerminationType::MAX_RUN_TIME;
+        case proto::TerminationOption_TerminationType_EVENT:
+            return PipeTerminationConfigTerminationType::EVENT;
+    }
+}
+
+PipeInputConfig ConvertInputConfigProto(proto::InputConfig proto) {
+    PipeInputConfig aidlConfig;
+    aidlConfig.options.type = ConvertInputType(proto.type());
+    aidlConfig.options.format = ConvertInputFormat(proto.format());
+    aidlConfig.options.width = proto.width();
+    aidlConfig.options.height = proto.height();
+    aidlConfig.options.stride = proto.stride();
+    aidlConfig.options.camId = proto.cam_id();
+    aidlConfig.configId = proto.config_id();
+    return aidlConfig;
+}
+
+PipeOffloadConfig ConvertOffloadConfigProto(proto::OffloadConfig proto) {
+    PipeOffloadConfig aidlConfig;
+
+    for (int i = 0; i < proto.options().offload_types_size(); i++) {
+        auto offloadType =
+            static_cast<proto::OffloadOption_OffloadType>(proto.options().offload_types()[i]);
+        PipeOffloadConfigOffloadType aidlType = ConvertOffloadType(offloadType);
+        aidlConfig.options.type.emplace_back(aidlType);
+        aidlConfig.options.isVirtual.emplace_back(proto.options().is_virtual()[i]);
+    }
+
+    aidlConfig.configId = proto.config_id();
+    return aidlConfig;
+}
+
+PipeOutputConfig ConvertOutputConfigProto(proto::OutputConfig proto) {
+    PipeOutputConfig aidlConfig;
+    aidlConfig.output.name = proto.stream_name();
+    aidlConfig.output.type = ConvertOutputType(proto.type());
+    aidlConfig.outputId = proto.stream_id();
+    return aidlConfig;
+}
+
+PipeTerminationConfig ConvertTerminationConfigProto(proto::TerminationConfig proto) {
+    PipeTerminationConfig aidlConfig;
+    aidlConfig.options.type = ConvertTerminationType(proto.options().type());
+    aidlConfig.options.qualifier = proto.options().qualifier();
+    aidlConfig.configId = proto.config_id();
+    return aidlConfig;
+}
+
+}  // namespace
+
+PipeDescriptor OptionsToPipeDesciptor(proto::Options options) {
+    PipeDescriptor desc;
+    for (int i = 0; i < options.input_configs_size(); i++) {
+        PipeInputConfig inputConfig = ConvertInputConfigProto(options.input_configs()[i]);
+        desc.inputConfig.emplace_back(inputConfig);
+    }
+
+    for (int i = 0; i < options.offload_configs_size(); i++) {
+        PipeOffloadConfig offloadConfig = ConvertOffloadConfigProto(options.offload_configs()[i]);
+        desc.offloadConfig.emplace_back(offloadConfig);
+    }
+
+    for (int i = 0; i < options.termination_configs_size(); i++) {
+        PipeTerminationConfig terminationConfig =
+            ConvertTerminationConfigProto(options.termination_configs()[i]);
+        desc.terminationConfig.emplace_back(terminationConfig);
+    }
+
+    for (int i = 0; i < options.output_configs_size(); i++) {
+        PipeOutputConfig outputConfig = ConvertOutputConfigProto(options.output_configs()[i]);
+        desc.outputConfig.emplace_back(outputConfig);
+    }
+    return desc;
+}
+
+}  // namespace runner_utils
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
diff --git a/computepipe/runner/utils/PipeOptionsConverter.h b/computepipe/runner/utils/PipeOptionsConverter.h
new file mode 100644
index 0000000..dc44eb1
--- /dev/null
+++ b/computepipe/runner/utils/PipeOptionsConverter.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 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 COMPUTEPIPE_RUNNER_UTILS_PIPEOPTIONSCONVERTER_H_
+#define COMPUTEPIPE_RUNNER_UTILS_PIPEOPTIONSCONVERTER_H_
+
+#include <aidl/android/automotive/computepipe/runner/BnPipeRunner.h>
+
+#include "Options.pb.h"
+
+namespace android {
+namespace automotive {
+namespace computepipe {
+namespace runner_utils {
+
+aidl::android::automotive::computepipe::runner::PipeDescriptor OptionsToPipeDesciptor(
+    proto::Options options);
+
+}  // namespace runner_utils
+}  // namespace computepipe
+}  // namespace automotive
+}  // namespace android
+
+#endif  // COMPUTEPIPE_RUNNER_UTILS_PIPEOPTIONSCONVERTER_H_
diff --git a/computepipe/runner/utils/RunnerInterface.cc b/computepipe/runner/utils/RunnerInterface.cc
index 4724092..66c2bea 100644
--- a/computepipe/runner/utils/RunnerInterface.cc
+++ b/computepipe/runner/utils/RunnerInterface.cc
@@ -12,13 +12,106 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#define LOG_TAG "RunnerIpcInterface"
+
 #include "RunnerInterface.h"
 
+#include <thread>
+
+#include <aidl/android/automotive/computepipe/registry/IPipeRegistration.h>
+#include <android/binder_manager.h>
+#include <android-base/logging.h>
+
 namespace android {
 namespace automotive {
 namespace computepipe {
 namespace runner_utils {
 
+using ::aidl::android::automotive::computepipe::registry::IPipeRegistration;
+using ::ndk::ScopedAStatus;
+
+namespace {
+const char kRegistryInterfaceName[] = "router";
+
+void deathNotifier(void* cookie) {
+    RunnerInterface* runnerIface = static_cast<RunnerInterface*>(cookie);
+    runnerIface->routerDied();
+}
+
+}  // namespace
+
+Status RunnerInterface::init() {
+    if (mPipeRunner) {
+        return Status::INVALID_ARGUMENT;
+    }
+
+    mPipeRunner = std::make_shared<InterfaceImpl>(mGraphOptions, mRunnerInterfaceCallbacks);
+    std::thread t(&RunnerInterface::tryRegisterPipeRunner, this);
+    t.detach();
+    return Status::SUCCESS;
+}
+
+bool RunnerInterface::tryRegisterPipeRunner() {
+    if (!mPipeRunner) {
+        LOG(ERROR) << "Init must be called before attempting to connect to router.";
+        return false;
+    }
+
+    const std::string instanceName =
+        std::string() + IPipeRegistration::descriptor + "/" + kRegistryInterfaceName;
+
+    for (int i =0; i < mMaxRouterConnectionAttempts; i++) {
+        if (i != 0) {
+            sleep(mRouterConnectionAttemptIntervalSeconds);
+        }
+
+        ndk::SpAIBinder binder(AServiceManager_getService(instanceName.c_str()));
+        if (binder.get() == nullptr) {
+            LOG(ERROR) << "Failed to connect to router service";
+            continue;
+        }
+
+        // Connected to router registry, register the runner and dealth callback.
+        std::shared_ptr<IPipeRegistration> registryService = IPipeRegistration::fromBinder(binder);
+        ndk::ScopedAStatus status =
+            registryService->registerPipeRunner(mGraphOptions.graph_name().c_str(), mPipeRunner);
+
+        if (!status.isOk()) {
+            LOG(ERROR) << "Failed to register runner instance at router registy.";
+            continue;
+        }
+
+        AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(&deathNotifier);
+        AIBinder_linkToDeath(registryService->asBinder().get(), recipient, this);
+        LOG(ERROR) << "Runner was registered at router registry.";
+        return true;
+    }
+
+    LOG(ERROR) << "Max connection attempts reached, router connection attempts failed.";
+    return false;
+}
+
+void RunnerInterface::routerDied() {
+    std::thread t(&RunnerInterface::tryRegisterPipeRunner, this);
+    t.detach();
+}
+
+// Thread-safe function to deliver new packets to client.
+Status RunnerInterface::newPacketNotification(int32_t streamId,
+                                              const std::shared_ptr<MemHandle>& packetHandle) {
+    if (!mPipeRunner) {
+        return Status::INVALID_ARGUMENT;
+    }
+    return mPipeRunner->newPacketNotification(streamId, packetHandle);
+}
+
+Status RunnerInterface::stateUpdateNotification(const GraphState newState) {
+    if (!mPipeRunner) {
+        return Status::INVALID_ARGUMENT;
+    }
+    return mPipeRunner->stateUpdateNotification(newState);
+}
+
 }  // namespace runner_utils
 }  // namespace computepipe
 }  // namespace automotive
diff --git a/computepipe/runner/utils/RunnerInterface.h b/computepipe/runner/utils/RunnerInterface.h
index bc6856e..2397628 100644
--- a/computepipe/runner/utils/RunnerInterface.h
+++ b/computepipe/runner/utils/RunnerInterface.h
@@ -16,13 +16,16 @@
 #define COMPUTEPIPE_RUNNER_UTILS_RUNNERINTERFACE_H_
 #include <aidl/android/automotive/computepipe/runner/BnPipeRunner.h>
 
+#include <memory>
 #include <string>
 
-#include "MemHandle.h"
+#include "InterfaceImpl.h"
 #include "RunnerInterfaceCallbacks.h"
 #include "types/GraphState.h"
 #include "types/Status.h"
 
+#include "Options.pb.h"
+
 namespace android {
 namespace automotive {
 namespace computepipe {
@@ -30,47 +33,40 @@
 
 // RunnerInterface registers an IPipeRunner interface with computepipe router.
 // RunnerInterface handles binder IPC calls and invokes appropriate callbacks.
-class RunnerInterface : public aidl::android::automotive::computepipe::runner::BnPipeRunner {
+class RunnerInterface {
   public:
-    explicit RunnerInterface(const std::string& graphName,
+    explicit RunnerInterface(const proto::Options graphOptions,
                              const RunnerInterfaceCallbacks& runnerInterfaceCallbacks)
-        : mGraphName(graphName), mRunnerInterfaceCallbacks(runnerInterfaceCallbacks) {
+        : mGraphOptions(graphOptions), mRunnerInterfaceCallbacks(runnerInterfaceCallbacks) {
     }
 
-    // Init() should be invoked when the process is ready to receive commands
+    ~RunnerInterface() {
+    }
+
+    // init() should be invoked when the process is ready to receive commands
     // from Clients.
-    Status Init();
+    Status init();
 
     // Thread-safe function to deliver new packets to client.
-    Status NewPacketNotification(int32_t streamId, const std::shared_ptr<MemHandle>& packetHandle);
+    Status newPacketNotification(int32_t streamId, const std::shared_ptr<MemHandle>& packetHandle);
 
     // Thread-safe function to notify clients of new state.
-    Status StateUpdateNotification(const GraphState newState);
+    Status stateUpdateNotification(const GraphState newState);
 
-    // Methods from android::automotive::computepipe::runner::BnPipeRunner
-    ndk::ScopedAStatus init(
-        const std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStateCallback>&
-            stateCb) override;
-    ndk::ScopedAStatus getPipeDescriptor(
-        aidl::android::automotive::computepipe::runner::PipeDescriptor* _aidl_return) override;
-    ndk::ScopedAStatus setPipeInputSource(int32_t configId) override;
-    ndk::ScopedAStatus setPipeOffloadOptions(int32_t configId) override;
-    ndk::ScopedAStatus setPipeTermination(int32_t configId) override;
-    ndk::ScopedAStatus setPipeOutputConfig(
-        int32_t streamId, int32_t maxInFlightCount,
-        const std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStream>& handler)
-        override;
-    ndk::ScopedAStatus applyPipeConfigs() override;
-    ndk::ScopedAStatus startPipe() override;
-    ndk::ScopedAStatus stopPipe() override;
-    ndk::ScopedAStatus doneWithPacket(int32_t id) override;
+    void routerDied();
 
   private:
-    std::string mGraphName;
-    const RunnerInterfaceCallbacks& mRunnerInterfaceCallbacks;
+    // Attempt to register pipe runner with router. Returns true on success.
+    // This is a blocking API, calling thread will be blocked until router connection is
+    // established or max attempts are made without success.
+    bool tryRegisterPipeRunner();
 
-    std::map<int, std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStateCallback>>
-        mPacketHandlers;
+    const int mMaxRouterConnectionAttempts = 10;
+    const int mRouterConnectionAttemptIntervalSeconds = 2;
+
+    const proto::Options mGraphOptions;
+    const RunnerInterfaceCallbacks mRunnerInterfaceCallbacks;
+    std::shared_ptr<InterfaceImpl> mPipeRunner = nullptr;
 };
 
 }  // namespace runner_utils
diff --git a/computepipe/runner/utils/RunnerInterfaceCallbacks.h b/computepipe/runner/utils/RunnerInterfaceCallbacks.h
index b3e29f6..f2f8ece 100644
--- a/computepipe/runner/utils/RunnerInterfaceCallbacks.h
+++ b/computepipe/runner/utils/RunnerInterfaceCallbacks.h
@@ -16,12 +16,12 @@
 #define COMPUTEPIPE_RUNNER_UTILS_RUNNERINTERFACECALLBACKS_H_
 
 #include <functional>
+#include <memory>
 #include <string>
 
 #include "ConfigurationCommand.pb.h"
 #include "ControlCommand.pb.h"
 #include "MemHandle.h"
-#include "RunnerInterface.h"
 #include "types/Status.h"
 
 namespace android {
@@ -32,12 +32,12 @@
 struct RunnerInterfaceCallbacks {
     explicit RunnerInterfaceCallbacks(
         std::function<Status(const proto::ControlCommand&)> processControlCommand,
-        std::function<Status(const proto::ConfigurationCommand&)>
-            processConfigurationCommand,
-        std::function<Status(const std::shared_ptr<MemHandle>&)> releasePacket) :
-            mProcessControlCommand(processControlCommand),
-            mProcessConfigurationCommand(processConfigurationCommand),
-            mReleasePacket(releasePacket) {}
+        std::function<Status(const proto::ConfigurationCommand&)> processConfigurationCommand,
+        std::function<Status(const std::shared_ptr<MemHandle>&)> releasePacket)
+        : mProcessControlCommand(processControlCommand),
+          mProcessConfigurationCommand(processConfigurationCommand),
+          mReleasePacket(releasePacket) {
+    }
 
     const std::function<Status(const proto::ControlCommand&)> mProcessControlCommand;
     const std::function<Status(const proto::ConfigurationCommand&)>
diff --git a/computepipe/tests/Android.bp b/computepipe/tests/Android.bp
index 84d072d..18919d2 100644
--- a/computepipe/tests/Android.bp
+++ b/computepipe/tests/Android.bp
@@ -13,68 +13,26 @@
 // limitations under the License.
 
 cc_test {
-    name: "registry_test",
-    test_suites: ["device-tests"],
-    srcs: [
-        "RegistryTest.cpp",
-	"FakeRunner.cpp",
-    ],
-    static_libs: [
-        "libgtest",
-        "libgmock",
-    ],
-    header_libs: [
-      "computepipe_router_headers",
-    ],
-    shared_libs: [
-        "libbinder",
-        "libutils",
-        "android.automotive.computepipe.registry-cpp",
-        "android.automotive.computepipe.runner-cpp",
-    ],
-}
-
-cc_test {
-    name: "pipecontext_test",
-    test_suites: ["device-tests"],
-    srcs: [
-        "PipeContextTest.cpp",
-	"FakeRunner.cpp",
-    ],
-    static_libs: [
-        "libgtest",
-        "libgmock",
-    ],
-    header_libs: [
-      "computepipe_router_headers",
-    ],
-    shared_libs: [
-        "libbinder",
-        "libutils",
-        "android.automotive.computepipe.runner-cpp",
-    ],
-}
-
-cc_test {
     name: "piperegistration_test",
     test_suites: ["device-tests"],
     srcs: [
         "PipeRegistrationTest.cpp",
-	"FakeRunner.cpp",
+        "FakeRunner.cpp",
     ],
     static_libs: [
         "libgtest",
         "libgmock",
     ],
     header_libs: [
-      "computepipe_router_headers",
+        "computepipe_router_headers",
     ],
     shared_libs: [
+        "libbinder_ndk",
         "libbinder",
         "libutils",
         "android.automotive.computepipe.router@1.0-impl",
-        "android.automotive.computepipe.runner-cpp",
-        "android.automotive.computepipe.registry-cpp",
+        "android.automotive.computepipe.runner-ndk_platform",
+        "android.automotive.computepipe.registry-ndk_platform",
     ],
 }
 
@@ -83,20 +41,21 @@
     test_suites: ["device-tests"],
     srcs: [
         "PipeQueryTest.cpp",
-	"FakeRunner.cpp",
+        "FakeRunner.cpp",
     ],
     static_libs: [
         "libgtest",
         "libgmock",
     ],
     header_libs: [
-      "computepipe_router_headers",
+        "computepipe_router_headers",
     ],
     shared_libs: [
         "libbinder",
+        "libbinder_ndk",
         "libutils",
         "android.automotive.computepipe.router@1.0-impl",
-        "android.automotive.computepipe.runner-cpp",
-        "android.automotive.computepipe.registry-cpp",
+        "android.automotive.computepipe.runner-ndk_platform",
+        "android.automotive.computepipe.registry-ndk_platform",
     ],
 }
diff --git a/computepipe/tests/FakeRunner.cpp b/computepipe/tests/FakeRunner.cpp
index e8334bd..a3c0237 100644
--- a/computepipe/tests/FakeRunner.cpp
+++ b/computepipe/tests/FakeRunner.cpp
@@ -21,70 +21,76 @@
 namespace computepipe {
 namespace tests {
 
-using namespace android::binder;
-using namespace android::automotive::computepipe::runner;
+using namespace aidl::android::automotive::computepipe::runner;
 
 // Methods from ::android::automotive::computepipe::runner::V1_0::IFakeRunnerV1_0 follow.
-Status FakeRunner::init(const sp<IPipeStateCallback>& stateCb) {
-    mStateCallback = stateCb;
-    return Status::ok();
+
+::ndk::ScopedAStatus FakeRunner::init(
+    const std::shared_ptr<
+        ::aidl::android::automotive::computepipe::runner::IPipeStateCallback>& /* in_statecb */) {
+    return ndk::ScopedAStatus::ok();
 }
 
-Status FakeRunner::getPipeDescriptor(
-    ::android::automotive::computepipe::runner::PipeDescriptor* _aidl_return) {
-    (void)_aidl_return;
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::getPipeDescriptor(
+    ::aidl::android::automotive::computepipe::runner::PipeDescriptor* desc) {
+    *desc = mDesc;
+    return ndk::ScopedAStatus::ok();
+}
+::ndk::ScopedAStatus FakeRunner::setPipeInputSource(int32_t /*in_configId*/) {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
+}
+::ndk::ScopedAStatus FakeRunner::setPipeOffloadOptions(int32_t /*in_configId*/) {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
+}
+::ndk::ScopedAStatus FakeRunner::setPipeTermination(int32_t /*in_configId*/) {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
 
-Status FakeRunner::setPipeInputSource(int32_t configId) {
-    (void)configId;
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::setPipeOutputConfig(
+    int32_t /*in_configId*/, int32_t /*in_maxInFlightCount*/,
+    const std::shared_ptr<
+        ::aidl::android::automotive::computepipe::runner::IPipeStream>& /*in_handler*/) {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
-
-Status FakeRunner::setPipeOffloadOptions(int32_t configId) {
-    (void)configId;
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::applyPipeConfigs() {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
-
-Status FakeRunner::setPipeTermination(int32_t configId) {
-    (void)configId;
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::startPipe() {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
-
-Status FakeRunner::setPipeOutputConfig(int32_t configId, int32_t maxInFlightCount,
-                                       const ::android::sp<IPipeStream>& handler) {
-    (void)configId;
-    (void)maxInFlightCount;
-    mOutputCallbacks.push_back(handler);
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::stopPipe() {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
-
-Status FakeRunner::applyPipeConfigs() {
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::doneWithPacket(int32_t /*in_id*/) {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
-
-Status FakeRunner::startPipe() {
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::getPipeDebugger(
+    std::shared_ptr<::aidl::android::automotive::computepipe::runner::IPipeDebugger>* /*_aidl_return*/) {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
-
-Status FakeRunner::stopPipe() {
-    return Status::ok();
+::ndk::ScopedAStatus FakeRunner::releaseRunner() {
+    ::ndk::ScopedAStatus _aidl_status;
+    _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+    return _aidl_status;
 }
-
-Status FakeRunner::doneWithPacket(int32_t id) {
-    (void)id;
-    return Status::ok();
-}
-
-Status FakeRunner::getPipeDebugger(sp<IPipeDebugger>* _aidl_return) {
-    (void)_aidl_return;
-    return Status::ok();
-}
-
-Status FakeRunner::releaseRunner() {
-    return Status::ok();
-}
-
 }  // namespace tests
 }  // namespace computepipe
 }  // namespace automotive
diff --git a/computepipe/tests/FakeRunner.h b/computepipe/tests/FakeRunner.h
index 4760432..23a5806 100644
--- a/computepipe/tests/FakeRunner.h
+++ b/computepipe/tests/FakeRunner.h
@@ -17,7 +17,8 @@
 #ifndef ANDROID_AUTOMOTIVE_COMPUTEPIPE_TESTS
 #define ANDROID_AUTOMOTIVE_COMPUTEPIPE_TESTS
 
-#include <android/automotive/computepipe/runner/BnPipeRunner.h>
+#include <aidl/android/automotive/computepipe/runner/BnPipeRunner.h>
+#include <aidl/android/automotive/computepipe/runner/IPipeRunner.h>
 
 #include <memory>
 
@@ -31,42 +32,37 @@
 // This is a fake runner class whose various methods can be mocked in order
 // to test the Runner logic.
 
-class FakeRunner : public runner::BnPipeRunner {
+class FakeRunner : public aidl::android::automotive::computepipe::runner::BnPipeRunner {
   public:
-    ::android::binder::Status init(
-        const ::android::sp<::android::automotive::computepipe::runner::IPipeStateCallback>& stateCb)
-        override;
-    ::android::binder::Status getPipeDescriptor(
-        ::android::automotive::computepipe::runner::PipeDescriptor* _aidl_return) override;
-    ::android::binder::Status setPipeInputSource(int32_t configId) override;
-    ::android::binder::Status setPipeOffloadOptions(int32_t configId) override;
-    ::android::binder::Status setPipeTermination(int32_t configId) override;
-    ::android::binder::Status setPipeOutputConfig(
-        int32_t configId, int32_t maxInFlightCount,
-        const ::android::sp<::android::automotive::computepipe::runner::IPipeStream>& handler)
-        override;
-    ::android::binder::Status applyPipeConfigs() override;
-    ::android::binder::Status startPipe() override;
-    ::android::binder::Status stopPipe() override;
-    ::android::binder::Status doneWithPacket(int32_t id) override;
-    ::android::binder::Status getPipeDebugger(
-        ::android::sp<::android::automotive::computepipe::runner::IPipeDebugger>* _aidl_return)
-        override;
-    ::android::binder::Status releaseRunner() override;
-    status_t linkToDeath(const sp<DeathRecipient>& recipient, void* cookie = nullptr,
-                         uint32_t flags = 0) override {
-        (void)recipient;
-        (void)cookie;
-        (void)flags;
-        return OK;
-    };
+    ::ndk::ScopedAStatus init(
+        const std::shared_ptr<::aidl::android::automotive::computepipe::runner::IPipeStateCallback>&
+            in_statecb) override;
+    ::ndk::ScopedAStatus getPipeDescriptor(
+        ::aidl::android::automotive::computepipe::runner::PipeDescriptor* _aidl_return) override;
+    ::ndk::ScopedAStatus setPipeInputSource(int32_t in_configId) override;
+    ::ndk::ScopedAStatus setPipeOffloadOptions(int32_t in_configId) override;
+    ::ndk::ScopedAStatus setPipeTermination(int32_t in_configId) override;
+    ::ndk::ScopedAStatus setPipeOutputConfig(
+        int32_t in_configId, int32_t in_maxInFlightCount,
+        const std::shared_ptr<::aidl::android::automotive::computepipe::runner::IPipeStream>&
+            in_handler) override;
+    ::ndk::ScopedAStatus applyPipeConfigs() override;
+    ::ndk::ScopedAStatus startPipe() override;
+    ::ndk::ScopedAStatus stopPipe() override;
+    ::ndk::ScopedAStatus doneWithPacket(int32_t in_id) override;
+    ::ndk::ScopedAStatus getPipeDebugger(
+        std::shared_ptr<::aidl::android::automotive::computepipe::runner::IPipeDebugger>*
+            _aidl_return) override;
+    ::ndk::ScopedAStatus releaseRunner() override;
     ~FakeRunner() {
         mOutputCallbacks.clear();
     }
 
   private:
-    std::vector<wp<::android::automotive::computepipe::runner::IPipeStream>> mOutputCallbacks;
-    wp<::android::automotive::computepipe::runner::IPipeStateCallback> mStateCallback;
+    aidl::android::automotive::computepipe::runner::PipeDescriptor mDesc;
+    std::vector<std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStream>>
+        mOutputCallbacks;
+    std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeStateCallback> mStateCallback;
 };
 
 }  // namespace tests
diff --git a/computepipe/tests/PipeContextTest.cpp b/computepipe/tests/PipeContextTest.cpp
deleted file mode 100644
index 3a0405e..0000000
--- a/computepipe/tests/PipeContextTest.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2019 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 <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <list>
-#include <string>
-#include <utility>
-
-#include "FakeRunner.h"
-#include "PipeContext.h"
-
-using namespace ::android::automotive::computepipe::router;
-using namespace ::android::automotive::computepipe::tests;
-using namespace ::testing;
-
-/**
- * Wraps a FakeRunner instance
- */
-struct WrapRunner {
-    WrapRunner(const android::sp<FakeRunner>& r) : mRunner(r) {
-    }
-    android::wp<FakeRunner> mRunner;
-};
-
-/**
- * Implements PipeHandle methods and manages the underlying IPC
- * object
- */
-class FakePipeHandle : public PipeHandle<WrapRunner> {
-  public:
-    explicit FakePipeHandle(const android::sp<FakeRunner>& r)
-        : PipeHandle(std::make_unique<WrapRunner>(r)) {
-    }
-    bool isAlive() override {
-        auto pRunner = mInterface->mRunner.promote();
-        if (pRunner == nullptr) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-    bool startPipeMonitor() override {
-        return true;
-    }
-    PipeHandle<WrapRunner>* clone() const override {
-        return new FakePipeHandle(mInterface->mRunner.promote());
-    }
-    ~FakePipeHandle() {
-        mInterface = nullptr;
-    }
-};
-
-TEST(PipeContextTest, IsAliveTest) {
-    android::sp<FakeRunner> runner = new FakeRunner();
-    std::unique_ptr<PipeHandle<WrapRunner>> pHandle = std::make_unique<FakePipeHandle>(runner);
-    ASSERT_TRUE(pHandle->isAlive());
-
-    PipeContext pContext(std::move(pHandle), "random");
-    ASSERT_TRUE(pContext.isAlive());
-    runner.clear();
-    ASSERT_FALSE(pContext.isAlive());
-}
-
-TEST(PipeContextTest, GetHandleTest) {
-    android::sp<FakeRunner> dummy = new FakeRunner();
-    std::unique_ptr<PipeHandle<WrapRunner>> pHandle = std::make_unique<FakePipeHandle>(dummy);
-    PipeContext pContext(std::move(pHandle), "random");
-
-    std::unique_ptr<PipeHandle<WrapRunner>> dupHandle = pContext.dupPipeHandle();
-    android::sp<FakeRunner> dummy2 = dupHandle->getInterface()->mRunner.promote();
-    ASSERT_THAT(dummy2->getStrongCount(), Eq(2));
-    dummy2.clear();
-
-    ASSERT_TRUE(dupHandle->isAlive());
-    dummy.clear();
-    ASSERT_FALSE(dupHandle->isAlive());
-    ASSERT_FALSE(pContext.isAlive());
-}
diff --git a/computepipe/tests/PipeQueryTest.cpp b/computepipe/tests/PipeQueryTest.cpp
index 2a1a137..acdee1d 100644
--- a/computepipe/tests/PipeQueryTest.cpp
+++ b/computepipe/tests/PipeQueryTest.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <android/automotive/computepipe/registry/BnClientInfo.h>
+#include <aidl/android/automotive/computepipe/registry/BnClientInfo.h>
 #include <binder/IInterface.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -32,9 +32,8 @@
 using namespace android::automotive::computepipe::router;
 using namespace android::automotive::computepipe::router::V1_0::implementation;
 using namespace android::automotive::computepipe::tests;
-using namespace android::automotive::computepipe::runner;
-using namespace android::automotive::computepipe::registry;
-using namespace android::binder;
+using namespace aidl::android::automotive::computepipe::runner;
+using namespace aidl::android::automotive::computepipe::registry;
 using namespace ::testing;
 
 /**
@@ -42,17 +41,10 @@
  */
 class FakeClientInfo : public BnClientInfo {
   public:
-    Status getClientId(int32_t* id) override {
+    ndk::ScopedAStatus getClientId(int32_t* id) override {
         *id = 1;
-        return Status::ok();
+        return ndk::ScopedAStatus::ok();
     }
-    android::status_t linkToDeath(const android::sp<DeathRecipient>& recipient,
-                                  void* cookie = nullptr, uint32_t flags = 0) override {
-        (void)recipient;
-        (void)cookie;
-        (void)flags;
-        return OK;
-    };
 };
 
 /**
@@ -86,7 +78,7 @@
     /**
      * Utility to generate fake runners
      */
-    void addFakeRunner(const std::string& name, const android::sp<IPipeRunner>& runnerIface) {
+    void addFakeRunner(const std::string& name, const std::shared_ptr<IPipeRunner>& runnerIface) {
         std::unique_ptr<PipeHandle<PipeRunner>> handle = std::make_unique<RunnerHandle>(runnerIface);
         Error status = mRegistry->RegisterPipe(std::move(handle), name);
         ASSERT_THAT(status, testing::Eq(Error::OK));
@@ -108,10 +100,10 @@
 
 // Check retrieval of inserted entries
 TEST_F(PipeQueryTest, GetGraphListTest) {
-    android::sp<IPipeRunner> dummy1 = new FakeRunner();
+    std::shared_ptr<IPipeRunner> dummy1 = ndk::SharedRefBase::make<FakeRunner>();
     addFakeRunner("dummy1", dummy1);
-    android::sp<IPipeRunner> dummy2 = new FakeRunner();
-    addFakeRunner("dummy2", dummy1);
+    std::shared_ptr<IPipeRunner> dummy2 = ndk::SharedRefBase::make<FakeRunner>();
+    addFakeRunner("dummy2", dummy2);
 
     std::vector<std::string>* outNames = new std::vector<std::string>();
     std::unique_ptr<PipeQuery> qIface = std::make_unique<PipeQuery>(mRegistry);
@@ -126,26 +118,12 @@
 
 // Check successful retrieval of runner
 TEST_F(PipeQueryTest, GetRunnerTest) {
-    android::sp<IPipeRunner> dummy1 = new FakeRunner();
+    std::shared_ptr<IPipeRunner> dummy1 = ndk::SharedRefBase::make<FakeRunner>();
     addFakeRunner("dummy1", dummy1);
 
     std::unique_ptr<PipeQuery> qIface = std::make_unique<PipeQuery>(mRegistry);
-    android::sp<IClientInfo> info = new FakeClientInfo();
-    android::sp<IPipeRunner> runner;
+    std::shared_ptr<IClientInfo> info = ndk::SharedRefBase::make<FakeClientInfo>();
+    std::shared_ptr<IPipeRunner> runner;
     ASSERT_TRUE(qIface->getPipeRunner("dummy1", info, &runner).isOk());
     EXPECT_THAT(runner, testing::NotNull());
 }
-
-// Check retrieval of dead runner
-TEST_F(PipeQueryTest, DeadRunnerTest) {
-    android::sp<IPipeRunner> dummy1 = new FakeRunner();
-    addFakeRunner("dummy1", dummy1);
-
-    std::unique_ptr<PipeQuery> qIface = std::make_unique<PipeQuery>(mRegistry);
-    dummy1.clear();
-    removeRunner("dummy1");
-    android::sp<IClientInfo> info = new FakeClientInfo();
-    android::sp<IPipeRunner> runner;
-    qIface->getPipeRunner("dummy1", info, &runner);
-    EXPECT_THAT(runner, testing::IsNull());
-}
diff --git a/computepipe/tests/PipeRegistrationTest.cpp b/computepipe/tests/PipeRegistrationTest.cpp
index c5287c6..1caf07b 100644
--- a/computepipe/tests/PipeRegistrationTest.cpp
+++ b/computepipe/tests/PipeRegistrationTest.cpp
@@ -30,10 +30,8 @@
 using namespace android::automotive::computepipe::router;
 using namespace android::automotive::computepipe::router::V1_0::implementation;
 using namespace android::automotive::computepipe::tests;
-using namespace android::automotive::computepipe::runner;
-using namespace android::automotive::computepipe::registry;
-using namespace android::binder;
-using android::sp;
+using namespace aidl::android::automotive::computepipe::runner;
+using namespace aidl::android::automotive::computepipe::registry;
 /**
  * Test fixture that manages the underlying registry creation and tear down
  */
@@ -52,15 +50,17 @@
 
 // Valid registration succeeds
 TEST_F(PipeRegistrationTest, RegisterFakeRunner) {
-    sp<IPipeRunner> dummy = new FakeRunner();
-    std::unique_ptr<IPipeRegistration> rIface(new PipeRegistration(this->mRegistry));
+    std::shared_ptr<IPipeRunner> dummy = ndk::SharedRefBase::make<FakeRunner>();
+    std::shared_ptr<IPipeRegistration> rIface =
+        ndk::SharedRefBase::make<PipeRegistration>(this->mRegistry);
     EXPECT_TRUE(rIface->registerPipeRunner("dummy", dummy).isOk());
 }
 
 // Duplicate registration fails
 TEST_F(PipeRegistrationTest, RegisterDuplicateRunner) {
-    sp<IPipeRunner> dummy = new FakeRunner();
-    std::unique_ptr<IPipeRegistration> rIface(new PipeRegistration(this->mRegistry));
+    std::shared_ptr<IPipeRunner> dummy = ndk::SharedRefBase::make<FakeRunner>();
+    std::shared_ptr<IPipeRegistration> rIface =
+        ndk::SharedRefBase::make<PipeRegistration>(this->mRegistry);
     ASSERT_TRUE(rIface->registerPipeRunner("dummy", dummy).isOk());
     EXPECT_FALSE(rIface->registerPipeRunner("dummy", dummy).isOk());
 }
diff --git a/computepipe/tests/RegistryTest.cpp b/computepipe/tests/RegistryTest.cpp
deleted file mode 100644
index c31f6a1..0000000
--- a/computepipe/tests/RegistryTest.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/**
- * Copyright 2019 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 <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <list>
-#include <string>
-
-#include "FakeRunner.h"
-#include "Registry.h"
-
-using namespace ::android::automotive::computepipe::router;
-using namespace ::android::automotive::computepipe::tests;
-using namespace ::android;
-using namespace ::testing;
-
-class FakeClient : public ClientHandle {
-  public:
-    uint32_t getClientId() override {
-        return 0;
-    }
-    bool isAlive() override {
-        return true;
-    }
-    bool startClientMonitor() override {
-        return true;
-    }
-    ~FakeClient() {
-    }
-};
-
-/**
- * Wraps a FakeRunner instance
- */
-struct WrapRunner {
-    WrapRunner(const sp<FakeRunner>& r) : mRunner(r) {
-    }
-    android::wp<FakeRunner> mRunner;
-};
-
-/**
- * Implements PipeHandle methods and manages the underlying IPC
- * object
- */
-class FakePipeHandle : public PipeHandle<WrapRunner> {
-  public:
-    explicit FakePipeHandle(const sp<FakeRunner>& r) : PipeHandle(std::make_unique<WrapRunner>(r)) {
-    }
-    bool isAlive() override {
-        auto pRunner = mInterface->mRunner.promote();
-        if (pRunner == nullptr) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-    bool startPipeMonitor() override {
-        return true;
-    }
-    PipeHandle<WrapRunner>* clone() const override {
-        return new FakePipeHandle(mInterface->mRunner.promote());
-    }
-    ~FakePipeHandle() {
-        mInterface = nullptr;
-    }
-};
-
-/**
- * Test for PipeRegistry::getRunner()
- * Check if the api does not mistakenly increment the refcount
- * Check if the api correctly handles bad client
- * Check if the api correctly handles multiclient error
- * Check if the api correctly handles a deleted runner retrieval
- * Check if registry implementation correctly deletes entry for
- * dead runner
- */
-TEST(RegistryTest, GetRunnerTest) {
-    PipeRegistry<WrapRunner> registry;
-    sp<FakeRunner> runner = new FakeRunner();
-    std::unique_ptr<PipeHandle<WrapRunner>> handle = std::make_unique<FakePipeHandle>(runner);
-    ASSERT_THAT(runner, testing::NotNull());
-    // Verify refcount
-    registry.RegisterPipe(std::move(handle), "random");
-    EXPECT_THAT(runner->getStrongCount(), Eq(1));
-    // Verify bad client
-    EXPECT_THAT(registry.getClientPipeHandle("random", nullptr), IsNull());
-    // Verify correct retrieval
-    std::unique_ptr<ClientHandle> client = std::make_unique<FakeClient>();
-    ASSERT_THAT(client, NotNull());
-    EXPECT_THAT(registry.getClientPipeHandle("random", std::move(client)), NotNull());
-    // verify multiclient failure
-    client.reset(new FakeClient());
-    EXPECT_THAT(registry.getClientPipeHandle("random", std::move(client)), IsNull());
-    // Verify deleted runner
-    sp<FakeRunner> dummy;
-    dummy = new FakeRunner();
-    std::unique_ptr<PipeHandle<WrapRunner>> dummyHandle = std::make_unique<FakePipeHandle>(dummy);
-    registry.RegisterPipe(std::move(dummyHandle), "dummy");
-    dummy.clear();
-    client.reset(new FakeClient());
-    EXPECT_THAT(registry.getClientPipeHandle("dummy", std::move(client)), IsNull());
-}
-
-/**
- * Test for PipeRegistry::getPipeList()
- * Check if the api correctly handles empty db
- */
-TEST(RegistryTest, GetPipeListTest) {
-    PipeRegistry<WrapRunner> registry;
-    // Confirm entry registry
-    std::list<std::string> names = registry.getPipeList();
-    ASSERT_THAT(names.size(), Eq(0));
-    // Confirm 1 entry
-    sp<FakeRunner> runner = new FakeRunner();
-    std::unique_ptr<PipeHandle<WrapRunner>> handle = std::make_unique<FakePipeHandle>(runner);
-    registry.RegisterPipe(std::move(handle), "random");
-    names = registry.getPipeList();
-    ASSERT_THAT(names.size(), Eq(1));
-    ASSERT_STREQ((*names.begin()).c_str(), "random");
-}
-
-/**
- * Test for PipeRegistry::registerPipe()
- * Check if the api correctly rejects duplicate entries
- * Check if the api correctly handles reregistration of a deleted runner
- */
-TEST(RegistryTest, RegisterPipeTest) {
-    PipeRegistry<WrapRunner> registry;
-    sp<FakeRunner> runner = new FakeRunner();
-    std::unique_ptr<PipeHandle<WrapRunner>> handle = std::make_unique<FakePipeHandle>(runner);
-    Error status = registry.RegisterPipe(std::move(handle), "random");
-    ASSERT_THAT(status, Eq(Error::OK));
-    // Duplicate entry
-    status = registry.RegisterPipe(nullptr, "random");
-    ASSERT_THAT(status, Eq(Error::DUPLICATE_PIPE));
-    // Deleted runner
-    runner.clear();
-    runner = new FakeRunner();
-    handle.reset(new FakePipeHandle(runner));
-    status = registry.RegisterPipe(std::move(handle), "random");
-    ASSERT_THAT(status, Eq(Error::OK));
-}
diff --git a/computepipe/tests/runner/Android.bp b/computepipe/tests/runner/Android.bp
new file mode 100644
index 0000000..a3edb37
--- /dev/null
+++ b/computepipe/tests/runner/Android.bp
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 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.
+
+cc_test {
+    name: "computepipe_semantic_manager_test",
+    test_suites: ["device-tests"],
+    srcs: [
+        "SemanticManagerTest.cpp",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+	"libcomputepipeprotos",
+    ],
+    shared_libs: [
+        "libcomputepipe_stream_manager",
+	"libprotobuf-cpp-full",
+    ],
+    header_libs: [
+        "computepipe_runner_includes",
+    ],
+    include_dirs: [
+        "packages/services/Car/computepipe"
+    ],
+}
diff --git a/computepipe/tests/runner/SemanticManagerTest.cpp b/computepipe/tests/runner/SemanticManagerTest.cpp
new file mode 100644
index 0000000..6316e5c
--- /dev/null
+++ b/computepipe/tests/runner/SemanticManagerTest.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 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 <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "OutputConfig.pb.h"
+#include "StreamManager.h"
+#include "gmock/gmock-matchers.h"
+#include "types/Status.h"
+
+using namespace android::automotive::computepipe::runner::stream_manager;
+using namespace android::automotive::computepipe;
+
+class SemanticManagerTest : public ::testing::Test {
+  protected:
+    static constexpr uint32_t kMaxSemanticDataSize = 1024;
+    /**
+     * Setup for the test fixture to initialize the semantic manager
+     * After this, the semantic manager should be in RESET state.
+     */
+    void SetUp() override {
+        proto::OutputConfig config;
+        config.set_type(proto::PacketType::SEMANTIC_DATA);
+        config.set_stream_name("semantic_stream");
+        mStreamManager = mFactory.getStreamManager(config);
+        std::function<Status(std::shared_ptr<MemHandle>)> cb =
+            [this](std::shared_ptr<MemHandle> handle) -> Status {
+            this->mPacketSize = handle->getSize();
+            this->mCurrentPacket = (char*)malloc(this->mPacketSize);
+            memcpy(mCurrentPacket, handle->getData(), this->mPacketSize);
+
+            return SUCCESS;
+        };
+        ASSERT_EQ(mStreamManager->setIpcDispatchCallback(cb), Status::SUCCESS);
+    }
+    void deleteCurrentPacket() {
+        if (mCurrentPacket) {
+            free(mCurrentPacket);
+            mCurrentPacket = nullptr;
+        }
+    }
+    void TearDown() override {
+        if (mCurrentPacket) {
+            free(mCurrentPacket);
+        }
+        mStreamManager = nullptr;
+    }
+    std::unique_ptr<StreamManager> mStreamManager;
+    StreamManagerFactory mFactory;
+    char* mCurrentPacket = nullptr;
+    uint32_t mPacketSize;
+};
+
+/**
+ * Checks the ability to start semantic stream management
+ * without config state
+ */
+TEST_F(SemanticManagerTest, NoConfigTest) {
+    EXPECT_EQ(mStreamManager->start(), Status::ILLEGAL_STATE);
+    mStreamManager->setMaxInFlightPackets(0);
+    EXPECT_EQ(mStreamManager->start(), Status::SUCCESS);
+}
+
+/**
+ * Checks Packet Queing without start.
+ * Checks Packet Queuing with bad arguments.
+ * Checks successful packet queuing.
+ */
+TEST_F(SemanticManagerTest, PacketQueueTest) {
+    ASSERT_EQ(mStreamManager->setMaxInFlightPackets(0), Status::SUCCESS);
+    ASSERT_EQ(mStreamManager->start(), Status::SUCCESS);
+    std::string fakeData("FakeData");
+    uint32_t size = fakeData.size();
+    EXPECT_EQ(mStreamManager->queuePacket(nullptr, size, 0), Status::INVALID_ARGUMENT);
+    EXPECT_EQ(mStreamManager->queuePacket(fakeData.c_str(), kMaxSemanticDataSize + 1, 0),
+              Status::INVALID_ARGUMENT);
+    EXPECT_EQ(mStreamManager->queuePacket(fakeData.c_str(), size, 0), Status::SUCCESS);
+    EXPECT_STREQ(mCurrentPacket, fakeData.c_str());
+}
diff --git a/computepipe/types/Status.h b/computepipe/types/Status.h
index ca2bc6e..4bd126f 100644
--- a/computepipe/types/Status.h
+++ b/computepipe/types/Status.h
@@ -23,6 +23,7 @@
     SUCCESS = 0,
     INTERNAL_ERROR,
     INVALID_ARGUMENT,
+    ILLEGAL_STATE,
     NO_MEMORY,
     FATAL_ERROR,
 };
diff --git a/service/res/values-af/strings.xml b/service/res/values-af/strings.xml
index 3de7e5e..e553b4c 100644
--- a/service/res/values-af/strings.xml
+++ b/service/res/values-af/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Aktiveer of deaktiveer motor se kenmerke"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Aktiveer of deaktiveer motor se kenmerke."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Toestel"</string>
 </resources>
diff --git a/service/res/values-am/strings.xml b/service/res/values-am/strings.xml
index e53d167..da70c27 100644
--- a/service/res/values-am/strings.xml
+++ b/service/res/values-am/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"የመኪና ባህሪዎችን አንቃ ወይም አሰናክል"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"የመኪና ባህሪዎችን አንቃ ወይም አሰናክል"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"የእኔ መሣሪያ"</string>
 </resources>
diff --git a/service/res/values-ar/strings.xml b/service/res/values-ar/strings.xml
index 7653861..9492091 100644
--- a/service/res/values-ar/strings.xml
+++ b/service/res/values-ar/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"تفعيل ميزات السيارة أو إيقافها"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"تفعيل ميزات السيارة أو إيقافها"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"جهازي"</string>
 </resources>
diff --git a/service/res/values-az/strings.xml b/service/res/values-az/strings.xml
index 645d40e..bedd037 100644
--- a/service/res/values-az/strings.xml
+++ b/service/res/values-az/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Avtomobilin xüsusiyyətlərini aktiv və ya deaktiv etmək"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Avtomobilin xüsusiyyətlərini aktiv və ya deaktiv etmək."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Cihazım"</string>
 </resources>
diff --git a/service/res/values-b+sr+Latn/strings.xml b/service/res/values-b+sr+Latn/strings.xml
index 61cbab2..f78007a 100644
--- a/service/res/values-b+sr+Latn/strings.xml
+++ b/service/res/values-b+sr+Latn/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Omogućavanje ili onemogućavanje funkcija automobila"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Omogućavanje ili onemogućavanje funkcija automobila."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moj uređaj"</string>
 </resources>
diff --git a/service/res/values-be/strings.xml b/service/res/values-be/strings.xml
index aeea7f8..22986a6 100644
--- a/service/res/values-be/strings.xml
+++ b/service/res/values-be/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Уключыць або выключыць функцыі аўтамабіля"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Уключыць або выключыць функцыі аўтамабіля."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мая прылада"</string>
 </resources>
diff --git a/service/res/values-bg/strings.xml b/service/res/values-bg/strings.xml
index 0b14653..d9f0d04 100644
--- a/service/res/values-bg/strings.xml
+++ b/service/res/values-bg/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Активиране или деактивиране на функциите на автомобила"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Активиране или деактивиране на функциите на автомобила."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Моето устройство"</string>
 </resources>
diff --git a/service/res/values-bn/strings.xml b/service/res/values-bn/strings.xml
index c1b0ac3..1cf6aff 100644
--- a/service/res/values-bn/strings.xml
+++ b/service/res/values-bn/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"গাড়ির ফিচার চালু বা বন্ধ করুন"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"গাড়ির ফিচার চালু বা বন্ধ করুন।"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"আমার ডিভাইস"</string>
 </resources>
diff --git a/service/res/values-bs/strings.xml b/service/res/values-bs/strings.xml
index 5c5aae8..bcebee2 100644
--- a/service/res/values-bs/strings.xml
+++ b/service/res/values-bs/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Omogućavanje ili onemogućavanje funkcija automobila"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Omogućavanje ili onemogućavanje funkcija automobila."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moj uređaj"</string>
 </resources>
diff --git a/service/res/values-ca/strings.xml b/service/res/values-ca/strings.xml
index c2e5203..f3d70d6 100644
--- a/service/res/values-ca/strings.xml
+++ b/service/res/values-ca/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Activa o desactiva les funcions del cotxe"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Activa o desactiva les funcions del cotxe."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"El meu dispositiu"</string>
 </resources>
diff --git a/service/res/values-cs/strings.xml b/service/res/values-cs/strings.xml
index bc041df..8c81008 100644
--- a/service/res/values-cs/strings.xml
+++ b/service/res/values-cs/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Zapnout nebo vypnout funkce auta"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Zapnout nebo vypnout funkce auta."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moje zařízení"</string>
 </resources>
diff --git a/service/res/values-da/strings.xml b/service/res/values-da/strings.xml
index 2c827a7..3df61c9 100644
--- a/service/res/values-da/strings.xml
+++ b/service/res/values-da/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Aktivér eller deaktiver bilens funktioner"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Aktivér eller deaktiver bilens funktioner."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Min enhed"</string>
 </resources>
diff --git a/service/res/values-de/strings.xml b/service/res/values-de/strings.xml
index 19faf92..feb75cf 100644
--- a/service/res/values-de/strings.xml
+++ b/service/res/values-de/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Funktionen des Autos aktivieren oder deaktivieren"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Funktionen des Autos aktivieren oder deaktivieren."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mein Gerät"</string>
 </resources>
diff --git a/service/res/values-el/strings.xml b/service/res/values-el/strings.xml
index ad24be7..fc105a2 100644
--- a/service/res/values-el/strings.xml
+++ b/service/res/values-el/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Ενεργοποίηση ή απενεργοποίηση των λειτουργιών του αυτοκινήτου."</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Ενεργοποίηση ή απενεργοποίηση των λειτουργιών του αυτοκινήτου."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Η συσκευή μου"</string>
 </resources>
diff --git a/service/res/values-en-rAU/strings.xml b/service/res/values-en-rAU/strings.xml
index 83bb45e..7f736af 100644
--- a/service/res/values-en-rAU/strings.xml
+++ b/service/res/values-en-rAU/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Enable or disable car’s features"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Enable or disable car’s features."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
 </resources>
diff --git a/service/res/values-en-rCA/strings.xml b/service/res/values-en-rCA/strings.xml
index 83bb45e..7f736af 100644
--- a/service/res/values-en-rCA/strings.xml
+++ b/service/res/values-en-rCA/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Enable or disable car’s features"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Enable or disable car’s features."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
 </resources>
diff --git a/service/res/values-en-rGB/strings.xml b/service/res/values-en-rGB/strings.xml
index 83bb45e..7f736af 100644
--- a/service/res/values-en-rGB/strings.xml
+++ b/service/res/values-en-rGB/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Enable or disable car’s features"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Enable or disable car’s features."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
 </resources>
diff --git a/service/res/values-en-rIN/strings.xml b/service/res/values-en-rIN/strings.xml
index 83bb45e..7f736af 100644
--- a/service/res/values-en-rIN/strings.xml
+++ b/service/res/values-en-rIN/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Enable or disable car’s features"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Enable or disable car’s features."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"My Device"</string>
 </resources>
diff --git a/service/res/values-en-rXC/strings.xml b/service/res/values-en-rXC/strings.xml
index b3c00ac..9d39a3f 100644
--- a/service/res/values-en-rXC/strings.xml
+++ b/service/res/values-en-rXC/strings.xml
@@ -201,5 +201,7 @@
     <string name="car_permission_desc_set_car_vendor_category_9" msgid="7274990520545034656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‎Control vendor specific properties in category 9.‎‏‎‎‏‎"</string>
     <string name="car_permission_label_set_car_vendor_category_10" msgid="366813764827342987">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎control vendor specific properties in category 10‎‏‎‎‏‎"</string>
     <string name="car_permission_desc_set_car_vendor_category_10" msgid="6353592281201463231">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎Control vendor specific properties in category 10.‎‏‎‎‏‎"</string>
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎Enable or disable car’s features‎‏‎‎‏‎"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎Enable or disable car’s features.‎‏‎‎‏‎"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎My Device‎‏‎‎‏‎"</string>
 </resources>
diff --git a/service/res/values-es-rUS/strings.xml b/service/res/values-es-rUS/strings.xml
index de37dc5..38a3882 100644
--- a/service/res/values-es-rUS/strings.xml
+++ b/service/res/values-es-rUS/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Habilitar o inhabilitar las funciones del vehículo"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Habilitar o inhabilitar las funciones del vehículo"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mi dispositivo"</string>
 </resources>
diff --git a/service/res/values-es/strings.xml b/service/res/values-es/strings.xml
index f7e6ab9..b78a053 100644
--- a/service/res/values-es/strings.xml
+++ b/service/res/values-es/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Habilitar o inhabilitar las funciones de un coche"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Habilitar o inhabilitar las funciones de un coche."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mi dispositivo"</string>
 </resources>
diff --git a/service/res/values-et/strings.xml b/service/res/values-et/strings.xml
index bc54338..5397d85 100644
--- a/service/res/values-et/strings.xml
+++ b/service/res/values-et/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Auto funktsioonide lubamine ja keelamine"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Võimalik on lubada ja keelata auto funktsioone."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Minu seade"</string>
 </resources>
diff --git a/service/res/values-eu/strings.xml b/service/res/values-eu/strings.xml
index f265e60..aa1e7ce 100644
--- a/service/res/values-eu/strings.xml
+++ b/service/res/values-eu/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Gaitu edo desgaitu autoaren eginbideak"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Gaitu edo desgaitu autoaren eginbideak."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Nire gailua"</string>
 </resources>
diff --git a/service/res/values-fa/strings.xml b/service/res/values-fa/strings.xml
index 0772793..9f87f87 100644
--- a/service/res/values-fa/strings.xml
+++ b/service/res/values-fa/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"فعال کردن یا غیرفعال کردن ویژگی‌های خودرو"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"ویژگی‌های خودرو را فعال یا غیرفعال کنید."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"دستگاه من"</string>
 </resources>
diff --git a/service/res/values-fi/strings.xml b/service/res/values-fi/strings.xml
index 258a75d..3a7f71c 100644
--- a/service/res/values-fi/strings.xml
+++ b/service/res/values-fi/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Ota auton ominaisuuksia käyttöön tai poista niitä käytöstä"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Ota auton ominaisuuksia käyttöön tai poista niitä käytöstä."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Oma laite"</string>
 </resources>
diff --git a/service/res/values-fr-rCA/strings.xml b/service/res/values-fr-rCA/strings.xml
index 308e519..e049a65 100644
--- a/service/res/values-fr-rCA/strings.xml
+++ b/service/res/values-fr-rCA/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Activez ou désactivez les fonctionnalités du véhicule"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Activez ou désactivez les fonctionnalités du véhicule."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mon appareil"</string>
 </resources>
diff --git a/service/res/values-fr/strings.xml b/service/res/values-fr/strings.xml
index 4a18ffd..96a6b90 100644
--- a/service/res/values-fr/strings.xml
+++ b/service/res/values-fr/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Activer ou désactiver les fonctionnalités de la voiture"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Activez ou désactivez les fonctionnalités de la voiture."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mon appareil"</string>
 </resources>
diff --git a/service/res/values-gl/strings.xml b/service/res/values-gl/strings.xml
index 205b75c..c01e5d1 100644
--- a/service/res/values-gl/strings.xml
+++ b/service/res/values-gl/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Activar ou desactivar funcións do coche"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Activa ou desactiva as funcións do coche."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Dispositivo"</string>
 </resources>
diff --git a/service/res/values-gu/strings.xml b/service/res/values-gu/strings.xml
index a3af09e..1a02106 100644
--- a/service/res/values-gu/strings.xml
+++ b/service/res/values-gu/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"કારની સુવિધા ચાલુ અથવા બંધ કરો"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"કારની સુવિધા ચાલુ અથવા બંધ કરો."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"મારું ડિવાઇસ"</string>
 </resources>
diff --git a/service/res/values-hi/strings.xml b/service/res/values-hi/strings.xml
index 13a9786..9c678da 100644
--- a/service/res/values-hi/strings.xml
+++ b/service/res/values-hi/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"कार की सुविधाएं चालू या बंद करें"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"कार की सुविधाएं चालू या बंद करें."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"मेरा डिवाइस"</string>
 </resources>
diff --git a/service/res/values-hr/strings.xml b/service/res/values-hr/strings.xml
index e65ccce..e59af0f 100644
--- a/service/res/values-hr/strings.xml
+++ b/service/res/values-hr/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Omogućivanje ili onemogućivanje značajki automobila"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Omogućivanje ili onemogućivanje značajki automobila."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moj uređaj"</string>
 </resources>
diff --git a/service/res/values-hu/strings.xml b/service/res/values-hu/strings.xml
index 611d228..16b6252 100644
--- a/service/res/values-hu/strings.xml
+++ b/service/res/values-hu/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Az autó funkcióinak engedélyezése vagy tiltása"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Az autó funkcióinak engedélyezése vagy tiltása."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Saját eszköz"</string>
 </resources>
diff --git a/service/res/values-hy/strings.xml b/service/res/values-hy/strings.xml
index 2049a35..4f1dfb9 100644
--- a/service/res/values-hy/strings.xml
+++ b/service/res/values-hy/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Միացնել կամ անջատել մեքենայի գործառույթները"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Միացնել կամ անջատել մեքենայի գործառույթները"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Իմ սարքը"</string>
 </resources>
diff --git a/service/res/values-in/strings.xml b/service/res/values-in/strings.xml
index 5ae6988..ebaa012 100644
--- a/service/res/values-in/strings.xml
+++ b/service/res/values-in/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Aktifkan atau nonaktifkan fitur mobil"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Aktifkan atau nonaktifkan fitur mobil."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Perangkat Saya"</string>
 </resources>
diff --git a/service/res/values-is/strings.xml b/service/res/values-is/strings.xml
index 40f6059..7908dea 100644
--- a/service/res/values-is/strings.xml
+++ b/service/res/values-is/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Kveikja eða slökkva á bíleiginleikum"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Kveikja eða slökkva á bíleiginleikum."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Tækið mitt"</string>
 </resources>
diff --git a/service/res/values-it/strings.xml b/service/res/values-it/strings.xml
index ca529ce..f437b5b 100644
--- a/service/res/values-it/strings.xml
+++ b/service/res/values-it/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_permission_label" msgid="741004755205554376">"Accesso alle informazioni dell\'automobile"</string>
+    <string name="car_permission_label" msgid="741004755205554376">"Accesso alle informazioni dell\'auto"</string>
     <string name="car_permission_desc" msgid="162499818870052725">"Consente di accedere alle informazioni dell\'automobile."</string>
     <string name="car_permission_label_camera" msgid="3725702064841827180">"Accesso alla videocamera dell\'automobile"</string>
     <string name="car_permission_desc_camera" msgid="917024932164501426">"Consente di accedere alle videocamere dell\'automobile."</string>
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Attiva o disattiva le funzionalità dell\'auto"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Attiva o disattiva le funzionalità dell\'auto."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mio dispositivo"</string>
 </resources>
diff --git a/service/res/values-ja/strings.xml b/service/res/values-ja/strings.xml
index 8bede1c..6e519d5 100644
--- a/service/res/values-ja/strings.xml
+++ b/service/res/values-ja/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"車の機能を有効または無効にします"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"車の機能を有効または無効にします。"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"自分のデバイス"</string>
 </resources>
diff --git a/service/res/values-ka/strings.xml b/service/res/values-ka/strings.xml
index f7b23e6..85e8fb4 100644
--- a/service/res/values-ka/strings.xml
+++ b/service/res/values-ka/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"მანქანის ფუნქციების ჩართვა ან გათიშვა"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"მანქანის ფუნქციების ჩართვა ან გათიშვა."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ჩემი მოწყობილობა"</string>
 </resources>
diff --git a/service/res/values-kk/strings.xml b/service/res/values-kk/strings.xml
index 261b8bd..00ae0b3 100644
--- a/service/res/values-kk/strings.xml
+++ b/service/res/values-kk/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Көлік функцияларын қосыңыз немесе өшіріңіз."</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Көлік функцияларын қосыңыз немесе өшіріңіз."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Құрылғым"</string>
 </resources>
diff --git a/service/res/values-km/strings.xml b/service/res/values-km/strings.xml
index bbf85fe..b061796 100644
--- a/service/res/values-km/strings.xml
+++ b/service/res/values-km/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"បើក ឬ​បិទ​មុខងារ​របស់​រថយន្ត"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"បើក ឬ​បិទ​មុខងារ​របស់​រថយន្ត​។"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ឧបករណ៍របស់ខ្ញុំ"</string>
 </resources>
diff --git a/service/res/values-kn/strings.xml b/service/res/values-kn/strings.xml
index f5d36b2..67e0811 100644
--- a/service/res/values-kn/strings.xml
+++ b/service/res/values-kn/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"ಕಾರ್ ಫೀಚರ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"ಕಾರ್ ಫೀಚರ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ನನ್ನ ಸಾಧನ"</string>
 </resources>
diff --git a/service/res/values-ko/strings.xml b/service/res/values-ko/strings.xml
index 04a1185..b69c9d5 100644
--- a/service/res/values-ko/strings.xml
+++ b/service/res/values-ko/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"차량 기능 사용 설정 또는 사용 중지"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"차량 기능 사용 설정 또는 사용 중지"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"내 기기"</string>
 </resources>
diff --git a/service/res/values-ky/strings.xml b/service/res/values-ky/strings.xml
index d20da61..b24e8b7 100644
--- a/service/res/values-ky/strings.xml
+++ b/service/res/values-ky/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Унаанын функцияларын иштетүү же өчүрүү"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Унаанын функцияларын иштетүү же өчүрүү."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Түзмөгүм"</string>
 </resources>
diff --git a/service/res/values-lo/strings.xml b/service/res/values-lo/strings.xml
index 7aa2623..bf12e92 100644
--- a/service/res/values-lo/strings.xml
+++ b/service/res/values-lo/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"ເປີດນຳໃຊ້ ຫຼື ປິດການນຳໃຊ້ຄຸນສົມບັດຂອງລົດ"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"ເປີດນຳໃຊ້ ຫຼື ປິດການນຳໃຊ້ຄຸນສົມບັດຂອງລົດ."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ອຸປະກອນຂອງຂ້ອຍ"</string>
 </resources>
diff --git a/service/res/values-lt/strings.xml b/service/res/values-lt/strings.xml
index 264615e..dcbae8f 100644
--- a/service/res/values-lt/strings.xml
+++ b/service/res/values-lt/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Įgalinti arba išjungti automobilio funkcijas"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Įgalinkite arba išjunkite automobilio funkcijas."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mano įrenginys"</string>
 </resources>
diff --git a/service/res/values-lv/strings.xml b/service/res/values-lv/strings.xml
index 9f22db7..af448a8 100644
--- a/service/res/values-lv/strings.xml
+++ b/service/res/values-lv/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Iespējot vai atspējot automašīnas funkcijas"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Iespējojiet vai atspējojiet automašīnas funkcijas."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mana ierīce"</string>
 </resources>
diff --git a/service/res/values-mk/strings.xml b/service/res/values-mk/strings.xml
index 09cc7f0..a969bfe 100644
--- a/service/res/values-mk/strings.xml
+++ b/service/res/values-mk/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Овозможување или оневозможување функции на автомобилот"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Овозможување или оневозможување функции на автомобилот."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мојот уред"</string>
 </resources>
diff --git a/service/res/values-ml/strings.xml b/service/res/values-ml/strings.xml
index 33cfb07..1fb8d71 100644
--- a/service/res/values-ml/strings.xml
+++ b/service/res/values-ml/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"കാറിന്റെ ഫീച്ചറുകൾ പ്രവർത്തനക്ഷമമോ പ്രവർത്തനരഹിതമോ ആക്കുക"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"കാറിന്റെ ഫീച്ചറുകൾ പ്രവർത്തനക്ഷമമോ പ്രവർത്തനരഹിതമോ ആക്കുക."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"എന്റെ ഉപകരണം"</string>
 </resources>
diff --git a/service/res/values-mn/strings.xml b/service/res/values-mn/strings.xml
index 3fa74a1..b3dfa8d 100644
--- a/service/res/values-mn/strings.xml
+++ b/service/res/values-mn/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Автомашины онцлогуудыг идэвхжүүлэх эсвэл идэвхгүй болгох"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Автомашины онцлогуудыг идэвхжүүлж эсвэл идэвхгүй болгоно уу."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Миний төхөөрөмж"</string>
 </resources>
diff --git a/service/res/values-mr/strings.xml b/service/res/values-mr/strings.xml
index 5e1646d..7b808c5 100644
--- a/service/res/values-mr/strings.xml
+++ b/service/res/values-mr/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"कारची वैशिष्ट्ये सुरू किंवा बंद करा"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"कारची वैशिष्ट्ये सुरू किंवा बंद करा."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"माझे डिव्हाइस"</string>
 </resources>
diff --git a/service/res/values-ms/strings.xml b/service/res/values-ms/strings.xml
index 378a3e3..1e33af3 100644
--- a/service/res/values-ms/strings.xml
+++ b/service/res/values-ms/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Dayakan atau lumpuhkan ciri kereta"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Dayakan atau lumpuhkan ciri kereta."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Peranti Saya"</string>
 </resources>
diff --git a/service/res/values-my/strings.xml b/service/res/values-my/strings.xml
index a40f5e2..a8f140e 100644
--- a/service/res/values-my/strings.xml
+++ b/service/res/values-my/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"ကား၏ ဝန်ဆောင်မှုများကို ပိတ်ရန် သို့မဟုတ် ပိတ်ရန်"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"ကား၏ ဝန်ဆောင်မှုများကို ဖွင့်ရန် သို့မဟုတ် ပိတ်ရန်။"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ကျွန်ုပ်၏စက်"</string>
 </resources>
diff --git a/service/res/values-nb/strings.xml b/service/res/values-nb/strings.xml
index db40e5b..e0fa6a4 100644
--- a/service/res/values-nb/strings.xml
+++ b/service/res/values-nb/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Slå bilens funksjoner på eller av"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Slå bilens funksjoner på eller av."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Enheten min"</string>
 </resources>
diff --git a/service/res/values-nl/strings.xml b/service/res/values-nl/strings.xml
index c55e392..8914b1f 100644
--- a/service/res/values-nl/strings.xml
+++ b/service/res/values-nl/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Functies van de auto in- of uitschakelen"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Functies van de auto in- of uitschakelen."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Mijn apparaat"</string>
 </resources>
diff --git a/service/res/values-or/strings.xml b/service/res/values-or/strings.xml
index 2564aea..c9023a0 100644
--- a/service/res/values-or/strings.xml
+++ b/service/res/values-or/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"କାରର ଫିଚର୍‌ଗୁଡ଼ିକୁ ସକ୍ଷମ କିମ୍ବା ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"କାରର ଫିଚର୍‌ଗୁଡ଼ିକୁ ସକ୍ଷମ କିମ୍ବା ଅକ୍ଷମ କରନ୍ତୁ।"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ମୋ ଡିଭାଇସ୍"</string>
 </resources>
diff --git a/service/res/values-pa/strings.xml b/service/res/values-pa/strings.xml
index 0565429..4f81704 100644
--- a/service/res/values-pa/strings.xml
+++ b/service/res/values-pa/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"ਕਾਰ ਦੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਚਾਲੂ ਜਾਂ ਬੰਦ ਕਰੋ"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"ਕਾਰ ਦੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਚਾਲੂ ਜਾਂ ਬੰਦ ਕਰੋ।"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"ਮੇਰਾ ਡੀਵਾਈਸ"</string>
 </resources>
diff --git a/service/res/values-pl/strings.xml b/service/res/values-pl/strings.xml
index f1cf903..9bb407c 100644
--- a/service/res/values-pl/strings.xml
+++ b/service/res/values-pl/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Włączanie i wyłączanie funkcji samochodu"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Włączanie i wyłączanie funkcji samochodu."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moje urządzenie"</string>
 </resources>
diff --git a/service/res/values-pt-rPT/strings.xml b/service/res/values-pt-rPT/strings.xml
index 0c31c54..fa45b32 100644
--- a/service/res/values-pt-rPT/strings.xml
+++ b/service/res/values-pt-rPT/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Ativar ou desativar as funcionalidades do automóvel"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Ative ou desative as funcionalidades do automóvel."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Dispositivo"</string>
 </resources>
diff --git a/service/res/values-pt/strings.xml b/service/res/values-pt/strings.xml
index feafc24..a3b5ed2 100644
--- a/service/res/values-pt/strings.xml
+++ b/service/res/values-pt/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Ativar ou desativar os recursos do carro"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Ativar ou desativar os recursos do carro."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Meu dispositivo"</string>
 </resources>
diff --git a/service/res/values-ro/strings.xml b/service/res/values-ro/strings.xml
index ac6a608..16e6fa4 100644
--- a/service/res/values-ro/strings.xml
+++ b/service/res/values-ro/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Activați sau dezactivați funcțiile mașinii"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Activați sau dezactivați funcțiile mașinii."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Dispozitivul meu"</string>
 </resources>
diff --git a/service/res/values-ru/strings.xml b/service/res/values-ru/strings.xml
index 0da8875..7b1a10d 100644
--- a/service/res/values-ru/strings.xml
+++ b/service/res/values-ru/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Включение и отключение функций автомобиля"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Включение и отключение функций автомобиля."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мое устройство"</string>
 </resources>
diff --git a/service/res/values-si/strings.xml b/service/res/values-si/strings.xml
index b234af5..9c14d20 100644
--- a/service/res/values-si/strings.xml
+++ b/service/res/values-si/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"මෝටර් රථයේ විශේෂාංග සබල හෝ අබල කරන්න"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"මෝටර් රථයේ විශේෂාංග සබල හෝ අබල කරන්න."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"මගේ උපාංගය"</string>
 </resources>
diff --git a/service/res/values-sk/strings.xml b/service/res/values-sk/strings.xml
index f9a506c..db03691 100644
--- a/service/res/values-sk/strings.xml
+++ b/service/res/values-sk/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Povoliť alebo zakázať funkcie auta"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Povoľte alebo zakážte funkcie auta."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moje zariadenie"</string>
 </resources>
diff --git a/service/res/values-sl/strings.xml b/service/res/values-sl/strings.xml
index 70dfe32..f86a63c 100644
--- a/service/res/values-sl/strings.xml
+++ b/service/res/values-sl/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Omogočanje ali onemogočanje funkcij avtomobila."</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Omogočanje ali onemogočanje funkcij avtomobila."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Moja naprava"</string>
 </resources>
diff --git a/service/res/values-sq/strings.xml b/service/res/values-sq/strings.xml
index be397a3..81a89ab 100644
--- a/service/res/values-sq/strings.xml
+++ b/service/res/values-sq/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Aktivizo ose çaktivizo veçoritë e makinës"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Aktivizo ose çaktivizo veçoritë e makinës."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Pajisja ime"</string>
 </resources>
diff --git a/service/res/values-sr/strings.xml b/service/res/values-sr/strings.xml
index 6c845f2..989e1fd 100644
--- a/service/res/values-sr/strings.xml
+++ b/service/res/values-sr/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Омогућавање или онемогућавање функција аутомобила"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Омогућавање или онемогућавање функција аутомобила."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мој уређај"</string>
 </resources>
diff --git a/service/res/values-sv/strings.xml b/service/res/values-sv/strings.xml
index 55fe5c6..05a1c11 100644
--- a/service/res/values-sv/strings.xml
+++ b/service/res/values-sv/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Aktivera eller inaktivera funktioner i bilen"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Aktivera eller inaktivera funktioner i bilen."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Min enhet"</string>
 </resources>
diff --git a/service/res/values-sw/strings.xml b/service/res/values-sw/strings.xml
index 6057799..48e8864 100644
--- a/service/res/values-sw/strings.xml
+++ b/service/res/values-sw/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Washa au uzime vipengele vya gari"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Washa au uzime vipengele vya gari."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Kifaa Changu"</string>
 </resources>
diff --git a/service/res/values-ta/strings.xml b/service/res/values-ta/strings.xml
index 44cd094..6f8a0df 100644
--- a/service/res/values-ta/strings.xml
+++ b/service/res/values-ta/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"காரின் அம்சங்களை இயக்கும் அல்லது முடக்கும்"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"காரின் அம்சங்களை இயக்கும் அல்லது முடக்கும்."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"எனது சாதனம்"</string>
 </resources>
diff --git a/service/res/values-th/strings.xml b/service/res/values-th/strings.xml
index a94a676..f0584da 100644
--- a/service/res/values-th/strings.xml
+++ b/service/res/values-th/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"เปิดหรือปิดใช้ฟีเจอร์ของรถยนต์"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"เปิดหรือปิดใช้ฟีเจอร์ของรถยนต์"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"อุปกรณ์ของฉัน"</string>
 </resources>
diff --git a/service/res/values-tl/strings.xml b/service/res/values-tl/strings.xml
index 181bbe8..1944897 100644
--- a/service/res/values-tl/strings.xml
+++ b/service/res/values-tl/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"I-enable o i-disable ang mga feature ng kotse."</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"I-enable o i-disable ang mga feature ng kotse."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Aking Device"</string>
 </resources>
diff --git a/service/res/values-tr/strings.xml b/service/res/values-tr/strings.xml
index c1fc8fe..ef9bfb9 100644
--- a/service/res/values-tr/strings.xml
+++ b/service/res/values-tr/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Arabanın özelliklerini etkinleştirin veya devre dışı bırakın"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Arabanın özelliklerini etkinleştirin veya devre dışı bırakın."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Cihazım"</string>
 </resources>
diff --git a/service/res/values-uk/strings.xml b/service/res/values-uk/strings.xml
index 7be2722..e1f1b5c 100644
--- a/service/res/values-uk/strings.xml
+++ b/service/res/values-uk/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Вмикати чи вимикати функції автомобіля"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Вмикати чи вимикати функції автомобіля"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Мій пристрій"</string>
 </resources>
diff --git a/service/res/values-ur/strings.xml b/service/res/values-ur/strings.xml
index d0758f8..c7c2474 100644
--- a/service/res/values-ur/strings.xml
+++ b/service/res/values-ur/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"کار کی خصوصیات کو فعال یا غیر فعال کریں"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"کار کی خصوصیات کو فعال یا غیر فعال کریں۔"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"میرا آلہ"</string>
 </resources>
diff --git a/service/res/values-uz/strings.xml b/service/res/values-uz/strings.xml
index 9e0bc06..5bfbccd 100644
--- a/service/res/values-uz/strings.xml
+++ b/service/res/values-uz/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Avtomobil funksiyalarini yoqish yoki faolsizlantirish"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Avtomobil funksiyalarini yoqish yoki faolsizlantirish"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Qurilmam"</string>
 </resources>
diff --git a/service/res/values-vi/strings.xml b/service/res/values-vi/strings.xml
index f53ad02..699aa6c 100644
--- a/service/res/values-vi/strings.xml
+++ b/service/res/values-vi/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Bật hoặc tắt các tính năng của ô tô"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Bật hoặc tắt các tính năng của ô tô."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Thiết bị của tôi"</string>
 </resources>
diff --git a/service/res/values-zh-rCN/strings.xml b/service/res/values-zh-rCN/strings.xml
index fdb86f7..531e2f7 100644
--- a/service/res/values-zh-rCN/strings.xml
+++ b/service/res/values-zh-rCN/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"启用或停用汽车的功能"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"启用或停用汽车的功能。"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"我的设备"</string>
 </resources>
diff --git a/service/res/values-zh-rHK/strings.xml b/service/res/values-zh-rHK/strings.xml
index eb6b25a..3f8f3fc 100644
--- a/service/res/values-zh-rHK/strings.xml
+++ b/service/res/values-zh-rHK/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"啟用或停用汽車的功能"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"啟用或停用汽車的功能。"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"我的裝置"</string>
 </resources>
diff --git a/service/res/values-zh-rTW/strings.xml b/service/res/values-zh-rTW/strings.xml
index 163eb0f..ee45563 100644
--- a/service/res/values-zh-rTW/strings.xml
+++ b/service/res/values-zh-rTW/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"啟用或停用車輛的功能"</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"啟用或停用車輛的功能。"</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"我的裝置"</string>
 </resources>
diff --git a/service/res/values-zu/strings.xml b/service/res/values-zu/strings.xml
index f6b49a1..3b794bd 100644
--- a/service/res/values-zu/strings.xml
+++ b/service/res/values-zu/strings.xml
@@ -275,5 +275,7 @@
     <skip />
     <!-- no translation found for car_permission_desc_set_car_vendor_category_10 (6353592281201463231) -->
     <skip />
+    <string name="car_permission_label_control_car_features" msgid="3905791560378888286">"Nika amandla noma khubaza izici zemoto."</string>
+    <string name="car_permission_desc_control_car_features" msgid="7646711104530599901">"Nika amandla noma khubaza izici zemoto."</string>
     <string name="trust_device_default_name" msgid="4213625926070261253">"Idivayisi yami"</string>
 </resources>
diff --git a/service/res/values/strings.xml b/service/res/values/strings.xml
index a24c240..61ec62f 100644
--- a/service/res/values/strings.xml
+++ b/service/res/values/strings.xml
@@ -271,184 +271,184 @@
     <string name="car_permission_desc_car_test_service">Control car\u2019s test mode</string>
 
     <!-- Permission text: apps control vendor properties related with window [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_window">control vendor specific window properties</string>
+    <string name="car_permission_label_set_car_vendor_category_window" translatable="false">control vendor specific window properties</string>
     <!-- Permission text: apps control vendor properties related with window [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_window">Control vendor specific window properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_window" translatable="false">Control vendor specific window properties.</string>
 
     <!-- Permission text: apps access vendor properties related with window [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_window">access vendor specific window properties</string>
+    <string name="car_permission_label_get_car_vendor_category_window" translatable="false">access vendor specific window properties</string>
     <!-- Permission text: apps access vendor properties related with window [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_window">Access vendor specific window properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_window" translatable="false">Access vendor specific window properties.</string>
 
     <!-- Permission text: apps control vendor properties related with door [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_door">control vendor specific door properties</string>
+    <string name="car_permission_label_set_car_vendor_category_door" translatable="false">control vendor specific door properties</string>
     <!-- Permission text: apps control vendor properties related with door [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_door">Control vendor specific door properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_door" translatable="false">Control vendor specific door properties.</string>
 
     <!-- Permission text: apps access vendor properties related with door [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_door">access vendor specific door properties</string>
+    <string name="car_permission_label_get_car_vendor_category_door" translatable="false">access vendor specific door properties</string>
     <!-- Permission text: apps access vendor properties related with door [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_door">Access vendor specific door properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_door" translatable="false">Access vendor specific door properties.</string>
 
     <!-- Permission text: apps control vendor properties related with seat [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_seat">control vendor specific seat properties</string>
+    <string name="car_permission_label_set_car_vendor_category_seat" translatable="false">control vendor specific seat properties</string>
     <!-- Permission text: apps control vendor properties related with seat [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_seat">Control vendor specific seat properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_seat" translatable="false">Control vendor specific seat properties.</string>
 
     <!-- Permission text: apps access vendor properties related with seat [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_seat">access vendor specific seat properties</string>
+    <string name="car_permission_label_get_car_vendor_category_seat" translatable="false">access vendor specific seat properties</string>
     <!-- Permission text: apps access vendor properties related with seat [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_seat">Access vendor specific seat properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_seat" translatable="false">Access vendor specific seat properties.</string>
 
     <!-- Permission text: apps control vendor properties related with mirror [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_mirror">control vendor specific mirror properties</string>
+    <string name="car_permission_label_set_car_vendor_category_mirror" translatable="false">control vendor specific mirror properties</string>
     <!-- Permission text: apps control vendor properties related with mirror [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_mirror">Control vendor specific mirror properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_mirror" translatable="false">Control vendor specific mirror properties.</string>
 
     <!-- Permission text: apps access vendor properties related with mirror [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_mirror">access vendor specific mirror properties</string>
+    <string name="car_permission_label_get_car_vendor_category_mirror" translatable="false">access vendor specific mirror properties</string>
     <!-- Permission text: apps access vendor properties related with mirror [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_mirror">Access vendor specific mirror properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_mirror" translatable="false">Access vendor specific mirror properties.</string>
 
     <!-- Permission text: apps control vendor properties related with info [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_info">control vendor specific information properties</string>
+    <string name="car_permission_label_set_car_vendor_category_info" translatable="false">control vendor specific information properties</string>
     <!-- Permission text: apps control vendor properties related with info [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_info">Control vendor specific information properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_info" translatable="false">Control vendor specific information properties.</string>
 
     <!-- Permission text: apps access vendor properties related with info [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_info">access vendor specific information properties</string>
+    <string name="car_permission_label_get_car_vendor_category_info" translatable="false">access vendor specific information properties</string>
     <!-- Permission text: apps access vendor properties related with info [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_info">Access vendor specific information properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_info" translatable="false">Access vendor specific information properties.</string>
 
     <!-- Permission text: apps control vendor properties related with engine [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_engine">control vendor specific engine properties</string>
+    <string name="car_permission_label_set_car_vendor_category_engine" translatable="false">control vendor specific engine properties</string>
     <!-- Permission text: apps control vendor properties related with engine [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_engine">Control vendor specific engine properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_engine" translatable="false">Control vendor specific engine properties.</string>
 
     <!-- Permission text: apps access vendor properties related with engine [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_engine">access vendor specific engine properties</string>
+    <string name="car_permission_label_get_car_vendor_category_engine" translatable="false">access vendor specific engine properties</string>
     <!-- Permission text: apps access vendor properties related with engine [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_engine">Access vendor specific engine properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_engine" translatable="false">Access vendor specific engine properties.</string>
 
     <!-- Permission text: apps control vendor properties related with hvac [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_hvac">control vendor specific hvac properties</string>
+    <string name="car_permission_label_set_car_vendor_category_hvac" translatable="false">control vendor specific hvac properties</string>
     <!-- Permission text: apps control vendor properties related with hvac [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_hvac">Control vendor specific hvac properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_hvac" translatable="false">Control vendor specific hvac properties.</string>
 
     <!-- Permission text: apps access vendor properties related with hvac [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_hvac">access vendor specific hvac properties</string>
+    <string name="car_permission_label_get_car_vendor_category_hvac" translatable="false">access vendor specific hvac properties</string>
     <!-- Permission text: apps access vendor properties related with hvac [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_hvac">Access vendor specific hvac properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_hvac" translatable="false">Access vendor specific hvac properties.</string>
 
     <!-- Permission text: apps control vendor properties related with light [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_light">control vendor specific light properties</string>
+    <string name="car_permission_label_set_car_vendor_category_light" translatable="false">control vendor specific light properties</string>
     <!-- Permission text: apps control vendor properties related with light [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_light">Control vendor specific light properties.</string>
+    <string name="car_permission_desc_set_car_vendor_category_light" translatable="false">Control vendor specific light properties.</string>
 
     <!-- Permission text: apps access vendor properties related with light [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_light">access vendor specific light properties</string>
+    <string name="car_permission_label_get_car_vendor_category_light" translatable="false">access vendor specific light properties</string>
     <!-- Permission text: apps access vendor properties related with light [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_light">Access vendor specific light properties.</string>
+    <string name="car_permission_desc_get_car_vendor_category_light" translatable="false">Access vendor specific light properties.</string>
 
     <!-- Permission text: apps access properties in category 1 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_1">access vendor specific properties in category 1</string>
+    <string name="car_permission_label_get_car_vendor_category_1" translatable="false">access vendor specific properties in category 1</string>
     <!-- Permission text: apps access vendor properties in category 1 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_1">Access vendor specific properties in category 1.</string>
+    <string name="car_permission_desc_get_car_vendor_category_1" translatable="false">Access vendor specific properties in category 1.</string>
 
     <!-- Permission text: apps access vendor properties in category 2 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_2">access vendor specific properties in category 2</string>
+    <string name="car_permission_label_get_car_vendor_category_2" translatable="false">access vendor specific properties in category 2</string>
     <!-- Permission text: apps access vendor properties in category 2 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_2">Access vendor specific properties in category 2.</string>
+    <string name="car_permission_desc_get_car_vendor_category_2" translatable="false">Access vendor specific properties in category 2.</string>
 
     <!-- Permission text: apps access properties in category 3 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_3">access vendor specific properties in category 3</string>
+    <string name="car_permission_label_get_car_vendor_category_3" translatable="false">access vendor specific properties in category 3</string>
     <!-- Permission text: apps access  properties in category 3 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_3">Access vendor specific properties in category 3.</string>
+    <string name="car_permission_desc_get_car_vendor_category_3" translatable="false">Access vendor specific properties in category 3.</string>
 
     <!-- Permission text: apps access vendor properties in category 4 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_4">access vendor specific properties in category 4</string>
+    <string name="car_permission_label_get_car_vendor_category_4" translatable="false">access vendor specific properties in category 4</string>
     <!-- Permission text: apps access vendor properties in category 4 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_4">Access vendor specific properties in category 4.</string>
+    <string name="car_permission_desc_get_car_vendor_category_4" translatable="false">Access vendor specific properties in category 4.</string>
 
     <!-- Permission text: apps access vendor properties in category 5 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_5">access vendor specific properties in category 5</string>
+    <string name="car_permission_label_get_car_vendor_category_5" translatable="false">access vendor specific properties in category 5</string>
     <!-- Permission text: apps access vendor properties in category 5 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_5">Access vendor specific properties in category 5.</string>
+    <string name="car_permission_desc_get_car_vendor_category_5" translatable="false">Access vendor specific properties in category 5.</string>
 
     <!-- Permission text: apps access vendor properties in category 6 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_6">access vendor specific properties in category 6</string>
+    <string name="car_permission_label_get_car_vendor_category_6" translatable="false">access vendor specific properties in category 6</string>
     <!-- Permission text: apps access and control vendor properties in category 6 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_6">Access vendor specific properties in category 6.</string>
+    <string name="car_permission_desc_get_car_vendor_category_6" translatable="false">Access vendor specific properties in category 6.</string>
 
     <!-- Permission text: apps access vendor properties in category 7 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_7">access vendor specific properties in category 7</string>
+    <string name="car_permission_label_get_car_vendor_category_7" translatable="false">access vendor specific properties in category 7</string>
     <!-- Permission text: apps access vendor properties in category 7 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_7">Access vendor specific properties in category 7.</string>
+    <string name="car_permission_desc_get_car_vendor_category_7" translatable="false">Access vendor specific properties in category 7.</string>
 
     <!-- Permission text: apps access vendor properties in category 8 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_8">access vendor specific properties in category 8</string>
+    <string name="car_permission_label_get_car_vendor_category_8" translatable="false">access vendor specific properties in category 8</string>
     <!-- Permission text: apps access vendor properties in category 8 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_8">Access vendor specific properties in category 8.</string>
+    <string name="car_permission_desc_get_car_vendor_category_8" translatable="false">Access vendor specific properties in category 8.</string>
 
     <!-- Permission text: apps access vendor properties in category 9 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_9">access vendor specific properties in category 9</string>
+    <string name="car_permission_label_get_car_vendor_category_9" translatable="false">access vendor specific properties in category 9</string>
     <!-- Permission text: apps access vendor properties in category 9 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_9">Access vendor specific properties in category 9.</string>
+    <string name="car_permission_desc_get_car_vendor_category_9" translatable="false">Access vendor specific properties in category 9.</string>
 
     <!-- Permission text: apps access vendor properties in category 10 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_get_car_vendor_category_10">access vendor specific properties in category 10</string>
+    <string name="car_permission_label_get_car_vendor_category_10" translatable="false">access vendor specific properties in category 10</string>
     <!-- Permission text: apps access vendor properties in category 10 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_get_car_vendor_category_10">Access vendor specific properties in category 10.</string>
+    <string name="car_permission_desc_get_car_vendor_category_10" translatable="false">Access vendor specific properties in category 10.</string>
 
     <!-- Permission text: apps control vendor properties in category 1 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_1">control vendor specific properties in category 1</string>
+    <string name="car_permission_label_set_car_vendor_category_1" translatable="false">control vendor specific properties in category 1</string>
     <!-- Permission text: apps control vendor properties in category 1 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_1">Control vendor specific properties in category 1.</string>
+    <string name="car_permission_desc_set_car_vendor_category_1" translatable="false">Control vendor specific properties in category 1.</string>
 
     <!-- Permission text: apps control vendor properties in category 2 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_2">control vendor specific properties in category 2</string>
+    <string name="car_permission_label_set_car_vendor_category_2" translatable="false">control vendor specific properties in category 2</string>
     <!-- Permission text: apps control vendor properties in category 2 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_2">Control vendor specific properties in category 2.</string>
+    <string name="car_permission_desc_set_car_vendor_category_2" translatable="false">Control vendor specific properties in category 2.</string>
 
     <!-- Permission text: apps control vendor properties in category 3 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_3">control vendor specific properties in category 3</string>
+    <string name="car_permission_label_set_car_vendor_category_3" translatable="false">control vendor specific properties in category 3</string>
     <!-- Permission text: apps control vendor properties in category 3 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_3">Control vendor specific properties in category 3.</string>
+    <string name="car_permission_desc_set_car_vendor_category_3" translatable="false">Control vendor specific properties in category 3.</string>
 
     <!-- Permission text: apps control vendor properties in category 4 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_4">control vendor specific properties in category 4</string>
+    <string name="car_permission_label_set_car_vendor_category_4" translatable="false">control vendor specific properties in category 4</string>
     <!-- Permission text: apps control vendor properties in category 4 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_4">Control vendor specific properties in category 4.</string>
+    <string name="car_permission_desc_set_car_vendor_category_4" translatable="false">Control vendor specific properties in category 4.</string>
 
     <!-- Permission text: apps control vendor properties in category 5 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_5">control vendor specific properties in category 5</string>
+    <string name="car_permission_label_set_car_vendor_category_5" translatable="false">control vendor specific properties in category 5</string>
     <!-- Permission text: apps control vendor properties in category 5 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_5">Control vendor specific properties in category 5.</string>
+    <string name="car_permission_desc_set_car_vendor_category_5" translatable="false">Control vendor specific properties in category 5.</string>
 
     <!-- Permission text: apps control vendor properties in category 6 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_6">control vendor specific properties in category 6</string>
+    <string name="car_permission_label_set_car_vendor_category_6" translatable="false">control vendor specific properties in category 6</string>
     <!-- Permission text: apps control vendor properties in category 6 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_6">Control vendor specific properties in category 6.</string>
+    <string name="car_permission_desc_set_car_vendor_category_6" translatable="false">Control vendor specific properties in category 6.</string>
 
     <!-- Permission text: apps control vendor properties in category 7 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_7">control vendor specific properties in category 7</string>
+    <string name="car_permission_label_set_car_vendor_category_7" translatable="false">control vendor specific properties in category 7</string>
     <!-- Permission text: apps control vendor properties in category 7 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_7">Control vendor specific properties in category 7.</string>
+    <string name="car_permission_desc_set_car_vendor_category_7" translatable="false">Control vendor specific properties in category 7.</string>
 
     <!-- Permission text: apps control vendor properties in category 8 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_8">control vendor specific properties in category 8</string>
+    <string name="car_permission_label_set_car_vendor_category_8" translatable="false">control vendor specific properties in category 8</string>
     <!-- Permission text: apps control vendor properties in category 8 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_8">Control vendor specific properties in category 8.</string>
+    <string name="car_permission_desc_set_car_vendor_category_8" translatable="false">Control vendor specific properties in category 8.</string>
 
     <!-- Permission text: apps control vendor properties in category 9 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_9">control vendor specific properties in category 9</string>
+    <string name="car_permission_label_set_car_vendor_category_9" translatable="false">control vendor specific properties in category 9</string>
     <!-- Permission text: apps control vendor properties in category 9 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_9">Control vendor specific properties in category 9.</string>
+    <string name="car_permission_desc_set_car_vendor_category_9" translatable="false">Control vendor specific properties in category 9.</string>
 
     <!-- Permission text: apps control vendor properties in category 10 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_label_set_car_vendor_category_10">control vendor specific properties in category 10</string>
+    <string name="car_permission_label_set_car_vendor_category_10" translatable="false">control vendor specific properties in category 10</string>
     <!-- Permission text: apps control vendor properties in category 10 [CHAR LIMIT=NONE] -->
-    <string name="car_permission_desc_set_car_vendor_category_10">Control vendor specific properties in category 10.</string>
+    <string name="car_permission_desc_set_car_vendor_category_10" translatable="false">Control vendor specific properties in category 10.</string>
 
     <!-- Permission text: enable or disable car's features [CHAR LIMIT=NONE] -->
     <string name="car_permission_label_control_car_features">Enable or disable car\u2019s features</string>
diff --git a/service/src/com/android/car/AppFocusService.java b/service/src/com/android/car/AppFocusService.java
index bb019c2..f3a668b 100644
--- a/service/src/com/android/car/AppFocusService.java
+++ b/service/src/com/android/car/AppFocusService.java
@@ -26,16 +26,18 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.util.ArraySet;
 import android.util.Log;
+import android.util.SparseArray;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * App focus service ensures only one instance of application type is active at a time.
@@ -46,17 +48,32 @@
     private static final boolean DBG_EVENT = false;
 
     private final SystemActivityMonitoringService mSystemActivityMonitoringService;
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
     private final ClientHolder mAllChangeClients;
+
+    @GuardedBy("mLock")
     private final OwnershipClientHolder mAllOwnershipClients;
+
     /** K: appType, V: client owning it */
-    private final HashMap<Integer, OwnershipClientInfo> mFocusOwners = new HashMap<>();
-    private final Set<Integer> mActiveAppTypes = new HashSet<>();
-    private final CopyOnWriteArrayList<FocusOwnershipCallback> mFocusOwnershipCallbacks =
-            new CopyOnWriteArrayList<>();
+    @GuardedBy("mLock")
+    private final SparseArray<OwnershipClientInfo> mFocusOwners = new SparseArray<>();
+
+    @GuardedBy("mLock")
+    private final Set<Integer> mActiveAppTypes = new ArraySet<>();
+
+    @GuardedBy("mLock")
+    private final List<FocusOwnershipCallback> mFocusOwnershipCallbacks = new ArrayList<>();
+
     private final BinderInterfaceContainer.BinderEventHandler<IAppFocusListener>
             mAllBinderEventHandler = bInterface -> { /* nothing to do.*/ };
 
+    @GuardedBy("mLock")
     private DispatchHandler mDispatchHandler;
+
+    @GuardedBy("mLock")
     private HandlerThread mHandlerThread;
 
     public AppFocusService(Context context,
@@ -68,7 +85,7 @@
 
     @Override
     public void registerFocusListener(IAppFocusListener listener, int appType) {
-        synchronized (this) {
+        synchronized (mLock) {
             ClientInfo info = (ClientInfo) mAllChangeClients.getBinderInterface(listener);
             if (info == null) {
                 info = new ClientInfo(mAllChangeClients, listener, Binder.getCallingUid(),
@@ -82,7 +99,7 @@
 
     @Override
     public void unregisterFocusListener(IAppFocusListener listener, int appType) {
-        synchronized (this) {
+        synchronized (mLock) {
             ClientInfo info = (ClientInfo) mAllChangeClients.getBinderInterface(listener);
             if (info == null) {
                 return;
@@ -96,26 +113,26 @@
 
     @Override
     public int[] getActiveAppTypes() {
-        synchronized (this) {
-            return toIntArray(mActiveAppTypes);
+        synchronized (mLock) {
+            return mActiveAppTypes.stream().mapToInt(Integer::intValue).toArray();
         }
     }
 
     @Override
     public boolean isOwningFocus(IAppFocusOwnershipCallback callback, int appType) {
-        synchronized (this) {
-            OwnershipClientInfo info =
-                    (OwnershipClientInfo) mAllOwnershipClients.getBinderInterface(callback);
-            if (info == null) {
-                return false;
-            }
-            return info.getOwnedAppTypes().contains(appType);
+        OwnershipClientInfo info;
+        synchronized (mLock) {
+            info = (OwnershipClientInfo) mAllOwnershipClients.getBinderInterface(callback);
         }
+        if (info == null) {
+            return false;
+        }
+        return info.getOwnedAppTypes().contains(appType);
     }
 
     @Override
     public int requestAppFocus(IAppFocusOwnershipCallback callback, int appType) {
-        synchronized (this) {
+        synchronized (mLock) {
             OwnershipClientInfo info =
                     (OwnershipClientInfo) mAllOwnershipClients.getBinderInterface(callback);
             if (info == null) {
@@ -172,7 +189,7 @@
 
     @Override
     public void abandonAppFocus(IAppFocusOwnershipCallback callback, int appType) {
-        synchronized (this) {
+        synchronized (mLock) {
             OwnershipClientInfo info =
                     (OwnershipClientInfo) mAllOwnershipClients.getBinderInterface(callback);
             if (info == null) {
@@ -188,7 +205,8 @@
                 // ignore as listener doesn't own focus.
                 return;
             }
-            if (mFocusOwners.remove(appType) != null) {
+            if (mFocusOwners.contains(appType)) {
+                mFocusOwners.remove(appType);
                 mActiveAppTypes.remove(appType);
                 info.removeOwnedAppType(appType);
                 if (DBG) {
@@ -212,7 +230,7 @@
 
     @Override
     public void init() {
-        synchronized (this) {
+        synchronized (mLock) {
             mHandlerThread = new HandlerThread(AppFocusService.class.getSimpleName());
             mHandlerThread.start();
             mDispatchHandler = new DispatchHandler(mHandlerThread.getLooper());
@@ -221,16 +239,22 @@
 
     @VisibleForTesting
     public Looper getLooper() {
-        return mHandlerThread.getLooper();
+        synchronized (mLock) {
+            return mHandlerThread.getLooper();
+        }
     }
 
     @Override
     public void release() {
-        synchronized (this) {
+        synchronized (mLock) {
+            if (mDispatchHandler == null) {
+                return;
+            }
             mHandlerThread.quitSafely();
             try {
                 mHandlerThread.join(1000);
             } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
                 Log.e(CarLog.TAG_APP_FOCUS, "Timeout while waiting for handler thread to join.");
             }
             mDispatchHandler = null;
@@ -245,15 +269,17 @@
     public void onBinderDeath(
             BinderInterfaceContainer.BinderInterface<IAppFocusOwnershipCallback> bInterface) {
         OwnershipClientInfo info = (OwnershipClientInfo) bInterface;
-        for (Integer appType : info.getOwnedAppTypes()) {
-            abandonAppFocus(bInterface.binderInterface, appType);
+        synchronized (mLock) {
+            for (Integer appType : info.getOwnedAppTypes()) {
+                abandonAppFocus(bInterface.binderInterface, appType);
+            }
         }
     }
 
     @Override
     public void dump(PrintWriter writer) {
         writer.println("**AppFocusService**");
-        synchronized (this) {
+        synchronized (mLock) {
             writer.println("mActiveAppTypes:" + mActiveAppTypes);
             for (BinderInterfaceContainer.BinderInterface<IAppFocusOwnershipCallback> client :
                     mAllOwnershipClients.getInterfaces()) {
@@ -267,8 +293,8 @@
      * Returns true if process with given uid and pid owns provided focus.
      */
     public boolean isFocusOwner(int uid, int pid, int appType) {
-        synchronized (this) {
-            if (mFocusOwners.containsKey(appType)) {
+        synchronized (mLock) {
+            if (mFocusOwners.contains(appType)) {
                 OwnershipClientInfo clientInfo = mFocusOwners.get(appType);
                 return clientInfo.getUid() == uid && clientInfo.getPid() == pid;
             }
@@ -291,16 +317,15 @@
      * {@link FocusOwnershipCallback#onFocusAcquired} call immediately in the same thread.
      */
     public void registerContextOwnerChangedCallback(FocusOwnershipCallback callback) {
-        mFocusOwnershipCallbacks.add(callback);
-
-        HashSet<Map.Entry<Integer, OwnershipClientInfo>> owners;
-        synchronized (this) {
-            owners = new HashSet<>(mFocusOwners.entrySet());
+        SparseArray<OwnershipClientInfo> owners;
+        synchronized (mLock) {
+            mFocusOwnershipCallbacks.add(callback);
+            owners = mFocusOwners.clone();
         }
-
-        for (Map.Entry<Integer, OwnershipClientInfo> entry : owners) {
-            OwnershipClientInfo clientInfo = entry.getValue();
-            callback.onFocusAcquired(entry.getKey(), clientInfo.getUid(), clientInfo.getPid());
+        for (int idx = 0; idx < owners.size(); idx++) {
+            int key = owners.keyAt(idx);
+            OwnershipClientInfo clientInfo = owners.valueAt(idx);
+            callback.onFocusAcquired(key, clientInfo.getUid(), clientInfo.getPid());
         }
     }
 
@@ -308,16 +333,19 @@
      * Unregisters provided callback.
      */
     public void unregisterContextOwnerChangedCallback(FocusOwnershipCallback callback) {
-        mFocusOwnershipCallbacks.remove(callback);
+        synchronized (mLock) {
+            mFocusOwnershipCallbacks.remove(callback);
+        }
     }
 
     private void updateFocusOwner(int appType, OwnershipClientInfo owner) {
         CarServiceUtils.runOnMain(() -> {
-            synchronized (this) {
+            List<FocusOwnershipCallback> focusOwnershipCallbacks;
+            synchronized (mLock) {
                 mFocusOwners.put(appType, owner);
+                focusOwnershipCallbacks = new ArrayList<>(mFocusOwnershipCallbacks);
             }
-
-            for (FocusOwnershipCallback callback : mFocusOwnershipCallbacks) {
+            for (FocusOwnershipCallback callback : focusOwnershipCallbacks) {
                 callback.onFocusAcquired(appType, owner.getUid(), owner.getPid());
             }
         });
@@ -357,11 +385,13 @@
         }
     }
 
-    private static class ClientInfo extends
+    private class ClientInfo extends
             BinderInterfaceContainer.BinderInterface<IAppFocusListener> {
         private final int mUid;
         private final int mPid;
-        private final Set<Integer> mAppTypes = new HashSet<>();
+
+        @GuardedBy("AppFocusService.mLock")
+        private final Set<Integer> mAppTypes = new ArraySet<>();
 
         private ClientInfo(ClientHolder holder, IAppFocusListener binder, int uid, int pid,
                 int appType) {
@@ -371,32 +401,40 @@
             this.mAppTypes.add(appType);
         }
 
-        private synchronized Set<Integer> getAppTypes() {
-            return mAppTypes;
+        private Set<Integer> getAppTypes() {
+            synchronized (mLock) {
+                return Collections.unmodifiableSet(mAppTypes);
+            }
         }
 
-        private synchronized boolean addAppType(Integer appType) {
-            return mAppTypes.add(appType);
+        private boolean addAppType(Integer appType) {
+            synchronized (mLock) {
+                return mAppTypes.add(appType);
+            }
         }
 
-        private synchronized boolean removeAppType(Integer appType) {
-            return mAppTypes.remove(appType);
+        private boolean removeAppType(Integer appType) {
+            synchronized (mLock) {
+                return mAppTypes.remove(appType);
+            }
         }
 
         @Override
         public String toString() {
-            synchronized (this) {
+            synchronized (mLock) {
                 return "ClientInfo{mUid=" + mUid + ",mPid=" + mPid
                         + ",appTypes=" + mAppTypes + "}";
             }
         }
     }
 
-    private static class OwnershipClientInfo extends
+    private class OwnershipClientInfo extends
             BinderInterfaceContainer.BinderInterface<IAppFocusOwnershipCallback> {
         private final int mUid;
         private final int mPid;
-        private final Set<Integer> mOwnedAppTypes = new HashSet<>();
+
+        @GuardedBy("AppFocusService.mLock")
+        private final Set<Integer> mOwnedAppTypes = new ArraySet<>();
 
         private OwnershipClientInfo(OwnershipClientHolder holder, IAppFocusOwnershipCallback binder,
                 int uid, int pid) {
@@ -405,25 +443,31 @@
             this.mPid = pid;
         }
 
-        private synchronized Set<Integer> getOwnedAppTypes() {
+        private Set<Integer> getOwnedAppTypes() {
             if (DBG_EVENT) {
                 Log.i(CarLog.TAG_APP_FOCUS, "getOwnedAppTypes " + mOwnedAppTypes);
             }
-            return mOwnedAppTypes;
+            synchronized (mLock) {
+                return Collections.unmodifiableSet(mOwnedAppTypes);
+            }
         }
 
-        private synchronized boolean addOwnedAppType(Integer appType) {
+        private boolean addOwnedAppType(Integer appType) {
             if (DBG_EVENT) {
                 Log.i(CarLog.TAG_APP_FOCUS, "addOwnedAppType " + appType);
             }
-            return mOwnedAppTypes.add(appType);
+            synchronized (mLock) {
+                return mOwnedAppTypes.add(appType);
+            }
         }
 
-        private synchronized boolean removeOwnedAppType(Integer appType) {
+        private boolean removeOwnedAppType(Integer appType) {
             if (DBG_EVENT) {
                 Log.i(CarLog.TAG_APP_FOCUS, "removeOwnedAppType " + appType);
             }
-            return mOwnedAppTypes.remove(appType);
+            synchronized (mLock) {
+                return mOwnedAppTypes.remove(appType);
+            }
         }
 
         int getUid() {
@@ -436,7 +480,7 @@
 
         @Override
         public String toString() {
-            synchronized (this) {
+            synchronized (mLock) {
                 return "ClientInfo{mUid=" + mUid + ",mPid=" + mPid
                         + ",owned=" + mOwnedAppTypes + "}";
             }
@@ -488,13 +532,4 @@
             }
         }
     }
-
-    private static int[] toIntArray(Set<Integer> intSet) {
-        int[] intArr = new int[intSet.size()];
-        int index = 0;
-        for (Integer value : intSet) {
-            intArr[index++] = value;
-        }
-        return intArr;
-    }
 }
diff --git a/service/src/com/android/car/CarPowerManagementService.java b/service/src/com/android/car/CarPowerManagementService.java
index 4eb3a96..bcf120c 100644
--- a/service/src/com/android/car/CarPowerManagementService.java
+++ b/service/src/com/android/car/CarPowerManagementService.java
@@ -22,6 +22,7 @@
 import android.car.hardware.power.ICarPowerStateListener;
 import android.car.userlib.CarUserManagerHelper;
 import android.content.Context;
+import android.content.res.Resources;
 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReq;
 import android.os.Build;
 import android.os.Handler;
@@ -99,6 +100,7 @@
     private boolean mIsBooting = true;
     @GuardedBy("mLock")
     private boolean mIsResuming;
+    private final boolean mDisableUserSwitchDuringResume;
 
     private final CarUserManagerHelper mCarUserManagerHelper;
 
@@ -127,14 +129,21 @@
         }
     }
 
-    public CarPowerManagementService(
-            Context context, PowerHalService powerHal, SystemInterface systemInterface,
-            CarUserManagerHelper carUserManagerHelper) {
+    public CarPowerManagementService(Context context, PowerHalService powerHal,
+            SystemInterface systemInterface, CarUserManagerHelper carUserManagerHelper) {
+        this(context, context.getResources(), powerHal, systemInterface, carUserManagerHelper);
+    }
+
+    @VisibleForTesting
+    CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal,
+            SystemInterface systemInterface, CarUserManagerHelper carUserManagerHelper) {
         mContext = context;
         mHal = powerHal;
         mSystemInterface = systemInterface;
         mCarUserManagerHelper = carUserManagerHelper;
-        sShutdownPrepareTimeMs = mContext.getResources().getInteger(
+        mDisableUserSwitchDuringResume = resources
+                .getBoolean(R.bool.config_disableUserSwitchDuringResume);
+        sShutdownPrepareTimeMs = resources.getInteger(
                 R.integer.maxGarageModeRunningDurationInSecs) * 1000;
         if (sShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) {
             Log.w(CarLog.TAG_POWER,
@@ -157,6 +166,7 @@
         mHandlerThread = null;
         mHandler = new PowerHandler(Looper.getMainLooper());
         mCarUserManagerHelper = null;
+        mDisableUserSwitchDuringResume = true;
     }
 
     @VisibleForTesting
@@ -169,6 +179,13 @@
         }
     }
 
+    @VisibleForTesting
+    protected HandlerThread getHandlerThread() {
+        synchronized (mLock) {
+            return mHandlerThread;
+        }
+    }
+
     @Override
     public void init() {
         synchronized (mLock) {
@@ -231,10 +248,13 @@
     }
 
     @VisibleForTesting
-    protected void clearIsBootingOrResuming() {
+    void setStateForTesting(boolean isBooting, boolean isResuming) {
         synchronized (mLock) {
-            mIsBooting = false;
-            mIsResuming = false;
+            Log.d(CarLog.TAG_POWER, "setStateForTesting():"
+                    + " booting(" + mIsBooting + ">" + isBooting + ")"
+                    + " resuming(" + mIsResuming + ">" + isResuming + ")");
+            mIsBooting = isBooting;
+            mIsResuming = isResuming;
         }
     }
 
@@ -331,8 +351,7 @@
                 Log.i(CarLog.TAG_POWER, "User switch disallowed while booting");
             } else if (mIsResuming) {
                 // The system is resuming after a suspension. Optionally disable user switching.
-                allowUserSwitch = !mContext.getResources()
-                        .getBoolean(R.bool.config_disableUserSwitchDuringResume);
+                allowUserSwitch = !mDisableUserSwitchDuringResume;
                 mIsBooting = false;
                 mIsResuming = false;
                 if (!allowUserSwitch) {
diff --git a/service/src/com/android/car/VmsLayersAvailability.java b/service/src/com/android/car/VmsLayersAvailability.java
index 2e17a89..a9bbc7a 100644
--- a/service/src/com/android/car/VmsLayersAvailability.java
+++ b/service/src/com/android/car/VmsLayersAvailability.java
@@ -109,9 +109,6 @@
             mPotentialLayersAndPublishers.clear();
             mAvailableAssociatedLayers = Collections.EMPTY_SET;
             mUnavailableAssociatedLayers = Collections.EMPTY_SET;
-            if (mSeq + 1 < mSeq) {
-                throw new IllegalStateException("Sequence is about to loop");
-            }
             mSeq += 1;
         }
     }
diff --git a/service/src/com/android/car/pm/CarPackageManagerService.java b/service/src/com/android/car/pm/CarPackageManagerService.java
index f128374..0c4a1fd 100644
--- a/service/src/com/android/car/pm/CarPackageManagerService.java
+++ b/service/src/com/android/car/pm/CarPackageManagerService.java
@@ -212,7 +212,7 @@
         if (DBG_POLICY_SET) {
             Log.i(CarLog.TAG_PACKAGE, "policy setting from binder call, client:" + packageName);
         }
-        doSetAppBlockingPolicy(packageName, policy, flags, true /*setNow*/);
+        doSetAppBlockingPolicy(packageName, policy, flags);
     }
 
     /**
@@ -223,8 +223,8 @@
         mSystemActivityMonitoringService.restartTask(taskId);
     }
 
-    private void doSetAppBlockingPolicy(String packageName, CarAppBlockingPolicy policy, int flags,
-            boolean setNow) {
+    private void doSetAppBlockingPolicy(String packageName, CarAppBlockingPolicy policy,
+            int flags) {
         if (mContext.checkCallingOrSelfPermission(Car.PERMISSION_CONTROL_APP_BLOCKING)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException(
@@ -239,18 +239,22 @@
             throw new IllegalArgumentException(
                     "Cannot set both FLAG_SET_POLICY_ADD and FLAG_SET_POLICY_REMOVE flag");
         }
-        mHandler.requestUpdatingPolicy(packageName, policy, flags);
-        if (setNow) {
-            mHandler.requestPolicySetting();
+        synchronized (mLock) {
             if ((flags & CarPackageManager.FLAG_SET_POLICY_WAIT_FOR_CHANGE) != 0) {
-                synchronized (policy) {
-                    try {
-                        policy.wait();
-                    } catch (InterruptedException e) {
-                        Log.e(CarLog.TAG_PACKAGE,
-                                "Interrupted wait during doSetAppBlockingPolicy");
-                        Thread.currentThread().interrupt();
+                mWaitingPolicies.add(policy);
+            }
+        }
+        mHandler.requestUpdatingPolicy(packageName, policy, flags);
+        if ((flags & CarPackageManager.FLAG_SET_POLICY_WAIT_FOR_CHANGE) != 0) {
+            synchronized (mLock) {
+                try {
+                    while (mWaitingPolicies.contains(policy)) {
+                        wait();
                     }
+                } catch (InterruptedException e) {
+                    // Pass it over binder call
+                    throw new IllegalStateException(
+                            "Interrupted while waiting for policy completion", e);
                 }
             }
         }
@@ -399,7 +403,8 @@
                 }
                 mProxies.clear();
             }
-            wakeupClientsWaitingForPolicySettingLocked();
+            mWaitingPolicies.clear();
+            notifyAll();
         }
         mContext.unregisterReceiver(mPackageParsingEventReceiver);
         mContext.unregisterReceiver(mUserSwitchedEventReceiver);
@@ -463,23 +468,6 @@
         }
     }
 
-    @GuardedBy("mLock")
-    private void wakeupClientsWaitingForPolicySettingLocked() {
-        for (CarAppBlockingPolicy waitingPolicy : mWaitingPolicies) {
-            synchronized (waitingPolicy) {
-                waitingPolicy.notifyAll();
-            }
-        }
-        mWaitingPolicies.clear();
-    }
-
-    private void doSetPolicy() {
-        synchronized (mLock) {
-            wakeupClientsWaitingForPolicySettingLocked();
-        }
-        blockTopActivitiesIfNecessary();
-    }
-
     private void doUpdatePolicy(String packageName, CarAppBlockingPolicy policy, int flags) {
         if (DBG_POLICY_SET) {
             Log.i(CarLog.TAG_PACKAGE, "setting policy from:" + packageName + ",policy:" + policy +
@@ -504,7 +492,8 @@
                 clientPolicy.replaceWhitelists(whitelistWrapper);
             }
             if ((flags & CarPackageManager.FLAG_SET_POLICY_WAIT_FOR_CHANGE) != 0) {
-                mWaitingPolicies.add(policy);
+                mWaitingPolicies.remove(policy);
+                notifyAll();
             }
             if (DBG_POLICY_SET) {
                 Log.i(CarLog.TAG_PACKAGE, "policy set:" + dumpPoliciesLocked(false));
@@ -862,7 +851,6 @@
         policyIntent.setAction(CarAppBlockingPolicyService.SERVICE_INTERFACE);
         List<ResolveInfo> policyInfos = mPackageManager.queryIntentServices(policyIntent, 0);
         if (policyInfos == null) { //no need to wait for service binding and retrieval.
-            mHandler.requestPolicySetting();
             return;
         }
         LinkedList<AppBlockingPolicyProxy> proxies = new LinkedList<>();
@@ -899,7 +887,6 @@
 
     private void doHandlePolicyConnection(AppBlockingPolicyProxy proxy,
             CarAppBlockingPolicy policy) {
-        boolean shouldSetPolicy = false;
         synchronized (mLock) {
             if (mProxies == null) {
                 proxy.disconnect();
@@ -907,7 +894,6 @@
             }
             mProxies.remove(proxy);
             if (mProxies.size() == 0) {
-                shouldSetPolicy = true;
                 mProxies = null;
             }
         }
@@ -917,13 +903,10 @@
                     Log.i(CarLog.TAG_PACKAGE, "policy setting from policy service:" +
                             proxy.getPackageName());
                 }
-                doSetAppBlockingPolicy(proxy.getPackageName(), policy, 0, false /*setNow*/);
+                doSetAppBlockingPolicy(proxy.getPackageName(), policy, 0);
             }
         } finally {
             proxy.disconnect();
-            if (shouldSetPolicy) {
-                mHandler.requestPolicySetting();
-            }
         }
     }
 
@@ -1194,11 +1177,10 @@
      * Reading policy and setting policy can take time. Run it in a separate handler thread.
      */
     private class PackageHandler extends Handler {
-        private final int MSG_INIT = 0;
-        private final int MSG_PARSE_PKG = 1;
-        private final int MSG_SET_POLICY = 2;
-        private final int MSG_UPDATE_POLICY = 3;
-        private final int MSG_RELEASE = 4;
+        private static final int MSG_INIT = 0;
+        private static final int MSG_PARSE_PKG = 1;
+        private static final int MSG_UPDATE_POLICY = 2;
+        private static final int MSG_RELEASE = 3;
 
         private PackageHandler(Looper looper) {
             super(looper);
@@ -1210,17 +1192,11 @@
         }
 
         private void requestRelease() {
-            removeMessages(MSG_SET_POLICY);
             removeMessages(MSG_UPDATE_POLICY);
             Message msg = obtainMessage(MSG_RELEASE);
             sendMessage(msg);
         }
 
-        private void requestPolicySetting() {
-            Message msg = obtainMessage(MSG_SET_POLICY);
-            sendMessage(msg);
-        }
-
         private void requestUpdatingPolicy(String packageName, CarAppBlockingPolicy policy,
                 int flags) {
             Pair<String, CarAppBlockingPolicy> pair = new Pair<>(packageName, policy);
@@ -1249,9 +1225,6 @@
                 case MSG_PARSE_PKG:
                     doParseInstalledPackages();
                     break;
-                case MSG_SET_POLICY:
-                    doSetPolicy();
-                    break;
                 case MSG_UPDATE_POLICY:
                     Pair<String, CarAppBlockingPolicy> pair =
                             (Pair<String, CarAppBlockingPolicy>) msg.obj;
diff --git a/tests/BugReportApp/Android.bp b/tests/BugReportApp/Android.bp
new file mode 100644
index 0000000..5034ebf
--- /dev/null
+++ b/tests/BugReportApp/Android.bp
@@ -0,0 +1,64 @@
+// Copyright (C) 2019 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.
+
+android_app {
+    name: "BugReportApp",
+
+    srcs: ["src/**/*.java"],
+
+    resource_dirs: ["res"],
+
+    platform_apis: true,
+
+    aaptflags: ["--auto-add-overlay"],
+
+    optimize: {
+        enabled: false,
+    },
+
+    certificate: "platform",
+
+    privileged: true,
+
+    dex_preopt: {
+        enabled: false,
+    },
+
+    libs: [
+        "android.car",
+    ],
+
+    static_libs: [
+        "androidx.recyclerview_recyclerview",
+        "car-br-auto-value-jar",
+        "car-br-google-api-client-android-jar",
+        "car-br-google-api-java-client-jar",
+        "car-br-google-http-client-android-jar",
+        "car-br-google-http-client-jackson2-jar",
+        "car-br-google-http-client-jar",
+        "car-br-google-oauth-client-jar",
+        "car-br-google-storage-services-jar",
+        "car-br-jackson-core-jar",
+        "car-br-grpc-context-jar",
+        "car-br-opencensus-api-jar",
+        "car-br-opencensus-contrib-http-util-jar",
+        "guava",
+        "jsr305",
+    ],
+
+    required: ["privapp_whitelist_com.android.car.bugreport"],
+
+    // Explicitly define annotation processors even if javac can find them from static_libs.
+    plugins: ["car-br-auto-value"],
+}
diff --git a/tests/BugReportApp/Android.mk b/tests/BugReportApp/Android.mk
deleted file mode 100644
index 905bb5a..0000000
--- a/tests/BugReportApp/Android.mk
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (C) 2019 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.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_PACKAGE_NAME := BugReportApp
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_AAPT_FLAGS := --auto-add-overlay
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_CERTIFICATE := platform
-
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_DEX_PREOPT := false
-
-LOCAL_JAVA_LIBRARIES += \
-    android.car
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.recyclerview_recyclerview \
-    br_google-api-java-client \
-    br_google-api-client-android \
-    br_google-oauth-client \
-    br_google-http-client \
-    br_google-http-client-android \
-    br_google-http-client-jackson2 \
-    br_jackson-core \
-    br_gson-2.1 \
-    br_google-storage-services \
-    br_apache_commons \
-    guava \
-    jsr305
-
-LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.car.bugreport
-
-include $(BUILD_PACKAGE)
-
-# ====  prebuilt library  ========================
-include $(CLEAR_VARS)
-
-COMMON_LIBS_PATH := ../../../../../prebuilts/tools/common/m2/repository
-
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
-    br_google-api-java-client:libs/google-api-client-1.25.0.jar \
-    br_google-api-client-android:libs/google-api-client-android-1.25.0.jar \
-    br_google-oauth-client:libs/google-oauth-client-1.25.0.jar \
-    br_google-http-client:libs/google-http-client-1.25.0.jar \
-    br_google-http-client-android:libs/google-http-client-android-1.25.0.jar \
-    br_jackson-core:libs/jackson-core-2.9.6.jar \
-    br_gson-2.1:libs/gson-2.1.jar \
-    br_google-http-client-jackson2:libs/google-http-client-jackson2-1.25.0.jar \
-    br_google-storage-services:libs/google-api-services-storage-v1-rev136-1.25.0.jar \
-    br_apache_commons:$(COMMON_LIBS_PATH)/org/eclipse/tycho/tycho-bundles-external/0.18.1/eclipse/plugins/org.apache.commons.codec_1.4.0.v201209201156.jar
-
-include $(BUILD_MULTI_PREBUILT)
diff --git a/tests/BugReportApp/AndroidManifest.xml b/tests/BugReportApp/AndroidManifest.xml
index cf0a7a9..3a768e8 100644
--- a/tests/BugReportApp/AndroidManifest.xml
+++ b/tests/BugReportApp/AndroidManifest.xml
@@ -16,8 +16,8 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.car.bugreport"
-          android:versionCode="8"
-          android:versionName="1.6.0">
+          android:versionCode="11"
+          android:versionName="1.7.0">
 
     <uses-permission android:name="android.car.permission.CAR_DRIVING_STATE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
@@ -29,8 +29,13 @@
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
     <uses-permission android:name="android.permission.DUMP"/>
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
 
-    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
+    <application android:label="@string/app_name"
+                 android:icon="@drawable/ic_launcher"
+                 android:requestLegacyExternalStorage="true">
         <activity android:name=".BugReportInfoActivity"
                   android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
                   android:exported="true"
@@ -42,16 +47,26 @@
             </intent-filter>
         </activity>
 
-        <!-- singleInstance allows starting bugreport dialog when BugReportInfoActivity is open. -->
+        <!--
+          singleInstance allows starting bugreport dialog when BugReportInfoActivity is open.
+        -->
         <activity android:name=".BugReportActivity"
                   android:theme="@android:style/Theme.DeviceDefault.Dialog"
                   android:exported="true"
-                  android:launchMode="singleInstance">
+                  android:launchMode="singleInstance"
+                  android:excludeFromRecents="true">
             <meta-data android:name="distractionOptimized" android:value="true"/>
+            <intent-filter>
+                <action android:name="com.android.car.bugreport.action.START_SILENT"/>
+            </intent-filter>
         </activity>
 
         <service android:name=".BugReportService"
-                 android:exported="false"/>
+                 android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.car.bugreport.action.START_SILENT"/>
+            </intent-filter>
+        </service>
 
         <service android:name="com.android.car.bugreport.UploadJob"
                  android:permission="android.permission.BIND_JOB_SERVICE"
diff --git a/tests/BugReportApp/README.md b/tests/BugReportApp/README.md
index 63a931a..695c819 100644
--- a/tests/BugReportApp/README.md
+++ b/tests/BugReportApp/README.md
@@ -38,16 +38,31 @@
 [overlayed](https://source.android.com/setup/develop/new-device#use-resource-overlays)
 for specific products.
 
+### Config
+
+Configs are defined in `Config.java`.
+
 ### System Properties
 
-- `android.car.bugreport.disableautoupload` - set it to `true` to disable auto-upload to Google
-   Cloud, and allow users to manually upload or copy the bugreports to flash drive.
+- `android.car.bugreport.enableautoupload` - please see Config#ENABLE_AUTO_UPLOAD to learn more.
+- `android.car.bugreport.force_enable` - set it `true` to enable bugreport app on **all builds**.
 
 ### Upload configuration
 
 BugReport app uses `res/raw/gcs_credentials.json` for authentication and
 `res/values/configs.xml` for obtaining GCS bucket name.
 
+## Starting bugreporting
+
+The app supports following intents:
+
+1. `adb shell am start com.android.car.bugreport/.BugReportActivity`
+    - generates `MetaBugReport.Type.INTERACTIVE` bug report, shows audio message dialog before
+    collecting bugreport.
+2. `adb shell am start-foreground-service -a com.android.car.bugreport.action.START_SILENT com.android.car.bugreport/.BugReportService`
+    - generates `MetaBugReport.Type.SILENT` bug report, without audio message. It shows audio dialog
+    after collecting bugreport.
+
 ## Testing
 
 ### Manually testing the app using the test script
diff --git a/tests/BugReportApp/libs/Android.bp b/tests/BugReportApp/libs/Android.bp
new file mode 100644
index 0000000..8f36053
--- /dev/null
+++ b/tests/BugReportApp/libs/Android.bp
@@ -0,0 +1,95 @@
+// Copyright (C) 2019 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.
+
+java_import {
+    name: "car-br-auto-value-jar",
+    host_supported: true,
+    sdk_version: "current",
+    jars: ["auto-value-1.5.2.jar"],
+}
+
+java_plugin {
+    name: "car-br-auto-value",
+    static_libs: [
+        "car-br-auto-value-jar",
+        "guava",
+    ],
+    processor_class: "com.google.auto.value.processor.AutoValueProcessor",
+}
+
+java_import {
+    name: "car-br-google-api-java-client-jar",
+    jars: ["google-api-client-1.30.2.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-google-api-client-android-jar",
+    jars: ["google-api-client-android-1.30.2.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-google-storage-services-jar",
+    jars: ["google-api-services-storage-v1-rev158-1.25.0.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-google-oauth-client-jar",
+    jars: ["google-oauth-client-1.30.1.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-google-http-client-jar",
+    jars: ["google-http-client-1.30.1.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-google-http-client-android-jar",
+    jars: ["google-http-client-android-1.30.1.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-google-http-client-jackson2-jar",
+    jars: ["google-http-client-jackson2-1.30.1.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-grpc-context-jar",
+    jars: ["grpc-context-1.19.0.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-jackson-core-jar",
+    jars: ["jackson-core-2.9.9.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-opencensus-api-jar",
+    jars: ["opencensus-api-0.21.0.jar"],
+    sdk_version: "current",
+}
+
+java_import {
+    name: "car-br-opencensus-contrib-http-util-jar",
+    jars: ["opencensus-contrib-http-util-0.21.0.jar"],
+    sdk_version: "current",
+}
diff --git a/tests/BugReportApp/libs/auto-value-1.5.2.jar b/tests/BugReportApp/libs/auto-value-1.5.2.jar
new file mode 100644
index 0000000..8ac0567
--- /dev/null
+++ b/tests/BugReportApp/libs/auto-value-1.5.2.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-client-1.25.0.jar b/tests/BugReportApp/libs/google-api-client-1.25.0.jar
deleted file mode 100644
index f1e65b2..0000000
--- a/tests/BugReportApp/libs/google-api-client-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-client-1.30.2.jar b/tests/BugReportApp/libs/google-api-client-1.30.2.jar
new file mode 100644
index 0000000..b2330d8
--- /dev/null
+++ b/tests/BugReportApp/libs/google-api-client-1.30.2.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-client-android-1.25.0.jar b/tests/BugReportApp/libs/google-api-client-android-1.25.0.jar
deleted file mode 100644
index 2e62e7a..0000000
--- a/tests/BugReportApp/libs/google-api-client-android-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-client-android-1.30.2.jar b/tests/BugReportApp/libs/google-api-client-android-1.30.2.jar
new file mode 100644
index 0000000..fb04d53
--- /dev/null
+++ b/tests/BugReportApp/libs/google-api-client-android-1.30.2.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-client-gson-1.25.0.jar b/tests/BugReportApp/libs/google-api-client-gson-1.25.0.jar
deleted file mode 100644
index 734491d..0000000
--- a/tests/BugReportApp/libs/google-api-client-gson-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-client-jackson2-1.25.0.jar b/tests/BugReportApp/libs/google-api-client-jackson2-1.25.0.jar
deleted file mode 100644
index da08ebe..0000000
--- a/tests/BugReportApp/libs/google-api-client-jackson2-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-services-storage-v1-rev136-1.25.0.jar b/tests/BugReportApp/libs/google-api-services-storage-v1-rev136-1.25.0.jar
deleted file mode 100644
index 2f265eb..0000000
--- a/tests/BugReportApp/libs/google-api-services-storage-v1-rev136-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-api-services-storage-v1-rev158-1.25.0.jar b/tests/BugReportApp/libs/google-api-services-storage-v1-rev158-1.25.0.jar
new file mode 100644
index 0000000..a8e58a6
--- /dev/null
+++ b/tests/BugReportApp/libs/google-api-services-storage-v1-rev158-1.25.0.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-1.25.0.jar b/tests/BugReportApp/libs/google-http-client-1.25.0.jar
deleted file mode 100644
index 84c8ce3..0000000
--- a/tests/BugReportApp/libs/google-http-client-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-1.30.1.jar b/tests/BugReportApp/libs/google-http-client-1.30.1.jar
new file mode 100644
index 0000000..aa2ea71
--- /dev/null
+++ b/tests/BugReportApp/libs/google-http-client-1.30.1.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-android-1.25.0.jar b/tests/BugReportApp/libs/google-http-client-android-1.25.0.jar
deleted file mode 100644
index f2bb0d4..0000000
--- a/tests/BugReportApp/libs/google-http-client-android-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-android-1.30.1.jar b/tests/BugReportApp/libs/google-http-client-android-1.30.1.jar
new file mode 100644
index 0000000..31c88a8
--- /dev/null
+++ b/tests/BugReportApp/libs/google-http-client-android-1.30.1.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-gson-1.25.0.jar b/tests/BugReportApp/libs/google-http-client-gson-1.25.0.jar
deleted file mode 100644
index 158c0c8..0000000
--- a/tests/BugReportApp/libs/google-http-client-gson-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-jackson2-1.25.0.jar b/tests/BugReportApp/libs/google-http-client-jackson2-1.25.0.jar
deleted file mode 100644
index 34f5646..0000000
--- a/tests/BugReportApp/libs/google-http-client-jackson2-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-jackson2-1.30.1.jar b/tests/BugReportApp/libs/google-http-client-jackson2-1.30.1.jar
new file mode 100644
index 0000000..021b6b7
--- /dev/null
+++ b/tests/BugReportApp/libs/google-http-client-jackson2-1.30.1.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/google-http-client-jdo-1.25.0.jar b/tests/BugReportApp/libs/google-http-client-jdo-1.25.0.jar
deleted file mode 100644
index dcb7461..0000000
--- a/tests/BugReportApp/libs/google-http-client-jdo-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-oauth-client-1.25.0.jar b/tests/BugReportApp/libs/google-oauth-client-1.25.0.jar
deleted file mode 100644
index 1304c30..0000000
--- a/tests/BugReportApp/libs/google-oauth-client-1.25.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/google-oauth-client-1.30.1.jar b/tests/BugReportApp/libs/google-oauth-client-1.30.1.jar
new file mode 100644
index 0000000..2489729
--- /dev/null
+++ b/tests/BugReportApp/libs/google-oauth-client-1.30.1.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/grpc-context-1.19.0.jar b/tests/BugReportApp/libs/grpc-context-1.19.0.jar
new file mode 100644
index 0000000..94b2e38
--- /dev/null
+++ b/tests/BugReportApp/libs/grpc-context-1.19.0.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/gson-2.1.jar b/tests/BugReportApp/libs/gson-2.1.jar
deleted file mode 100644
index 83c5c99..0000000
--- a/tests/BugReportApp/libs/gson-2.1.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/httpclient-4.5.5.jar b/tests/BugReportApp/libs/httpclient-4.5.5.jar
deleted file mode 100644
index 7796b0e..0000000
--- a/tests/BugReportApp/libs/httpclient-4.5.5.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/jackson-core-2.9.6.jar b/tests/BugReportApp/libs/jackson-core-2.9.6.jar
deleted file mode 100644
index 09e7dd2..0000000
--- a/tests/BugReportApp/libs/jackson-core-2.9.6.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/jackson-core-2.9.9.jar b/tests/BugReportApp/libs/jackson-core-2.9.9.jar
new file mode 100644
index 0000000..02bd446
--- /dev/null
+++ b/tests/BugReportApp/libs/jackson-core-2.9.9.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/jdo2-api-2.3-eb.jar b/tests/BugReportApp/libs/jdo2-api-2.3-eb.jar
deleted file mode 100644
index a039ae7..0000000
--- a/tests/BugReportApp/libs/jdo2-api-2.3-eb.jar
+++ /dev/null
Binary files differ
diff --git a/tests/BugReportApp/libs/opencensus-api-0.21.0.jar b/tests/BugReportApp/libs/opencensus-api-0.21.0.jar
new file mode 100644
index 0000000..ad0646e
--- /dev/null
+++ b/tests/BugReportApp/libs/opencensus-api-0.21.0.jar
Binary files differ
diff --git a/tests/BugReportApp/libs/opencensus-contrib-http-util-0.21.0.jar b/tests/BugReportApp/libs/opencensus-contrib-http-util-0.21.0.jar
new file mode 100644
index 0000000..32f0e51
--- /dev/null
+++ b/tests/BugReportApp/libs/opencensus-contrib-http-util-0.21.0.jar
Binary files differ
diff --git a/tests/BugReportApp/res/layout/bug_info_view.xml b/tests/BugReportApp/res/layout/bug_info_view.xml
index 3736c00..199b368 100644
--- a/tests/BugReportApp/res/layout/bug_info_view.xml
+++ b/tests/BugReportApp/res/layout/bug_info_view.xml
@@ -26,99 +26,68 @@
         android:orientation="vertical">
 
         <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="TITLE"
-            android:textColor="@android:color/holo_green_light"
-            android:textSize="28sp" />
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="USER"
-            android:textColor="@android:color/holo_red_dark"
-            android:textSize="28sp" />
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="BUG TIME"
-            android:textColor="@android:color/holo_red_light"
-            android:textSize="28sp" />
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="STATUS"
-            android:textColor="@android:color/holo_orange_light"
-            android:textSize="28sp" />
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="OTHER"
-            android:textColor="@android:color/holo_blue_dark"
-            android:textSize="28sp" />
-
-        <Button
-            android:id="@+id/bug_info_upload_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/bug_report_user_action_button_padding"
-            android:textSize="@dimen/bug_report_button_text_size"
-            android:text="@string/bugreport_upload_button_text" />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingLeft="10dp"
-        android:orientation="vertical">
-
-        <TextView
             android:id="@+id/bug_info_row_title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="left"
-            android:textSize="28sp" />
+            android:textColor="@*android:color/car_yellow_500"
+            android:textSize="@dimen/bug_report_default_text_size" />
 
-
-        <TextView
-            android:id="@+id/bug_info_row_user"
+        <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textSize="28sp" />
-
-
-        <TextView
-            android:id="@+id/bug_info_row_timestamp"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textSize="28sp" />
-
-
-        <TextView
-            android:id="@+id/bug_info_row_status"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textSize="28sp" />
-
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="@dimen/bug_report_horizontal_layout_children_margin"
+                android:text="@string/bugreport_info_status"
+                android:textSize="@dimen/bug_report_default_text_size" />
+            <TextView
+                android:id="@+id/bug_info_row_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="@dimen/bug_report_default_text_size" />
+        </LinearLayout>
 
         <TextView
             android:id="@+id/bug_info_row_message"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textSize="28sp" />
+            android:visibility="gone"
+            android:textSize="@dimen/bug_report_default_text_size" />
 
-        <Button
-            android:id="@+id/bug_info_move_button"
+        <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/bug_report_user_action_button_padding"
-            android:textSize="@dimen/bug_report_button_text_size"
-            android:text="@string/bugreport_move_button_text" />
-
+            android:orientation="horizontal">
+            <Button
+                android:id="@+id/bug_info_add_audio_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/bug_report_user_action_button_padding"
+                android:layout_marginRight="@dimen/bug_report_horizontal_layout_children_margin"
+                android:visibility="gone"
+                android:textSize="@dimen/bug_report_button_text_size"
+                android:text="@string/bugreport_add_audio_button_text" />
+            <Button
+                android:id="@+id/bug_info_upload_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/bug_report_user_action_button_padding"
+                android:layout_marginRight="@dimen/bug_report_horizontal_layout_children_margin"
+                android:visibility="gone"
+                android:textSize="@dimen/bug_report_button_text_size"
+                android:text="@string/bugreport_upload_button_text" />
+            <Button
+                android:id="@+id/bug_info_move_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/bug_report_user_action_button_padding"
+                android:visibility="gone"
+                android:textSize="@dimen/bug_report_button_text_size"
+                android:text="@string/bugreport_move_button_text" />
+        </LinearLayout>
     </LinearLayout>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/tests/BugReportApp/res/layout/bug_report_activity.xml b/tests/BugReportApp/res/layout/bug_report_activity.xml
index ccb4d28..1b1907d 100644
--- a/tests/BugReportApp/res/layout/bug_report_activity.xml
+++ b/tests/BugReportApp/res/layout/bug_report_activity.xml
@@ -16,15 +16,16 @@
 -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@color/bugreport_background"
+    android:padding="@dimen/bug_report_padding"
+    android:orientation="vertical">
 
     <LinearLayout
         android:id="@+id/submit_bug_report_layout"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:padding="@dimen/bug_report_padding"
-        android:background="@color/bugreport_background"
         android:visibility="gone"
         android:orientation="vertical">
         <TextView
@@ -34,6 +35,16 @@
             android:textColor="@color/bugreport_text"
             android:gravity="center"
             android:text="@string/bugreport_dialog_title"/>
+        <TextView
+            android:id="@+id/bug_report_add_audio_to_existing"
+            android:layout_marginTop="@dimen/bug_report_voice_recording_margin_top"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="@color/bugreport_text"
+            android:gravity="center"
+            android:visibility="gone"
+            android:text="@string/bugreport_dialog_add_audio_to_existing"/>
         <com.android.car.bugreport.VoiceRecordingView
             android:id="@+id/voice_recording_view"
             android:layout_marginTop="@dimen/bug_report_voice_recording_margin_top"
@@ -65,23 +76,12 @@
             android:layout_marginTop="@dimen/bug_report_button_margin_top"
             android:padding="@dimen/bug_report_secondary_button_padding"
             android:text="@string/bugreport_dialog_cancel"/>
-        <Button
-            android:id="@+id/button_show_bugreports"
-            style="@style/standard_button"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/bug_report_button_margin_top"
-            android:padding="@dimen/bug_report_small_button_padding"
-            android:visibility="gone"
-            android:text="@string/bugreport_dialog_show_bugreports"/>
     </LinearLayout>
 
     <LinearLayout
         android:id="@+id/in_progress_layout"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:background="@color/bugreport_background"
-        android:padding="@dimen/bug_report_padding"
         android:visibility="gone"
         android:orientation="vertical">
         <TextView
@@ -115,4 +115,14 @@
             android:padding="@dimen/bug_report_secondary_button_padding"
             android:text="@string/bugreport_dialog_close"/>
     </LinearLayout>
+
+    <Button
+        android:id="@+id/button_show_bugreports"
+        style="@style/standard_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/bug_report_button_margin_top"
+        android:padding="@dimen/bug_report_small_button_padding"
+        android:visibility="gone"
+        android:text="@string/bugreport_dialog_show_bugreports"/>
 </LinearLayout>
diff --git a/tests/BugReportApp/res/values/dimens.xml b/tests/BugReportApp/res/values/dimens.xml
index 4a5f270..7f7967f 100644
--- a/tests/BugReportApp/res/values/dimens.xml
+++ b/tests/BugReportApp/res/values/dimens.xml
@@ -19,6 +19,8 @@
     <!-- Margin between edge of BugReportActivity dialog and content -->
     <dimen name="bug_report_padding">30dp</dimen>
 
+    <dimen name="bug_report_default_text_size">28dp</dimen>
+
     <!-- VoiceRecordingView dimensions -->
     <dimen name="bug_report_voice_recording_margin_top">20dp</dimen>
     <dimen name="bug_report_voice_recording_height">40dp</dimen>
@@ -34,4 +36,6 @@
     <!-- ProgressBar dimensions -->
     <dimen name="bug_report_progress_bar_margin_top">32dp</dimen>
 
+    <!-- Horizontal layout children margins. -->
+    <dimen name="bug_report_horizontal_layout_children_margin">12dp</dimen>
 </resources>
diff --git a/tests/BugReportApp/res/values/strings.xml b/tests/BugReportApp/res/values/strings.xml
index bca00fa..b3b125a 100644
--- a/tests/BugReportApp/res/values/strings.xml
+++ b/tests/BugReportApp/res/values/strings.xml
@@ -15,35 +15,43 @@
      limitations under the License.
 -->
 <resources>
-    <string name="app_name" translatable="false">Bug Report</string>
+    <string name="app_name">Bug Report</string>
 
-    <string name="bugreport_info_quit" translatable="false">Close</string>
-    <string name="bugreport_info_start" translatable="false">Start Bug Report</string>
+    <string name="bugreport_info_quit">Close</string>
+    <string name="bugreport_info_start">Start Bug Report</string>
+    <string name="bugreport_info_status">Status:</string>
 
-    <string name="bugreport_dialog_submit" translatable="false">Submit</string>
-    <string name="bugreport_dialog_cancel" translatable="false">Cancel</string>
-    <string name="bugreport_dialog_show_bugreports" translatable="false">Show Bug Reports</string>
-    <string name="bugreport_dialog_close" translatable="false">Close</string>
-    <string name="bugreport_dialog_title" translatable="false">Speak &amp; Describe The Issue</string>
-    <string name="bugreport_dialog_recording_finished" translatable="false">Recording finished</string>
-    <string name="bugreport_dialog_in_progress_title" translatable="false">A bug report is already being collected</string>
-    <string name="bugreport_dialog_in_progress_title_finished" translatable="false">A bug report has been collected</string>
-    <string name="bugreport_move_button_text" translatable="false">Move</string>
-    <string name="bugreport_upload_button_text" translatable="false">Upload</string>
+    <string name="bugreport_dialog_submit">Submit</string>
+    <string name="bugreport_dialog_cancel">Cancel</string>
+    <!-- A button: uploads bugreport with recorded audio message. -->
+    <string name="bugreport_dialog_upload">Upload</string>
+    <!-- A button: saves recorded audio message. -->
+    <string name="bugreport_dialog_save">Save</string>
+    <string name="bugreport_dialog_show_bugreports">Show Bug Reports</string>
+    <string name="bugreport_dialog_close">Close</string>
+    <string name="bugreport_dialog_title">Speak &amp; Describe The Issue</string>
+    <!-- %s is the timestamp of a bugreport. -->
+    <string name="bugreport_dialog_add_audio_to_existing">Audio message for bug report at %s</string>
+    <string name="bugreport_dialog_recording_finished">Recording finished</string>
+    <string name="bugreport_dialog_in_progress_title">A bug report is already being collected</string>
+    <string name="bugreport_dialog_in_progress_title_finished">A bug report has been collected</string>
+    <!-- A button to add audio message to the bugreport. It will show Save button on the dialog. -->
+    <string name="bugreport_add_audio_button_text">Add Audio</string>
+    <!-- A button to add audio message to the bugreport; it will show Upload button on the dialog. -->
+    <string name="bugreport_add_audio_upload_button_text">Add Audio &amp; Upload</string>
+    <string name="bugreport_move_button_text">Move to USB</string>
+    <string name="bugreport_upload_button_text">Upload</string>
+    <string name="bugreport_upload_gcs_button_text">Upload to GCS</string>
 
-    <string name="toast_permissions_denied" translatable="false">Please grant permissions</string>
-    <string name="toast_bug_report_in_progress" translatable="false">Bug report already being collected</string>
-    <string name="toast_timed_out" translatable="false">Timed out, cancelling</string>
-    <string name="toast_status_failed" translatable="false">Bug report failed</string>
-    <string name="toast_status_finished" translatable="false">Bug report finished</string>
-    <string name="toast_status_pending_upload" translatable="false">Bug report ready for upload</string>
-    <string name="toast_status_screencap_failed" translatable="false">Screen capture failed</string>
-    <string name="toast_status_dump_state_failed" translatable="false">Dump state failed</string>
+    <string name="toast_permissions_denied">Please grant permissions</string>
+    <string name="toast_bug_report_in_progress">Bug report already being collected</string>
+    <string name="toast_bug_report_started">Bug reporting is started</string>
+    <string name="toast_status_failed">Bug report failed</string>
+    <string name="toast_status_screencap_failed">Screen capture failed</string>
+    <string name="toast_status_dump_state_failed">Dump state failed</string>
 
     <!-- Notification strings -->
-    <string name="notification_bugreport_in_progress" translatable="false">Bug report is in progress</string>
-    <string name="notification_bugreport_finished_title" translatable="false">Bug report is collected</string>
-    <string name="notification_bugreport_manual_upload_finished_text" translatable="false">Please upload it when the car is parked</string>
-    <string name="notification_bugreport_auto_upload_finished_text" translatable="false">The report will be upload automatically</string>
-    <string name="notification_bugreport_channel_name" translatable="false">Bug report status channel</string>
+    <string name="notification_bugreport_in_progress">Bug report is in progress</string>
+    <string name="notification_bugreport_finished_title">Bug report is collected</string>
+    <string name="notification_bugreport_channel_name">Bug report status channel</string>
 </resources>
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/BugInfoAdapter.java b/tests/BugReportApp/src/com/android/car/bugreport/BugInfoAdapter.java
index cdc9388..4a7f1d7 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/BugInfoAdapter.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/BugInfoAdapter.java
@@ -23,63 +23,77 @@
 
 import androidx.recyclerview.widget.RecyclerView;
 
+import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * Shows bugreport title, status, status message and user action buttons. "Upload to Google" button
+ * is enabled when the status is {@link Status#STATUS_PENDING_USER_ACTION}, "Move to USB" button is
+ * enabled only when status is  {@link Status#STATUS_PENDING_USER_ACTION} and USB device is plugged
+ * in.
+ */
 public class BugInfoAdapter extends RecyclerView.Adapter<BugInfoAdapter.BugInfoViewHolder> {
-
     static final int BUTTON_TYPE_UPLOAD = 0;
     static final int BUTTON_TYPE_MOVE = 1;
+    static final int BUTTON_TYPE_ADD_AUDIO = 2;
 
     /** Provides a handler for click events*/
     interface ItemClickedListener {
-        /** onItemClicked handles click events differently depending on provided buttonType and
-         * uses additional information provided in metaBugReport. */
-        void onItemClicked(int buttonType, MetaBugReport metaBugReport);
+        /**
+         * Handles click events differently depending on provided buttonType and
+         * uses additional information provided in metaBugReport.
+         *
+         * @param buttonType One of {@link #BUTTON_TYPE_UPLOAD}, {@link #BUTTON_TYPE_MOVE} or
+         *                   {@link #BUTTON_TYPE_ADD_AUDIO}.
+         * @param metaBugReport Selected bugreport.
+         * @param holder ViewHolder of the clicked item.
+         */
+        void onItemClicked(int buttonType, MetaBugReport metaBugReport, BugInfoViewHolder holder);
     }
 
     /**
      * Reference to each bug report info views.
      */
-    public static class BugInfoViewHolder extends RecyclerView.ViewHolder {
+    static class BugInfoViewHolder extends RecyclerView.ViewHolder {
         /** Title view */
-        public TextView titleView;
-
-        /** User view */
-        public TextView userView;
-
-        /** TimeStamp View */
-        public TextView timestampView;
+        TextView mTitleView;
 
         /** Status View */
-        public TextView statusView;
+        TextView mStatusView;
 
         /** Message View */
-        public TextView messageView;
+        TextView mMessageView;
 
         /** Move Button */
-        public Button moveButton;
+        Button mMoveButton;
 
         /** Upload Button */
-        public Button uploadButton;
+        Button mUploadButton;
+
+        /** Add Audio Button */
+        Button mAddAudioButton;
 
         BugInfoViewHolder(View v) {
             super(v);
-            titleView = itemView.findViewById(R.id.bug_info_row_title);
-            userView = itemView.findViewById(R.id.bug_info_row_user);
-            timestampView = itemView.findViewById(R.id.bug_info_row_timestamp);
-            statusView = itemView.findViewById(R.id.bug_info_row_status);
-            messageView = itemView.findViewById(R.id.bug_info_row_message);
-            moveButton = itemView.findViewById(R.id.bug_info_move_button);
-            uploadButton = itemView.findViewById(R.id.bug_info_upload_button);
+            mTitleView = itemView.findViewById(R.id.bug_info_row_title);
+            mStatusView = itemView.findViewById(R.id.bug_info_row_status);
+            mMessageView = itemView.findViewById(R.id.bug_info_row_message);
+            mMoveButton = itemView.findViewById(R.id.bug_info_move_button);
+            mUploadButton = itemView.findViewById(R.id.bug_info_upload_button);
+            mAddAudioButton = itemView.findViewById(R.id.bug_info_add_audio_button);
         }
     }
 
-    private final List<MetaBugReport> mDataset;
+    private List<MetaBugReport> mDataset;
     private final ItemClickedListener mItemClickedListener;
+    private final Config mConfig;
 
-    BugInfoAdapter(List<MetaBugReport> dataSet, ItemClickedListener itemClickedListener) {
-        mDataset = dataSet;
+    BugInfoAdapter(ItemClickedListener itemClickedListener, Config config) {
         mItemClickedListener = itemClickedListener;
+        mDataset = new ArrayList<>();
+        mConfig = config;
+        // Allow RecyclerView to efficiently update UI; getItemId() is implemented below.
+        setHasStableIds(true);
     }
 
     @Override
@@ -93,22 +107,74 @@
     @Override
     public void onBindViewHolder(BugInfoViewHolder holder, int position) {
         MetaBugReport bugreport = mDataset.get(position);
-        holder.titleView.setText(mDataset.get(position).getTitle());
-        holder.userView.setText(mDataset.get(position).getUsername());
-        holder.timestampView.setText(mDataset.get(position).getTimestamp());
-        holder.statusView.setText(Status.toString(mDataset.get(position).getStatus()));
-        holder.messageView.setText(mDataset.get(position).getStatusMessage());
-        if (bugreport.getStatus() == Status.STATUS_PENDING_USER_ACTION.getValue()
-                || bugreport.getStatus() == Status.STATUS_MOVE_FAILED.getValue()
-                || bugreport.getStatus() == Status.STATUS_UPLOAD_FAILED.getValue()) {
-            holder.moveButton.setOnClickListener(
-                    view -> mItemClickedListener.onItemClicked(BUTTON_TYPE_MOVE, bugreport));
-            holder.uploadButton.setOnClickListener(
-                    view -> mItemClickedListener.onItemClicked(BUTTON_TYPE_UPLOAD, bugreport));
+        holder.mTitleView.setText(bugreport.getTitle());
+        holder.mStatusView.setText(Status.toString(bugreport.getStatus()));
+        holder.mMessageView.setText(bugreport.getStatusMessage());
+        if (bugreport.getStatusMessage().isEmpty()) {
+            holder.mMessageView.setVisibility(View.GONE);
         } else {
-            holder.moveButton.setEnabled(false);
-            holder.uploadButton.setEnabled(false);
+            holder.mMessageView.setVisibility(View.VISIBLE);
         }
+        boolean enableUserActionButtons =
+                bugreport.getStatus() == Status.STATUS_PENDING_USER_ACTION.getValue()
+                        || bugreport.getStatus() == Status.STATUS_MOVE_FAILED.getValue()
+                        || bugreport.getStatus() == Status.STATUS_UPLOAD_FAILED.getValue();
+        if (enableUserActionButtons) {
+            holder.mMoveButton.setEnabled(true);
+            holder.mMoveButton.setVisibility(View.VISIBLE);
+            holder.mMoveButton.setOnClickListener(
+                    view -> mItemClickedListener.onItemClicked(BUTTON_TYPE_MOVE, bugreport,
+                            holder));
+        } else {
+            holder.mMoveButton.setEnabled(false);
+            holder.mMoveButton.setVisibility(View.GONE);
+        }
+        // Always enable upload to GCS button, because the app is enabled only for userdebug,
+        // and sometimes Config might not be properly set.
+        if (enableUserActionButtons) {
+            holder.mUploadButton.setText(R.string.bugreport_upload_gcs_button_text);
+            holder.mUploadButton.setEnabled(true);
+            holder.mUploadButton.setVisibility(View.VISIBLE);
+            holder.mUploadButton.setOnClickListener(
+                    view -> mItemClickedListener.onItemClicked(BUTTON_TYPE_UPLOAD, bugreport,
+                            holder));
+        } else {
+            holder.mUploadButton.setVisibility(View.GONE);
+            holder.mUploadButton.setEnabled(false);
+        }
+        if (bugreport.getStatus() == Status.STATUS_AUDIO_PENDING.getValue()) {
+            if (mConfig.getAutoUpload()) {
+                holder.mAddAudioButton.setText(R.string.bugreport_add_audio_upload_button_text);
+            } else {
+                holder.mAddAudioButton.setText(R.string.bugreport_add_audio_button_text);
+            }
+            holder.mAddAudioButton.setEnabled(true);
+            holder.mAddAudioButton.setVisibility(View.VISIBLE);
+            holder.mAddAudioButton.setOnClickListener(view ->
+                    mItemClickedListener.onItemClicked(BUTTON_TYPE_ADD_AUDIO, bugreport, holder));
+        } else {
+            holder.mAddAudioButton.setEnabled(false);
+            holder.mAddAudioButton.setVisibility(View.GONE);
+        }
+    }
+
+    /** Sets dataSet; it copies the list, because it modifies it in this adapter. */
+    void setDataset(List<MetaBugReport> bugReports) {
+        mDataset = new ArrayList<>(bugReports);
+        notifyDataSetChanged();
+    }
+
+    /** Update a bug report in the data set. */
+    void updateBugReportInDataSet(MetaBugReport bugReport, int position) {
+        if (position != RecyclerView.NO_POSITION) {
+            mDataset.set(position, bugReport);
+            notifyItemChanged(position);
+        }
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return mDataset.get(position).getId();
     }
 
     @Override
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/BugReportActivity.java b/tests/BugReportApp/src/com/android/car/bugreport/BugReportActivity.java
index 9c41277..5f9a231 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/BugReportActivity.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/BugReportActivity.java
@@ -15,7 +15,6 @@
  */
 package com.android.car.bugreport;
 
-import static com.android.car.bugreport.BugReportService.EXTRA_META_BUG_REPORT;
 import static com.android.car.bugreport.BugReportService.MAX_PROGRESS_VALUE;
 
 import android.Manifest;
@@ -25,6 +24,7 @@
 import android.car.drivingstate.CarDrivingStateEvent;
 import android.car.drivingstate.CarDrivingStateManager;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
@@ -41,14 +41,19 @@
 import android.util.Log;
 import android.view.View;
 import android.view.Window;
+import android.widget.Button;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.google.common.base.Preconditions;
+import com.google.common.io.ByteStreams;
+
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.Random;
@@ -65,33 +70,52 @@
 public class BugReportActivity extends Activity {
     private static final String TAG = BugReportActivity.class.getSimpleName();
 
+    /** Starts silent (no audio message recording) bugreporting. */
+    private static final String ACTION_START_SILENT =
+            "com.android.car.bugreport.action.START_SILENT";
+
+    /** This is deprecated action. Please start SILENT bugreport using {@link BugReportService}. */
+    private static final String ACTION_ADD_AUDIO =
+            "com.android.car.bugreport.action.ADD_AUDIO";
+
     private static final int VOICE_MESSAGE_MAX_DURATION_MILLIS = 60 * 1000;
     private static final int AUDIO_PERMISSIONS_REQUEST_ID = 1;
 
-    private static final DateFormat BUG_REPORT_TIMESTAMP_DATE_FORMAT =
-            new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
+    private static final String EXTRA_BUGREPORT_ID = "bugreport-id";
 
+    /**
+     * NOTE: mRecorder related messages are cleared when the activity finishes.
+     */
     private final Handler mHandler = new Handler(Looper.getMainLooper());
 
+    /** Look up string length, e.g. [ABCDEF]. */
+    static final int LOOKUP_STRING_LENGTH = 6;
+
     private TextView mInProgressTitleText;
     private ProgressBar mProgressBar;
     private TextView mProgressText;
+    private TextView mAddAudioText;
     private VoiceRecordingView mVoiceRecordingView;
     private View mVoiceRecordingFinishedView;
     private View mSubmitBugReportLayout;
     private View mInProgressLayout;
     private View mShowBugReportsButton;
+    private Button mSubmitButton;
 
     private boolean mBound;
     private boolean mAudioRecordingStarted;
-    private boolean mBugReportServiceStarted;
+    private boolean mIsNewBugReport;
+    private boolean mIsOnActivityStartedWithBugReportServiceBoundCalled;
+    private boolean mIsSubmitButtonClicked;
     private BugReportService mService;
     private MediaRecorder mRecorder;
     private MetaBugReport mMetaBugReport;
+    private File mAudioFile;
     private Car mCar;
     private CarDrivingStateManager mDrivingStateManager;
     private AudioManager mAudioManager;
     private AudioFocusRequest mLastAudioFocusRequest;
+    private Config mConfig;
 
     /** Defines callbacks for service binding, passed to bindService() */
     private ServiceConnection mConnection = new ServiceConnection() {
@@ -100,7 +124,7 @@
             BugReportService.ServiceBinder binder = (BugReportService.ServiceBinder) service;
             mService = binder.getService();
             mBound = true;
-            startAudioMessageRecording();
+            onActivityStartedWithBugReportServiceBound();
         }
 
         @Override
@@ -110,7 +134,7 @@
         }
     };
 
-    private final ServiceConnection mServiceConnection = new ServiceConnection() {
+    private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             try {
@@ -118,6 +142,8 @@
                         Car.CAR_DRIVING_STATE_SERVICE);
                 mDrivingStateManager.registerListener(
                         BugReportActivity.this::onCarDrivingStateChanged);
+                // Call onCarDrivingStateChanged(), because it's not called when Car is connected.
+                onCarDrivingStateChanged(mDrivingStateManager.getCurrentCarDrivingState());
             } catch (CarNotConnectedException e) {
                 Log.w(TAG, "Failed to get CarDrivingStateManager.", e);
             }
@@ -128,30 +154,24 @@
         }
     };
 
+    /**
+     * Builds an intent that starts {@link BugReportActivity} to add audio message to the existing
+     * bug report.
+     */
+    static Intent buildAddAudioIntent(Context context, MetaBugReport bug) {
+        Intent addAudioIntent = new Intent(context, BugReportActivity.class);
+        addAudioIntent.setAction(ACTION_ADD_AUDIO);
+        addAudioIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        addAudioIntent.putExtra(EXTRA_BUGREPORT_ID, bug.getId());
+        return addAudioIntent;
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
+        Preconditions.checkState(Config.isBugReportEnabled(), "BugReport is disabled.");
+
         super.onCreate(savedInstanceState);
-
         requestWindowFeature(Window.FEATURE_NO_TITLE);
-        setContentView(R.layout.bug_report_activity);
-
-        mInProgressTitleText = findViewById(R.id.in_progress_title_text);
-        mProgressBar = findViewById(R.id.progress_bar);
-        mProgressText = findViewById(R.id.progress_text);
-        mVoiceRecordingView = findViewById(R.id.voice_recording_view);
-        mVoiceRecordingFinishedView = findViewById(R.id.voice_recording_finished_text_view);
-        mSubmitBugReportLayout = findViewById(R.id.submit_bug_report_layout);
-        mInProgressLayout = findViewById(R.id.in_progress_layout);
-        mShowBugReportsButton = findViewById(R.id.button_show_bugreports);
-
-        mShowBugReportsButton.setOnClickListener(this::buttonShowBugReportsClick);
-        findViewById(R.id.button_submit).setOnClickListener(this::buttonSubmitClick);
-        findViewById(R.id.button_cancel).setOnClickListener(this::buttonCancelClick);
-        findViewById(R.id.button_close).setOnClickListener(this::buttonCancelClick);
-
-        mCar = Car.createCar(this, mServiceConnection);
-        mCar.connect();
-        mAudioManager = getSystemService(AudioManager.class);
 
         // Bind to BugReportService.
         Intent intent = new Intent(this, BugReportService.class);
@@ -163,26 +183,35 @@
         super.onStart();
 
         if (mBound) {
-            startAudioMessageRecording();
+            onActivityStartedWithBugReportServiceBound();
         }
     }
 
     @Override
     protected void onStop() {
         super.onStop();
-        if (!mBugReportServiceStarted && mAudioRecordingStarted) {
+        // If SUBMIT button is clicked, cancelling audio has been taken care of.
+        if (!mIsSubmitButtonClicked) {
             cancelAudioMessageRecording();
         }
         if (mBound) {
             mService.removeBugReportProgressListener();
         }
+        // Reset variables for the next onStart().
+        mAudioRecordingStarted = false;
+        mIsSubmitButtonClicked = false;
+        mIsOnActivityStartedWithBugReportServiceBoundCalled = false;
+        mMetaBugReport = null;
+        mAudioFile = null;
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
 
-        mHandler.removeCallbacksAndMessages(null);
+        if (mRecorder != null) {
+            mHandler.removeCallbacksAndMessages(/* token= */ mRecorder);
+        }
         if (mBound) {
             unbindService(mConnection);
             mBound = false;
@@ -194,7 +223,14 @@
     }
 
     private void onCarDrivingStateChanged(CarDrivingStateEvent event) {
-        if (event.eventValue == CarDrivingStateEvent.DRIVING_STATE_PARKED) {
+        // When adding audio message to the existing bugreport, do not show "Show Bug Reports"
+        // button, users either should explicitly Submit or Cancel.
+        if (mAudioRecordingStarted && !mIsNewBugReport) {
+            mShowBugReportsButton.setVisibility(View.GONE);
+            return;
+        }
+        if (event.eventValue == CarDrivingStateEvent.DRIVING_STATE_PARKED
+                || event.eventValue == CarDrivingStateEvent.DRIVING_STATE_IDLING) {
             mShowBugReportsButton.setVisibility(View.VISIBLE);
         } else {
             mShowBugReportsButton.setVisibility(View.GONE);
@@ -210,6 +246,43 @@
         }
     }
 
+    private void prepareUi() {
+        if (mSubmitBugReportLayout != null) {
+            return;
+        }
+        setContentView(R.layout.bug_report_activity);
+
+        // Connect to the services here, because they are used only when showing the dialog.
+        // We need to minimize system state change when performing SILENT bug report.
+        mConfig = new Config();
+        mConfig.start();
+        mCar = Car.createCar(this, mCarServiceConnection);
+        mCar.connect();
+
+        mInProgressTitleText = findViewById(R.id.in_progress_title_text);
+        mProgressBar = findViewById(R.id.progress_bar);
+        mProgressText = findViewById(R.id.progress_text);
+        mAddAudioText = findViewById(R.id.bug_report_add_audio_to_existing);
+        mVoiceRecordingView = findViewById(R.id.voice_recording_view);
+        mVoiceRecordingFinishedView = findViewById(R.id.voice_recording_finished_text_view);
+        mSubmitBugReportLayout = findViewById(R.id.submit_bug_report_layout);
+        mInProgressLayout = findViewById(R.id.in_progress_layout);
+        mShowBugReportsButton = findViewById(R.id.button_show_bugreports);
+        mSubmitButton = findViewById(R.id.button_submit);
+
+        mShowBugReportsButton.setOnClickListener(this::buttonShowBugReportsClick);
+        mSubmitButton.setOnClickListener(this::buttonSubmitClick);
+        findViewById(R.id.button_cancel).setOnClickListener(this::buttonCancelClick);
+        findViewById(R.id.button_close).setOnClickListener(this::buttonCancelClick);
+
+        if (mIsNewBugReport) {
+            mSubmitButton.setText(R.string.bugreport_dialog_submit);
+        } else {
+            mSubmitButton.setText(mConfig.getAutoUpload()
+                    ? R.string.bugreport_dialog_upload : R.string.bugreport_dialog_save);
+        }
+    }
+
     private void showInProgressUi() {
         mSubmitBugReportLayout.setVisibility(View.GONE);
         mInProgressLayout.setVisibility(View.VISIBLE);
@@ -231,7 +304,6 @@
         mShowBugReportsButton.setVisibility(View.GONE);
         if (mDrivingStateManager != null) {
             try {
-                // Call onCarDrivingStateChanged(), because it's not called when Car is connected.
                 onCarDrivingStateChanged(mDrivingStateManager.getCurrentCarDrivingState());
             } catch (CarNotConnectedException e) {
                 Log.e(TAG, "Failed to get current driving state.", e);
@@ -244,28 +316,89 @@
      *
      * <p>This method expected to be called when the activity is started and bound to the service.
      */
-    private void startAudioMessageRecording() {
-        mService.setBugReportProgressListener(this::onProgressChanged);
+    private void onActivityStartedWithBugReportServiceBound() {
+        if (mIsOnActivityStartedWithBugReportServiceBoundCalled) {
+            return;
+        }
+        mIsOnActivityStartedWithBugReportServiceBoundCalled = true;
 
         if (mService.isCollectingBugReport()) {
             Log.i(TAG, "Bug report is already being collected.");
+            mService.setBugReportProgressListener(this::onProgressChanged);
+            prepareUi();
             showInProgressUi();
             return;
         }
 
+        if (ACTION_START_SILENT.equals(getIntent().getAction())) {
+            Log.i(TAG, "Starting a silent bugreport.");
+            MetaBugReport bugReport = createBugReport(this, MetaBugReport.TYPE_SILENT);
+            startBugReportCollection(bugReport);
+            finish();
+            return;
+        }
+
+        // Close the notification shade and other dialogs when showing BugReportActivity dialog.
+        sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+
+        if (ACTION_ADD_AUDIO.equals(getIntent().getAction())) {
+            addAudioToExistingBugReport(
+                    getIntent().getIntExtra(EXTRA_BUGREPORT_ID, /* defaultValue= */ -1));
+            return;
+        }
+
+        Log.i(TAG, "Starting an interactive bugreport.");
+        createNewBugReportWithAudioMessage();
+    }
+
+    private void addAudioToExistingBugReport(int bugreportId) {
+        MetaBugReport bug = BugStorageUtils.findBugReport(this, bugreportId).orElseThrow(
+                () -> new RuntimeException("Failed to find bug report with id " + bugreportId));
+        Log.i(TAG, "Adding audio to the existing bugreport " + bug.getTimestamp());
+        if (bug.getStatus() != Status.STATUS_AUDIO_PENDING.getValue()) {
+            Log.e(TAG, "Failed to add audio, bad status, expected "
+                    + Status.STATUS_AUDIO_PENDING.getValue() + ", got " + bug.getStatus());
+            finish();
+        }
+        File audioFile;
+        try {
+            audioFile = File.createTempFile("audio", "mp3", getCacheDir());
+        } catch (IOException e) {
+            throw new RuntimeException("failed to create temp audio file");
+        }
+        startAudioMessageRecording(/* isNewBugReport= */ false, bug, audioFile);
+    }
+
+    private void createNewBugReportWithAudioMessage() {
+        MetaBugReport bug = createBugReport(this, MetaBugReport.TYPE_INTERACTIVE);
+        startAudioMessageRecording(
+                /* isNewBugReport= */ true,
+                bug,
+                FileUtils.getFileWithSuffix(this, bug.getTimestamp(), "-message.3gp"));
+    }
+
+    /** Shows a dialog UI and starts recording audio message. */
+    private void startAudioMessageRecording(
+            boolean isNewBugReport, MetaBugReport bug, File audioFile) {
         if (mAudioRecordingStarted) {
             Log.i(TAG, "Audio message recording is already started.");
             return;
         }
-
         mAudioRecordingStarted = true;
+        mAudioManager = getSystemService(AudioManager.class);
+        mIsNewBugReport = isNewBugReport;
+        mMetaBugReport = bug;
+        mAudioFile = audioFile;
+        prepareUi();
         showSubmitBugReportUi(/* isRecording= */ true);
-
-        Date initiatedAt = new Date();
-        String timestamp = BUG_REPORT_TIMESTAMP_DATE_FORMAT.format(initiatedAt);
-        String username = getCurrentUserName();
-        String title = BugReportTitleGenerator.generateBugReportTitle(initiatedAt, username);
-        mMetaBugReport = BugStorageUtils.createBugReport(this, title, timestamp, username);
+        if (isNewBugReport) {
+            mAddAudioText.setVisibility(View.GONE);
+        } else {
+            mAddAudioText.setVisibility(View.VISIBLE);
+            mAddAudioText.setText(String.format(
+                    getString(R.string.bugreport_dialog_add_audio_to_existing),
+                    mMetaBugReport.getTimestamp()));
+        }
 
         if (!hasRecordPermissions()) {
             requestRecordPermissions();
@@ -282,10 +415,17 @@
             return;
         }
         stopAudioRecording();
-        File tempDir = FileUtils.getTempDir(this, mMetaBugReport.getTimestamp());
-        new DeleteDirectoryAsyncTask().execute(tempDir);
-        BugStorageUtils.setBugReportStatus(this, mMetaBugReport, Status.STATUS_USER_CANCELLED, "");
-        Log.i(TAG, "Bug report is cancelled");
+        if (mIsNewBugReport) {
+            // The app creates a temp dir only for new INTERACTIVE bugreports.
+            File tempDir = FileUtils.getTempDir(this, mMetaBugReport.getTimestamp());
+            new DeleteFilesAndDirectoriesAsyncTask().execute(tempDir);
+        } else {
+            BugStorageUtils.deleteBugReportFiles(this, mMetaBugReport.getId());
+            new DeleteFilesAndDirectoriesAsyncTask().execute(mAudioFile);
+        }
+        BugStorageUtils.setBugReportStatus(
+                this, mMetaBugReport, Status.STATUS_USER_CANCELLED, "");
+        Log.i(TAG, "Bug report " + mMetaBugReport.getTimestamp() + " is cancelled");
         mAudioRecordingStarted = false;
     }
 
@@ -294,36 +434,46 @@
     }
 
     private void buttonSubmitClick(View view) {
-        startBugReportingInService();
+        stopAudioRecording();
+        mIsSubmitButtonClicked = true;
+        if (mIsNewBugReport) {
+            Log.i(TAG, "Starting bugreport service.");
+            startBugReportCollection(mMetaBugReport);
+        } else {
+            Log.i(TAG, "Adding audio file to the bugreport " + mMetaBugReport.getTimestamp());
+            new AddAudioToBugReportAsyncTask(this, mConfig, mMetaBugReport, mAudioFile).execute();
+        }
+        setResult(Activity.RESULT_OK);
         finish();
     }
 
+    /** Starts the {@link BugReportService} to collect bug report. */
+    private void startBugReportCollection(MetaBugReport bug) {
+        Bundle bundle = new Bundle();
+        bundle.putParcelable(BugReportService.EXTRA_META_BUG_REPORT, bug);
+        Intent intent = new Intent(this, BugReportService.class);
+        intent.putExtras(bundle);
+        startForegroundService(intent);
+    }
+
     /**
      * Starts {@link BugReportInfoActivity} and finishes current activity, so it won't be running
-     * in the background and closing {@link BugReportInfoActivity} will not open it again.
+     * in the background and closing {@link BugReportInfoActivity} will not open the current
+     * activity again.
      */
     private void buttonShowBugReportsClick(View view) {
+        // First cancel the audio recording, then delete the bug report from database.
         cancelAudioMessageRecording();
         // Delete the bugreport from database, otherwise pressing "Show Bugreports" button will
         // create unnecessary cancelled bugreports.
         if (mMetaBugReport != null) {
-            BugStorageUtils.deleteBugReport(this, mMetaBugReport.getId());
+            BugStorageUtils.completeDeleteBugReport(this, mMetaBugReport.getId());
         }
         Intent intent = new Intent(this, BugReportInfoActivity.class);
         startActivity(intent);
         finish();
     }
 
-    private void startBugReportingInService() {
-        stopAudioRecording();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(EXTRA_META_BUG_REPORT, mMetaBugReport);
-        Intent intent = new Intent(this, BugReportService.class);
-        intent.putExtras(bundle);
-        startService(intent);
-        mBugReportServiceStarted = true;
-    }
-
     private void requestRecordPermissions() {
         requestPermissions(
                 new String[]{Manifest.permission.RECORD_AUDIO}, AUDIO_PERMISSIONS_REQUEST_ID);
@@ -343,7 +493,9 @@
         for (int i = 0; i < grantResults.length; i++) {
             if (Manifest.permission.RECORD_AUDIO.equals(permissions[i])
                     && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
-                startRecordingWithPermission();
+                // Start recording from UI thread, otherwise when MediaRecord#start() fails,
+                // stack trace gets confusing.
+                mHandler.post(this::startRecordingWithPermission);
                 return;
             }
         }
@@ -361,9 +513,7 @@
     }
 
     private void startRecordingWithPermission() {
-        File recordingFile = FileUtils.getFileWithSuffix(this, mMetaBugReport.getTimestamp(),
-                "-message.3gp");
-        Log.i(TAG, "Started voice recording, and saving audio to " + recordingFile);
+        Log.i(TAG, "Started voice recording, and saving audio to " + mAudioFile);
 
         mLastAudioFocusRequest = new AudioFocusRequest.Builder(
                         AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)
@@ -388,12 +538,12 @@
                 Log.i(TAG, "OnMediaRecorderInfo: what=" + what + ", extra=" + extra));
         mRecorder.setOnErrorListener((MediaRecorder recorder, int what, int extra) ->
                 Log.i(TAG, "OnMediaRecorderError: what=" + what + ", extra=" + extra));
-        mRecorder.setOutputFile(recordingFile);
+        mRecorder.setOutputFile(mAudioFile);
 
         try {
             mRecorder.prepare();
         } catch (IOException e) {
-            Log.e(TAG, "Failed on MediaRecorder#prepare(), filename: " + recordingFile, e);
+            Log.e(TAG, "Failed on MediaRecorder#prepare(), filename: " + mAudioFile, e);
             finish();
             return;
         }
@@ -401,19 +551,21 @@
         mRecorder.start();
         mVoiceRecordingView.setRecorder(mRecorder);
 
+        // Messages with token mRecorder are cleared when the activity finishes or recording stops.
         mHandler.postDelayed(() -> {
             Log.i(TAG, "Timed out while recording voice message, cancelling.");
             stopAudioRecording();
             showSubmitBugReportUi(/* isRecording= */ false);
-        }, VOICE_MESSAGE_MAX_DURATION_MILLIS);
+        }, /* token= */ mRecorder, VOICE_MESSAGE_MAX_DURATION_MILLIS);
     }
 
     private void stopAudioRecording() {
         if (mRecorder != null) {
             Log.i(TAG, "Recording ended, stopping the MediaRecorder.");
+            mHandler.removeCallbacksAndMessages(/* token= */ mRecorder);
             try {
                 mRecorder.stop();
-            } catch (IllegalStateException e) {
+            } catch (RuntimeException e) {
                 // Sometimes MediaRecorder doesn't start and stopping it throws an error.
                 // We just log these cases, no need to crash the app.
                 Log.w(TAG, "Couldn't stop media recorder", e);
@@ -430,11 +582,24 @@
         mVoiceRecordingView.setRecorder(null);
     }
 
-    private String getCurrentUserName() {
-        UserManager um = UserManager.get(this);
+    private static String getCurrentUserName(Context context) {
+        UserManager um = UserManager.get(context);
         return um.getUserName();
     }
 
+    /**
+     * Creates a {@link MetaBugReport} and saves it in a local sqlite database.
+     *
+     * @param context an Android context.
+     * @param type bug report type, {@link MetaBugReport.BugReportType}.
+     */
+    static MetaBugReport createBugReport(Context context, int type) {
+        String timestamp = MetaBugReport.toBugReportTimestamp(new Date());
+        String username = getCurrentUserName(context);
+        String title = BugReportTitleGenerator.generateBugReportTitle(timestamp, username);
+        return BugStorageUtils.createBugReport(context, title, timestamp, username, type);
+    }
+
     /** A helper class to generate bugreport title. */
     private static final class BugReportTitleGenerator {
         /** Contains easily readable characters. */
@@ -442,17 +607,14 @@
                 new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P',
                         'R', 'S', 'T', 'U', 'W', 'X', 'Y', 'Z'};
 
-        private static final int LOOKUP_STRING_LENGTH = 6;
-
         /**
          * Generates a bugreport title from given timestamp and username.
          *
          * <p>Example: "[A45E8] Feedback from user Driver at 2019-09-21_12:00:00"
          */
-        static String generateBugReportTitle(Date initiatedAt, String username) {
+        static String generateBugReportTitle(String timestamp, String username) {
             // Lookup string is used to search a bug in Buganizer (see b/130915969).
             String lookupString = generateRandomString(LOOKUP_STRING_LENGTH);
-            String timestamp = BUG_REPORT_TIMESTAMP_DATE_FORMAT.format(initiatedAt);
             return "[" + lookupString + "] Feedback from user " + username + " at " + timestamp;
         }
 
@@ -467,15 +629,66 @@
         }
     }
 
-    /** AsyncTask that recursively deletes directories. */
-    private static class DeleteDirectoryAsyncTask extends AsyncTask<File, Void, Void> {
+    /** AsyncTask that recursively deletes files and directories. */
+    private static class DeleteFilesAndDirectoriesAsyncTask extends AsyncTask<File, Void, Void> {
         @Override
         protected Void doInBackground(File... files) {
             for (File file : files) {
                 Log.i(TAG, "Deleting " + file.getAbsolutePath());
-                FileUtils.deleteDirectory(file);
+                if (file.isFile()) {
+                    file.delete();
+                } else {
+                    FileUtils.deleteDirectory(file);
+                }
             }
             return null;
         }
     }
+
+    /**
+     * AsyncTask that moves audio file to the system user's {@link FileUtils#getPendingDir} and
+     * sets status to either STATUS_UPLOAD_PENDING or STATUS_PENDING_USER_ACTION.
+     */
+    private static class AddAudioToBugReportAsyncTask extends AsyncTask<Void, Void, Void> {
+        private final Context mContext;
+        private final Config mConfig;
+        private final File mAudioFile;
+        private final MetaBugReport mOriginalBug;
+
+        AddAudioToBugReportAsyncTask(
+                Context context, Config config, MetaBugReport bug, File audioFile) {
+            mContext = context;
+            mConfig = config;
+            mOriginalBug = bug;
+            mAudioFile = audioFile;
+        }
+
+        @Override
+        protected Void doInBackground(Void... voids) {
+            String audioFileName = FileUtils.getAudioFileName(
+                    MetaBugReport.toBugReportTimestamp(new Date()), mOriginalBug);
+            MetaBugReport bug = BugStorageUtils.update(mContext,
+                    mOriginalBug.toBuilder().setAudioFileName(audioFileName).build());
+            try (OutputStream out = BugStorageUtils.openAudioMessageFileToWrite(mContext, bug);
+                 InputStream input = new FileInputStream(mAudioFile)) {
+                ByteStreams.copy(input, out);
+            } catch (IOException e) {
+                BugStorageUtils.setBugReportStatus(mContext, bug,
+                        com.android.car.bugreport.Status.STATUS_WRITE_FAILED,
+                        "Failed to write audio to bug report");
+                Log.e(TAG, "Failed to write audio to bug report", e);
+                return null;
+            }
+            if (mConfig.getAutoUpload()) {
+                BugStorageUtils.setBugReportStatus(mContext, bug,
+                        com.android.car.bugreport.Status.STATUS_UPLOAD_PENDING, "");
+            } else {
+                BugStorageUtils.setBugReportStatus(mContext, bug,
+                        com.android.car.bugreport.Status.STATUS_PENDING_USER_ACTION, "");
+                BugReportService.showBugReportFinishedNotification(mContext, bug);
+            }
+            mAudioFile.delete();
+            return null;
+        }
+    }
 }
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/BugReportInfoActivity.java b/tests/BugReportApp/src/com/android/car/bugreport/BugReportInfoActivity.java
index 8071f99..017052a 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/BugReportInfoActivity.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/BugReportInfoActivity.java
@@ -21,9 +21,13 @@
 import android.app.NotificationManager;
 import android.content.ContentResolver;
 import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
 import android.provider.DocumentsContract;
 import android.util.Log;
 import android.view.View;
@@ -33,10 +37,16 @@
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.io.ByteStreams;
+
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
@@ -47,105 +57,26 @@
 public class BugReportInfoActivity extends Activity {
     public static final String TAG = BugReportInfoActivity.class.getSimpleName();
 
+    /** Used for moving bug reports to a new location (e.g. USB drive). */
     private static final int SELECT_DIRECTORY_REQUEST_CODE = 1;
 
+    /** Used to start {@link BugReportActivity} to add audio message. */
+    private static final int ADD_AUDIO_MESSAGE_REQUEST_CODE = 2;
+
     private RecyclerView mRecyclerView;
-    private RecyclerView.Adapter mAdapter;
+    private BugInfoAdapter mBugInfoAdapter;
     private RecyclerView.LayoutManager mLayoutManager;
     private NotificationManager mNotificationManager;
     private MetaBugReport mLastSelectedBugReport;
-
-    private static final class AsyncMoveFilesTask extends AsyncTask<Void, Void, Boolean> {
-        private final BugReportInfoActivity mActivity;
-        private final MetaBugReport mBugReport;
-        private final Uri mDestinationDirUri;
-
-        AsyncMoveFilesTask(BugReportInfoActivity activity, MetaBugReport bugReport,
-                Uri destinationDir) {
-            mActivity = activity;
-            mBugReport = bugReport;
-            mDestinationDirUri = destinationDir;
-        }
-
-        @Override
-        protected Boolean doInBackground(Void... params) {
-            Uri sourceUri = BugStorageProvider.buildUriWithBugId(mBugReport.getId());
-            ContentResolver resolver = mActivity.getContentResolver();
-            String documentId = DocumentsContract.getTreeDocumentId(mDestinationDirUri);
-            Uri parentDocumentUri =
-                    DocumentsContract.buildDocumentUriUsingTree(mDestinationDirUri, documentId);
-            String mimeType = resolver.getType(sourceUri);
-            try {
-                Uri newFileUri = DocumentsContract.createDocument(resolver, parentDocumentUri,
-                        mimeType,
-                        new File(mBugReport.getFilePath()).toPath().getFileName().toString());
-                if (newFileUri == null) {
-                    Log.e(TAG, "Unable to create a new file.");
-                    return false;
-                }
-                try (InputStream input = resolver.openInputStream(sourceUri);
-                     OutputStream output = resolver.openOutputStream(newFileUri)) {
-                    byte[] buffer = new byte[4096];
-                    int len;
-                    while ((len = input.read(buffer)) > 0) {
-                        output.write(buffer, 0, len);
-                    }
-                }
-                BugStorageUtils.setBugReportStatus(
-                        mActivity, mBugReport,
-                        com.android.car.bugreport.Status.STATUS_MOVE_SUCCESSFUL, "");
-            } catch (IOException e) {
-                Log.e(TAG, "Failed to create the bug report in the location.", e);
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        protected void onPostExecute(Boolean moveSuccessful) {
-            if (!moveSuccessful) {
-                BugStorageUtils.setBugReportStatus(
-                        mActivity, mBugReport,
-                        com.android.car.bugreport.Status.STATUS_MOVE_FAILED, "");
-            }
-            // Refresh the UI to reflect the new status.
-            new BugReportInfoTask(mActivity).execute();
-        }
-    }
-
-    private static final class BugReportInfoTask extends
-            AsyncTask<Void, Void, List<MetaBugReport>> {
-        private final WeakReference<BugReportInfoActivity> mBugReportInfoActivityWeakReference;
-
-        BugReportInfoTask(BugReportInfoActivity activity) {
-            mBugReportInfoActivityWeakReference = new WeakReference<>(activity);
-        }
-
-        @Override
-        protected List<MetaBugReport> doInBackground(Void... voids) {
-            BugReportInfoActivity activity = mBugReportInfoActivityWeakReference.get();
-            if (activity == null) {
-                Log.w(TAG, "Activity is gone, cancelling BugReportInfoTask.");
-                return new ArrayList<>();
-            }
-            return BugStorageUtils.getAllBugReportsDescending(activity);
-        }
-
-        @Override
-        protected void onPostExecute(List<MetaBugReport> result) {
-            BugReportInfoActivity activity = mBugReportInfoActivityWeakReference.get();
-            if (activity == null) {
-                Log.w(TAG, "Activity is gone, cancelling onPostExecute.");
-                return;
-            }
-            activity.mAdapter = new BugInfoAdapter(result, activity::onBugReportItemClicked);
-            activity.mRecyclerView.setAdapter(activity.mAdapter);
-            activity.mRecyclerView.getAdapter().notifyDataSetChanged();
-        }
-    }
+    private BugInfoAdapter.BugInfoViewHolder mLastSelectedBugInfoViewHolder;
+    private BugStorageObserver mBugStorageObserver;
+    private Config mConfig;
+    private boolean mAudioRecordingStarted;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        Preconditions.checkState(Config.isBugReportEnabled(), "BugReport is disabled.");
+
         super.onCreate(savedInstanceState);
         setContentView(R.layout.bug_report_info_activity);
 
@@ -159,9 +90,13 @@
         mRecyclerView.addItemDecoration(new DividerItemDecoration(mRecyclerView.getContext(),
                 DividerItemDecoration.VERTICAL));
 
-        // specify an adapter (see also next example)
-        mAdapter = new BugInfoAdapter(new ArrayList<>(), this::onBugReportItemClicked);
-        mRecyclerView.setAdapter(mAdapter);
+        mConfig = new Config();
+        mConfig.start();
+
+        mBugInfoAdapter = new BugInfoAdapter(this::onBugReportItemClicked, mConfig);
+        mRecyclerView.setAdapter(mBugInfoAdapter);
+
+        mBugStorageObserver = new BugStorageObserver(this, new Handler());
 
         findViewById(R.id.quit_button).setOnClickListener(this::onQuitButtonClick);
         findViewById(R.id.start_bug_report_button).setOnClickListener(
@@ -175,7 +110,16 @@
     @Override
     protected void onStart() {
         super.onStart();
-        new BugReportInfoTask(this).execute();
+        new BugReportsLoaderAsyncTask(this).execute();
+        // As BugStorageProvider is running under user0, we register using USER_ALL.
+        getContentResolver().registerContentObserver(BugStorageProvider.BUGREPORT_CONTENT_URI, true,
+                mBugStorageObserver, UserHandle.USER_ALL);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        getContentResolver().unregisterContentObserver(mBugStorageObserver);
     }
 
     /**
@@ -186,17 +130,26 @@
         mNotificationManager.cancel(BugReportService.BUGREPORT_FINISHED_NOTIF_ID);
     }
 
-    private void onBugReportItemClicked(int buttonType, MetaBugReport bugReport) {
+    private void onBugReportItemClicked(
+            int buttonType, MetaBugReport bugReport, BugInfoAdapter.BugInfoViewHolder holder) {
         if (buttonType == BugInfoAdapter.BUTTON_TYPE_UPLOAD) {
-            Log.i(TAG, "Uploading " + bugReport.getFilePath());
+            Log.i(TAG, "Uploading " + bugReport.getTimestamp());
             BugStorageUtils.setBugReportStatus(this, bugReport, Status.STATUS_UPLOAD_PENDING, "");
             // Refresh the UI to reflect the new status.
-            new BugReportInfoTask(this).execute();
+            new BugReportsLoaderAsyncTask(this).execute();
         } else if (buttonType == BugInfoAdapter.BUTTON_TYPE_MOVE) {
-            Log.i(TAG, "Moving " + bugReport.getFilePath());
+            Log.i(TAG, "Moving " + bugReport.getTimestamp());
             mLastSelectedBugReport = bugReport;
+            mLastSelectedBugInfoViewHolder = holder;
             startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE),
                     SELECT_DIRECTORY_REQUEST_CODE);
+        } else if (buttonType == BugInfoAdapter.BUTTON_TYPE_ADD_AUDIO) {
+            // Check mAudioRecordingStarted to prevent double click to BUTTON_TYPE_ADD_AUDIO.
+            if (!mAudioRecordingStarted) {
+                mAudioRecordingStarted = true;
+                startActivityForResult(BugReportActivity.buildAddAudioIntent(this, bugReport),
+                        ADD_AUDIO_MESSAGE_REQUEST_CODE);
+            }
         } else {
             throw new IllegalStateException("unreachable");
         }
@@ -211,11 +164,20 @@
                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
             Uri destDirUri = data.getData();
             getContentResolver().takePersistableUriPermission(destDirUri, takeFlags);
-            if (mLastSelectedBugReport == null) {
+            if (mLastSelectedBugReport == null || mLastSelectedBugInfoViewHolder == null) {
                 Log.w(TAG, "No bug report is selected.");
                 return;
             }
-            new AsyncMoveFilesTask(this, mLastSelectedBugReport, destDirUri).execute();
+            MetaBugReport updatedBugReport = BugStorageUtils.setBugReportStatus(this,
+                    mLastSelectedBugReport, Status.STATUS_MOVE_IN_PROGRESS, "");
+            mBugInfoAdapter.updateBugReportInDataSet(
+                    updatedBugReport, mLastSelectedBugInfoViewHolder.getAdapterPosition());
+            new AsyncMoveFilesTask(
+                this,
+                    mBugInfoAdapter,
+                    updatedBugReport,
+                    mLastSelectedBugInfoViewHolder,
+                    destDirUri).execute();
         }
     }
 
@@ -230,4 +192,161 @@
         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         startActivity(intent);
     }
+
+    /**
+     * Print the Provider's state into the given stream. This gets invoked if
+     * you run "adb shell dumpsys activity BugReportInfoActivity".
+     *
+     * @param prefix Desired prefix to prepend at each line of output.
+     * @param fd The raw file descriptor that the dump is being sent to.
+     * @param writer The PrintWriter to which you should dump your state.  This will be
+     * closed for you after you return.
+     * @param args additional arguments to the dump request.
+     */
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        super.dump(prefix, fd, writer, args);
+        mConfig.dump(prefix, writer);
+    }
+
+    /**
+     * Moves bugreport zip to USB drive and updates RecyclerView.
+     *
+     * <p>It merges bugreport zip file and audio file into one final zip file and moves it.
+     */
+    private static final class AsyncMoveFilesTask extends AsyncTask<Void, Void, MetaBugReport> {
+        private final BugReportInfoActivity mActivity;
+        private final MetaBugReport mBugReport;
+        private final Uri mDestinationDirUri;
+        /** RecyclerView.Adapter that contains all the bug reports. */
+        private final BugInfoAdapter mBugInfoAdapter;
+        /** ViewHolder for {@link #mBugReport}. */
+        private final BugInfoAdapter.BugInfoViewHolder mBugViewHolder;
+        private final ContentResolver mResolver;
+
+        AsyncMoveFilesTask(BugReportInfoActivity activity, BugInfoAdapter bugInfoAdapter,
+                MetaBugReport bugReport, BugInfoAdapter.BugInfoViewHolder holder,
+                Uri destinationDir) {
+            mActivity = activity;
+            mBugInfoAdapter = bugInfoAdapter;
+            mBugReport = bugReport;
+            mBugViewHolder = holder;
+            mDestinationDirUri = destinationDir;
+            mResolver = mActivity.getContentResolver();
+        }
+
+        /** Moves the bugreport to the USB drive and returns the updated {@link MetaBugReport}. */
+        @Override
+        protected MetaBugReport doInBackground(Void... params) {
+            try {
+                return copyFilesToUsb();
+            } catch (IOException e) {
+                Log.e(TAG, "Failed to copy bugreport "
+                        + mBugReport.getTimestamp() + " to USB", e);
+                return BugStorageUtils.setBugReportStatus(
+                    mActivity, mBugReport,
+                    com.android.car.bugreport.Status.STATUS_MOVE_FAILED, e);
+            }
+        }
+
+        private MetaBugReport copyFilesToUsb() throws IOException {
+            String documentId = DocumentsContract.getTreeDocumentId(mDestinationDirUri);
+            Uri parentDocumentUri =
+                    DocumentsContract.buildDocumentUriUsingTree(mDestinationDirUri, documentId);
+            if (!Strings.isNullOrEmpty(mBugReport.getFilePath())) {
+                // There are still old bugreports with deprecated filePath.
+                Uri sourceUri = BugStorageProvider.buildUriWithSegment(
+                        mBugReport.getId(), BugStorageProvider.URL_SEGMENT_OPEN_FILE);
+                copyFileToUsb(
+                        new File(mBugReport.getFilePath()).getName(), sourceUri, parentDocumentUri);
+            } else {
+                Uri sourceBugReport = BugStorageProvider.buildUriWithSegment(
+                        mBugReport.getId(), BugStorageProvider.URL_SEGMENT_OPEN_BUGREPORT_FILE);
+                copyFileToUsb(
+                        mBugReport.getBugReportFileName(), sourceBugReport, parentDocumentUri);
+                Uri sourceAudio = BugStorageProvider.buildUriWithSegment(
+                        mBugReport.getId(), BugStorageProvider.URL_SEGMENT_OPEN_AUDIO_FILE);
+                copyFileToUsb(mBugReport.getAudioFileName(), sourceAudio, parentDocumentUri);
+            }
+            Log.d(TAG, "Deleting local bug report files.");
+            BugStorageUtils.deleteBugReportFiles(mActivity, mBugReport.getId());
+            return BugStorageUtils.setBugReportStatus(mActivity, mBugReport,
+                    com.android.car.bugreport.Status.STATUS_MOVE_SUCCESSFUL,
+                    "Moved to: " + mDestinationDirUri.getPath());
+        }
+
+        private void copyFileToUsb(String filename, Uri sourceUri, Uri parentDocumentUri)
+                throws IOException {
+            String mimeType = mResolver.getType(sourceUri);
+            Uri newFileUri = DocumentsContract.createDocument(
+                    mResolver, parentDocumentUri, mimeType, filename);
+            if (newFileUri == null) {
+                throw new IOException("Unable to create a file " + filename + " in USB");
+            }
+            try (InputStream input = mResolver.openInputStream(sourceUri);
+                 AssetFileDescriptor fd = mResolver.openAssetFileDescriptor(newFileUri, "w")) {
+                OutputStream output = fd.createOutputStream();
+                ByteStreams.copy(input, output);
+                // Force sync the written data from memory to the disk.
+                fd.getFileDescriptor().sync();
+            }
+        }
+
+        @Override
+        protected void onPostExecute(MetaBugReport updatedBugReport) {
+            // Refresh the UI to reflect the new status.
+            mBugInfoAdapter.updateBugReportInDataSet(
+                    updatedBugReport, mBugViewHolder.getAdapterPosition());
+        }
+    }
+
+    /** Asynchronously loads bugreports from {@link BugStorageProvider}. */
+    private static final class BugReportsLoaderAsyncTask extends
+            AsyncTask<Void, Void, List<MetaBugReport>> {
+        private final WeakReference<BugReportInfoActivity> mBugReportInfoActivityWeakReference;
+
+        BugReportsLoaderAsyncTask(BugReportInfoActivity activity) {
+            mBugReportInfoActivityWeakReference = new WeakReference<>(activity);
+        }
+
+        @Override
+        protected List<MetaBugReport> doInBackground(Void... voids) {
+            BugReportInfoActivity activity = mBugReportInfoActivityWeakReference.get();
+            if (activity == null) {
+                Log.w(TAG, "Activity is gone, cancelling BugReportsLoaderAsyncTask.");
+                return new ArrayList<>();
+            }
+            return BugStorageUtils.getAllBugReportsDescending(activity);
+        }
+
+        @Override
+        protected void onPostExecute(List<MetaBugReport> result) {
+            BugReportInfoActivity activity = mBugReportInfoActivityWeakReference.get();
+            if (activity == null) {
+                Log.w(TAG, "Activity is gone, cancelling onPostExecute.");
+                return;
+            }
+            activity.mBugInfoAdapter.setDataset(result);
+        }
+    }
+
+    /** Observer for {@link BugStorageProvider}. */
+    private static class BugStorageObserver extends ContentObserver {
+        private final BugReportInfoActivity mInfoActivity;
+
+        /**
+         * Creates a content observer.
+         *
+         * @param activity A {@link BugReportInfoActivity} instance.
+         * @param handler The handler to run {@link #onChange} on, or null if none.
+         */
+        BugStorageObserver(BugReportInfoActivity activity, Handler handler) {
+            super(handler);
+            mInfoActivity = activity;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            new BugReportsLoaderAsyncTask(mInfoActivity).execute();
+        }
+    }
 }
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/BugReportService.java b/tests/BugReportApp/src/com/android/car/bugreport/BugReportService.java
index 378c883..dcfeb2b 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/BugReportService.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/BugReportService.java
@@ -27,7 +27,12 @@
 import android.car.Car;
 import android.car.CarBugreportManager;
 import android.car.CarNotConnectedException;
+import android.content.Context;
 import android.content.Intent;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -38,33 +43,32 @@
 import android.util.Log;
 import android.widget.Toast;
 
+import com.google.common.base.Preconditions;
+import com.google.common.io.ByteStreams;
 import com.google.common.util.concurrent.AtomicDouble;
 
-import libcore.io.IoUtils;
-
 import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.Enumeration;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 import java.util.zip.ZipOutputStream;
 
 /**
  * Service that captures screenshot and bug report using dumpstate and bluetooth snoop logs.
  *
- * <p>After collecting all the logs it updates the {@link MetaBugReport} using {@link
- * BugStorageProvider}, which in turn schedules bug report to upload.
+ * <p>After collecting all the logs it sets the {@link MetaBugReport} status to
+ * {@link Status#STATUS_AUDIO_PENDING} or {@link Status#STATUS_PENDING_USER_ACTION} depending
+ * on {@link MetaBugReport#getType}.
+ *
+ * <p>If the service is started with action {@link #ACTION_START_SILENT}, it will start
+ * bugreporting without showing dialog and recording audio message, see
+ * {@link MetaBugReport#TYPE_SILENT}.
  */
 public class BugReportService extends Service {
     private static final String TAG = BugReportService.class.getSimpleName();
@@ -74,6 +78,10 @@
      */
     static final String EXTRA_META_BUG_REPORT = "meta_bug_report";
 
+    /** Starts silent (no audio message recording) bugreporting. */
+    private static final String ACTION_START_SILENT =
+            "com.android.car.bugreport.action.START_SILENT";
+
     // Wait a short time before starting to capture the bugreport and the screen, so that
     // bugreport activity can detach from the view tree.
     // It is ugly to have a timeout, but it is ok here because such a delay should not really
@@ -81,6 +89,12 @@
     // this, the best option is probably to wait for onDetach events from view tree.
     private static final int ACTIVITY_FINISH_DELAY_MILLIS = 1000;
 
+    /**
+     * Wait a short time before showing "bugreport started" toast message, because the service
+     * will take a screenshot of the screen.
+     */
+    private static final int BUGREPORT_STARTED_TOAST_DELAY_MILLIS = 2000;
+
     private static final String BT_SNOOP_LOG_LOCATION = "/data/misc/bluetooth/logs/btsnoop_hci.log";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
@@ -90,9 +104,10 @@
     /** Notifications on this channel will pop-up. */
     private static final String STATUS_CHANNEL_ID = "BUGREPORT_STATUS_CHANNEL";
 
+    /** Persistent notification is shown when bugreport is in progress or waiting for audio. */
     private static final int BUGREPORT_IN_PROGRESS_NOTIF_ID = 1;
 
-    /** The notification is shown when bugreport is collected. */
+    /** Dismissible notification is shown when bugreport is collected. */
     static final int BUGREPORT_FINISHED_NOTIF_ID = 2;
 
     private static final String OUTPUT_ZIP_FILE = "output_file.zip";
@@ -119,9 +134,16 @@
     private Car mCar;
     private CarBugreportManager mBugreportManager;
     private CarBugreportManager.CarBugreportManagerCallback mCallback;
+    private Config mConfig;
 
     /** A handler on the main thread. */
     private Handler mHandler;
+    /**
+     * A handler to the main thread to show toast messages, it will be cleared when the service
+     * finishes. We need to clear it otherwise when bugreport fails, it will show "bugreport start"
+     * toast, which will confuse users.
+     */
+    private Handler mHandlerToast;
 
     /** A listener that's notified when bugreport progress changes. */
     interface BugReportProgressListener {
@@ -141,7 +163,7 @@
         }
     }
 
-    /** A handler on a main thread. */
+    /** A handler on the main thread. */
     private class BugReportHandler extends Handler {
         @Override
         public void handleMessage(Message message) {
@@ -161,6 +183,8 @@
 
     @Override
     public void onCreate() {
+        Preconditions.checkState(Config.isBugReportEnabled(), "BugReport is disabled.");
+
         mNotificationManager = getSystemService(NotificationManager.class);
         mNotificationManager.createNotificationChannel(new NotificationChannel(
                 PROGRESS_CHANNEL_ID,
@@ -172,34 +196,58 @@
                 NotificationManager.IMPORTANCE_HIGH));
         mSingleThreadExecutor = Executors.newSingleThreadScheduledExecutor();
         mHandler = new BugReportHandler();
+        mHandlerToast = new Handler();
+        mConfig = new Config();
+        mConfig.start();
+        // Synchronously connect to the car service.
         mCar = Car.createCar(this);
         try {
             mBugreportManager = (CarBugreportManager) mCar.getCarManager(Car.CAR_BUGREPORT_SERVICE);
         } catch (CarNotConnectedException | NoClassDefFoundError e) {
-            Log.w(TAG, "Couldn't get CarBugreportManager", e);
+            throw new IllegalStateException("Failed to get CarBugreportManager.", e);
         }
     }
 
     @Override
+    public void onDestroy() {
+        if (DEBUG) {
+            Log.d(TAG, "Service destroyed");
+        }
+        mCar.disconnect();
+    }
+
+    @Override
     public int onStartCommand(final Intent intent, int flags, int startId) {
-        if (mIsCollectingBugReport.get()) {
+        if (mIsCollectingBugReport.getAndSet(true)) {
             Log.w(TAG, "bug report is already being collected, ignoring");
             Toast.makeText(this, R.string.toast_bug_report_in_progress, Toast.LENGTH_SHORT).show();
             return START_NOT_STICKY;
         }
+
         Log.i(TAG, String.format("Will start collecting bug report, version=%s",
                 getPackageVersion(this)));
-        mIsCollectingBugReport.set(true);
+
+        if (ACTION_START_SILENT.equals(intent.getAction())) {
+            Log.i(TAG, "Starting a silent bugreport.");
+            mMetaBugReport = BugReportActivity.createBugReport(this, MetaBugReport.TYPE_SILENT);
+        } else {
+            Bundle extras = intent.getExtras();
+            mMetaBugReport = extras.getParcelable(EXTRA_META_BUG_REPORT);
+        }
+
         mBugReportProgress.set(0);
 
         startForeground(BUGREPORT_IN_PROGRESS_NOTIF_ID, buildProgressNotification());
         showProgressNotification();
 
-        Bundle extras = intent.getExtras();
-        mMetaBugReport = extras.getParcelable(EXTRA_META_BUG_REPORT);
-
         collectBugReport();
 
+        // Show a short lived "bugreport started" toast message after a short delay.
+        mHandlerToast.postDelayed(() -> {
+            Toast.makeText(this,
+                    getText(R.string.toast_bug_report_started), Toast.LENGTH_LONG).show();
+        }, BUGREPORT_STARTED_TOAST_DELAY_MILLIS);
+
         // If the service process gets killed due to heavy memory pressure, do not restart.
         return START_NOT_STICKY;
     }
@@ -213,6 +261,9 @@
     }
 
     private Notification buildProgressNotification() {
+        Intent intent = new Intent(getApplicationContext(), BugReportInfoActivity.class);
+        PendingIntent startBugReportInfoActivity =
+                PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
         return new Notification.Builder(this, PROGRESS_CHANNEL_ID)
                 .setContentTitle(getText(R.string.notification_bugreport_in_progress))
                 .setSubText(String.format("%.1f%%", mBugReportProgress.get()))
@@ -220,6 +271,7 @@
                 .setCategory(Notification.CATEGORY_STATUS)
                 .setOngoing(true)
                 .setProgress((int) MAX_PROGRESS_VALUE, (int) mBugReportProgress.get(), false)
+                .setContentIntent(startBugReportInfoActivity)
                 .build();
     }
 
@@ -266,9 +318,14 @@
         Log.i(TAG, "Grabbing bt snoop log");
         File result = FileUtils.getFileWithSuffix(this, mMetaBugReport.getTimestamp(),
                 "-btsnoop.bin.log");
-        try {
-            copyBinaryStream(new FileInputStream(new File(BT_SNOOP_LOG_LOCATION)),
-                    new FileOutputStream(result));
+        File snoopFile = new File(BT_SNOOP_LOG_LOCATION);
+        if (!snoopFile.exists()) {
+            Log.w(TAG, BT_SNOOP_LOG_LOCATION + " not found, skipping");
+            return;
+        }
+        try (FileInputStream input = new FileInputStream(snoopFile);
+             FileOutputStream output = new FileOutputStream(result)) {
+            ByteStreams.copy(input, output);
         } catch (IOException e) {
             // this regularly happens when snooplog is not enabled so do not log as an error
             Log.i(TAG, "Failed to grab bt snooplog, continuing to take bug report.", e);
@@ -307,14 +364,21 @@
         mCallback = new CarBugreportManager.CarBugreportManagerCallback() {
             @Override
             public void onError(int errorCode) {
-                Log.e(TAG, "Bugreport failed " + errorCode);
-                showToast(R.string.toast_status_failed);
-                // TODO(b/133520419): show this error on Info page or add to zip file.
-                scheduleZipTask();
+                Log.e(TAG, "CarBugreportManager failed: " + errorCode);
                 // We let the UI know that bug reporting is finished, because the next step is to
                 // zip everything and upload.
                 mBugReportProgress.set(MAX_PROGRESS_VALUE);
                 sendProgressEventToHandler(MAX_PROGRESS_VALUE);
+                showToast(R.string.toast_status_failed);
+                BugStorageUtils.setBugReportStatus(
+                        BugReportService.this, mMetaBugReport,
+                        Status.STATUS_WRITE_FAILED, "CarBugreportManager failed: " + errorCode);
+                mIsCollectingBugReport.set(false);
+                mHandler.post(() -> {
+                    mNotificationManager.cancel(BUGREPORT_IN_PROGRESS_NOTIF_ID);
+                    stopForeground(true);
+                });
+                mHandlerToast.removeCallbacksAndMessages(null);
             }
 
             @Override
@@ -325,86 +389,102 @@
 
             @Override
             public void onFinished() {
-                Log.i(TAG, "Bugreport finished");
-                scheduleZipTask();
+                Log.d(TAG, "CarBugreportManager finished");
                 mBugReportProgress.set(MAX_PROGRESS_VALUE);
                 sendProgressEventToHandler(MAX_PROGRESS_VALUE);
+                mSingleThreadExecutor.submit(BugReportService.this::zipDirectoryAndUpdateStatus);
             }
         };
         mBugreportManager.requestBugreport(outFd, extraOutFd, mCallback);
     }
 
-    private void scheduleZipTask() {
-        mSingleThreadExecutor.submit(this::zipDirectoryAndScheduleForUpload);
-    }
-
     /**
      * Shows a clickable bugreport finished notification. When clicked it opens
      * {@link BugReportInfoActivity}.
      */
-    private void showBugReportFinishedNotification() {
-        Intent intent = new Intent(getApplicationContext(), BugReportInfoActivity.class);
+    static void showBugReportFinishedNotification(Context context, MetaBugReport bug) {
+        Intent intent = new Intent(context, BugReportInfoActivity.class);
         PendingIntent startBugReportInfoActivity =
-                PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
+                PendingIntent.getActivity(context, 0, intent, 0);
         Notification notification = new Notification
-                .Builder(getApplicationContext(), STATUS_CHANNEL_ID)
-                .setContentTitle(getText(R.string.notification_bugreport_finished_title))
-                .setContentText(getText(JobSchedulingUtils.uploadByDefault()
-                        ? R.string.notification_bugreport_auto_upload_finished_text
-                        : R.string.notification_bugreport_manual_upload_finished_text))
+                .Builder(context, STATUS_CHANNEL_ID)
+                .setContentTitle(context.getText(R.string.notification_bugreport_finished_title))
+                .setContentText(bug.getTitle())
                 .setCategory(Notification.CATEGORY_STATUS)
                 .setSmallIcon(R.drawable.ic_upload)
                 .setContentIntent(startBugReportInfoActivity)
                 .build();
-        mNotificationManager.notify(BUGREPORT_FINISHED_NOTIF_ID, notification);
+        context.getSystemService(NotificationManager.class)
+                .notify(BUGREPORT_FINISHED_NOTIF_ID, notification);
     }
 
-    private void zipDirectoryAndScheduleForUpload() {
+    /**
+     * Zips the temp directory, writes to the system user's {@link FileUtils#getPendingDir} and
+     * updates the bug report status.
+     *
+     * <p>For {@link MetaBugReport#TYPE_INTERACTIVE}: Sets status to either STATUS_UPLOAD_PENDING or
+     * STATUS_PENDING_USER_ACTION and shows a regular notification.
+     *
+     * <p>For {@link MetaBugReport#TYPE_SILENT}: Sets status to STATUS_AUDIO_PENDING and shows
+     * a dialog to record audio message.
+     */
+    private void zipDirectoryAndUpdateStatus() {
         try {
-            // When OutputStream from openBugReportFile is closed, BugStorageProvider automatically
-            // schedules an upload job.
-            zipDirectoryToOutputStream(
-                    FileUtils.createTempDir(this, mMetaBugReport.getTimestamp()),
-                    BugStorageUtils.openBugReportFile(this, mMetaBugReport));
-            showBugReportFinishedNotification();
+            // All the generated zip files, images and audio messages are located in this dir.
+            // This is located under the current user.
+            String bugreportFileName = FileUtils.getZipFileName(mMetaBugReport);
+            Log.d(TAG, "Zipping bugreport into " + bugreportFileName);
+            mMetaBugReport = BugStorageUtils.update(this,
+                    mMetaBugReport.toBuilder().setBugReportFileName(bugreportFileName).build());
+            File bugReportTempDir = FileUtils.createTempDir(this, mMetaBugReport.getTimestamp());
+            zipDirectoryToOutputStream(bugReportTempDir,
+                    BugStorageUtils.openBugReportFileToWrite(this, mMetaBugReport));
+            mIsCollectingBugReport.set(false);
         } catch (IOException e) {
             Log.e(TAG, "Failed to zip files", e);
             BugStorageUtils.setBugReportStatus(this, mMetaBugReport, Status.STATUS_WRITE_FAILED,
                     MESSAGE_FAILURE_ZIP);
             showToast(R.string.toast_status_failed);
+            return;
         }
-        mIsCollectingBugReport.set(false);
-        showToast(R.string.toast_status_finished);
-        mHandler.post(() -> stopForeground(true));
+        if (mMetaBugReport.getType() == MetaBugReport.TYPE_SILENT) {
+            BugStorageUtils.setBugReportStatus(BugReportService.this,
+                    mMetaBugReport, Status.STATUS_AUDIO_PENDING, /* message= */ "");
+            playNotificationSound();
+            startActivity(BugReportActivity.buildAddAudioIntent(this, mMetaBugReport));
+        } else {
+            // NOTE: If bugreport type is INTERACTIVE, it will already contain an audio message.
+            Status status = mConfig.getAutoUpload()
+                    ? Status.STATUS_UPLOAD_PENDING : Status.STATUS_PENDING_USER_ACTION;
+            BugStorageUtils.setBugReportStatus(BugReportService.this,
+                    mMetaBugReport, status, /* message= */ "");
+            showBugReportFinishedNotification(this, mMetaBugReport);
+        }
+        mHandler.post(() -> {
+            mNotificationManager.cancel(BUGREPORT_IN_PROGRESS_NOTIF_ID);
+            stopForeground(true);
+        });
+        mHandlerToast.removeCallbacksAndMessages(null);
     }
 
-    @Override
-    public void onDestroy() {
-        if (DEBUG) {
-            Log.d(TAG, "Service destroyed");
+    private void playNotificationSound() {
+        Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
+        Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), notification);
+        if (ringtone == null) {
+            Log.w(TAG, "No notification ringtone found.");
+            return;
         }
-    }
-
-    private static void copyBinaryStream(InputStream in, OutputStream out) throws IOException {
-        OutputStream writer = null;
-        InputStream reader = null;
-        try {
-            writer = new DataOutputStream(out);
-            reader = new DataInputStream(in);
-            rawCopyStream(writer, reader);
-        } finally {
-            IoUtils.closeQuietly(reader);
-            IoUtils.closeQuietly(writer);
+        float volume = ringtone.getVolume();
+        // Use volume from audio manager, otherwise default ringtone volume can be too loud.
+        AudioManager audioManager = getSystemService(AudioManager.class);
+        if (audioManager != null) {
+            int currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
+            int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION);
+            volume = (currentVolume + 0.0f) / maxVolume;
         }
-    }
-
-    // does not close the reader or writer.
-    private static void rawCopyStream(OutputStream writer, InputStream reader) throws IOException {
-        int read;
-        byte[] buf = new byte[8192];
-        while ((read = reader.read(buf, 0, buf.length)) > 0) {
-            writer.write(buf, 0, read);
-        }
+        Log.v(TAG, "Using volume " + volume);
+        ringtone.setVolume(volume);
+        ringtone.play();
     }
 
     /**
@@ -425,59 +505,23 @@
         Log.v(TAG, "zipping directory " + dirToZip.getAbsolutePath());
 
         File[] listFiles = dirToZip.listFiles();
-        ZipOutputStream zipStream = new ZipOutputStream(new BufferedOutputStream(outStream));
-        try {
+        try (ZipOutputStream zipStream = new ZipOutputStream(new BufferedOutputStream(outStream))) {
             for (File file : listFiles) {
                 if (file.isDirectory()) {
                     continue;
                 }
-                if (file.length() == 0) {
-                    // If there were issues with reading from dumpstate socket, the dumpstate zip
-                    // file still might be available in
-                    // /data/user_de/0/com.android.shell/files/bugreports/.
-                    Log.w(TAG, "File " + file.getName() + " is empty, skipping.");
-                    return;
-                }
                 String filename = file.getName();
-
                 // only for the zipped output file, we add individual entries to zip file.
                 if (filename.equals(OUTPUT_ZIP_FILE) || filename.equals(EXTRA_OUTPUT_ZIP_FILE)) {
-                    extractZippedFileToOutputStream(file, zipStream);
+                    ZipUtils.extractZippedFileToZipStream(file, zipStream);
                 } else {
-                    try (FileInputStream reader = new FileInputStream(file)) {
-                        addFileToOutputStream(filename, reader, zipStream);
-                    }
+                    ZipUtils.addFileToZipStream(file, zipStream);
                 }
             }
         } finally {
-            zipStream.close();
             outStream.close();
         }
         // Zipping successful, now cleanup the temp dir.
         FileUtils.deleteDirectory(dirToZip);
     }
-
-    private void extractZippedFileToOutputStream(File file, ZipOutputStream zipStream)
-            throws IOException {
-        ZipFile zipFile = new ZipFile(file);
-        Enumeration<? extends ZipEntry> entries = zipFile.entries();
-        while (entries.hasMoreElements()) {
-            ZipEntry entry = entries.nextElement();
-            try (InputStream stream = zipFile.getInputStream(entry)) {
-                addFileToOutputStream(entry.getName(), stream, zipStream);
-            }
-        }
-    }
-
-    private void addFileToOutputStream(
-            String filename, InputStream reader, ZipOutputStream zipStream) {
-        ZipEntry entry = new ZipEntry(filename);
-        try {
-            zipStream.putNextEntry(entry);
-            rawCopyStream(zipStream, reader);
-            zipStream.closeEntry();
-        } catch (IOException e) {
-            Log.w(TAG, "Failed to add file " + filename + " to the zip.", e);
-        }
-    }
 }
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/BugStorageProvider.java b/tests/BugReportApp/src/com/android/car/bugreport/BugStorageProvider.java
index 095a668..1abbdb2 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/BugStorageProvider.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/BugStorageProvider.java
@@ -17,6 +17,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.content.Context;
@@ -26,13 +27,19 @@
 import android.database.sqlite.SQLiteOpenHelper;
 import android.net.Uri;
 import android.os.CancellationSignal;
-import android.os.Handler;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
-import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.function.Function;
 
 
 /**
@@ -40,32 +47,76 @@
  * In Android Automotive user 0 runs as the system and all the time, while other users won't once
  * their session ends. This content provider enables bug reports to be uploaded even after
  * user session ends.
+ *
+ * <p>A bugreport constists of two files: bugreport zip file and audio file. Audio file is added
+ * later through notification. {@link SimpleUploaderAsyncTask} merges two files into one zip file
+ * before uploading.
+ *
+ * <p>All files are stored under system user's {@link FileUtils#getPendingDir}.
  */
 public class BugStorageProvider extends ContentProvider {
     private static final String TAG = BugStorageProvider.class.getSimpleName();
 
     private static final String AUTHORITY = "com.android.car.bugreport";
     private static final String BUG_REPORTS_TABLE = "bugreports";
-    static final Uri BUGREPORT_CONTENT_URI =
-            Uri.parse("content://" + AUTHORITY + "/" + BUG_REPORTS_TABLE);
 
-    static final String COLUMN_ID = "_ID";
-    static final String COLUMN_USERNAME = "username";
-    static final String COLUMN_TITLE = "title";
-    static final String COLUMN_TIMESTAMP = "timestamp";
-    static final String COLUMN_DESCRIPTION = "description";
-    static final String COLUMN_FILEPATH = "filepath";
-    static final String COLUMN_STATUS = "status";
-    static final String COLUMN_STATUS_MESSAGE = "message";
+    /** Deletes files associated with a bug report. */
+    static final String URL_SEGMENT_DELETE_FILES = "deleteZipFile";
+    /** Destructively deletes a bug report. */
+    static final String URL_SEGMENT_COMPLETE_DELETE = "completeDelete";
+    /** Opens bugreport file of a bug report, uses column {@link #COLUMN_BUGREPORT_FILENAME}. */
+    static final String URL_SEGMENT_OPEN_BUGREPORT_FILE = "openBugReportFile";
+    /** Opens audio file of a bug report, uses column {@link #URL_MATCHED_OPEN_AUDIO_FILE}. */
+    static final String URL_SEGMENT_OPEN_AUDIO_FILE = "openAudioFile";
+    /**
+     * Opens final bugreport zip file, uses column {@link #COLUMN_FILEPATH}.
+     *
+     * <p>NOTE: This is the old way of storing final zipped bugreport. In
+     * {@code BugStorageProvider#AUDIO_VERSION} {@link #COLUMN_FILEPATH} is dropped. But there are
+     * still some devices with this field set.
+     */
+    static final String URL_SEGMENT_OPEN_FILE = "openFile";
 
     // URL Matcher IDs.
     private static final int URL_MATCHED_BUG_REPORTS_URI = 1;
     private static final int URL_MATCHED_BUG_REPORT_ID_URI = 2;
+    private static final int URL_MATCHED_DELETE_FILES = 3;
+    private static final int URL_MATCHED_COMPLETE_DELETE = 4;
+    private static final int URL_MATCHED_OPEN_BUGREPORT_FILE = 5;
+    private static final int URL_MATCHED_OPEN_AUDIO_FILE = 6;
+    private static final int URL_MATCHED_OPEN_FILE = 7;
 
-    private Handler mHandler;
+    @StringDef({
+            URL_SEGMENT_DELETE_FILES,
+            URL_SEGMENT_COMPLETE_DELETE,
+            URL_SEGMENT_OPEN_BUGREPORT_FILE,
+            URL_SEGMENT_OPEN_AUDIO_FILE,
+            URL_SEGMENT_OPEN_FILE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface UriActionSegments {}
+
+    static final Uri BUGREPORT_CONTENT_URI =
+            Uri.parse("content://" + AUTHORITY + "/" + BUG_REPORTS_TABLE);
+
+    /** See {@link MetaBugReport} for column descriptions. */
+    static final String COLUMN_ID = "_ID";
+    static final String COLUMN_USERNAME = "username";
+    static final String COLUMN_TITLE = "title";
+    static final String COLUMN_TIMESTAMP = "timestamp";
+    /** not used anymore */
+    static final String COLUMN_DESCRIPTION = "description";
+    /** not used anymore, but some devices still might have bugreports with this field set. */
+    static final String COLUMN_FILEPATH = "filepath";
+    static final String COLUMN_STATUS = "status";
+    static final String COLUMN_STATUS_MESSAGE = "message";
+    static final String COLUMN_TYPE = "type";
+    static final String COLUMN_BUGREPORT_FILENAME = "bugreport_filename";
+    static final String COLUMN_AUDIO_FILENAME = "audio_filename";
 
     private DatabaseHelper mDatabaseHelper;
     private final UriMatcher mUriMatcher;
+    private Config mConfig;
 
     /**
      * A helper class to work with sqlite database.
@@ -78,9 +129,13 @@
         /**
          * All changes in database versions should be recorded here.
          * 1: Initial version.
+         * 2: Add integer column details_needed.
+         * 3: Add string column audio_filename and bugreport_filename.
          */
         private static final int INITIAL_VERSION = 1;
-        private static final int DATABASE_VERSION = INITIAL_VERSION;
+        private static final int TYPE_VERSION = 2;
+        private static final int AUDIO_VERSION = 3;
+        private static final int DATABASE_VERSION = AUDIO_VERSION;
 
         private static final String CREATE_TABLE = "CREATE TABLE " + BUG_REPORTS_TABLE + " ("
                 + COLUMN_ID + " INTEGER PRIMARY KEY,"
@@ -90,7 +145,10 @@
                 + COLUMN_DESCRIPTION + " TEXT NULL,"
                 + COLUMN_FILEPATH + " TEXT DEFAULT NULL,"
                 + COLUMN_STATUS + " INTEGER DEFAULT " + Status.STATUS_WRITE_PENDING.getValue() + ","
-                + COLUMN_STATUS_MESSAGE + " TEXT NULL"
+                + COLUMN_STATUS_MESSAGE + " TEXT NULL,"
+                + COLUMN_TYPE + " INTEGER DEFAULT " + MetaBugReport.TYPE_INTERACTIVE + ","
+                + COLUMN_BUGREPORT_FILENAME + " TEXT DEFAULT NULL,"
+                + COLUMN_AUDIO_FILENAME + " TEXT DEFAULT NULL"
                 + ");";
 
         DatabaseHelper(Context context) {
@@ -105,24 +163,56 @@
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
             Log.w(TAG, "Upgrading from " + oldVersion + " to " + newVersion);
+            if (oldVersion < TYPE_VERSION) {
+                db.execSQL("ALTER TABLE " + BUG_REPORTS_TABLE + " ADD COLUMN "
+                        + COLUMN_TYPE + " INTEGER DEFAULT " + MetaBugReport.TYPE_INTERACTIVE);
+            }
+            if (oldVersion < AUDIO_VERSION) {
+                db.execSQL("ALTER TABLE " + BUG_REPORTS_TABLE + " ADD COLUMN "
+                        + COLUMN_BUGREPORT_FILENAME + " TEXT DEFAULT NULL");
+                db.execSQL("ALTER TABLE " + BUG_REPORTS_TABLE + " ADD COLUMN "
+                        + COLUMN_AUDIO_FILENAME + " TEXT DEFAULT NULL");
+            }
         }
     }
 
-    /** Builds {@link Uri} that points to a bugreport entry with provided bugreport id. */
-    static Uri buildUriWithBugId(int bugReportId) {
-        return Uri.parse("content://" + AUTHORITY + "/" + BUG_REPORTS_TABLE + "/" + bugReportId);
+    /**
+     * Builds an {@link Uri} that points to the single bug report and performs an action
+     * defined by given URI segment.
+     */
+    static Uri buildUriWithSegment(int bugReportId, @UriActionSegments String segment) {
+        return Uri.parse("content://" + AUTHORITY + "/" + BUG_REPORTS_TABLE + "/"
+                + segment + "/" + bugReportId);
     }
 
     public BugStorageProvider() {
         mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
         mUriMatcher.addURI(AUTHORITY, BUG_REPORTS_TABLE, URL_MATCHED_BUG_REPORTS_URI);
         mUriMatcher.addURI(AUTHORITY, BUG_REPORTS_TABLE + "/#", URL_MATCHED_BUG_REPORT_ID_URI);
+        mUriMatcher.addURI(
+                AUTHORITY, BUG_REPORTS_TABLE + "/" + URL_SEGMENT_DELETE_FILES + "/#",
+                URL_MATCHED_DELETE_FILES);
+        mUriMatcher.addURI(
+                AUTHORITY, BUG_REPORTS_TABLE + "/" + URL_SEGMENT_COMPLETE_DELETE + "/#",
+                URL_MATCHED_COMPLETE_DELETE);
+        mUriMatcher.addURI(
+                AUTHORITY, BUG_REPORTS_TABLE + "/" + URL_SEGMENT_OPEN_BUGREPORT_FILE + "/#",
+                URL_MATCHED_OPEN_BUGREPORT_FILE);
+        mUriMatcher.addURI(
+                AUTHORITY, BUG_REPORTS_TABLE + "/" + URL_SEGMENT_OPEN_AUDIO_FILE + "/#",
+                URL_MATCHED_OPEN_AUDIO_FILE);
+        mUriMatcher.addURI(
+                AUTHORITY, BUG_REPORTS_TABLE + "/" + URL_SEGMENT_OPEN_FILE + "/#",
+                URL_MATCHED_OPEN_FILE);
     }
 
     @Override
     public boolean onCreate() {
+        Preconditions.checkState(Config.isBugReportEnabled(), "BugReport is disabled.");
+
         mDatabaseHelper = new DatabaseHelper(getContext());
-        mHandler = new Handler();
+        mConfig = new Config();
+        mConfig.start();
         return true;
     }
 
@@ -181,10 +271,6 @@
         switch (mUriMatcher.match(uri)) {
             case URL_MATCHED_BUG_REPORTS_URI:
                 table = BUG_REPORTS_TABLE;
-                String filepath = FileUtils.getZipFile(getContext(),
-                        (String) values.get(COLUMN_TIMESTAMP),
-                        (String) values.get(COLUMN_USERNAME)).getPath();
-                values.put(COLUMN_FILEPATH, filepath);
                 break;
             default:
                 throw new IllegalArgumentException("unknown uri" + uri);
@@ -203,31 +289,46 @@
     @Nullable
     @Override
     public String getType(@NonNull Uri uri) {
-        if (mUriMatcher.match(uri) != URL_MATCHED_BUG_REPORT_ID_URI) {
-            throw new IllegalArgumentException("unknown uri:" + uri);
+        switch (mUriMatcher.match(uri)) {
+            case URL_MATCHED_OPEN_BUGREPORT_FILE:
+            case URL_MATCHED_OPEN_FILE:
+                return "application/zip";
+            case URL_MATCHED_OPEN_AUDIO_FILE:
+                return "audio/3gpp";
+            default:
+                throw new IllegalArgumentException("unknown uri:" + uri);
         }
-        // We only store zip files in this provider.
-        return "application/zip";
     }
 
     @Override
     public int delete(
             @NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
+        SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
         switch (mUriMatcher.match(uri)) {
-            //  returns the bugreport that match the id.
-            case URL_MATCHED_BUG_REPORT_ID_URI:
+            case URL_MATCHED_DELETE_FILES:
                 if (selection != null || selectionArgs != null) {
                     throw new IllegalArgumentException("selection is not allowed for "
-                            + URL_MATCHED_BUG_REPORT_ID_URI);
+                            + URL_MATCHED_DELETE_FILES);
+                }
+                if (deleteFilesFor(getBugReportFromUri(uri))) {
+                    getContext().getContentResolver().notifyChange(uri, null);
+                    return 1;
+                }
+                return 0;
+            case URL_MATCHED_COMPLETE_DELETE:
+                if (selection != null || selectionArgs != null) {
+                    throw new IllegalArgumentException("selection is not allowed for "
+                            + URL_MATCHED_COMPLETE_DELETE);
                 }
                 selection = COLUMN_ID + " = ?";
                 selectionArgs = new String[]{uri.getLastPathSegment()};
-                break;
+                // Ignore the results of zip file deletion, possibly it wasn't even created.
+                deleteFilesFor(getBugReportFromUri(uri));
+                getContext().getContentResolver().notifyChange(uri, null);
+                return db.delete(BUG_REPORTS_TABLE, selection, selectionArgs);
             default:
                 throw new IllegalArgumentException("Unknown URL " + uri);
         }
-        SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
-        return db.delete(BUG_REPORTS_TABLE, selection, selectionArgs);
     }
 
     @Override
@@ -263,77 +364,72 @@
     }
 
     /**
-     * This is called when the OutputStream is requested by
-     * {@link BugStorageUtils#openBugReportFile}.
+     * This is called when a file is opened.
      *
-     * It expects the file to be a zip file and schedules an upload under the primary user.
+     * <p>See {@link BugStorageUtils#openBugReportFileToWrite},
+     * {@link BugStorageUtils#openAudioMessageFileToWrite}.
      */
     @Nullable
     @Override
     public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode)
             throws FileNotFoundException {
-        if (mUriMatcher.match(uri) != URL_MATCHED_BUG_REPORT_ID_URI) {
-            throw new IllegalArgumentException("unknown uri:" + uri);
+        Function<MetaBugReport, String> fileNameExtractor;
+        switch (mUriMatcher.match(uri)) {
+            case URL_MATCHED_OPEN_BUGREPORT_FILE:
+                fileNameExtractor = MetaBugReport::getBugReportFileName;
+                break;
+            case URL_MATCHED_OPEN_AUDIO_FILE:
+                fileNameExtractor = MetaBugReport::getAudioFileName;
+                break;
+            case URL_MATCHED_OPEN_FILE:
+                File file = new File(getBugReportFromUri(uri).getFilePath());
+                Log.v(TAG, "Opening file " + file + " with mode " + mode);
+                return ParcelFileDescriptor.open(file, ParcelFileDescriptor.parseMode(mode));
+            default:
+                throw new IllegalArgumentException("unknown uri:" + uri);
         }
-
-        Cursor c = query(uri, new String[]{COLUMN_FILEPATH}, null, null, null);
-        int count = (c != null) ? c.getCount() : 0;
-        if (count != 1) {
-            // If there is not exactly one result, throw an appropriate
-            // exception.
-            if (c != null) {
-                c.close();
-            }
-            if (count == 0) {
-                throw new FileNotFoundException("No entry for " + uri);
-            }
-            throw new FileNotFoundException("Multiple items at " + uri);
-        }
-
-        c.moveToFirst();
-        int i = c.getColumnIndex(COLUMN_FILEPATH);
-        String path = (i >= 0 ? c.getString(i) : null);
-        c.close();
-        if (path == null) {
-            throw new FileNotFoundException("Column for path not found.");
-        }
-
+        // URI contains bugreport ID as the last segment, see the matched urls.
+        MetaBugReport bugReport = getBugReportFromUri(uri);
+        File file = new File(
+                FileUtils.getPendingDir(getContext()), fileNameExtractor.apply(bugReport));
+        Log.v(TAG, "Opening file " + file + " with mode " + mode);
         int modeBits = ParcelFileDescriptor.parseMode(mode);
-        try {
-            return ParcelFileDescriptor.open(new File(path), modeBits, mHandler, e -> {
-                if (mode.equals("r")) {
-                    Log.i(TAG, "File " + path + " opened in read-only mode.");
-                    return;
-                } else if (!mode.equals("w")) {
-                    Log.e(TAG, "Only read-only or write-only mode supported; mode=" + mode);
-                    return;
-                }
-                Log.i(TAG, "File " + path + " opened in write-only mode.");
-                Status status;
-                if (e == null) {
-                    // success writing the file. Update the field to indicate bugreport
-                    // is ready for upload
-                    status = JobSchedulingUtils.uploadByDefault() ? Status.STATUS_UPLOAD_PENDING
-                            : Status.STATUS_PENDING_USER_ACTION;
-                } else {
-                    // We log it and ignore it
-                    Log.e(TAG, "Bug report file write failed ", e);
-                    status = Status.STATUS_WRITE_FAILED;
-                }
-                SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
-                ContentValues values = new ContentValues();
-                values.put(COLUMN_STATUS, status.getValue());
-                db.update(BUG_REPORTS_TABLE, values, COLUMN_ID + "=?",
-                        new String[]{ uri.getLastPathSegment() });
-                if (status == Status.STATUS_UPLOAD_PENDING) {
-                    JobSchedulingUtils.scheduleUploadJob(BugStorageProvider.this.getContext());
-                }
-                Log.i(TAG, "Finished adding bugreport " + path + " " + uri);
-            });
-        } catch (IOException e) {
-            // An IOException (for example not being able to open the file, will crash us.
-            // That is ok.
-            throw new RuntimeException(e);
+        return ParcelFileDescriptor.open(file, modeBits);
+    }
+
+    private MetaBugReport getBugReportFromUri(@NonNull Uri uri) {
+        int bugreportId = Integer.parseInt(uri.getLastPathSegment());
+        return BugStorageUtils.findBugReport(getContext(), bugreportId)
+                .orElseThrow(() -> new IllegalArgumentException("No record found for " + uri));
+    }
+
+    /**
+     * Print the Provider's state into the given stream. This gets invoked if
+     * you run "dumpsys activity provider com.android.car.bugreport/.BugStorageProvider".
+     *
+     * @param fd The raw file descriptor that the dump is being sent to.
+     * @param writer The PrintWriter to which you should dump your state.  This will be
+     * closed for you after you return.
+     * @param args additional arguments to the dump request.
+     */
+    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        writer.println("BugStorageProvider:");
+        mConfig.dump(/* prefix= */ "  ", writer);
+    }
+
+    private boolean deleteFilesFor(MetaBugReport bugReport) {
+        if (!Strings.isNullOrEmpty(bugReport.getFilePath())) {
+            // Old bugreports have only filePath.
+            return new File(bugReport.getFilePath()).delete();
         }
+        File pendingDir = FileUtils.getPendingDir(getContext());
+        boolean result = true;
+        if (!Strings.isNullOrEmpty(bugReport.getAudioFileName())) {
+            result = new File(pendingDir, bugReport.getAudioFileName()).delete();
+        }
+        if (!Strings.isNullOrEmpty(bugReport.getBugReportFileName())) {
+            result = result && new File(pendingDir, bugReport.getBugReportFileName()).delete();
+        }
+        return result;
     }
 }
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/BugStorageUtils.java b/tests/BugReportApp/src/com/android/car/bugreport/BugStorageUtils.java
index 34fd3dd..cd0a12e 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/BugStorageUtils.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/BugStorageUtils.java
@@ -15,12 +15,15 @@
  */
 package com.android.car.bugreport;
 
+import static com.android.car.bugreport.BugStorageProvider.COLUMN_AUDIO_FILENAME;
+import static com.android.car.bugreport.BugStorageProvider.COLUMN_BUGREPORT_FILENAME;
 import static com.android.car.bugreport.BugStorageProvider.COLUMN_FILEPATH;
 import static com.android.car.bugreport.BugStorageProvider.COLUMN_ID;
 import static com.android.car.bugreport.BugStorageProvider.COLUMN_STATUS;
 import static com.android.car.bugreport.BugStorageProvider.COLUMN_STATUS_MESSAGE;
 import static com.android.car.bugreport.BugStorageProvider.COLUMN_TIMESTAMP;
 import static com.android.car.bugreport.BugStorageProvider.COLUMN_TITLE;
+import static com.android.car.bugreport.BugStorageProvider.COLUMN_TYPE;
 import static com.android.car.bugreport.BugStorageProvider.COLUMN_USERNAME;
 
 import android.annotation.NonNull;
@@ -30,18 +33,21 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
-import android.text.TextUtils;
 import android.util.Log;
 
 import com.google.api.client.auth.oauth2.TokenResponseException;
+import com.google.common.base.Strings;
 
 import java.io.FileNotFoundException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 
 /**
  * A class that hides details when communicating with the bug storage provider.
@@ -68,6 +74,7 @@
      * @param title     - title of the bug report.
      * @param timestamp - timestamp when the bug report was initiated.
      * @param username  - current user name. Note, it's a user name, not an account name.
+     * @param type      - bug report type, {@link MetaBugReport.BugReportType}.
      * @return an instance of {@link MetaBugReport} that was created in a database.
      */
     @NonNull
@@ -75,68 +82,95 @@
             @NonNull Context context,
             @NonNull String title,
             @NonNull String timestamp,
-            @NonNull String username) {
+            @NonNull String username,
+            @MetaBugReport.BugReportType int type) {
         // insert bug report username and title
         ContentValues values = new ContentValues();
         values.put(COLUMN_TITLE, title);
         values.put(COLUMN_TIMESTAMP, timestamp);
         values.put(COLUMN_USERNAME, username);
+        values.put(COLUMN_TYPE, type);
 
         ContentResolver r = context.getContentResolver();
         Uri uri = r.insert(BugStorageProvider.BUGREPORT_CONTENT_URI, values);
-
-        Cursor c = r.query(uri, new String[]{COLUMN_ID}, null, null, null);
-        int count = (c == null) ? 0 : c.getCount();
-        if (count != 1) {
-            throw new RuntimeException("Could not create a bug report entry.");
-        }
-        c.moveToFirst();
-        int id = getInt(c, COLUMN_ID);
-        c.close();
-        return new MetaBugReport.Builder(id, timestamp)
-                .setTitle(title)
-                .setUserName(username)
-                .build();
+        return findBugReport(context, Integer.parseInt(uri.getLastPathSegment())).get();
     }
 
-    /**
-     * Returns a file stream to write the zipped file to. The content provider listens for file
-     * descriptor to be closed, and as soon as it is closed, {@link BugStorageProvider} schedules
-     * it for upload.
-     *
-     * @param context       - an application context.
-     * @param metaBugReport - a bug report.
-     * @return a file descriptor where a zip content should be written.
-     */
+    /** Returns an output stream to write the zipped file to. */
     @NonNull
-    static OutputStream openBugReportFile(
+    static OutputStream openBugReportFileToWrite(
             @NonNull Context context, @NonNull MetaBugReport metaBugReport)
             throws FileNotFoundException {
         ContentResolver r = context.getContentResolver();
+        return r.openOutputStream(BugStorageProvider.buildUriWithSegment(
+                metaBugReport.getId(), BugStorageProvider.URL_SEGMENT_OPEN_BUGREPORT_FILE));
+    }
 
-        // Write the file. When file is closed, bug report record status
-        // will automatically be made ready for uploading.
-        return r.openOutputStream(BugStorageProvider.buildUriWithBugId(metaBugReport.getId()));
+    /** Returns an output stream to write the audio message file to. */
+    static OutputStream openAudioMessageFileToWrite(
+            @NonNull Context context, @NonNull MetaBugReport metaBugReport)
+            throws FileNotFoundException {
+        ContentResolver r = context.getContentResolver();
+        return r.openOutputStream(BugStorageProvider.buildUriWithSegment(
+                metaBugReport.getId(), BugStorageProvider.URL_SEGMENT_OPEN_AUDIO_FILE));
     }
 
     /**
-     * Deletes {@link MetaBugReport} record from a local database. Returns true if the record was
-     * deleted.
+     * Returns an input stream to read the final zip file from.
+     *
+     * <p>NOTE: This is the old way of storing final zipped bugreport. See
+     * {@link BugStorageProvider#URL_SEGMENT_OPEN_FILE} for more info.
+     */
+    static InputStream openFileToRead(Context context, MetaBugReport bug)
+            throws FileNotFoundException {
+        return context.getContentResolver().openInputStream(
+                BugStorageProvider.buildUriWithSegment(
+                        bug.getId(), BugStorageProvider.URL_SEGMENT_OPEN_FILE));
+    }
+
+    /** Returns an input stream to read the bug report zip file from. */
+    static InputStream openBugReportFileToRead(Context context, MetaBugReport bug)
+            throws FileNotFoundException {
+        return context.getContentResolver().openInputStream(
+                BugStorageProvider.buildUriWithSegment(
+                        bug.getId(), BugStorageProvider.URL_SEGMENT_OPEN_BUGREPORT_FILE));
+    }
+
+    /** Returns an input stream to read the audio file from. */
+    static InputStream openAudioFileToRead(Context context, MetaBugReport bug)
+            throws FileNotFoundException {
+        return context.getContentResolver().openInputStream(
+                BugStorageProvider.buildUriWithSegment(
+                        bug.getId(), BugStorageProvider.URL_SEGMENT_OPEN_AUDIO_FILE));
+    }
+
+    /**
+     * Deletes {@link MetaBugReport} record from a local database and deletes the associated file.
+     *
+     * <p>WARNING: destructive operation.
      *
      * @param context     - an application context.
      * @param bugReportId - a bug report id.
      * @return true if the record was deleted.
      */
-    static boolean deleteBugReport(@NonNull Context context, int bugReportId) {
+    static boolean completeDeleteBugReport(@NonNull Context context, int bugReportId) {
         ContentResolver r = context.getContentResolver();
-        return r.delete(BugStorageProvider.buildUriWithBugId(bugReportId), null, null) == 1;
+        return r.delete(BugStorageProvider.buildUriWithSegment(
+                bugReportId, BugStorageProvider.URL_SEGMENT_COMPLETE_DELETE), null, null) == 1;
+    }
+
+    /** Deletes all files for given bugreport id; doesn't delete sqlite3 record. */
+    static boolean deleteBugReportFiles(@NonNull Context context, int bugReportId) {
+        ContentResolver r = context.getContentResolver();
+        return r.delete(BugStorageProvider.buildUriWithSegment(
+                bugReportId, BugStorageProvider.URL_SEGMENT_DELETE_FILES), null, null) == 1;
     }
 
     /**
-     * Returns bugreports that are waiting to be uploaded.
+     * Returns all the bugreports that are waiting to be uploaded.
      */
     @NonNull
-    public static List<MetaBugReport> getPendingBugReports(@NonNull Context context) {
+    public static List<MetaBugReport> getUploadPendingBugReports(@NonNull Context context) {
         String selection = COLUMN_STATUS + "=?";
         String[] selectionArgs = new String[]{
                 Integer.toString(Status.STATUS_UPLOAD_PENDING.getValue())};
@@ -152,17 +186,32 @@
         return getBugreports(context, null, null, COLUMN_ID + " DESC");
     }
 
-    private static List<MetaBugReport> getBugreports(Context context, String selection,
-            String[] selectionArgs, String order) {
+    /** Returns {@link MetaBugReport} for given bugreport id. */
+    static Optional<MetaBugReport> findBugReport(Context context, int bugreportId) {
+        String selection = COLUMN_ID + " = ?";
+        String[] selectionArgs = new String[]{Integer.toString(bugreportId)};
+        List<MetaBugReport> bugs = BugStorageUtils.getBugreports(
+                context, selection, selectionArgs, null);
+        if (bugs.isEmpty()) {
+            return Optional.empty();
+        }
+        return Optional.of(bugs.get(0));
+    }
+
+    private static List<MetaBugReport> getBugreports(
+            Context context, String selection, String[] selectionArgs, String order) {
         ArrayList<MetaBugReport> bugReports = new ArrayList<>();
         String[] projection = {
                 COLUMN_ID,
                 COLUMN_USERNAME,
                 COLUMN_TITLE,
                 COLUMN_TIMESTAMP,
+                COLUMN_BUGREPORT_FILENAME,
+                COLUMN_AUDIO_FILENAME,
                 COLUMN_FILEPATH,
                 COLUMN_STATUS,
-                COLUMN_STATUS_MESSAGE};
+                COLUMN_STATUS_MESSAGE,
+                COLUMN_TYPE};
         ContentResolver r = context.getContentResolver();
         Cursor c = r.query(BugStorageProvider.BUGREPORT_CONTENT_URI, projection,
                 selection, selectionArgs, order);
@@ -171,13 +220,17 @@
 
         if (count > 0) c.moveToFirst();
         for (int i = 0; i < count; i++) {
-            MetaBugReport meta = new MetaBugReport.Builder(getInt(c, COLUMN_ID),
-                    getString(c, COLUMN_TIMESTAMP))
+            MetaBugReport meta = MetaBugReport.builder()
+                    .setId(getInt(c, COLUMN_ID))
+                    .setTimestamp(getString(c, COLUMN_TIMESTAMP))
                     .setUserName(getString(c, COLUMN_USERNAME))
                     .setTitle(getString(c, COLUMN_TITLE))
-                    .setFilepath(getString(c, COLUMN_FILEPATH))
+                    .setBugReportFileName(getString(c, COLUMN_BUGREPORT_FILENAME))
+                    .setAudioFileName(getString(c, COLUMN_AUDIO_FILENAME))
+                    .setFilePath(getString(c, COLUMN_FILEPATH))
                     .setStatus(getInt(c, COLUMN_STATUS))
                     .setStatusMessage(getString(c, COLUMN_STATUS_MESSAGE))
+                    .setType(getInt(c, COLUMN_TYPE))
                     .build();
             bugReports.add(meta);
             c.moveToNext();
@@ -207,7 +260,7 @@
             Log.w(TAG, "Column " + colName + " not found.");
             return "";
         }
-        return c.getString(colIndex);
+        return Strings.nullToEmpty(c.getString(colIndex));
     }
 
     /**
@@ -219,13 +272,6 @@
     }
 
     /**
-     * Sets bugreport status to upload failed.
-     */
-    public static void setUploadFailed(Context context, MetaBugReport bugReport, Exception e) {
-        setBugReportStatus(context, bugReport, Status.STATUS_UPLOAD_FAILED, getRootCauseMessage(e));
-    }
-
-    /**
      * Sets bugreport status pending, and update the message to last exception message.
      *
      * <p>Used when a transient error has occurred.
@@ -244,6 +290,22 @@
         setBugReportStatus(context, bugReport, Status.STATUS_UPLOAD_PENDING, msg);
     }
 
+    /**
+     * Sets {@link MetaBugReport} status {@link Status#STATUS_EXPIRED}.
+     * Deletes the associated zip file from disk.
+     *
+     * @return true if succeeded.
+     */
+    static boolean expireBugReport(@NonNull Context context,
+            @NonNull MetaBugReport metaBugReport, @NonNull Instant expiredAt) {
+        metaBugReport = setBugReportStatus(
+                context, metaBugReport, Status.STATUS_EXPIRED, "Expired on " + expiredAt);
+        if (metaBugReport.getStatus() != Status.STATUS_EXPIRED.getValue()) {
+            return false;
+        }
+        return deleteBugReportFiles(context, metaBugReport.getId());
+    }
+
     /** Gets the root cause of the error. */
     @NonNull
     private static String getRootCauseMessage(@Nullable Throwable t) {
@@ -260,18 +322,52 @@
         return t.getMessage();
     }
 
-    /** Updates bug report record status. */
-    static void setBugReportStatus(
+    /**
+     * Updates bug report record status.
+     *
+     * <p>NOTE: When status is set to STATUS_UPLOAD_PENDING, BugStorageProvider automatically
+     * schedules the bugreport to be uploaded.
+     *
+     * @return Updated {@link MetaBugReport}.
+     */
+    static MetaBugReport setBugReportStatus(
             Context context, MetaBugReport bugReport, Status status, String message) {
-        // update status
+        return update(context, bugReport.toBuilder()
+                .setStatus(status.getValue())
+                .setStatusMessage(message)
+                .build());
+    }
+
+    /**
+     * Updates bug report record status.
+     *
+     * <p>NOTE: When status is set to STATUS_UPLOAD_PENDING, BugStorageProvider automatically
+     * schedules the bugreport to be uploaded.
+     *
+     * @return Updated {@link MetaBugReport}.
+     */
+    static MetaBugReport setBugReportStatus(
+            Context context, MetaBugReport bugReport, Status status, Exception e) {
+        return setBugReportStatus(context, bugReport, status, getRootCauseMessage(e));
+    }
+
+    /**
+     * Updates the bugreport and returns the updated version.
+     *
+     * <p>NOTE: doesn't update all the fields.
+     */
+    static MetaBugReport update(Context context, MetaBugReport bugReport) {
+        // Update only necessary fields.
         ContentValues values = new ContentValues();
-        values.put(COLUMN_STATUS, status.getValue());
-        if (!TextUtils.isEmpty(message)) {
-            values.put(COLUMN_STATUS_MESSAGE, message);
-        }
+        values.put(COLUMN_BUGREPORT_FILENAME, bugReport.getBugReportFileName());
+        values.put(COLUMN_AUDIO_FILENAME, bugReport.getAudioFileName());
+        values.put(COLUMN_STATUS, bugReport.getStatus());
+        values.put(COLUMN_STATUS_MESSAGE, bugReport.getStatusMessage());
         String where = COLUMN_ID + "=" + bugReport.getId();
-        context.getContentResolver().update(BugStorageProvider.BUGREPORT_CONTENT_URI, values,
-                where, null);
+        context.getContentResolver().update(
+                BugStorageProvider.BUGREPORT_CONTENT_URI, values, where, null);
+        return findBugReport(context, bugReport.getId()).orElseThrow(
+                () -> new IllegalArgumentException("Bug " + bugReport.getId() + " not found"));
     }
 
     private static String currentTimestamp() {
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/Config.java b/tests/BugReportApp/src/com/android/car/bugreport/Config.java
new file mode 100644
index 0000000..db1e03c
--- /dev/null
+++ b/tests/BugReportApp/src/com/android/car/bugreport/Config.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2019 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.bugreport;
+
+import android.app.ActivityThread;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.provider.DeviceConfig;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.PrintWriter;
+
+/**
+ * Contains config for BugReport App.
+ *
+ * <p>The config is kept synchronized with {@code car} namespace. It's not defined in
+ * {@link DeviceConfig}.
+ *
+ * <ul>To get/set the flags via adb:
+ *   <li>{@code adb shell device_config get car bugreport_upload_destination}
+ *   <li>{@code adb shell device_config put car bugreport_upload_destination gcs}
+ *   <li>{@code adb shell device_config delete car bugreport_upload_destination}
+ * </ul>
+ */
+final class Config {
+    private static final String TAG = Config.class.getSimpleName();
+
+    /**
+     * Namespace for all Android Automotive related features.
+     *
+     * <p>In the future it will move to {@code DeviceConfig#NAMESPACE_CAR}.
+     */
+    private static final String NAMESPACE_CAR = "car";
+
+    /**
+     * A string flag, can be one of {@code null} or {@link #UPLOAD_DESTINATION_GCS}.
+     */
+    private static final String KEY_BUGREPORT_UPLOAD_DESTINATION = "bugreport_upload_destination";
+
+    /**
+     * A value for {@link #KEY_BUGREPORT_UPLOAD_DESTINATION}.
+     *
+     * Upload bugreports to GCS. Only works in {@code userdebug} or {@code eng} builds.
+     */
+    private static final String UPLOAD_DESTINATION_GCS = "gcs";
+
+    /**
+     * A system property to force enable the app bypassing the {@code userdebug/eng} build check.
+     */
+    private static final String PROP_FORCE_ENABLE = "android.car.bugreport.force_enable";
+
+    /**
+     * Temporary flag to retain the old behavior.
+     *
+     * Default is {@code true}.
+     *
+     * TODO(b/143183993): Disable auto-upload to GCS after testing DeviceConfig.
+     */
+    private static final String ENABLE_AUTO_UPLOAD = "android.car.bugreport.enableautoupload";
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private String mUploadDestination = null;
+
+    void start() {
+        DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_CAR,
+                ActivityThread.currentApplication().getMainExecutor(), this::onPropertiesChanged);
+        updateConstants();
+    }
+
+    private void onPropertiesChanged(DeviceConfig.Properties properties) {
+        if (properties.getKeyset().contains(KEY_BUGREPORT_UPLOAD_DESTINATION)) {
+            updateConstants();
+        }
+    }
+
+    /** Returns true if bugreport app is enabled for this device. */
+    static boolean isBugReportEnabled() {
+        return Build.IS_DEBUGGABLE || SystemProperties.getBoolean(PROP_FORCE_ENABLE, false);
+    }
+
+    /** If new bugreports should be scheduled for uploading. */
+    boolean getAutoUpload() {
+        if (isTempForceAutoUploadGcsEnabled()) {
+            Log.d(TAG, "Enabling auto-upload because ENABLE_AUTO_UPLOAD is true");
+            return true;
+        }
+        // TODO(b/144851443): Enable auto-upload only if upload destination is Gcs until
+        //                    we create a way to allow implementing OEMs custom upload logic.
+        return isUploadDestinationGcs();
+    }
+
+    /**
+     * Returns {@link true} if bugreport upload destination is GCS.
+     */
+    boolean isUploadDestinationGcs() {
+        if (isTempForceAutoUploadGcsEnabled()) {
+            Log.d(TAG, "Setting upload dest to GCS ENABLE_AUTO_UPLOAD is true");
+            return true;
+        }
+        // NOTE: enable it only for userdebug builds, unless it's force enabled using a system
+        //       property.
+        return UPLOAD_DESTINATION_GCS.equals(getUploadDestination()) && Build.IS_DEBUGGABLE;
+    }
+
+    private static boolean isTempForceAutoUploadGcsEnabled() {
+        return SystemProperties.getBoolean(ENABLE_AUTO_UPLOAD, /* def= */ true);
+    }
+
+    /**
+     * Returns value of a flag {@link #KEY_BUGREPORT_UPLOAD_DESTINATION}.
+     */
+    private String getUploadDestination() {
+        synchronized (mLock) {
+            return mUploadDestination;
+        }
+    }
+
+    private void updateConstants() {
+        synchronized (mLock) {
+            mUploadDestination = DeviceConfig.getString(NAMESPACE_CAR,
+                    KEY_BUGREPORT_UPLOAD_DESTINATION, /* defaultValue= */ null);
+        }
+    }
+
+    void dump(String prefix, PrintWriter pw) {
+        pw.println(prefix + "car.bugreport.Config:");
+
+        pw.print(prefix + "  ");
+        pw.print("getAutoUpload");
+        pw.print("=");
+        pw.println(getAutoUpload() ? "true" : "false");
+
+        pw.print(prefix + "  ");
+        pw.print("getUploadDestination");
+        pw.print("=");
+        pw.println(getUploadDestination());
+
+        pw.print(prefix + "  ");
+        pw.print("isUploadDestinationGcs");
+        pw.print("=");
+        pw.println(isUploadDestinationGcs());
+    }
+}
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/FileUtils.java b/tests/BugReportApp/src/com/android/car/bugreport/FileUtils.java
index 0f36859..bf12aa7 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/FileUtils.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/FileUtils.java
@@ -17,6 +17,8 @@
 
 import android.content.Context;
 
+import com.google.common.base.Preconditions;
+
 import java.io.File;
 
 /**
@@ -34,14 +36,16 @@
  */
 public class FileUtils {
     private static final String PREFIX = "bugreport-";
-    // bug reports waiting to be uploaded
+    /** A directory under the system user; contains bugreport zip files and audio files. */
     private static final String PENDING_DIR = "bug_reports_pending";
-    // temporary directory, used for zipping files
+    // Temporary directory under the current user, used for zipping files.
     private static final String TEMP_DIR = "bug_reports_temp";
 
     private static final String FS = "@";
 
-    private static File getPendingDir(Context context) {
+    static File getPendingDir(Context context) {
+        Preconditions.checkArgument(context.getUser().isSystem(),
+                "Must be called from the system user.");
         File dir = new File(context.getDataDir(), PENDING_DIR);
         dir.mkdirs();
         return dir;
@@ -62,15 +66,38 @@
      * single file.
      */
     static File getTempDir(Context context, String timestamp) {
+        Preconditions.checkArgument(!context.getUser().isSystem(),
+                "Must be called from the current user.");
         return new File(context.getDataDir(), TEMP_DIR + "/" + timestamp);
     }
 
     /**
-     * Returns zip file directory with the given timestamp and ldap
+     * Constructs a bugreport zip file name.
+     *
+     * <p>Add lookup code to the filename to allow matching audio file and bugreport file in USB.
      */
-    static File getZipFile(Context context, String timestamp, String ldap) {
-        File zipdir = getPendingDir(context);
-        return new File(zipdir, PREFIX + ldap + FS + timestamp + ".zip");
+    static String getZipFileName(MetaBugReport bug) {
+        String lookupCode = extractLookupCode(bug);
+        return PREFIX + bug.getUserName() + FS + bug.getTimestamp() + "-" + lookupCode + ".zip";
+    }
+
+    /**
+     * Constructs a audio message file name.
+     *
+     * <p>Add lookup code to the filename to allow matching audio file and bugreport file in USB.
+     *
+     * @param timestamp - current timestamp, when audio was created.
+     * @param bug       - a bug report.
+     */
+    static String getAudioFileName(String timestamp, MetaBugReport bug) {
+        String lookupCode = extractLookupCode(bug);
+        return PREFIX + bug.getUserName() + FS + timestamp + "-" + lookupCode + "-message.3gp";
+    }
+
+    private static String extractLookupCode(MetaBugReport bug) {
+        Preconditions.checkArgument(bug.getTitle().startsWith("["),
+                "Invalid bugreport title, doesn't contain lookup code. ");
+        return bug.getTitle().substring(1, BugReportActivity.LOOKUP_STRING_LENGTH + 1);
     }
 
     /**
@@ -99,7 +126,6 @@
         return new File(getTempDir(context, timestamp), name);
     }
 
-
     /**
      * Deletes a directory and its contents recursively
      *
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/JobSchedulingUtils.java b/tests/BugReportApp/src/com/android/car/bugreport/JobSchedulingUtils.java
index 922c910..ec09b1f 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/JobSchedulingUtils.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/JobSchedulingUtils.java
@@ -19,7 +19,6 @@
 import android.app.job.JobScheduler;
 import android.content.ComponentName;
 import android.content.Context;
-import android.os.SystemProperties;
 import android.util.Log;
 
 /**
@@ -32,15 +31,7 @@
     private static final int RETRY_DELAY_IN_MS = 5_000;
 
     /**
-     * The system property to disable auto-upload when bug reports are collected. When auto-upload
-     * is disabled, the app waits for user action on collected bug reports: user can either
-     * upload to Google Cloud or copy to flash drive.
-     */
-    private static final String PROP_DISABLE_AUTO_UPLOAD =
-            "android.car.bugreport.disableautoupload";
-
-    /**
-     * Schedules an upload job under the current user.
+     * Schedules {@link UploadJob} under the current user.
      *
      * <p>Make sure this method is called under the primary user.
      *
@@ -72,15 +63,4 @@
                 .setBackoffCriteria(RETRY_DELAY_IN_MS, JobInfo.BACKOFF_POLICY_LINEAR)
                 .build());
     }
-
-    /**
-     * Returns true if collected bugreports should be uploaded automatically.
-     *
-     * <p>If it returns false, the app maps to an alternative workflow that requires user action
-     * after bugreport is successfully written. A user then has an option to choose whether to
-     * upload the bugreport or copy it to an external drive.
-     */
-    static boolean uploadByDefault() {
-        return !SystemProperties.getBoolean(PROP_DISABLE_AUTO_UPLOAD, false);
-    }
 }
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/MetaBugReport.java b/tests/BugReportApp/src/com/android/car/bugreport/MetaBugReport.java
index eeb491f..e458e22 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/MetaBugReport.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/MetaBugReport.java
@@ -15,77 +15,95 @@
  */
 package com.android.car.bugreport;
 
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-/** Represents the information that a bugreport can contain. */
-public final class MetaBugReport implements Parcelable {
-    private final int mId;
-    private final String mTimestamp;
-    private final String mTitle;
-    private final String mUsername;
-    private final String mFilePath;
-    private final int mStatus;
-    private final String mStatusMessage;
+import com.google.auto.value.AutoValue;
 
-    private MetaBugReport(Builder builder) {
-        mId = builder.mId;
-        mTimestamp = builder.mTimestamp;
-        mTitle = builder.mTitle;
-        mUsername = builder.mUsername;
-        mFilePath = builder.mFilePath;
-        mStatus = builder.mStatus;
-        mStatusMessage = builder.mStatusMessage;
-    }
+import java.lang.annotation.Retention;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/** Represents the information that a bugreport can contain. */
+@AutoValue
+abstract class MetaBugReport implements Parcelable {
+
+    private static final DateFormat BUG_REPORT_TIMESTAMP_DATE_FORMAT =
+            new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
+
+    /** The app records audio message when initiated. Can change audio state. */
+    static final int TYPE_INTERACTIVE = 0;
+
+    /**
+     * The app doesn't show dialog and doesn't record audio when initiated. It allows user to
+     * add audio message when bugreport is collected.
+     */
+    static final int TYPE_SILENT = 1;
+
+    /** Annotation for bug report types. */
+    @Retention(SOURCE)
+    @IntDef({TYPE_INTERACTIVE, TYPE_SILENT})
+    @interface BugReportType {};
 
     /**
      * @return Id of the bug report. Bug report id monotonically increases and is unique.
      */
-    public int getId() {
-        return mId;
-    }
+    public abstract int getId();
 
     /**
      * @return Username (LDAP) that created this bugreport
      */
-    public String getUsername() {
-        return mUsername == null ? "" : mUsername;
-    }
+    public abstract String getUserName();
 
     /**
      * @return Title of the bug.
      */
-    public String getTitle() {
-        return mTitle == null ? "" : mTitle;
-    }
+    public abstract String getTitle();
 
     /**
      * @return Timestamp when the bug report is initialized.
      */
-    public String getTimestamp() {
-        return mTimestamp == null ? "" : mTimestamp;
-    }
+    public abstract String getTimestamp();
 
     /**
-     * @return path to the zip file
+     * @return path to the zip file stored under the system user.
+     *
+     * <p>NOTE: This is the old way of storing final zipped bugreport. See
+     * {@link BugStorageProvider#URL_SEGMENT_OPEN_FILE} for more info.
      */
-    public String getFilePath() {
-        return mFilePath == null ? "" : mFilePath;
-    }
+    public abstract String getFilePath();
 
     /**
-     * @return Status of the bug upload.
+     * @return filename of the bug report zip file stored under the system user.
      */
-    public int getStatus() {
-        return mStatus;
-    }
+    public abstract String getBugReportFileName();
+
+    /**
+     * @return filename of the audio message file stored under the system user.
+     */
+    public abstract String getAudioFileName();
+
+    /**
+     * @return {@link Status} of the bug upload.
+     */
+    public abstract int getStatus();
 
     /**
      * @return StatusMessage of the bug upload.
      */
-    public String getStatusMessage() {
-        return mStatusMessage == null ? "" : mStatusMessage;
-    }
+    public abstract String getStatusMessage();
+
+    /**
+     * @return {@link BugReportType}.
+     */
+    public abstract int getType();
+
+    /** @return {@link Builder} from the meta bug report. */
+    public abstract Builder toBuilder();
 
     @Override
     public int describeContents() {
@@ -94,13 +112,33 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mId);
-        dest.writeString(mTimestamp);
-        dest.writeString(mTitle);
-        dest.writeString(mUsername);
-        dest.writeString(mFilePath);
-        dest.writeInt(mStatus);
-        dest.writeString(mStatusMessage);
+        dest.writeInt(getId());
+        dest.writeString(getTimestamp());
+        dest.writeString(getTitle());
+        dest.writeString(getUserName());
+        dest.writeString(getFilePath());
+        dest.writeString(getBugReportFileName());
+        dest.writeString(getAudioFileName());
+        dest.writeInt(getStatus());
+        dest.writeString(getStatusMessage());
+        dest.writeInt(getType());
+    }
+
+    /** Converts {@link Date} to bugreport timestamp. */
+    static String toBugReportTimestamp(Date date) {
+        return BUG_REPORT_TIMESTAMP_DATE_FORMAT.format(date);
+    }
+
+    /** Creates a {@link Builder} with default, non-null values. */
+    static Builder builder() {
+        return new AutoValue_MetaBugReport.Builder()
+                .setTimestamp("")
+                .setFilePath("")
+                .setBugReportFileName("")
+                .setAudioFileName("")
+                .setStatusMessage("")
+                .setTitle("")
+                .setUserName("");
     }
 
     /** A creator that's used by Parcelable. */
@@ -112,14 +150,22 @@
                     String title = in.readString();
                     String username = in.readString();
                     String filePath = in.readString();
+                    String bugReportFileName = in.readString();
+                    String audioFileName = in.readString();
                     int status = in.readInt();
                     String statusMessage = in.readString();
-                    return new Builder(id, timestamp)
+                    int type = in.readInt();
+                    return MetaBugReport.builder()
+                            .setId(id)
+                            .setTimestamp(timestamp)
                             .setTitle(title)
                             .setUserName(username)
-                            .setFilepath(filePath)
+                            .setFilePath(filePath)
+                            .setBugReportFileName(bugReportFileName)
+                            .setAudioFileName(audioFileName)
                             .setStatus(status)
                             .setStatusMessage(statusMessage)
+                            .setType(type)
                             .build();
                 }
 
@@ -129,59 +175,38 @@
             };
 
     /** Builder for MetaBugReport. */
-    public static class Builder {
-        private final int mId;
-        private final String mTimestamp;
-        private String mTitle;
-        private String mUsername;
-        private String mFilePath;
-        private int mStatus;
-        private String mStatusMessage;
+    @AutoValue.Builder
+    abstract static class Builder {
+        /** Sets id. */
+        public abstract Builder setId(int id);
 
-        /**
-         * Initializes MetaBugReport.Builder.
-         *
-         * @param id        - mandatory bugreport id
-         * @param timestamp - mandatory timestamp when bugreport initialized.
-         */
-        public Builder(int id, String timestamp) {
-            mId = id;
-            mTimestamp = timestamp;
-        }
+        /** Sets timestamp. */
+        public abstract Builder setTimestamp(String timestamp);
 
         /** Sets title. */
-        public Builder setTitle(String title) {
-            mTitle = title;
-            return this;
-        }
+        public abstract Builder setTitle(String title);
 
         /** Sets username. */
-        public Builder setUserName(String username) {
-            mUsername = username;
-            return this;
-        }
+        public abstract Builder setUserName(String username);
 
         /** Sets filepath. */
-        public Builder setFilepath(String filePath) {
-            mFilePath = filePath;
-            return this;
-        }
+        public abstract Builder setFilePath(String filePath);
 
-        /** Sets status. */
-        public Builder setStatus(int status) {
-            mStatus = status;
-            return this;
-        }
+        /** Sets bugReportFileName. */
+        public abstract Builder setBugReportFileName(String bugReportFileName);
+
+        /** Sets audioFileName. */
+        public abstract Builder setAudioFileName(String audioFileName);
+
+        /** Sets {@link Status}. */
+        public abstract Builder setStatus(int status);
 
         /** Sets statusmessage. */
-        public Builder setStatusMessage(String statusMessage) {
-            mStatusMessage = statusMessage;
-            return this;
-        }
+        public abstract Builder setStatusMessage(String statusMessage);
 
-        /** Returns a {@link MetaBugReport}. */
-        public MetaBugReport build() {
-            return new MetaBugReport(this);
-        }
+        /** Sets the {@link BugReportType}. */
+        public abstract Builder setType(@BugReportType int type);
+
+        public abstract MetaBugReport build();
     }
 }
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/SimpleUploaderAsyncTask.java b/tests/BugReportApp/src/com/android/car/bugreport/SimpleUploaderAsyncTask.java
index 7cca613..0cc5c1a 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/SimpleUploaderAsyncTask.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/SimpleUploaderAsyncTask.java
@@ -29,18 +29,24 @@
 import com.google.api.client.json.jackson2.JacksonFactory;
 import com.google.api.services.storage.Storage;
 import com.google.api.services.storage.model.StorageObject;
+import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
 
+import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.zip.ZipOutputStream;
 
 /**
- * Uploads a file to GCS using a simple (no-multipart / no-resume) upload policy.
+ * Uploads a bugreport files to GCS using a simple (no-multipart / no-resume) upload policy.
+ *
+ * <p>It merges bugreport zip file and audio file into one final zip file and uploads it.
  *
  * <p>Please see {@code res/values/configs.xml} and {@code res/raw/gcs_credentials.json} for the
  * configuration.
@@ -113,14 +119,51 @@
         Storage storage = new Storage.Builder(httpTransport, jsonFactory, credential)
                 .setApplicationName("Bugreportupload/1.0").build();
 
-        File bugReportFile = new File(bugReport.getFilePath());
-        String fileName = bugReportFile.getName();
-        try (FileInputStream inputStream = new FileInputStream(bugReportFile)) {
-            StorageObject object = uploadSimple(storage, bugReport, fileName, inputStream);
-            Log.v(TAG, "finished uploading object " + object.getName() + " file " + fileName);
+        File tmpBugReportFile = zipBugReportFiles(bugReport);
+        Log.d(TAG, "Uploading file " + tmpBugReportFile);
+        try {
+            // Upload filename is bugreport filename, although, now it contains the audio message.
+            String fileName = bugReport.getBugReportFileName();
+            try (FileInputStream inputStream = new FileInputStream(tmpBugReportFile)) {
+                StorageObject object = uploadSimple(storage, bugReport, fileName, inputStream);
+                Log.v(TAG, "finished uploading object " + object.getName() + " file " + fileName);
+            }
+            File pendingDir = FileUtils.getPendingDir(mContext);
+            // Delete only after successful upload; the files are needed for retry.
+            if (!Strings.isNullOrEmpty(bugReport.getAudioFileName())) {
+                Log.v(TAG, "Deleting file " + bugReport.getAudioFileName());
+                new File(pendingDir, bugReport.getAudioFileName()).delete();
+            }
+            if (!Strings.isNullOrEmpty(bugReport.getBugReportFileName())) {
+                Log.v(TAG, "Deleting file " + bugReport.getBugReportFileName());
+                new File(pendingDir, bugReport.getBugReportFileName()).delete();
+            }
+        } finally {
+            // Delete the temp file if it's not a MetaBugReport#getFilePath, because it's needed
+            // for retry.
+            if (Strings.isNullOrEmpty(bugReport.getFilePath())) {
+                Log.v(TAG, "Deleting file " + tmpBugReportFile);
+                tmpBugReportFile.delete();
+            }
         }
-        Log.v(TAG, "Deleting file " + fileName);
-        bugReportFile.delete();
+    }
+
+    private File zipBugReportFiles(MetaBugReport bugReport) throws IOException {
+        if (!Strings.isNullOrEmpty(bugReport.getFilePath())) {
+            // Old bugreports still have this field.
+            return new File(bugReport.getFilePath());
+        }
+        File finalZipFile =
+                File.createTempFile("bugreport", ".zip", mContext.getCacheDir());
+        File pendingDir = FileUtils.getPendingDir(mContext);
+        try (ZipOutputStream zipStream = new ZipOutputStream(
+                new BufferedOutputStream(new FileOutputStream(finalZipFile)))) {
+            ZipUtils.extractZippedFileToZipStream(
+                    new File(pendingDir, bugReport.getBugReportFileName()), zipStream);
+            ZipUtils.addFileToZipStream(
+                    new File(pendingDir, bugReport.getAudioFileName()), zipStream);
+        }
+        return finalZipFile;
     }
 
     @Override
@@ -131,7 +174,7 @@
     /** Returns true is there are more files to upload. */
     @Override
     protected Boolean doInBackground(Void... voids) {
-        List<MetaBugReport> bugReports = BugStorageUtils.getPendingBugReports(mContext);
+        List<MetaBugReport> bugReports = BugStorageUtils.getUploadPendingBugReports(mContext);
 
         for (MetaBugReport bugReport : bugReports) {
             try {
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/StartUpBootReceiver.java b/tests/BugReportApp/src/com/android/car/bugreport/StartUpBootReceiver.java
index 07b5843..7528c21 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/StartUpBootReceiver.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/StartUpBootReceiver.java
@@ -33,6 +33,9 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
+        if (!Config.isBugReportEnabled()) {
+            return;
+        }
         // Run it only once for the system user (u0) and ignore for other users.
         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         if (!userManager.isSystemUser()) {
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/Status.java b/tests/BugReportApp/src/com/android/car/bugreport/Status.java
index 2c1e6dc..84250bb 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/Status.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/Status.java
@@ -42,7 +42,16 @@
     STATUS_MOVE_SUCCESSFUL(7),
 
     // Bugreport move has failed.
-    STATUS_MOVE_FAILED(8);
+    STATUS_MOVE_FAILED(8),
+
+    // Bugreport is moving to USB drive.
+    STATUS_MOVE_IN_PROGRESS(9),
+
+    // Bugreport is expired. Associated file is deleted from the disk.
+    STATUS_EXPIRED(10),
+
+    // Bugreport needs audio message.
+    STATUS_AUDIO_PENDING(11);
 
     private final int mValue;
 
@@ -76,6 +85,12 @@
                 return "Move successful";
             case 8:
                 return "Move failed";
+            case 9:
+                return "Move in progress";
+            case 10:
+                return "Expired";
+            case 11:
+                return "Audio message pending";
         }
         return "unknown";
     }
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/UploadJob.java b/tests/BugReportApp/src/com/android/car/bugreport/UploadJob.java
index c6d7ec8..a0b9cec 100644
--- a/tests/BugReportApp/src/com/android/car/bugreport/UploadJob.java
+++ b/tests/BugReportApp/src/com/android/car/bugreport/UploadJob.java
@@ -27,6 +27,9 @@
 
     @Override
     public boolean onStartJob(final JobParameters jobParameters) {
+        if (!Config.isBugReportEnabled()) {
+            return false;
+        }
         Log.v(TAG, "Starting upload job");
         mUploader = new SimpleUploaderAsyncTask(
                 this, reschedule -> jobFinished(jobParameters, reschedule));
diff --git a/tests/BugReportApp/src/com/android/car/bugreport/ZipUtils.java b/tests/BugReportApp/src/com/android/car/bugreport/ZipUtils.java
new file mode 100644
index 0000000..93dad40
--- /dev/null
+++ b/tests/BugReportApp/src/com/android/car/bugreport/ZipUtils.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.bugreport;
+
+import android.util.Log;
+
+import com.google.common.io.ByteStreams;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+/** Zip utility functions. */
+final class ZipUtils {
+    private static final String TAG = ZipUtils.class.getSimpleName();
+
+    /** Extracts the contents of a zip file to the zip output stream. */
+    static void extractZippedFileToZipStream(File file, ZipOutputStream zipStream) {
+        if (!file.exists()) {
+            Log.w(TAG, "File " + file + " not found");
+            return;
+        }
+        if (file.length() == 0) {
+            // If there were issues with reading from dumpstate socket, the dumpstate zip
+            // file still might be available in
+            // /data/user_de/0/com.android.shell/files/bugreports/.
+            Log.w(TAG, "Zip file " + file.getName() + " is empty, skipping.");
+            return;
+        }
+        try (ZipFile zipFile = new ZipFile(file)) {
+            Enumeration<? extends ZipEntry> entries = zipFile.entries();
+            while (entries.hasMoreElements()) {
+                ZipEntry entry = entries.nextElement();
+                try (InputStream stream = zipFile.getInputStream(entry)) {
+                    writeInputStreamToZipStream(entry.getName(), stream, zipStream);
+                }
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to add " + file + " to zip", e);
+        }
+    }
+
+    /** Adds a file to the zip output stream. */
+    static void addFileToZipStream(File file, ZipOutputStream zipStream) {
+        if (!file.exists()) {
+            Log.w(TAG, "File " + file + " not found");
+            return;
+        }
+        if (file.length() == 0) {
+            Log.w(TAG, "File " + file.getName() + " is empty, skipping.");
+            return;
+        }
+        try (FileInputStream audioInput = new FileInputStream(file)) {
+            writeInputStreamToZipStream(file.getName(), audioInput, zipStream);
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to add " + file + "to the final zip");
+        }
+    }
+
+    private static void writeInputStreamToZipStream(
+            String filename, InputStream input, ZipOutputStream zipStream) throws IOException {
+        ZipEntry entry = new ZipEntry(filename);
+        zipStream.putNextEntry(entry);
+        ByteStreams.copy(input, zipStream);
+        zipStream.closeEntry();
+    }
+
+    private ZipUtils() {}
+}
diff --git a/tests/BugReportApp/tests/Android.bp b/tests/BugReportApp/tests/Android.bp
new file mode 100644
index 0000000..9f54a75
--- /dev/null
+++ b/tests/BugReportApp/tests/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 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.
+
+android_test {
+    name: "BugReportAppTest",
+
+    srcs: ["src/**/*.java"],
+
+    instrumentation_for: "BugReportApp",
+
+    certificate: "platform",
+    optimize: {
+        enabled: false,
+    },
+    platform_apis: true,
+
+    libs: [
+        "android.test.base",
+        "android.test.mock",
+        "android.test.runner",
+    ],
+
+    static_libs: [
+        "android-support-test",
+        "truth-prebuilt",
+    ],
+
+    test_suites: [
+        "device-tests",
+    ],
+}
diff --git a/tests/BugReportApp/tests/AndroidManifest.xml b/tests/BugReportApp/tests/AndroidManifest.xml
new file mode 100644
index 0000000..26736c6
--- /dev/null
+++ b/tests/BugReportApp/tests/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.car.bugreport.tests" >
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+            android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:label="BugReportAppTest"
+            android:targetPackage="com.android.car.bugreport" />
+</manifest>
diff --git a/tests/BugReportApp/tests/src/com/google/android/car/bugreport/BugStorageUtilsTest.java b/tests/BugReportApp/tests/src/com/google/android/car/bugreport/BugStorageUtilsTest.java
new file mode 100644
index 0000000..29dcc19
--- /dev/null
+++ b/tests/BugReportApp/tests/src/com/google/android/car/bugreport/BugStorageUtilsTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2019 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.bugreport;
+
+import static com.android.car.bugreport.MetaBugReport.TYPE_INTERACTIVE;
+import static com.android.car.bugreport.Status.STATUS_PENDING_USER_ACTION;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.time.Instant;
+import java.util.Date;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class BugStorageUtilsTest {
+    private static final String TIMESTAMP_TODAY = MetaBugReport.toBugReportTimestamp(new Date());
+    private static final String BUGREPORT_ZIP_FILE_NAME = "bugreport@ASD.zip";
+    private static final int BUGREPORT_ZIP_FILE_CONTENT = 1;
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void test_createBugReport_createsAndReturnsMetaBugReport() throws Exception {
+        MetaBugReport bug = createBugReportWithStatus(TIMESTAMP_TODAY,
+                STATUS_PENDING_USER_ACTION, TYPE_INTERACTIVE, /* createBugReportFile= */ true);
+
+        assertThat(BugStorageUtils.findBugReport(mContext, bug.getId()).get()).isEqualTo(bug);
+    }
+
+    @Test
+    public void test_expireBugReport_marksBugReportDeletedAndDeletesZip() throws Exception {
+        MetaBugReport bug = createBugReportWithStatus(TIMESTAMP_TODAY,
+                STATUS_PENDING_USER_ACTION, TYPE_INTERACTIVE, /* createBugReportFile= */ true);
+        try (InputStream in = BugStorageUtils.openBugReportFileToRead(mContext, bug)) {
+            assertThat(in).isNotNull();
+        }
+        Instant now = Instant.now();
+
+        boolean deleteResult = BugStorageUtils.expireBugReport(mContext, bug, now);
+
+        assertThat(deleteResult).isTrue();
+        assertThat(BugStorageUtils.findBugReport(mContext, bug.getId()).get())
+                .isEqualTo(bug.toBuilder()
+                        .setStatus(Status.STATUS_EXPIRED.getValue())
+                        .setStatusMessage("Expired on " + now).build());
+        assertThrows(FileNotFoundException.class, () ->
+                BugStorageUtils.openBugReportFileToRead(mContext, bug));
+    }
+
+    @Test
+    public void test_completeDeleteBugReport_removesBugReportRecordFromDb() throws Exception {
+        MetaBugReport bug = createBugReportWithStatus(TIMESTAMP_TODAY,
+                STATUS_PENDING_USER_ACTION, TYPE_INTERACTIVE, /* createBugReportFile= */ true);
+        try (InputStream in = BugStorageUtils.openBugReportFileToRead(mContext, bug)) {
+            assertThat(in).isNotNull();
+        }
+
+        boolean deleteResult = BugStorageUtils.completeDeleteBugReport(mContext, bug.getId());
+
+        assertThat(deleteResult).isTrue();
+        assertThat(BugStorageUtils.findBugReport(mContext, bug.getId()).isPresent()).isFalse();
+        assertThrows(IllegalArgumentException.class, () ->
+                BugStorageUtils.openBugReportFileToRead(mContext, bug));
+    }
+
+    private MetaBugReport createBugReportWithStatus(
+            String timestamp, Status status, int type, boolean createBugReportFile)
+            throws IOException {
+        MetaBugReport bugReport = BugStorageUtils.createBugReport(
+                mContext, "sample title", timestamp, "driver", type);
+        if (createBugReportFile) {
+            bugReport = BugStorageUtils.update(mContext,
+                    bugReport.toBuilder().setBugReportFileName(BUGREPORT_ZIP_FILE_NAME).build());
+            try (OutputStream out = BugStorageUtils.openBugReportFileToWrite(mContext, bugReport)) {
+                out.write(BUGREPORT_ZIP_FILE_CONTENT);
+            }
+        }
+        return BugStorageUtils.setBugReportStatus(mContext, bugReport, status, "");
+    }
+
+    private static void assertThrows(Class<? extends Throwable> exceptionClass,
+            ExceptionRunnable r) {
+        try {
+            r.run();
+        } catch (Throwable e) {
+            assertTrue("Expected exception type " + exceptionClass.getName() + " but got "
+                    + e.getClass().getName(), exceptionClass.isAssignableFrom(e.getClass()));
+            return;
+        }
+        fail("Expected exception type " + exceptionClass.getName()
+                + ", but no exception was thrown");
+    }
+
+    private interface ExceptionRunnable {
+        void run() throws Exception;
+    }
+}
diff --git a/tests/BugReportApp/utils/bugreport_app_tester.py b/tests/BugReportApp/utils/bugreport_app_tester.py
index 0fb7e53..f095a53 100755
--- a/tests/BugReportApp/utils/bugreport_app_tester.py
+++ b/tests/BugReportApp/utils/bugreport_app_tester.py
@@ -56,13 +56,17 @@
 SQLITE_DB_DIR = '/data/user/0/%s/databases' % BUGREPORT_PACKAGE
 SQLITE_DB_PATH = SQLITE_DB_DIR + '/bugreport.db'
 
-# The statuses are from `src/com/android/car/bugreport/Status.java.
+# The statuses are from `src/com.android.car.bugreport/Status.java.
 STATUS_WRITE_PENDING = 0
 STATUS_WRITE_FAILED = 1
 STATUS_UPLOAD_PENDING = 2
 STATUS_UPLOAD_SUCCESS = 3
 STATUS_UPLOAD_FAILED = 4
 STATUS_USER_CANCELLED = 5
+STATUS_PENDING_USER_ACTION = 6
+STATUS_MOVE_SUCCESSFUL = 7
+STATUS_MOVE_FAILED = 8
+STATUS_MOVE_IN_PROGRESS = 9
 
 DUMPSTATE_DEADLINE_SEC = 300  # 10 minutes.
 UPLOAD_DEADLINE_SEC = 180  # 3 minutes.
@@ -120,6 +124,14 @@
     return 'UPLOAD_FAILED'
   elif status == STATUS_USER_CANCELLED:
     return 'USER_CANCELLED'
+  elif status == STATUS_PENDING_USER_ACTION:
+    return 'PENDING_USER_ACTION'
+  elif status == STATUS_MOVE_SUCCESSFUL:
+    return 'MOVE_SUCCESSFUL'
+  elif status == STATUS_MOVE_FAILED:
+    return 'MOVE_FAILED'
+  elif status == STATUS_MOVE_IN_PROGRESS:
+    return 'MOVE_IN_PROGRESS'
   return 'UNKNOWN_STATUS'
 
 
@@ -337,7 +349,7 @@
             _bugreport_status_to_str(meta_bugreport.status))
 
   def _wait_for_bugreport_to_complete(self, bugreport_id):
-    """Waits until status changes to UPLOAD_PENDING.
+    """Waits until status changes to WRITE_PENDING.
 
     It means dumpstate (bugreport) is completed (or failed).
 
@@ -356,13 +368,17 @@
     print('\nDumpstate (bugreport) completed (or failed).')
 
   def _wait_for_bugreport_to_upload(self, bugreport_id):
-    """Waits bugreport to be uploaded and returns None if succeeds."""
+    """Waits bugreport to be uploaded and returns None if succeeds.
+
+    NOTE: If "android.car.bugreport.disableautoupload" system property is set,
+    the App will not upload.
+    """
     print('\nWaiting for the bug report to be uploaded.')
     err_msg = self._wait_for_bugreport_status_to_change_to(
         STATUS_UPLOAD_SUCCESS,
         UPLOAD_DEADLINE_SEC,
         bugreport_id,
-        allowed_statuses=[STATUS_UPLOAD_PENDING])
+        allowed_statuses=[STATUS_UPLOAD_PENDING, STATUS_PENDING_USER_ACTION])
     if err_msg:
       print('Failed to upload: %s' % err_msg)
       return err_msg
diff --git a/tests/CarDeveloperOptions/res/values-ar/strings.xml b/tests/CarDeveloperOptions/res/values-ar/strings.xml
index bdcb7d0..ce6bb1c 100644
--- a/tests/CarDeveloperOptions/res/values-ar/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ar/strings.xml
@@ -2347,7 +2347,7 @@
     <string name="power_usage_level_and_status" msgid="8873534076894160727">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATUS">%2$s</xliff:g>"</string>
     <string name="power_discharge_remaining" msgid="3461915627093471868">"الوقت المتبقي: <xliff:g id="REMAIN">%1$s</xliff:g>"</string>
     <string name="power_charge_remaining" msgid="2730510256218879651">"<xliff:g id="UNTIL_CHARGED">%1$s</xliff:g> للشحن"</string>
-    <string name="background_activity_title" msgid="7207836362312111483">"تقييد الخلفية"</string>
+    <string name="background_activity_title" msgid="7207836362312111483">"حظر العمل في الخلفية"</string>
     <string name="background_activity_summary" msgid="582372194738538145">"السماح بتشغيل التطبيق في الخلفية"</string>
     <string name="background_activity_summary_disabled" msgid="457944930942085876">"غير مسموح بتشغيل التطبيق في الخلفية"</string>
     <string name="background_activity_summary_whitelisted" msgid="4713321059375873828">"يتعذر تقييد استخدام الخلفية."</string>
@@ -2446,7 +2446,7 @@
     <string name="battery_tip_restrict_app_dialog_message" msgid="6905822297507947381">"لتوفير شحن البطارية، أوقف <xliff:g id="APP">%1$s</xliff:g> عن استخدام البطارية في الخلفية علمًا بأن هذا التطبيق قد لا يعمل على نحو صحيح وقد تتأخر الإشعارات."</string>
     <string name="battery_tip_restrict_apps_less_than_5_dialog_message" msgid="4225881888543582456">"لتوفير شحن البطارية، أوقف هذه التطبيقات عن استخدام البطارية في الخلفية علمًا بأن التطبيقات المقيدة قد لا تعمل على نحو صحيح وقد تتأخر الإشعارات.\n\nالتطبيقات:"</string>
     <string name="battery_tip_restrict_apps_more_than_5_dialog_message" msgid="1748375562539446634">"لتوفير شحن البطارية، أوقف هذه التطبيقات عن استخدام البطارية في الخلفية علمًا بأن التطبيقات المقيدة قد لا تعمل على نحو صحيح وقد تتأخر الإشعارات.\n\nالتطبيقات:\n<xliff:g id="APP_LIST">%1$s</xliff:g>."</string>
-    <string name="battery_tip_restrict_app_dialog_ok" msgid="2573410775701913487">"تقييد"</string>
+    <string name="battery_tip_restrict_app_dialog_ok" msgid="2573410775701913487">"حظر التشغيل"</string>
     <string name="battery_tip_unrestrict_app_dialog_title" msgid="812458516399125710">"هل تريد إزالة التقييد؟"</string>
     <string name="battery_tip_unrestrict_app_dialog_message" msgid="8120081438825031335">"سيتمكّن هذا التطبيق من استخدام البطارية في الخلفية، وقد يؤدي ذلك إلى نفاد شحنها قبل الوقت المتوقع."</string>
     <string name="battery_tip_unrestrict_app_dialog_ok" msgid="9154938931448151479">"إزالة"</string>
diff --git a/tests/CarDeveloperOptions/res/values-bn/strings.xml b/tests/CarDeveloperOptions/res/values-bn/strings.xml
index e2c8d76..fcb6999 100644
--- a/tests/CarDeveloperOptions/res/values-bn/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-bn/strings.xml
@@ -1183,7 +1183,7 @@
     <string name="brightness" msgid="7309120144111305275">"উজ্জ্বলতার স্তর"</string>
     <string name="brightness_title" msgid="5660190946911149690">"উজ্জ্বলতা"</string>
     <string name="brightness_summary" msgid="8687101964451818730">"স্ক্রীনের উজ্জ্বলতা সামঞ্জস্য করুন"</string>
-    <string name="auto_brightness_title" msgid="908511534369820426">"অ্যাডাপ্টিভ উজ্জ্বলতা"</string>
+    <string name="auto_brightness_title" msgid="908511534369820426">"অভিযোজিত উজ্জ্বলতা"</string>
     <string name="auto_brightness_summary_on" msgid="121488862610275737">"চালু আছে"</string>
     <string name="auto_brightness_summary_off" msgid="8569141123211510256">"বন্ধ আছে"</string>
     <string name="auto_brightness_summary_very_low" msgid="7625647285740629347">"পছন্দের উজ্জ্বলতার মান খুব কম"</string>
@@ -3128,7 +3128,7 @@
     <string name="keywords_battery_saver_sticky" msgid="8733804259716284872">"ব্যাটারি সেভার, স্টিকি, লেগে থাকা, পাওয়ার সেভার, ব্যাটারি"</string>
     <string name="default_sound" msgid="6675629744816442953">"ডিফল্ট সাউন্ড"</string>
     <string name="sound_settings_summary" msgid="8467549670633195109">"রিং ভলিউম <xliff:g id="PERCENTAGE">%1$s</xliff:g> তে রয়েছে"</string>
-    <string name="sound_dashboard_summary" msgid="5187301919242823508">"ভলিউম, কম্পন, বিরক্ত করবে না"</string>
+    <string name="sound_dashboard_summary" msgid="5187301919242823508">"ভলিউম, ভাইব্রেশন, বিরক্ত করবে না"</string>
     <string name="sound_settings_summary_vibrate" msgid="2194491116884798590">"রিঙ্গারকে ভাইব্রেট অবস্থায় সেট করা হয়েছে"</string>
     <string name="sound_settings_summary_silent" msgid="899823817462768876">"রিঙ্গারকে নীরব অবস্থায় সেট করা হয়েছে"</string>
     <string name="sound_settings_example_summary" msgid="2091822107298841827">"রিং ভলিউম ৮০% তে রয়েছে"</string>
diff --git a/tests/CarDeveloperOptions/res/values-bs/strings.xml b/tests/CarDeveloperOptions/res/values-bs/strings.xml
index ce5a987..5504da2 100644
--- a/tests/CarDeveloperOptions/res/values-bs/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-bs/strings.xml
@@ -3736,7 +3736,7 @@
     <string name="usage_access" msgid="2023443456361489516">"Pristup korištenju"</string>
     <string name="permit_usage_access" msgid="3321727608629752758">"Dopusti pristup korištenju"</string>
     <string name="app_usage_preference" msgid="5691545073101551727">"Postavke upotrebe aplikacija"</string>
-    <string name="time_spent_in_app_pref_title" msgid="2803186835902798451">"Vrijeme upotrebe"</string>
+    <string name="time_spent_in_app_pref_title" msgid="2803186835902798451">"Vrijeme korištenja uređaja"</string>
     <string name="usage_access_description" msgid="2178083292760305207">"Pristup korištenju omogućava aplikaciji da prati koje druge aplikacije koristite i koliko često, kao i da vidi vašeg mobilnog operatera, postavke jezika i druge detalje."</string>
     <string name="memory_settings_title" msgid="7867148522014070721">"Memorija"</string>
     <string name="memory_details_title" msgid="6364825184513396865">"Detalji o memoriji"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ca/strings.xml b/tests/CarDeveloperOptions/res/values-ca/strings.xml
index 9789a8a..fe126af 100644
--- a/tests/CarDeveloperOptions/res/values-ca/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ca/strings.xml
@@ -1221,11 +1221,11 @@
     <string name="night_display_summary_off" msgid="8850539785332228069">"Desactivada / <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="night_display_summary_off_auto_mode_never" msgid="8618824386434992487">"No s\'activarà mai automàticament"</string>
     <string name="night_display_summary_off_auto_mode_custom" msgid="596847003171394411">"S\'activarà automàticament a les <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="night_display_summary_off_auto_mode_twilight" msgid="4071750976585359952">"S\'activarà automàticament quan es pongui el sol"</string>
+    <string name="night_display_summary_off_auto_mode_twilight" msgid="4071750976585359952">"S\'activarà automàticament al vespre"</string>
     <string name="night_display_summary_on" msgid="6580571388791426596">"Activat / <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="night_display_summary_on_auto_mode_never" msgid="5461580863060506687">"No es desactivarà mai automàticament"</string>
     <string name="night_display_summary_on_auto_mode_custom" msgid="2200631112239399233">"Es desactivarà automàticament a les <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="night_display_summary_on_auto_mode_twilight" msgid="8386769601369289561">"Es desactivarà automàticament quan surti el sol"</string>
+    <string name="night_display_summary_on_auto_mode_twilight" msgid="8386769601369289561">"Es desactivarà automàticament a l\'alba"</string>
     <string name="night_display_activation_on_manual" msgid="8379477527072027346">"Activa ara"</string>
     <string name="night_display_activation_off_manual" msgid="7776082151269794201">"Desactiva ara"</string>
     <string name="night_display_activation_on_twilight" msgid="5610294051700287249">"Activa fins a l\'alba"</string>
@@ -3294,7 +3294,7 @@
     <string name="other_sound_category_preference_title" msgid="2045757472469840859">"Vibracions i altres sons"</string>
     <string name="configure_notification_settings" msgid="291914315140851270">"Notificacions"</string>
     <string name="recent_notifications" msgid="8125865995065032049">"Enviades fa poc"</string>
-    <string name="recent_notifications_see_all_title" msgid="4089007770442871469">"Mostra-les totes des de fa 7 dies"</string>
+    <string name="recent_notifications_see_all_title" msgid="4089007770442871469">"Mostra totes les dels 7 darrers dies"</string>
     <string name="advanced_section_header" msgid="984680389373090015">"Configuració avançada"</string>
     <string name="profile_section_header" msgid="5471479005472037417">"Notificacions de la feina"</string>
     <string name="asst_capability_prioritizer_title" msgid="3488284760645922160">"Prioritat de les notificacions automàtiques"</string>
diff --git a/tests/CarDeveloperOptions/res/values-da/strings.xml b/tests/CarDeveloperOptions/res/values-da/strings.xml
index 6e5e892..6883803 100644
--- a/tests/CarDeveloperOptions/res/values-da/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-da/strings.xml
@@ -1213,7 +1213,7 @@
     <string name="night_display_auto_mode_title" msgid="8493573087102481588">"Tidsplan"</string>
     <string name="night_display_auto_mode_never" msgid="2897444637217807088">"Ingen"</string>
     <string name="night_display_auto_mode_custom" msgid="1400891076453963151">"Aktiveres på valgt tidspunkt"</string>
-    <string name="night_display_auto_mode_twilight" msgid="4000162110017520674">"Aktiveres fra sol ned til sol op"</string>
+    <string name="night_display_auto_mode_twilight" msgid="4000162110017520674">"Aktiveres fra solnedgang til solopgang"</string>
     <string name="night_display_start_time_title" msgid="1069255169673371077">"Starttidspunkt"</string>
     <string name="night_display_end_time_title" msgid="2760793157124245911">"Sluttidspunkt"</string>
     <string name="night_display_status_title" msgid="1727020934735770319">"Status"</string>
diff --git a/tests/CarDeveloperOptions/res/values-fa/strings.xml b/tests/CarDeveloperOptions/res/values-fa/strings.xml
index ef79cc5..ade25b4 100644
--- a/tests/CarDeveloperOptions/res/values-fa/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-fa/strings.xml
@@ -1849,7 +1849,7 @@
     <string name="filter_dlg_title" msgid="115313222190512670">"انتخاب گزینه‌های فیلتر"</string>
     <string name="filter_apps_all" msgid="3938077534861382701">"همه برنامه‌ها"</string>
     <string name="filter_apps_disabled" msgid="5394488790555678117">"برنامه‌های غیرفعال‌شده"</string>
-    <string name="filter_apps_third_party" msgid="3985794876813232322">"دانلودشده"</string>
+    <string name="filter_apps_third_party" msgid="3985794876813232322">"بارگیری‌شده"</string>
     <string name="filter_apps_running" msgid="6852975378502426359">"در حال اجرا"</string>
     <string name="filter_apps_onsdcard" product="nosdcard" msgid="3501701148760911442">"حافظهٔ USB"</string>
     <string name="filter_apps_onsdcard" product="default" msgid="135989136394672864">"در کارت SD"</string>
diff --git a/tests/CarDeveloperOptions/res/values-fr/strings.xml b/tests/CarDeveloperOptions/res/values-fr/strings.xml
index 2a2e64f..57f384e 100644
--- a/tests/CarDeveloperOptions/res/values-fr/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-fr/strings.xml
@@ -1225,7 +1225,7 @@
     <string name="night_display_summary_on" msgid="6580571388791426596">"Activé - <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="night_display_summary_on_auto_mode_never" msgid="5461580863060506687">"Ne jamais désactiver automatiquement"</string>
     <string name="night_display_summary_on_auto_mode_custom" msgid="2200631112239399233">"Désactiver automatiquement à <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="night_display_summary_on_auto_mode_twilight" msgid="8386769601369289561">"Désactiver automatiquement au lever du soleil"</string>
+    <string name="night_display_summary_on_auto_mode_twilight" msgid="8386769601369289561">"Se désactivera automatiquement au lever du soleil"</string>
     <string name="night_display_activation_on_manual" msgid="8379477527072027346">"Activer maintenant"</string>
     <string name="night_display_activation_off_manual" msgid="7776082151269794201">"Désactiver"</string>
     <string name="night_display_activation_on_twilight" msgid="5610294051700287249">"Activer jusqu\'au lever du soleil"</string>
diff --git a/tests/CarDeveloperOptions/res/values-gu/strings.xml b/tests/CarDeveloperOptions/res/values-gu/strings.xml
index acf4b4b..fdd8b9a 100644
--- a/tests/CarDeveloperOptions/res/values-gu/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-gu/strings.xml
@@ -823,7 +823,7 @@
     <string name="art_verifier_for_debuggable_summary" msgid="2204242476996701111">"ડીબગ કરવા યોગ્ય ઍપ માટે બાઇટકોડને ચકાસવા ARTને મંજૂરી આપો"</string>
     <string name="nfc_quick_toggle_title" msgid="4990697912813795002">"NFC"</string>
     <string name="nfc_quick_toggle_summary" product="tablet" msgid="983451155092850657">"જ્યારે ટેબ્લેટ બીજા ઉપકરણને ટચ કરે ત્યારે ડેટા વિનિમયની મંજૂરી આપો"</string>
-    <string name="nfc_quick_toggle_summary" product="default" msgid="7141056939052895142">"જ્યારે ફોન બીજા ઉપકરણને ટચ કરે ત્યારે ડેટા વિનિમયની મંજૂરી આપો"</string>
+    <string name="nfc_quick_toggle_summary" product="default" msgid="7141056939052895142">"જ્યારે ફોન બીજા ડિવાઇસને ટચ કરે ત્યારે ડેટા વિનિમયની મંજૂરી આપો"</string>
     <string name="nfc_disclaimer_title" msgid="4860231267351602970">"NFC ચાલુ કરો"</string>
     <string name="nfc_disclaimer_content" msgid="3066113577854565782">"NFC આ ઉપકરણ અને અન્ય નજીકના ઉપકરણો અથવા લક્ષ્યો વચ્ચે ડેટાની આપ-લે કરે છે, જેમ કે ચુકવણી ટર્મિનલ્સ, અ‍ૅક્સેસ રીડર્સ અને ક્રિયા-પ્રતિક્રિયાત્મક જાહેરાતો અથવા ટૅગ્સ."</string>
     <string name="nfc_secure_settings_title" msgid="5153751163174916581">"NFCને સુરક્ષિત કરો"</string>
@@ -1168,7 +1168,7 @@
     <string name="accessibility_personal_account_title" msgid="7251761883688839354">"વ્યક્તિગત એકાઉન્ટ - <xliff:g id="MANAGED_BY">%s</xliff:g>"</string>
     <string name="search_settings" msgid="5809250790214921377">"શોધો"</string>
     <string name="display_settings" msgid="1045535829232307190">"ડિસ્પ્લે"</string>
-    <string name="accelerometer_title" msgid="2427487734964971453">"સ્ક્રીનને આપમેળે ફેરવો"</string>
+    <string name="accelerometer_title" msgid="2427487734964971453">"ઑટો રોટેટ સ્ક્રીન"</string>
     <string name="color_mode_title" msgid="8164858320869449142">"રંગો"</string>
     <string name="color_mode_option_natural" msgid="1292837781836645320">"કુદરતી"</string>
     <string name="color_mode_option_boosted" msgid="453557938434778933">"બુસ્ટ કરેલ"</string>
@@ -1219,7 +1219,7 @@
     <string name="night_display_status_title" msgid="1727020934735770319">"સ્થિતિ"</string>
     <string name="night_display_temperature_title" msgid="8375126629902616296">"તીવ્રતા"</string>
     <string name="night_display_summary_off" msgid="8850539785332228069">"બંધ / <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="night_display_summary_off_auto_mode_never" msgid="8618824386434992487">"આપમેળે ક્યારેય ચાલુ નહીં થાય"</string>
+    <string name="night_display_summary_off_auto_mode_never" msgid="8618824386434992487">"ક્યારેય ઑટોમૅટિક રીતે ચાલુ નહીં થાય"</string>
     <string name="night_display_summary_off_auto_mode_custom" msgid="596847003171394411">"<xliff:g id="ID_1">%1$s</xliff:g> વાગ્યે આપમેળે ચાલુ થઈ જશે"</string>
     <string name="night_display_summary_off_auto_mode_twilight" msgid="4071750976585359952">"સૂર્યાસ્ત સમયે આપમેળે ચાલુ થઈ જશે"</string>
     <string name="night_display_summary_on" msgid="6580571388791426596">"ચાલુ / <xliff:g id="ID_1">%1$s</xliff:g>"</string>
@@ -2382,7 +2382,7 @@
     <string name="usage_type_data_wifi_send" msgid="4457097885099163617">"વાઇ-ફાઇ પૅકેટ્સ મોકલ્યાં"</string>
     <string name="usage_type_data_wifi_recv" msgid="6629526425662663926">"વાઇ-ફાઇ પૅકેટ્સ પ્રાપ્ત થયાં"</string>
     <string name="usage_type_audio" msgid="510459400845396879">"ઑડિઓ"</string>
-    <string name="usage_type_video" msgid="8161701367674306793">"વીડિઓ"</string>
+    <string name="usage_type_video" msgid="8161701367674306793">"વીડિયો"</string>
     <string name="usage_type_camera" msgid="2276450385733155264">"કૅમેરો"</string>
     <string name="usage_type_flashlight" msgid="954750302897154167">"ફ્લેશલાઇટ"</string>
     <string name="usage_type_on_time" msgid="4622180623970638221">"સમય ચાલુ"</string>
@@ -2973,7 +2973,7 @@
     <string name="restriction_nfc_enable_title" msgid="5146674482590550598">"NFC"</string>
     <string name="restriction_nfc_enable_summary_config" msgid="405349698260328073">"જ્યારે આ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> બીજા NFC ઉપકરણને ટચ કરે ત્યારે ડેટા ફેરબદલીની મંજૂરી આપો"</string>
     <string name="restriction_nfc_enable_summary" product="tablet" msgid="3292205836938064931">"જ્યારે ટેબ્લેટ બીજા ઉપકરણને ટચ કરે ત્યારે ડેટા વિનિમયની મંજૂરી આપો"</string>
-    <string name="restriction_nfc_enable_summary" product="default" msgid="226439584043333608">"જ્યારે ફોન બીજા ઉપકરણને ટચ કરે ત્યારે ડેટા વિનિમયની મંજૂરી આપો"</string>
+    <string name="restriction_nfc_enable_summary" product="default" msgid="226439584043333608">"જ્યારે ફોન બીજા ડિવાઇસને ટચ કરે ત્યારે ડેટા વિનિમયની મંજૂરી આપો"</string>
     <string name="restriction_location_enable_title" msgid="358506740636434856">"સ્થાન"</string>
     <string name="restriction_location_enable_summary" msgid="4159500201124004463">"એપ્લિકેશન્સને તમારી સ્થાન માહિતીનો ઉપયોગ કરવા દો"</string>
     <string name="wizard_back" msgid="223654213898117594">"પાછળ"</string>
diff --git a/tests/CarDeveloperOptions/res/values-hi/strings.xml b/tests/CarDeveloperOptions/res/values-hi/strings.xml
index 59684f8..d8f5db5 100644
--- a/tests/CarDeveloperOptions/res/values-hi/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-hi/strings.xml
@@ -128,7 +128,7 @@
     <string name="bluetooth_notif_title" msgid="5090288898529286011">"दूसरे डिवाइस से जोड़ने का अनुरोध किया गया है"</string>
     <string name="bluetooth_notif_message" msgid="6612367890895077938">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> से युग्मित करने के लिए टैप करें."</string>
     <string name="bluetooth_show_received_files" msgid="5060846395852236652">"मिलने वाली फ़ाइलें"</string>
-    <string name="bluetooth_show_files_received_via_bluetooth" msgid="1699095577431389560">"ब्लूटूथ के ज़रिए मिली फ़ाइलें"</string>
+    <string name="bluetooth_show_files_received_via_bluetooth" msgid="1699095577431389560">"ब्लूटूथ से मिली फ़ाइलें"</string>
     <string name="device_picker" msgid="8345264486071697705">"ब्लूटूथ डिवाइस चुनें"</string>
     <string name="bluetooth_ask_enablement" msgid="8716802066127746062">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्लूटूथ को चालू करना चाहता है"</string>
     <string name="bluetooth_ask_disablement" msgid="7125319551097350783">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्लूटूथ को बंद करना चाहता है"</string>
@@ -823,7 +823,7 @@
     <string name="art_verifier_for_debuggable_summary" msgid="2204242476996701111">"डीबग किए जा सकने वाले ऐप्लिकेशन के लिए, ART को बाइटकोड की पुष्टि करने की मंज़ूरी दें"</string>
     <string name="nfc_quick_toggle_title" msgid="4990697912813795002">"आस-पास के डिवाइस से संपर्क (एनएफसी)"</string>
     <string name="nfc_quick_toggle_summary" product="tablet" msgid="983451155092850657">"जब टैबलेट अन्य डिवाइस को स्पर्श करे तो डेटा ट्रांसफर करने दें"</string>
-    <string name="nfc_quick_toggle_summary" product="default" msgid="7141056939052895142">"जब फ़ोन दूसरे डिवाइस को टच करे तो डेटा ट्रांसफर करने दें"</string>
+    <string name="nfc_quick_toggle_summary" product="default" msgid="7141056939052895142">"जब फ़ोन दूसरे डिवाइस को टच करे, तो डेटा ट्रांसफर करने दें"</string>
     <string name="nfc_disclaimer_title" msgid="4860231267351602970">"NFC चालू करें"</string>
     <string name="nfc_disclaimer_content" msgid="3066113577854565782">"NFC इस डिवाइस और आस-पास के अन्य डिवाइस या लक्ष्यों के बीच डेटा का लेन-देन करता है, जैसे कि भुगतान टर्मिनल, ऐक्सेस रीडर और सहभागी विज्ञापन या टैग."</string>
     <string name="nfc_secure_settings_title" msgid="5153751163174916581">"NFC सुरक्षित करें"</string>
diff --git a/tests/CarDeveloperOptions/res/values-hy/strings.xml b/tests/CarDeveloperOptions/res/values-hy/strings.xml
index 68f6947..9f370ae 100644
--- a/tests/CarDeveloperOptions/res/values-hy/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-hy/strings.xml
@@ -56,7 +56,7 @@
     <string name="radio_info_ims_reg_status" msgid="4771711884059371514">"IMS-ի գրանցում՝ <xliff:g id="STATUS">%1$s</xliff:g>\nVoice over LTE՝ <xliff:g id="AVAILABILITY_0">%2$s</xliff:g>\nVoice over WiFi՝ <xliff:g id="AVAILABILITY_1">%3$s</xliff:g>\nՏեսազանգ՝ <xliff:g id="AVAILABILITY_2">%4$s</xliff:g>\nUT միջերես՝ <xliff:g id="AVAILABILITY_3">%5$s</xliff:g>"</string>
     <string name="radioInfo_service_in" msgid="1297020186765943857">"Շահագործման մեջ է"</string>
     <string name="radioInfo_service_out" msgid="8460363463722476510">"Չի շահագործվում"</string>
-    <string name="radioInfo_service_emergency" msgid="7674989004735662599">"Միայն արտակարգ իրավիճակների զանգեր"</string>
+    <string name="radioInfo_service_emergency" msgid="7674989004735662599">"Միայն շտապ կանչեր"</string>
     <string name="radioInfo_service_off" msgid="1873939869994136791">"Ռադիոն անջատված է"</string>
     <string name="radioInfo_roaming_in" msgid="7059350234710947417">"Ռոումինգ"</string>
     <string name="radioInfo_roaming_not" msgid="7733269160603599835">"Ռոումինգում չէ"</string>
diff --git a/tests/CarDeveloperOptions/res/values-it/arrays.xml b/tests/CarDeveloperOptions/res/values-it/arrays.xml
index 11d6291..22a26a0 100644
--- a/tests/CarDeveloperOptions/res/values-it/arrays.xml
+++ b/tests/CarDeveloperOptions/res/values-it/arrays.xml
@@ -479,7 +479,7 @@
     <item msgid="5079453644557603349">"Chiaro"</item>
   </string-array>
   <string-array name="autofill_logging_level_entries">
-    <item msgid="6882729786516723474">"Off"</item>
+    <item msgid="6882729786516723474">"OFF"</item>
     <item msgid="4072198137051566919">"Debug"</item>
     <item msgid="2473005316958868509">"Dettagliata"</item>
   </string-array>
diff --git a/tests/CarDeveloperOptions/res/values-it/strings.xml b/tests/CarDeveloperOptions/res/values-it/strings.xml
index 30b4ef7..d5855cc 100644
--- a/tests/CarDeveloperOptions/res/values-it/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-it/strings.xml
@@ -370,7 +370,7 @@
     <string name="Accounts_settings_title" msgid="7901374987121953746">"Account"</string>
     <string name="location_settings_title" msgid="2707201457572301030">"Geolocalizzazione"</string>
     <string name="location_settings_master_switch_title" msgid="3108016866082816733">"Usa geolocalizzazione"</string>
-    <string name="location_settings_summary_location_off" msgid="5563530256978372978">"Off"</string>
+    <string name="location_settings_summary_location_off" msgid="5563530256978372978">"OFF"</string>
     <plurals name="location_settings_summary_location_on" formatted="false" msgid="7893342914540884818">
       <item quantity="other">On - <xliff:g id="COUNT_1">%1$d</xliff:g> app possono accedere alla posizione</item>
       <item quantity="one">On - <xliff:g id="COUNT_0">%1$d</xliff:g> app può accedere alla posizione</item>
@@ -830,7 +830,7 @@
     <string name="nfc_secure_toggle_summary" product="default" msgid="7631183023440112192">"Consenti il pagamento NFC e l\'utilizzo di biglietti per il trasporto pubblico solo quando lo schermo è sbloccato"</string>
     <string name="android_beam_settings_title" msgid="3083436415873738389">"Android Beam"</string>
     <string name="android_beam_on_summary" msgid="8068287225180474199">"Pronto a trasmettere i contenuti dell\'app tramite NFC"</string>
-    <string name="android_beam_off_summary" msgid="7365818039159364600">"Off"</string>
+    <string name="android_beam_off_summary" msgid="7365818039159364600">"OFF"</string>
     <string name="nfc_disabled_summary" msgid="2181777971122724361">"Non disponibile perché la tecnologia NFC non è attiva"</string>
     <string name="android_beam_label" msgid="5340299879556025708">"Android Beam"</string>
     <string name="android_beam_explained" msgid="4501176353247859329">"Quando questa funzione è attiva, puoi trasmettere contenuti di app a un altro dispositivo che supporta la tecnologia NFC tenendo vicini i dispositivi. Ad esempio, puoi trasmettere pagine web, video di YouTube, contatti e altro ancora.\n\nÈ sufficiente avvicinare i dispositivi (generalmente mettendo a contatto le parti posteriori), quindi toccare lo schermo. L\'app stabilisce quali dati trasferire."</string>
@@ -1185,13 +1185,13 @@
     <string name="brightness_summary" msgid="8687101964451818730">"Regola la luminosità dello schermo"</string>
     <string name="auto_brightness_title" msgid="908511534369820426">"Luminosità adattiva"</string>
     <string name="auto_brightness_summary_on" msgid="121488862610275737">"Attiva"</string>
-    <string name="auto_brightness_summary_off" msgid="8569141123211510256">"Off"</string>
+    <string name="auto_brightness_summary_off" msgid="8569141123211510256">"OFF"</string>
     <string name="auto_brightness_summary_very_low" msgid="7625647285740629347">"Luminosità preferita molto bassa"</string>
     <string name="auto_brightness_summary_low" msgid="1829314781781906712">"Luminosità preferita bassa"</string>
     <string name="auto_brightness_summary_default" msgid="4095465958108128891">"Luminosità preferita predefinita"</string>
     <string name="auto_brightness_summary_high" msgid="8980041483278767898">"Luminosità preferita alta"</string>
     <string name="auto_brightness_summary_very_high" msgid="8891768063638513875">"Luminosità preferita molto alta"</string>
-    <string name="auto_brightness_off_title" msgid="6410562081118281572">"Off"</string>
+    <string name="auto_brightness_off_title" msgid="6410562081118281572">"OFF"</string>
     <string name="auto_brightness_very_low_title" msgid="8716493755125824074">"Molto bassa"</string>
     <string name="auto_brightness_low_title" msgid="5005479920075366970">"Bassa"</string>
     <string name="auto_brightness_default_title" msgid="5446692891470912829">"Predefinita"</string>
@@ -1205,7 +1205,7 @@
     <string name="display_white_balance_title" msgid="5747260735311935143">"Bilanciamento bianco display"</string>
     <string name="adaptive_sleep_title" msgid="3237620948260957018">"Screen aware"</string>
     <string name="adaptive_sleep_summary_on" msgid="6670369739228487082">"On/Lo schermo non si spegne se lo stai guardando"</string>
-    <string name="adaptive_sleep_summary_off" msgid="2891586225954973431">"Off"</string>
+    <string name="adaptive_sleep_summary_off" msgid="2891586225954973431">"OFF"</string>
     <string name="adaptive_sleep_description" msgid="812673735459170009">"Consente di impedire lo spegnimento dello schermo se lo stai guardando."</string>
     <string name="adaptive_sleep_privacy" msgid="5706802215479902623">"Screen aware usa la fotocamera anteriore per controllare se qualcuno sta guardando lo schermo. Funziona sul dispositivo e le immagini non vengono mai memorizzate o inviate a Google."</string>
     <string name="night_display_title" msgid="1305002424893349814">"Luminosità notturna"</string>
@@ -1218,7 +1218,7 @@
     <string name="night_display_end_time_title" msgid="2760793157124245911">"Ora fine"</string>
     <string name="night_display_status_title" msgid="1727020934735770319">"Stato"</string>
     <string name="night_display_temperature_title" msgid="8375126629902616296">"Intensità"</string>
-    <string name="night_display_summary_off" msgid="8850539785332228069">"Off/<xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="night_display_summary_off" msgid="8850539785332228069">"OFF/<xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="night_display_summary_off_auto_mode_never" msgid="8618824386434992487">"Non verrà mai attivata automaticamente"</string>
     <string name="night_display_summary_off_auto_mode_custom" msgid="596847003171394411">"Verrà attivata automaticamente alle ore <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="night_display_summary_off_auto_mode_twilight" msgid="4071750976585359952">"Verrà attivata automaticamente al tramonto"</string>
@@ -1249,7 +1249,7 @@
     <string name="screensaver_settings_summary_sleep" msgid="6097363596749362692">"Durante la ricarica"</string>
     <string name="screensaver_settings_summary_dock" msgid="6297808146601570196">"Quando inserito nel dock"</string>
     <string name="screensaver_settings_summary_never" msgid="3995259444981620707">"Mai"</string>
-    <string name="screensaver_settings_summary_off" msgid="6119947316484763131">"Off"</string>
+    <string name="screensaver_settings_summary_off" msgid="6119947316484763131">"OFF"</string>
     <string name="screensaver_settings_disabled_prompt" msgid="1897518064782596947">"Attiva il salvaschermo per controllare ciò che accade quando il telefono è inserito nel dock e/o in standby."</string>
     <string name="screensaver_settings_when_to_dream" msgid="3763052013516826348">"Quando avviare"</string>
     <string name="screensaver_settings_current" msgid="4017556173596361672">"Salvaschermo attuale"</string>
@@ -2108,7 +2108,7 @@
       <item quantity="one"><xliff:g id="NUMBER_DEVICE_COUNT_0">%1$d</xliff:g> apparecchio acustico salvato</item>
     </plurals>
     <string name="accessibility_summary_state_enabled" msgid="7357731696603247963">"On"</string>
-    <string name="accessibility_summary_state_disabled" msgid="9197369047683087620">"Off"</string>
+    <string name="accessibility_summary_state_disabled" msgid="9197369047683087620">"OFF"</string>
     <string name="accessibility_summary_state_stopped" msgid="3170264683616172746">"Non funziona. Tocca per avere informazioni."</string>
     <string name="accessibility_description_state_stopped" msgid="7666178628053039493">"Questo servizio non funziona correttamente."</string>
     <string name="enable_quick_setting" msgid="1580451877998661255">"Mostra in Impostazioni rapide"</string>
@@ -2144,7 +2144,7 @@
     <string name="accessibility_vibration_intensity_high" msgid="7850793704772123134">"Vibrazione alta"</string>
     <string name="accessibility_menu_item_settings" msgid="6809813639403725032">"Impostazioni"</string>
     <string name="accessibility_feature_state_on" msgid="8649102771420898911">"On"</string>
-    <string name="accessibility_feature_state_off" msgid="7536392255214437050">"Off"</string>
+    <string name="accessibility_feature_state_off" msgid="7536392255214437050">"OFF"</string>
     <string name="captioning_preview_title" msgid="6072706647310074854">"Anteprima"</string>
     <string name="captioning_standard_options_title" msgid="4124898413348084226">"Opzioni standard"</string>
     <string name="captioning_locale" msgid="4734464353806207943">"Lingua"</string>
@@ -2191,7 +2191,7 @@
     <string name="accessibility_service_default_description" msgid="857921874644864502">"Nessuna descrizione fornita."</string>
     <string name="settings_button" msgid="8557747862035866953">"Impostazioni"</string>
     <string name="print_settings" msgid="7886184656544483072">"Stampa"</string>
-    <string name="print_settings_summary_no_service" msgid="634173687975841526">"Off"</string>
+    <string name="print_settings_summary_no_service" msgid="634173687975841526">"OFF"</string>
     <plurals name="print_settings_summary" formatted="false" msgid="7580293760281445137">
       <item quantity="other"><xliff:g id="COUNT">%1$d</xliff:g> servizi di stampa attivi</item>
       <item quantity="one">1 servizio di stampa attivo</item>
@@ -2206,7 +2206,7 @@
     <string name="print_menu_item_settings" msgid="2654804159012579508">"Impostazioni"</string>
     <string name="print_menu_item_add_printers" msgid="8198201275621756510">"Aggiungi stampanti"</string>
     <string name="print_feature_state_on" msgid="1838010230650403367">"On"</string>
-    <string name="print_feature_state_off" msgid="208580346723223688">"Off"</string>
+    <string name="print_feature_state_off" msgid="208580346723223688">"OFF"</string>
     <string name="print_menu_item_add_service" msgid="6803000110578493782">"Aggiungi servizio"</string>
     <string name="print_menu_item_add_printer" msgid="8529196211179574921">"Aggiungi stampante"</string>
     <string name="print_menu_item_search" msgid="1165316329772287360">"Cerca"</string>
@@ -2334,7 +2334,7 @@
     <string name="battery_auto_restriction_title" msgid="488905332794794076">"Usa Battery Manager"</string>
     <string name="battery_auto_restriction_summary" msgid="1638072655581821837">"Rileva quando le app scaricano la batteria"</string>
     <string name="battery_manager_on" msgid="5626982529932239656">"Opzione attiva/Rileva quando le app scaricano la batteria"</string>
-    <string name="battery_manager_off" msgid="9114027524232450371">"Off"</string>
+    <string name="battery_manager_off" msgid="9114027524232450371">"OFF"</string>
     <plurals name="battery_manager_app_restricted" formatted="false" msgid="6721813588142691216">
       <item quantity="other">%1$d app con restrizioni</item>
       <item quantity="one">%1$d app con restrizioni</item>
@@ -2546,7 +2546,7 @@
     <string name="emergency_tone_summary" msgid="8035940153401622240">"Imposta il comportamento in caso di chiamata di emergenza"</string>
     <string name="privacy_settings_title" msgid="3573891462732375772">"Backup"</string>
     <string name="backup_summary_state_on" msgid="1725597360282574647">"On"</string>
-    <string name="backup_summary_state_off" msgid="7138020503288730492">"Off"</string>
+    <string name="backup_summary_state_off" msgid="7138020503288730492">"OFF"</string>
     <string name="backup_section_title" msgid="8177209731777904656">"Backup e ripristino"</string>
     <string name="personal_data_section_title" msgid="9161854418510071558">"Dati personali"</string>
     <string name="backup_data_title" msgid="4461508563849583624">"Backup dei miei dati"</string>
@@ -3239,8 +3239,8 @@
     <string name="zen_interruption_level_priority" msgid="9178419297408319234">"Solo con priorità"</string>
     <string name="zen_mode_and_condition" msgid="4123722186007123567">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="zen_mode_sound_summary_on_with_info" msgid="2539952366467518398">"On/<xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="zen_mode_sound_summary_off_with_info" msgid="3910718455243440265">"Off/<xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="zen_mode_sound_summary_off" msgid="2800265178411749309">"Off"</string>
+    <string name="zen_mode_sound_summary_off_with_info" msgid="3910718455243440265">"OFF/<xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="zen_mode_sound_summary_off" msgid="2800265178411749309">"OFF"</string>
     <string name="zen_mode_sound_summary_on" msgid="6964666541479146310">"On"</string>
     <string name="zen_mode_duration_summary_always_prompt" msgid="7642321938427056823">"Chiedi ogni volta (a meno che l\'opzione non sia stata attivata automaticamente)"</string>
     <string name="zen_mode_duration_summary_forever" msgid="4563938129424903030">"Fino alla disattivazione (a meno che l\'opzione non sia stata attivata automaticamente)"</string>
@@ -3551,7 +3551,7 @@
     <string name="device_feedback" msgid="4042352891448769818">"Invia feedback sul dispositivo"</string>
     <string name="restr_pin_enter_admin_pin" msgid="8577847751493521230">"Inserisci PIN amministratore"</string>
     <string name="switch_on_text" msgid="7100491749799298324">"On"</string>
-    <string name="switch_off_text" msgid="3539551289454353555">"Off"</string>
+    <string name="switch_off_text" msgid="3539551289454353555">"OFF"</string>
     <string name="screen_pinning_title" msgid="578020318289781102">"Blocco su schermo"</string>
     <string name="screen_pinning_description" msgid="3814537379086412278">"Quando l\'impostazione è attiva, puoi usare il blocco su schermo per lasciare visibile la schermata corrente finché non la sblocchi.\n\nPer usare la funzione:\n\n1. Assicurati che il blocco su schermo sia attivo\n\n2. Apri Panoramica\n\n3. Tocca l\'icona dell\'app in alto nella schermata, quindi tocca Blocca"</string>
     <string name="screen_pinning_unlock_pattern" msgid="1060334707088339444">"Richiedi sequenza di sblocco prima di sbloccare"</string>
@@ -3602,7 +3602,7 @@
     <string name="notifications_label" msgid="2792398288062643318">"Notifiche"</string>
     <string name="notifications_enabled" msgid="439339392141736137">"On"</string>
     <string name="notifications_enabled_with_info" msgid="7706460489443809452">"<xliff:g id="NOTIFICATIONS_SENT">%1$s</xliff:g>/<xliff:g id="NOTIFICATIONS_CATEGORIES_OFF">%2$s</xliff:g>"</string>
-    <string name="notifications_disabled" msgid="316658185757688983">"Off"</string>
+    <string name="notifications_disabled" msgid="316658185757688983">"OFF"</string>
     <string name="notifications_partly_blocked" msgid="6330451240669068819">"<xliff:g id="COUNT_0">%1$d</xliff:g> di <xliff:g id="COUNT_1">%2$d</xliff:g> categorie disattivate"</string>
     <string name="notifications_silenced" msgid="538923056987616372">"Senza audio"</string>
     <string name="notifications_redacted" msgid="308836040236690014">"Nessun contenuto riservato nella schermata di blocco"</string>
@@ -3987,7 +3987,7 @@
     <string name="unrestricted_data_saver" msgid="9139401849550738720">"Dati senza limitazioni"</string>
     <string name="restrict_background_blacklisted" msgid="7158991683849067124">"I dati in background sono disattivati"</string>
     <string name="data_saver_on" msgid="7281809065420480881">"On"</string>
-    <string name="data_saver_off" msgid="7439439787358504018">"Off"</string>
+    <string name="data_saver_off" msgid="7439439787358504018">"OFF"</string>
     <string name="data_saver_switch_title" msgid="8244008132112735207">"Usa Risparmio dati"</string>
     <string name="unrestricted_app_title" msgid="4390661122069905122">"Uso dati senza limitazioni"</string>
     <string name="unrestricted_app_summary" msgid="2829141815077800483">"Consenti accesso senza limitazioni con Risparmio dati attivo"</string>
@@ -4140,7 +4140,7 @@
     <string name="fingerprint_swipe_for_notifications_summary" product="device" msgid="7950264130913070035">"Per controllare le notifiche, scorri verso il basso sul sensore di impronte digitali sul retro del dispositivo."</string>
     <string name="fingerprint_swipe_for_notifications_suggestion_title" msgid="948946491233738823">"Visualizza rapidamente le notifiche"</string>
     <string name="gesture_setting_on" msgid="7573680730101327866">"On"</string>
-    <string name="gesture_setting_off" msgid="2540159841716890511">"Off"</string>
+    <string name="gesture_setting_off" msgid="2540159841716890511">"OFF"</string>
     <string name="oem_unlock_enable_disabled_summary_bootloader_unlocked" msgid="7233244080078311793">"Il bootloader è già sbloccato"</string>
     <string name="oem_unlock_enable_disabled_summary_connectivity" msgid="262986780389836168">"Devi prima connetterti a Internet"</string>
     <string name="oem_unlock_enable_disabled_summary_connectivity_or_locked" msgid="3331374502670483142">"Connettiti a Internet o contatta il tuo operatore"</string>
@@ -4263,7 +4263,7 @@
     <string name="show_operator_name_title" msgid="5056163028128447308">"Nome della rete"</string>
     <string name="show_operator_name_summary" msgid="6352180285743777497">"Nome della Rete Display nella bara di stato"</string>
     <string name="storage_manager_indicator" msgid="4255140732848476875">"Gestione memoria: <xliff:g id="STATUS">^1</xliff:g>"</string>
-    <string name="storage_manager_indicator_off" msgid="6404056007102580777">"Off"</string>
+    <string name="storage_manager_indicator_off" msgid="6404056007102580777">"OFF"</string>
     <string name="storage_manager_indicator_on" msgid="5295306384982062320">"Attiva"</string>
     <string name="install_type_instant" msgid="6248487669862821874">"App istantanea"</string>
     <string name="automatic_storage_manager_deactivation_warning" msgid="7867793739491286374">"Disattivare la gestione della memoria?"</string>
@@ -4408,7 +4408,7 @@
     <string name="mobile_network_sim_name" msgid="8228870017368926761">"Nome SIM"</string>
     <string name="mobile_network_sim_name_rename" msgid="4810736493612513152">"Rinomina"</string>
     <string name="mobile_network_use_sim_on" msgid="1944823242539751387">"Utilizza SIM"</string>
-    <string name="mobile_network_use_sim_off" msgid="2077820358051946635">"Off"</string>
+    <string name="mobile_network_use_sim_off" msgid="2077820358051946635">"OFF"</string>
     <string name="mobile_network_esim_swap_confirm_title" msgid="6077154427380613615">"Passare a <xliff:g id="CARRIER">%1$s</xliff:g>?"</string>
     <string name="mobile_network_esim_swap_confirm_body" msgid="1192274915146275063">"È possibile attivare una sola SIM scaricata alla volta.\n\nIl passaggio a <xliff:g id="CARRIER1">%1$s</xliff:g> non annullerà il servizio di <xliff:g id="CARRIER2">%2$s</xliff:g>."</string>
     <string name="mobile_network_esim_swap_confirm_ok" msgid="4253442720111626242">"Passa a <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ka/strings.xml b/tests/CarDeveloperOptions/res/values-ka/strings.xml
index 1a0838f..a167d28 100644
--- a/tests/CarDeveloperOptions/res/values-ka/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ka/strings.xml
@@ -1219,7 +1219,7 @@
     <string name="night_display_status_title" msgid="1727020934735770319">"სტატუსი"</string>
     <string name="night_display_temperature_title" msgid="8375126629902616296">"ინტენსივობა"</string>
     <string name="night_display_summary_off" msgid="8850539785332228069">"გამორთულია / <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="night_display_summary_off_auto_mode_never" msgid="8618824386434992487">"არასოდეს ჩაირთოს ავტომატურად"</string>
+    <string name="night_display_summary_off_auto_mode_never" msgid="8618824386434992487">"არასოდეს ჩაირთვება ავტომატურად"</string>
     <string name="night_display_summary_off_auto_mode_custom" msgid="596847003171394411">"ავტომატურად ჩაირთვება <xliff:g id="ID_1">%1$s</xliff:g>-ზე"</string>
     <string name="night_display_summary_off_auto_mode_twilight" msgid="4071750976585359952">"ავტომატურად ჩაირთვება მზის ჩასვლისას"</string>
     <string name="night_display_summary_on" msgid="6580571388791426596">"ჩართულია / <xliff:g id="ID_1">%1$s</xliff:g>"</string>
diff --git a/tests/CarDeveloperOptions/res/values-kk/strings.xml b/tests/CarDeveloperOptions/res/values-kk/strings.xml
index 18bf1f1..2f33cb7 100644
--- a/tests/CarDeveloperOptions/res/values-kk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-kk/strings.xml
@@ -1173,7 +1173,7 @@
     <string name="color_mode_option_natural" msgid="1292837781836645320">"Табиғи"</string>
     <string name="color_mode_option_boosted" msgid="453557938434778933">"Жарқын"</string>
     <string name="color_mode_option_saturated" msgid="7758384943407859851">"Қаныққан"</string>
-    <string name="color_mode_option_automatic" msgid="6572718611315165117">"Адаптивті"</string>
+    <string name="color_mode_option_automatic" msgid="6572718611315165117">"Бейімделгіш"</string>
     <string name="color_mode_summary_natural" msgid="1247153893843263340">"Тек анық түстерді пайдаланыңыз"</string>
     <string name="color_mode_summary_automatic" msgid="6066740785261330514">"Түстердің ашықтығы мен анықтығын реттеңіз"</string>
     <string name="accelerometer_summary_on" product="tablet" msgid="5750977897791656412">"Планшетті айналдырғанда бағытын автоматты түрде ауыстыру"</string>
diff --git a/tests/CarDeveloperOptions/res/values-km/strings.xml b/tests/CarDeveloperOptions/res/values-km/strings.xml
index 01f5390..7027289 100644
--- a/tests/CarDeveloperOptions/res/values-km/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-km/strings.xml
@@ -128,7 +128,7 @@
     <string name="bluetooth_notif_title" msgid="5090288898529286011">"សំណើ​ផ្គូផ្គង"</string>
     <string name="bluetooth_notif_message" msgid="6612367890895077938">"ប៉ះដើម្បីផ្គូផ្គងជាមួយ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ។"</string>
     <string name="bluetooth_show_received_files" msgid="5060846395852236652">"ឯកសារ​ដែល​បានទទួល"</string>
-    <string name="bluetooth_show_files_received_via_bluetooth" msgid="1699095577431389560">"បាន​ទទួល​ឯកសារ​តាម​រយៈ​ប៊្លូធូស"</string>
+    <string name="bluetooth_show_files_received_via_bluetooth" msgid="1699095577431389560">"ឯកសារដែលបាន​ទទួល​​តាម​រយៈ​ប៊្លូធូស"</string>
     <string name="device_picker" msgid="8345264486071697705">"ជ្រើស​ឧបករណ៍​ប៊្លូ​ធូ​ស"</string>
     <string name="bluetooth_ask_enablement" msgid="8716802066127746062">"<xliff:g id="APP_NAME">%1$s</xliff:g> ចង់បើកប៊្លូធូស"</string>
     <string name="bluetooth_ask_disablement" msgid="7125319551097350783">"<xliff:g id="APP_NAME">%1$s</xliff:g> ចង់បិទប៊្លូធូស"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ky/strings.xml b/tests/CarDeveloperOptions/res/values-ky/strings.xml
index 5768b44..c775813d 100644
--- a/tests/CarDeveloperOptions/res/values-ky/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ky/strings.xml
@@ -56,7 +56,7 @@
     <string name="radio_info_ims_reg_status" msgid="4771711884059371514">"IMS каттоосу: <xliff:g id="STATUS">%1$s</xliff:g>\nLTE аркылуу аудио чалуу: <xliff:g id="AVAILABILITY_0">%2$s</xliff:g>\nWiFi аркылуу аудио чалуу: <xliff:g id="AVAILABILITY_1">%3$s</xliff:g>\nВидео чалуу: <xliff:g id="AVAILABILITY_2">%4$s</xliff:g>\nUT интерфейс: <xliff:g id="AVAILABILITY_3">%5$s</xliff:g>"</string>
     <string name="radioInfo_service_in" msgid="1297020186765943857">"Тейлөө аймагында"</string>
     <string name="radioInfo_service_out" msgid="8460363463722476510">"Тейлөө аймагынын сыртында"</string>
-    <string name="radioInfo_service_emergency" msgid="7674989004735662599">"Өзгөчө кырдаалда гана чалганга болот"</string>
+    <string name="radioInfo_service_emergency" msgid="7674989004735662599">"Кырсыктаганда гана чалууга болот"</string>
     <string name="radioInfo_service_off" msgid="1873939869994136791">"Радио өчүк"</string>
     <string name="radioInfo_roaming_in" msgid="7059350234710947417">"Роуминг"</string>
     <string name="radioInfo_roaming_not" msgid="7733269160603599835">"Роумингде эмес"</string>
@@ -4515,5 +4515,5 @@
     <string name="automatic_system_heap_dump_summary" msgid="4962129546638974661">"Android тутуму өтө көп эстутумун колдоногондо, автоматтык түрдө анын үймө дампын тартып алуу"</string>
     <string name="wifi_disconnect_button_text" msgid="787688024070426706">"Ажыратуу"</string>
     <string name="wfc_disclaimer_emergency_limitation_title_text" msgid="26884532087670844">"Шашылыш чалуулар"</string>
-    <string name="wfc_disclaimer_emergency_limitation_desc_text" msgid="8726152486964822599">"Операторуңуз Wi‑Fi аркылуу шашылыш чалууларды колдоого албайт.\nТүзмөгүңүз шашылыш чалууну аткаруу үчүн автоматтык түрдө мобилдик тармакка которулат.\nШашылык чалууларды мобилдик тармак иштеген аймактарда гана аткарууга болот."</string>
+    <string name="wfc_disclaimer_emergency_limitation_desc_text" msgid="8726152486964822599">"Операторуңузда кырсыктаганда Wi‑Fi аркылуу чалуу мүмкүнчүлүгү каралган эмес.\nКырсыктаганда жардамга келчү кызматтарга чалганыңызда, түзмөгүңүз автоматтык түрдө мобилдик тармакка которулат.\nМындай кырдаалдарда мобилдик тармак кармаган аймактарда гана чала аласыз."</string>
 </resources>
diff --git a/tests/CarDeveloperOptions/res/values-mcc262-mnc02-ky/strings.xml b/tests/CarDeveloperOptions/res/values-mcc262-mnc02-ky/strings.xml
index 825e8ba..a7fc2a3 100644
--- a/tests/CarDeveloperOptions/res/values-mcc262-mnc02-ky/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-mcc262-mnc02-ky/strings.xml
@@ -16,5 +16,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="wifi_calling_off_explanation_2" msgid="4142074253083399456">\n\n" Өзгөчө кырдаалда Wi-Fi аркылуу чала албайсыз. Өзгөчө кырдаалда чалууга аракет кылганыңызда түзмөгүңүз автоматтык түрдө мобилдик тармакты пайдаланат. Өзгөчө кырдаалда мобилдик тармак кармаган аймактарда гана чала аласыз."</string>
+    <string name="wifi_calling_off_explanation_2" msgid="4142074253083399456">\n\n" Кырсыктаганда Wi-Fi аркылуу чала албайсыз. Мындай кырдаалдарда чалууга аракет кылганыңызда, түзмөгүңүз автоматтык түрдө мобилдик тармакты пайдаланып, мобилдик тармак кармаган аймактарда гана чала аласыз."</string>
 </resources>
diff --git a/tests/CarDeveloperOptions/res/values-mk/strings.xml b/tests/CarDeveloperOptions/res/values-mk/strings.xml
index 1e8fa66..6b7df69 100644
--- a/tests/CarDeveloperOptions/res/values-mk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-mk/strings.xml
@@ -3319,7 +3319,7 @@
     <string name="notification_pulse_title" msgid="4861418327614907116">"Трепкај со сијаличката"</string>
     <string name="lock_screen_notifications_title" msgid="6889072265118747835">"На заклучен екран"</string>
     <string name="locked_work_profile_notification_title" msgid="8307025804986190658">"При заклучен работен профил"</string>
-    <string name="lock_screen_notifications_summary_show" msgid="5788874994455257378">"Прикажи ја целата содржина од известувањето"</string>
+    <string name="lock_screen_notifications_summary_show" msgid="5788874994455257378">"Прикажи ја целата содржина од известувањата"</string>
     <string name="lock_screen_notifications_summary_hide" msgid="3668806866535260143">"Сокриј чувствителни содржини"</string>
     <string name="lock_screen_notifications_summary_disable" msgid="3259929507369817672">"Воопшто не прикажувај известувања"</string>
     <string name="lock_screen_notifications_interstitial_message" msgid="4230189215124387818">"Кога уредот е заклучен, како сакате да се прикажуваат известувањата?"</string>
diff --git a/tests/CarDeveloperOptions/res/values-ml/strings.xml b/tests/CarDeveloperOptions/res/values-ml/strings.xml
index 73bbd68..1d98219 100644
--- a/tests/CarDeveloperOptions/res/values-ml/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-ml/strings.xml
@@ -128,7 +128,7 @@
     <string name="bluetooth_notif_title" msgid="5090288898529286011">"ജോടിയാക്കൽ അഭ്യർത്ഥന"</string>
     <string name="bluetooth_notif_message" msgid="6612367890895077938">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്ന ഉപകരണവുമായി ജോടിയാക്കാൻ ടാപ്പുചെയ്യുക."</string>
     <string name="bluetooth_show_received_files" msgid="5060846395852236652">"സ്വീകരിച്ച ഫയലുകള്‍"</string>
-    <string name="bluetooth_show_files_received_via_bluetooth" msgid="1699095577431389560">"Bluetooth വഴി ഫയലുകൾ സ്വീകരിച്ചു"</string>
+    <string name="bluetooth_show_files_received_via_bluetooth" msgid="1699095577431389560">"Bluetooth വഴി സ്വീകരിച്ച ഫയലുകൾ"</string>
     <string name="device_picker" msgid="8345264486071697705">"ബ്ലൂടൂത്തുപകരണം തിരഞ്ഞെടുക്കൂ"</string>
     <string name="bluetooth_ask_enablement" msgid="8716802066127746062">"Bluetooth ഓണാക്കാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> താൽപ്പര്യപ്പെടുന്നു"</string>
     <string name="bluetooth_ask_disablement" msgid="7125319551097350783">"Bluetooth ഓഫാക്കാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> താൽപ്പര്യപ്പെടുന്നു"</string>
@@ -1225,7 +1225,7 @@
     <string name="night_display_summary_on" msgid="6580571388791426596">"ഓൺ / <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="night_display_summary_on_auto_mode_never" msgid="5461580863060506687">"ഒരിക്കലും സ്വമേധയാ ഓഫാകില്ല"</string>
     <string name="night_display_summary_on_auto_mode_custom" msgid="2200631112239399233">"<xliff:g id="ID_1">%1$s</xliff:g>-ന് സ്വമേധയാ ഓഫാകും"</string>
-    <string name="night_display_summary_on_auto_mode_twilight" msgid="8386769601369289561">"സൂര്യോദയ സമയത്ത് സ്വമേധയാ ഓഫാകും"</string>
+    <string name="night_display_summary_on_auto_mode_twilight" msgid="8386769601369289561">"സൂര്യോദയ സമയത്ത് സ്വയമേവ ഓഫാകും"</string>
     <string name="night_display_activation_on_manual" msgid="8379477527072027346">"ഇപ്പോൾ ഓണാക്കുക"</string>
     <string name="night_display_activation_off_manual" msgid="7776082151269794201">"ഇപ്പോൾ ഓഫാക്കുക"</string>
     <string name="night_display_activation_on_twilight" msgid="5610294051700287249">"സൂര്യോദയം വരെ ഓണാക്കുക"</string>
diff --git a/tests/CarDeveloperOptions/res/values-mr/strings.xml b/tests/CarDeveloperOptions/res/values-mr/strings.xml
index f942c1f..de4c570 100644
--- a/tests/CarDeveloperOptions/res/values-mr/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-mr/strings.xml
@@ -1183,7 +1183,7 @@
     <string name="brightness" msgid="7309120144111305275">"चकाकी स्तर"</string>
     <string name="brightness_title" msgid="5660190946911149690">"चकाकी"</string>
     <string name="brightness_summary" msgid="8687101964451818730">"स्क्रीनची चकाकी समायोजित करा"</string>
-    <string name="auto_brightness_title" msgid="908511534369820426">"अ‍ॅडाप्टिव्ह ब्राइटनेस"</string>
+    <string name="auto_brightness_title" msgid="908511534369820426">"अ‍ॅडॅप्टिव्ह ब्राइटनेस"</string>
     <string name="auto_brightness_summary_on" msgid="121488862610275737">"सुरू"</string>
     <string name="auto_brightness_summary_off" msgid="8569141123211510256">"बंद"</string>
     <string name="auto_brightness_summary_very_low" msgid="7625647285740629347">"प्राधान्य दिलेली उज्ज्वलता खूप कमी आहे"</string>
@@ -3034,7 +3034,7 @@
     <string name="network_dashboard_summary_mobile" msgid="5560545061217580626">"मोबाइल"</string>
     <string name="network_dashboard_summary_data_usage" msgid="4695629715072542102">"डेटा वापर"</string>
     <string name="network_dashboard_summary_hotspot" msgid="3928610802321995214">"हॉटस्पॉट"</string>
-    <string name="connected_devices_dashboard_title" msgid="7795222675849060444">"कनेक्‍ट केलेले डिव्‍हाइस"</string>
+    <string name="connected_devices_dashboard_title" msgid="7795222675849060444">"कनेक्‍ट केलेली डिव्‍हाइस"</string>
     <string name="connected_devices_dashboard_summary" msgid="1072664369515033179">"ब्लूटूथ, ड्रायव्हिंग मोड, NFC"</string>
     <string name="connected_devices_dashboard_no_nfc_summary" msgid="2610085597733526722">"ब्लूटूथ, ड्रायव्हिंग मोड"</string>
     <string name="connected_devices_dashboard_no_driving_mode_summary" msgid="3524409078596318803">"ब्लूटूथ, NFC"</string>
diff --git a/tests/CarDeveloperOptions/res/values-pl/strings.xml b/tests/CarDeveloperOptions/res/values-pl/strings.xml
index 8c29317..cf10b3b 100644
--- a/tests/CarDeveloperOptions/res/values-pl/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-pl/strings.xml
@@ -3382,7 +3382,7 @@
     <string name="other_sound_category_preference_title" msgid="2045757472469840859">"Inne dźwięki i wibracje"</string>
     <string name="configure_notification_settings" msgid="291914315140851270">"Powiadomienia"</string>
     <string name="recent_notifications" msgid="8125865995065032049">"Ostatnio wysłane"</string>
-    <string name="recent_notifications_see_all_title" msgid="4089007770442871469">"Zobacz wszystkie z ostatnich siedmiu dni"</string>
+    <string name="recent_notifications_see_all_title" msgid="4089007770442871469">"Zobacz wszystkie z ostatnich 7 dni"</string>
     <string name="advanced_section_header" msgid="984680389373090015">"Zaawansowane"</string>
     <string name="profile_section_header" msgid="5471479005472037417">"Powiadomienia związane z pracą"</string>
     <string name="asst_capability_prioritizer_title" msgid="3488284760645922160">"Automatyczne nadawanie priorytetów powiadomieniom"</string>
@@ -4066,11 +4066,11 @@
     <string name="cell_data_template" msgid="5473177306229738078">"<xliff:g id="AMOUNT">^1</xliff:g> danych mobilnych"</string>
     <string name="wifi_data_template" msgid="3146090439147042068">"Dane Wi-Fi: <xliff:g id="AMOUNT">^1</xliff:g>"</string>
     <string name="ethernet_data_template" msgid="6414118030827090119">"Dane ethernet: <xliff:g id="AMOUNT">^1</xliff:g>"</string>
-    <string name="billing_cycle" msgid="5740717948341713190">"Dane i limit"</string>
+    <string name="billing_cycle" msgid="5740717948341713190">"Ostrzeżenie dotyczące danych i limit"</string>
     <string name="app_usage_cycle" msgid="213483325132959663">"Cykl użycia danych w aplikacjach"</string>
-    <string name="cell_data_warning" msgid="8902740337286652689">"Próg ostrzegawczy: <xliff:g id="ID_1">^1</xliff:g>"</string>
+    <string name="cell_data_warning" msgid="8902740337286652689">"Ostrzeżenie dotyczące danych: <xliff:g id="ID_1">^1</xliff:g>"</string>
     <string name="cell_data_limit" msgid="3175933829235314233">"Limit danych: <xliff:g id="ID_1">^1</xliff:g>"</string>
-    <string name="cell_data_warning_and_limit" msgid="3846150001253927594">"Próg ostrzegawczy: <xliff:g id="ID_1">^1</xliff:g> / limit danych: <xliff:g id="ID_2">^2</xliff:g>"</string>
+    <string name="cell_data_warning_and_limit" msgid="3846150001253927594">"Ostrzeżenie dotyczące danych: <xliff:g id="ID_1">^1</xliff:g> / limit danych: <xliff:g id="ID_2">^2</xliff:g>"</string>
     <string name="billing_cycle_fragment_summary" msgid="4926047002107855543">"<xliff:g id="ID_1">%1$s</xliff:g>. każdego miesiąca"</string>
     <string name="network_restrictions" msgid="196294262243618198">"Ograniczenia sieci"</string>
     <plurals name="network_restrictions_summary" formatted="false" msgid="1664494781594839837">
@@ -4081,8 +4081,8 @@
     </plurals>
     <string name="operator_warning" msgid="4676042739221117031">"Operator komórkowy może obliczać ilość przesłanych danych inaczej niż urządzenie"</string>
     <string name="data_used_template" msgid="761605393453849477">"Wykorzystano <xliff:g id="ID_1">%1$s</xliff:g>"</string>
-    <string name="set_data_warning" msgid="8115980184415563941">"Ustaw próg ostrzegawczy"</string>
-    <string name="data_warning" msgid="2699207195535036240">"Próg ostrzegawczy"</string>
+    <string name="set_data_warning" msgid="8115980184415563941">"Ustaw ostrzeżenie dotyczące danych"</string>
+    <string name="data_warning" msgid="2699207195535036240">"Ostrzeżenie dotyczące danych"</string>
     <string name="data_warning_footnote" msgid="965724845580257305">"Ostrzeżenie dotyczące użycia danych i limit danych są oparte na pomiarach wykonywanych przez Twoje urządzenie. Dane operatora mogą być inne."</string>
     <string name="set_data_limit" msgid="5043770023229990674">"Ustaw limit transmisji danych"</string>
     <string name="data_limit" msgid="5793521160051596228">"Limit danych"</string>
diff --git a/tests/CarDeveloperOptions/res/values-sq/strings.xml b/tests/CarDeveloperOptions/res/values-sq/strings.xml
index d7f31e1..d5b1709 100644
--- a/tests/CarDeveloperOptions/res/values-sq/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-sq/strings.xml
@@ -2664,7 +2664,7 @@
     <string name="data_usage_menu_show_ethernet" msgid="2130574690318410238">"Shfaq përdorimin e Eternetit"</string>
     <string name="data_usage_menu_hide_ethernet" msgid="1191233197312414533">"Fshih përdorimin e eternetit"</string>
     <string name="data_usage_menu_metered" msgid="3087525150259956831">"Kufizimet e rrjetit"</string>
-    <string name="data_usage_menu_auto_sync" msgid="3350154877737572146">"Të dhënat e autosinkronizimit"</string>
+    <string name="data_usage_menu_auto_sync" msgid="3350154877737572146">"Të dhënat e sinkronizimit automatik"</string>
     <string name="data_usage_menu_sim_cards" msgid="8508154611676507088">"Kartat SIM"</string>
     <string name="data_usage_cellular_data_summary" msgid="9162777397135709280">"U ndërpre në kufi"</string>
     <string name="account_settings_menu_auto_sync" msgid="2673669556006027506">"Auto-sinkronizo të dhënat"</string>
diff --git a/tests/CarDeveloperOptions/res/values-uk/strings.xml b/tests/CarDeveloperOptions/res/values-uk/strings.xml
index 9940077..ca11eb5 100644
--- a/tests/CarDeveloperOptions/res/values-uk/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-uk/strings.xml
@@ -2579,7 +2579,7 @@
     <string name="voice_interactor_preference_summary" msgid="7321365727286121067">"Підтримка команд швидкого запуску та взаємодії"</string>
     <string name="voice_recognizer_preference_summary" msgid="3681161319745912594">"Просте перетворення мовлення на текст"</string>
     <string name="voice_interaction_security_warning" msgid="4986261746316889768">"Ця служба голосового вводу зможе постійно відстежувати голос і контролювати додатки, у яких увімкнено голосовий ввід, від вашого імені. Вона походить із додатка <xliff:g id="VOICE_INPUT_SERVICE_APP_NAME">%s</xliff:g>. Увімкнути цю службу?"</string>
-    <string name="tts_engine_preference_title" msgid="1183116842356275061">"Бажана система"</string>
+    <string name="tts_engine_preference_title" msgid="1183116842356275061">"Система за умовчанням"</string>
     <string name="tts_engine_settings_title" msgid="4079757915136562358">"Налаштування системи"</string>
     <string name="tts_sliders_title" msgid="1927481069989092278">"Темп і тон мовлення"</string>
     <string name="tts_engine_section_title" msgid="7796486438271227076">"Система"</string>
diff --git a/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml b/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml
index 64cf41a..2c94d17 100644
--- a/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml
+++ b/tests/CarDeveloperOptions/res/values-zh-rHK/strings.xml
@@ -1208,7 +1208,7 @@
     <string name="adaptive_sleep_summary_off" msgid="2891586225954973431">"關閉"</string>
     <string name="adaptive_sleep_description" msgid="812673735459170009">"防止在您望向螢幕時螢幕關閉。"</string>
     <string name="adaptive_sleep_privacy" msgid="5706802215479902623">"螢幕意識利用前置鏡頭偵測使用者是否正望向螢幕。此功能只在裝置上使用,同時圖片不會被儲存或傳送至 Google。"</string>
-    <string name="night_display_title" msgid="1305002424893349814">"夜燈模式"</string>
+    <string name="night_display_title" msgid="1305002424893349814">"夜間模式"</string>
     <string name="night_display_text" msgid="5330502493684652527">"「夜燈模式」會將螢幕調校至橙黃色,在光線昏暗的環境下看螢幕或閱讀時就更舒適,並讓您更易入睡。"</string>
     <string name="night_display_auto_mode_title" msgid="8493573087102481588">"設定時間"</string>
     <string name="night_display_auto_mode_never" msgid="2897444637217807088">"無"</string>
@@ -2029,7 +2029,7 @@
     <string name="allow_bind_app_widget_activity_always_allow_bind" msgid="1185486443615658430">"永遠允許「<xliff:g id="WIDGET_HOST_NAME">%1$s</xliff:g>」建立小工具並存取其資料"</string>
     <string name="usage_stats_label" msgid="3128999956478977035">"用量統計資料"</string>
     <string name="testing_usage_stats" msgid="704965692323956976">"用量統計資料"</string>
-    <string name="display_order_text" msgid="2973620313510295873">"排序依據:"</string>
+    <string name="display_order_text" msgid="2973620313510295873">"排序方式:"</string>
     <string name="app_name_label" msgid="2258469951312794816">"應用程式"</string>
     <string name="last_time_used_label" msgid="1119322667349666930">"上次使用時間"</string>
     <string name="usage_time_label" msgid="5615725415876461039">"使用時間"</string>
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFeatureProviderImpl.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFeatureProviderImpl.java
index 87f52e3..de184cf 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFeatureProviderImpl.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFeatureProviderImpl.java
@@ -243,16 +243,15 @@
         ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
 
         if (tile.userHandle == null || tile.isPrimaryProfileOnly()) {
-            mMetricsFeatureProvider.logDashboardStartIntent(mContext, intent, sourceMetricCategory);
+            mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory);
             activity.startActivityForResult(intent, 0);
         } else if (tile.userHandle.size() == 1) {
-            mMetricsFeatureProvider.logDashboardStartIntent(mContext, intent, sourceMetricCategory);
+            mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory);
             activity.startActivityForResultAsUser(intent, 0, tile.userHandle.get(0));
         } else {
             final UserHandle userHandle = intent.getParcelableExtra(EXTRA_USER);
             if (userHandle != null && tile.userHandle.contains(userHandle)) {
-                mMetricsFeatureProvider.logDashboardStartIntent(
-                    mContext, intent, sourceMetricCategory);
+                mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory);
                 activity.startActivityForResultAsUser(intent, 0, userHandle);
             } else {
                 ProfileSelectDialog.show(activity.getSupportFragmentManager(), tile);
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFragment.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFragment.java
index e021e6b..a08ad0f 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFragment.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/dashboard/DashboardFragment.java
@@ -197,8 +197,7 @@
         Collection<List<AbstractPreferenceController>> controllers =
                 mPreferenceControllers.values();
         // If preference contains intent, log it before handling.
-        mMetricsFeatureProvider.logDashboardStartIntent(
-                getContext(), preference.getIntent(), getMetricsCategory());
+        mMetricsFeatureProvider.logStartedIntent(preference.getIntent(), getMetricsCategory());
         // Give all controllers a chance to handle click.
         for (List<AbstractPreferenceController> controllerList : controllers) {
             for (AbstractPreferenceController controller : controllerList) {
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/wifi/WifiConfigController.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/wifi/WifiConfigController.java
index 02b5278..61abd4c 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/wifi/WifiConfigController.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/wifi/WifiConfigController.java
@@ -329,17 +329,10 @@
                 showProxyFields();
                 final CheckBox advancedTogglebox =
                         (CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox);
-                mView.findViewById(R.id.wifi_advanced_toggle).setVisibility(
-                        mAccessPoint.isCarrierAp() ? View.GONE : View.VISIBLE);
                 advancedTogglebox.setOnCheckedChangeListener(this);
                 advancedTogglebox.setChecked(showAdvancedFields);
                 mView.findViewById(R.id.wifi_advanced_fields)
                         .setVisibility(showAdvancedFields ? View.VISIBLE : View.GONE);
-                if (mAccessPoint.isCarrierAp()) {
-                    addRow(group, R.string.wifi_carrier_connect,
-                            String.format(mContext.getString(R.string.wifi_carrier_content),
-                            mAccessPoint.getCarrierName()));
-                }
             }
 
             if (mMode == WifiConfigUiBase.MODE_MODIFY) {
@@ -976,10 +969,6 @@
             mEapIdentityView = (TextView) mView.findViewById(R.id.identity);
             mEapAnonymousView = (TextView) mView.findViewById(R.id.anonymous);
 
-            if (mAccessPoint != null && mAccessPoint.isCarrierAp()) {
-                mEapMethodSpinner.setSelection(mAccessPoint.getCarrierApEapType());
-            }
-
             loadCertificates(
                     mEapCaCertSpinner,
                     Credentials.CA_CERTIFICATE,
@@ -1147,9 +1136,6 @@
                 setUserCertInvisible();
                 setPasswordInvisible();
                 setIdentityInvisible();
-                if (mAccessPoint != null && mAccessPoint.isCarrierAp()) {
-                    setEapMethodInvisible();
-                }
                 break;
         }
 
diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
index a30b9b4..b069ef4 100644
--- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
+++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
@@ -146,13 +146,6 @@
 
         <activity android:name=".activityview.ActivityViewTestFragment"/>
 
-        <!-- temporary solution until b/68882625 is fixed. -->
-        <receiver android:name=".touchsound.DisableTouchSoundOnBoot" android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.BOOT_COMPLETED"/>
-            </intent-filter>
-        </receiver>
-
         <service android:name=".vendorservice.LogLifecycleService"
                  android:exported="false" android:directBootAware="true">
         </service>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/touchsound/DisableTouchSoundOnBoot.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/touchsound/DisableTouchSoundOnBoot.java
deleted file mode 100644
index 2c81bda..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/touchsound/DisableTouchSoundOnBoot.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.car.kitchensink.touchsound;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.Settings;
-import android.util.Log;
-
-/**
- * Temp solution until b/68882625 is fixed
- */
-public class DisableTouchSoundOnBoot extends BroadcastReceiver {
-
-    private static final String KEY_TOUCH_SOUNDS = "sound_effects_enabled";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        Log.w("DisableTouchSoundOnBoot", "disabling touch sound");
-        Settings.System.putInt(context.getContentResolver(), KEY_TOUCH_SOUNDS, 0);
-    }
-}
diff --git a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
index eef9638..56540dd 100644
--- a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
@@ -17,10 +17,12 @@
 package com.android.car;
 
 import android.car.Car;
+import android.car.VehicleAreaType;
 import android.car.hardware.CarPropertyConfig;
 import android.car.hardware.CarPropertyValue;
 import android.car.hardware.property.CarPropertyManager;
 import android.hardware.automotive.vehicle.V2_0.VehicleArea;
+import android.hardware.automotive.vehicle.V2_0.VehicleAreaSeat;
 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyGroup;
 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType;
@@ -67,9 +69,17 @@
     private static final Object[] EXPECTED_VALUE_2 = {"android", true, 3, 1.1f, 2f};
 
     private static final int CUSTOM_GLOBAL_MIXED_PROP_ID_1 =
-            0x1101 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.MIXED | VehicleArea.GLOBAL;
+            0x1101 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.MIXED | VehicleArea.SEAT;
     private static final int CUSTOM_GLOBAL_MIXED_PROP_ID_2 =
             0x1102 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.MIXED | VehicleArea.GLOBAL;
+    // Use FAKE_PROPERTY_ID to test api return null or throw exception.
+    private static final int FAKE_PROPERTY_ID = 0x111;
+
+    private static final int DRIVER_SIDE_AREA_ID = VehicleAreaSeat.ROW_1_LEFT
+                                                    | VehicleAreaSeat.ROW_2_LEFT;
+    private static final int PASSENGER_SIDE_AREA_ID = VehicleAreaSeat.ROW_1_RIGHT
+                                                    | VehicleAreaSeat.ROW_2_CENTER
+                                                    | VehicleAreaSeat.ROW_2_RIGHT;
 
     private CarPropertyManager mManager;
 
@@ -116,14 +126,49 @@
         Assert.assertArrayEquals(EXPECTED_VALUE_2, result.getValue());
     }
 
+    @Test
+    public void testGetPropertyConfig() {
+        CarPropertyConfig config = mManager.getCarPropertyConfig(CUSTOM_GLOBAL_MIXED_PROP_ID_1);
+        Assert.assertEquals(CUSTOM_GLOBAL_MIXED_PROP_ID_1, config.getPropertyId());
+        // return null if can not find the propertyConfig for the property.
+        Assert.assertNull(mManager.getCarPropertyConfig(FAKE_PROPERTY_ID));
+    }
+
+    @Test
+    public void testGetAreaId() {
+        int result = mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_1, VehicleAreaSeat.ROW_1_LEFT);
+        Assert.assertEquals(DRIVER_SIDE_AREA_ID, result);
+
+        //test for the GLOBAL property
+        int globalAreaId =
+                mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_2, VehicleAreaSeat.ROW_1_LEFT);
+        Assert.assertEquals(VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, globalAreaId);
+
+        //test exception
+        try {
+            int areaId = mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_1,
+                    VehicleAreaSeat.ROW_3_CENTER);
+            Assert.fail("Unexpected areaId: " + areaId);
+        } catch (IllegalArgumentException e) {
+            Log.v(TAG, e.getMessage());
+        }
+
+        try {
+            // test exception
+            int areaIdForFakeProp = mManager.getAreaId(FAKE_PROPERTY_ID,
+                    VehicleAreaSeat.ROW_1_LEFT);
+            Assert.fail("Unexpected areaId for fake property: " + areaIdForFakeProp);
+        } catch (IllegalArgumentException e) {
+            Log.v(TAG, e.getMessage());
+        }
+    }
 
     @Override
     protected synchronized void configureMockedHal() {
         PropertyHandler handler = new PropertyHandler();
-        addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_1, handler).setConfigArray(CONFIG_ARRAY_1);
+        addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_1, handler).setConfigArray(CONFIG_ARRAY_1)
+                .addAreaConfig(DRIVER_SIDE_AREA_ID).addAreaConfig(PASSENGER_SIDE_AREA_ID);
         addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_2, handler).setConfigArray(CONFIG_ARRAY_2);
-
-
     }
 
     private class PropertyHandler implements VehicleHalPropertyHandler {
diff --git a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
index c0369a2..6c06b56 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
@@ -18,22 +18,33 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
-import static org.mockito.Mockito.mock;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
 import android.car.hardware.power.ICarPowerStateListener;
 import android.car.userlib.CarUserManagerHelper;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReq;
 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateShutdownParam;
 import android.os.RemoteException;
-import android.test.AndroidTestCase;
+import android.os.UserManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
+import androidx.test.platform.app.InstrumentationRegistry;
+
 import com.android.car.hal.PowerHalService;
 import com.android.car.hal.PowerHalService.PowerState;
 import com.android.car.systeminterface.DisplayInterface;
@@ -43,55 +54,95 @@
 import com.android.car.systeminterface.WakeLockInterface;
 import com.android.car.test.utils.TemporaryDirectory;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoSession;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.quality.Strictness;
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
 import java.time.Duration;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
 @SmallTest
-public class CarPowerManagementServiceTest extends AndroidTestCase {
+@RunWith(MockitoJUnitRunner.class)
+public class CarPowerManagementServiceTest {
     private static final String TAG = CarPowerManagementServiceTest.class.getSimpleName();
     private static final long WAIT_TIMEOUT_MS = 2000;
     private static final long WAIT_TIMEOUT_LONG_MS = 5000;
+    private static final int NO_USER_INFO_FLAGS = 0;
 
     private final MockDisplayInterface mDisplayInterface = new MockDisplayInterface();
     private final MockSystemStateInterface mSystemStateInterface = new MockSystemStateInterface();
     private final MockWakeLockInterface mWakeLockInterface = new MockWakeLockInterface();
     private final MockIOInterface mIOInterface = new MockIOInterface();
     private final PowerSignalListener mPowerSignalListener = new PowerSignalListener();
+    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
 
     private MockitoSession mSession;
-    private CarUserManagerHelper mCarUserManagerHelper;
+
     private MockedPowerHalService mPowerHal;
     private SystemInterface mSystemInterface;
     private CarPowerManagementService mService;
     private CompletableFuture<Void> mFuture;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Mock
+    private CarUserManagerHelper mCarUserManagerHelper;
+    @Mock
+    private UserManager mUserManager;
+    @Mock
+    private Resources mResources;
+
+    // Wakeup time for the test; it's automatically set based on @WakeupTime annotation
+    private int mWakeupTime;
+
+    @Rule
+    public final TestRule setWakeupTimeRule = new TestWatcher() {
+        protected void starting(Description description) {
+            final String testName = description.getMethodName();
+            try {
+                Method testMethod = CarPowerManagementServiceTest.class.getMethod(testName);
+                WakeupTime wakeupAnnotation = testMethod.getAnnotation(WakeupTime.class);
+                if (wakeupAnnotation != null) {
+                    mWakeupTime = wakeupAnnotation.value();
+                    Log.d(TAG, "Using annotated wakeup time: " + mWakeupTime);
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Could not infer wakeupTime for " + testName, e);
+            }
+        }
+    };
+
+    @Before
+    public void setUp() throws Exception {
         mSession = mockitoSession()
                 .strictness(Strictness.LENIENT)
                 .spyStatic(ActivityManager.class)
                 .startMocking();
         mPowerHal = new MockedPowerHalService(true /*isPowerStateSupported*/,
                 true /*isDeepSleepAllowed*/, true /*isTimedWakeupAllowed*/);
-        mSystemInterface = SystemInterface.Builder.defaultSystemInterface(getContext())
+        mSystemInterface = SystemInterface.Builder.defaultSystemInterface(mContext)
             .withDisplayInterface(mDisplayInterface)
             .withSystemStateInterface(mSystemStateInterface)
             .withWakeLockInterface(mWakeLockInterface)
             .withIOInterface(mIOInterface).build();
-        mCarUserManagerHelper = mock(CarUserManagerHelper.class);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
         if (mService != null) {
             mService.release();
         }
@@ -102,41 +153,54 @@
     /**
      * Helper method to create mService and initialize a test case
      */
-    private void initTest(int wakeupTime) throws Exception {
-        mService = new CarPowerManagementService(getContext(), mPowerHal, mSystemInterface,
-                mCarUserManagerHelper);
+    private void initTest() throws Exception {
+        when(mResources.getInteger(R.integer.maxGarageModeRunningDurationInSecs))
+                .thenReturn(900);
+        when(mResources.getBoolean(R.bool.config_disableUserSwitchDuringResume))
+                .thenReturn(false);
+
+        Log.i(TAG, "initTest(): overridden overlay properties: "
+                + "config_disableUserSwitchDuringResume="
+                + mResources.getBoolean(R.bool.config_disableUserSwitchDuringResume)
+                + ", maxGarageModeRunningDurationInSecs="
+                + mResources.getInteger(R.integer.maxGarageModeRunningDurationInSecs));
+        mService = new CarPowerManagementService(mContext, mResources, mPowerHal,
+                mSystemInterface, mCarUserManagerHelper);
         mService.init();
         CarPowerManagementService.setShutdownPrepareTimeout(0);
         mPowerHal.setSignalListener(mPowerSignalListener);
-        if (wakeupTime > 0) {
+        if (mWakeupTime > 0) {
             registerListenerToService();
-            mService.scheduleNextWakeupTime(wakeupTime);
+            mService.scheduleNextWakeupTime(mWakeupTime);
         }
         assertStateReceived(MockedPowerHalService.SET_WAIT_FOR_VHAL, 0);
     }
 
+    @Test
     public void testBootComplete() throws Exception {
-        initTest(0);
+        initTest();
     }
 
+    @Test
     public void testDisplayOn() throws Exception {
         // start with display off
         mSystemInterface.setDisplayState(false);
         mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS);
-        initTest(0);
+        initTest();
         // Transition to ON state
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.ON, 0));
 
         // display should be turned on as it started with off state.
-        assertTrue(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
+        assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isTrue();
     }
 
+    @Test
     public void testShutdown() throws Exception {
-        initTest(0);
+        initTest();
 
         // Transition to ON state
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.ON, 0));
-        assertTrue(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
+        assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isTrue();
 
         mPowerHal.setCurrentPowerState(
                 new PowerState(
@@ -145,17 +209,18 @@
         // Since modules have to manually schedule next wakeup, we should not schedule next wakeup
         // To test module behavior, we need to actually implement mock listener module.
         assertStateReceived(PowerHalService.SET_SHUTDOWN_START, 0);
-        assertFalse(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
+        assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isFalse();
         mPowerSignalListener.waitForShutdown(WAIT_TIMEOUT_MS);
         mSystemStateInterface.waitForShutdown(WAIT_TIMEOUT_MS);
     }
 
+    @Test
     public void testSleepImmediately() throws Exception {
-        initTest(0);
+        initTest();
 
         // Transition to ON state
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.ON, 0));
-        assertTrue(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
+        assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isTrue();
 
         mPowerHal.setCurrentPowerState(
                 new PowerState(
@@ -164,30 +229,32 @@
         // Since modules have to manually schedule next wakeup, we should not schedule next wakeup
         // To test module behavior, we need to actually implement mock listener module.
         assertStateReceived(PowerHalService.SET_SHUTDOWN_START, 0);
-        assertFalse(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
+        assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isFalse();
         mPowerSignalListener.waitForShutdown(WAIT_TIMEOUT_MS);
         mSystemStateInterface.waitForShutdown(WAIT_TIMEOUT_MS);
     }
 
+    @Test
+    @WakeupTime(100)
     public void testShutdownWithProcessing() throws Exception {
-        final int wakeupTime = 100;
-        initTest(wakeupTime);
+        initTest();
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, 0));
         assertStateReceivedForShutdownOrSleepWithPostpone(
-                PowerHalService.SET_SHUTDOWN_START, WAIT_TIMEOUT_LONG_MS, wakeupTime);
+                PowerHalService.SET_SHUTDOWN_START, WAIT_TIMEOUT_LONG_MS, mWakeupTime);
         mPowerSignalListener.waitForShutdown(WAIT_TIMEOUT_MS);
         // Send the finished signal
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.FINISHED, 0));
         mSystemStateInterface.waitForShutdown(WAIT_TIMEOUT_MS);
     }
 
+    @Test
+    @WakeupTime(100)
     public void testSleepEntryAndWakeup() throws Exception {
-        final int wakeupTime = 100;
-        initTest(wakeupTime);
+        initTest();
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE,
                 VehicleApPowerStateShutdownParam.CAN_SLEEP));
         assertStateReceivedForShutdownOrSleepWithPostpone(
-                PowerHalService.SET_DEEP_SLEEP_ENTRY, WAIT_TIMEOUT_LONG_MS, wakeupTime);
+                PowerHalService.SET_DEEP_SLEEP_ENTRY, WAIT_TIMEOUT_LONG_MS, mWakeupTime);
         mPowerSignalListener.waitForSleepEntry(WAIT_TIMEOUT_MS);
         // Send the finished signal from HAL to CPMS
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.FINISHED, 0));
@@ -196,51 +263,57 @@
         mPowerSignalListener.waitForSleepExit(WAIT_TIMEOUT_MS);
     }
 
+    @Test
     public void testSleepEntryAndWakeUpForProcessing() throws Exception {
-        final int wakeupTime = 100;
-        initTest(wakeupTime);
+        initTest();
+        setUserInfo(10, NO_USER_INFO_FLAGS);
+        setUserInfo(11, NO_USER_INFO_FLAGS);
+        setCurrentUser(10);
+        setInitialUser(11);
 
-        // set up for user switching after display on
-        final int currentUserId = 10;
-        final int newUserId = 11;
-        when(mCarUserManagerHelper.getInitialUser()).thenReturn(newUserId);
-        when(ActivityManager.getCurrentUser()).thenReturn(currentUserId);
+        suspendAndResumeForUserSwitchingTests();
 
-        mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.ON, 0));
-        assertTrue(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
+        verifyUserSwitched(11);
+    }
+
+    private void suspendAndResumeForUserSwitchingTests() throws Exception {
+        Log.d(TAG, "suspend()");
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE,
                 VehicleApPowerStateShutdownParam.CAN_SLEEP));
-        assertFalse(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
+        assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isFalse();
         assertStateReceivedForShutdownOrSleepWithPostpone(
-                PowerHalService.SET_DEEP_SLEEP_ENTRY, WAIT_TIMEOUT_LONG_MS, wakeupTime);
+                PowerHalService.SET_DEEP_SLEEP_ENTRY, WAIT_TIMEOUT_LONG_MS, mWakeupTime);
         mPowerSignalListener.waitForSleepEntry(WAIT_TIMEOUT_MS);
+
         // Send the finished signal
+        Log.d(TAG, "resume()");
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.FINISHED, 0));
         mSystemStateInterface.setWakeupCausedByTimer(true);
         mSystemStateInterface.waitForSleepEntryAndWakeup(WAIT_TIMEOUT_MS);
         assertStateReceived(PowerHalService.SET_DEEP_SLEEP_EXIT, 0);
         mPowerSignalListener.waitForSleepExit(WAIT_TIMEOUT_MS);
-        mService.scheduleNextWakeupTime(wakeupTime);
+        mService.scheduleNextWakeupTime(mWakeupTime);
         // second processing after wakeup
-        assertFalse(mDisplayInterface.getDisplayState());
-        // do not skip user switching part.
-        mService.clearIsBootingOrResuming();
+        assertThat(mDisplayInterface.getDisplayState()).isFalse();
+
+        mService.setStateForTesting(/* isBooting= */ false, /* isResuming= */ true);
+
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.ON, 0));
-        assertTrue(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS));
-        // user switching should have been requested.
-        verify(mCarUserManagerHelper, times(1)).switchToUserId(newUserId);
+        assertThat(mDisplayInterface.waitForDisplayStateChange(WAIT_TIMEOUT_MS)).isTrue();
+        // Should wait until Handler has finished ON processing.
+        CarServiceUtils.runOnLooperSync(mService.getHandlerThread().getLooper(), () -> { });
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE,
                 VehicleApPowerStateShutdownParam.CAN_SLEEP));
         assertStateReceivedForShutdownOrSleepWithPostpone(
-                PowerHalService.SET_DEEP_SLEEP_ENTRY, WAIT_TIMEOUT_LONG_MS, wakeupTime);
+                PowerHalService.SET_DEEP_SLEEP_ENTRY, WAIT_TIMEOUT_LONG_MS, mWakeupTime);
         mPowerSignalListener.waitForSleepEntry(WAIT_TIMEOUT_MS);
         mPowerHal.setCurrentPowerState(new PowerState(VehicleApPowerStateReq.FINISHED, 0));
-        // PM will shutdown system as it was not woken-up due to timer and it is not power on.
+        // PM will shutdown system as it was not woken-up due timer and it is not power on.
         mSystemStateInterface.setWakeupCausedByTimer(false);
         mSystemStateInterface.waitForSleepEntryAndWakeup(WAIT_TIMEOUT_MS);
         // Since we just woke up from shutdown, wake up time will be 0
         assertStateReceived(PowerHalService.SET_DEEP_SLEEP_EXIT, 0);
-        assertFalse(mDisplayInterface.getDisplayState());
+        assertThat(mDisplayInterface.getDisplayState()).isFalse();
     }
 
     private void registerListenerToService() {
@@ -265,8 +338,8 @@
 
     private void assertStateReceived(int expectedState, int expectedParam) throws Exception {
         int[] state = mPowerHal.waitForSend(WAIT_TIMEOUT_MS);
-        assertEquals(expectedState, state[0]);
-        assertEquals(expectedParam, state[1]);
+        assertThat(state[0]).isEqualTo(expectedState);
+        assertThat(state[1]).isEqualTo(expectedParam);
     }
 
     private void assertStateReceivedForShutdownOrSleepWithPostpone(
@@ -280,7 +353,7 @@
                 continue;
             }
             if (state[0] == lastState) {
-                assertEquals(expectedParamForShutdownOrSuspend, state[1]);
+                assertThat(state[1]).isEqualTo(expectedParamForShutdownOrSuspend);
                 return;
             }
         }
@@ -293,6 +366,30 @@
         }
     }
 
+    private void setInitialUser(int userId) {
+        when(mCarUserManagerHelper.getInitialUser()).thenReturn(userId);
+    }
+
+    private void setCurrentUser(int userId) {
+        when(ActivityManager.getCurrentUser()).thenReturn(userId);
+    }
+
+    private void setUserInfo(int userId, int flags) {
+        setUserInfo(userId, /* name= */ null, flags);
+    }
+
+    private void setUserInfo(int userId, @Nullable String name, int flags) {
+        final UserInfo userInfo = new UserInfo();
+        userInfo.id = userId;
+        userInfo.name = name;
+        userInfo.flags = flags;
+        when(mUserManager.getUserInfo(userId)).thenReturn(userInfo);
+    }
+
+    private void verifyUserSwitched(int userId) {
+        verify(mCarUserManagerHelper, times(1)).switchToUserId(userId);
+    }
+
     private static final class MockDisplayInterface implements DisplayInterface {
         private boolean mDisplayOn = true;
         private final Semaphore mDisplayStateWait = new Semaphore(0);
@@ -446,4 +543,10 @@
             }
         }
     }
+
+    @Retention(RUNTIME)
+    @Target({METHOD})
+    public static @interface WakeupTime {
+        int value();
+    }
 }
diff --git a/tools/emulator/VehicleHalProto_pb2.py b/tools/emulator/VehicleHalProto_pb2.py
index 3278ed7..6e964f6 100644
--- a/tools/emulator/VehicleHalProto_pb2.py
+++ b/tools/emulator/VehicleHalProto_pb2.py
@@ -1,153 +1,164 @@
+# -*- coding: utf-8 -*-
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: VehicleHalProto.proto
 
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
 from google.protobuf.internal import enum_type_wrapper
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
 from google.protobuf import reflection as _reflection
-from google.protobuf import descriptor_pb2
+from google.protobuf import symbol_database as _symbol_database
 # @@protoc_insertion_point(imports)
 
+_sym_db = _symbol_database.Default()
+
 
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='VehicleHalProto.proto',
-  package='emulator',
-  serialized_pb='\n\x15VehicleHalProto.proto\x12\x08\x65mulator\"\xba\x01\n\x11VehicleAreaConfig\x12\x0f\n\x07\x61rea_id\x18\x01 \x02(\x05\x12\x17\n\x0fmin_int32_value\x18\x02 \x01(\x11\x12\x17\n\x0fmax_int32_value\x18\x03 \x01(\x11\x12\x17\n\x0fmin_int64_value\x18\x04 \x01(\x12\x12\x17\n\x0fmax_int64_value\x18\x05 \x01(\x12\x12\x17\n\x0fmin_float_value\x18\x06 \x01(\x02\x12\x17\n\x0fmax_float_value\x18\x07 \x01(\x02\"\x9b\x02\n\x11VehiclePropConfig\x12\x0c\n\x04prop\x18\x01 \x02(\x05\x12\x0e\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x05\x12\x13\n\x0b\x63hange_mode\x18\x03 \x01(\x05\x12\x12\n\nvalue_type\x18\x04 \x01(\x05\x12\x17\n\x0fsupported_areas\x18\x05 \x01(\x05\x12\x31\n\x0c\x61rea_configs\x18\x06 \x03(\x0b\x32\x1b.emulator.VehicleAreaConfig\x12\x14\n\x0c\x63onfig_flags\x18\x07 \x01(\x05\x12\x14\n\x0c\x63onfig_array\x18\x08 \x03(\x05\x12\x15\n\rconfig_string\x18\t \x01(\t\x12\x17\n\x0fmin_sample_rate\x18\n \x01(\x02\x12\x17\n\x0fmax_sample_rate\x18\x0b \x01(\x02\"\xf2\x01\n\x10VehiclePropValue\x12\x0c\n\x04prop\x18\x01 \x02(\x05\x12\x12\n\nvalue_type\x18\x02 \x01(\x05\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\x12+\n\x06status\x18\n \x01(\x0e\x32\x1b.emulator.VehiclePropStatus\x12\x0f\n\x07\x61rea_id\x18\x04 \x01(\x05\x12\x14\n\x0cint32_values\x18\x05 \x03(\x11\x12\x14\n\x0cint64_values\x18\x06 \x03(\x12\x12\x14\n\x0c\x66loat_values\x18\x07 \x03(\x02\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\x12\x13\n\x0b\x62ytes_value\x18\t \x01(\x0c\"/\n\x0eVehiclePropGet\x12\x0c\n\x04prop\x18\x01 \x02(\x05\x12\x0f\n\x07\x61rea_id\x18\x02 \x01(\x05\"\xd8\x01\n\x0f\x45mulatorMessage\x12#\n\x08msg_type\x18\x01 \x02(\x0e\x32\x11.emulator.MsgType\x12 \n\x06status\x18\x02 \x01(\x0e\x32\x10.emulator.Status\x12&\n\x04prop\x18\x03 \x03(\x0b\x32\x18.emulator.VehiclePropGet\x12+\n\x06\x63onfig\x18\x04 \x03(\x0b\x32\x1b.emulator.VehiclePropConfig\x12)\n\x05value\x18\x05 \x03(\x0b\x32\x1a.emulator.VehiclePropValue*\x8a\x02\n\x07MsgType\x12\x12\n\x0eGET_CONFIG_CMD\x10\x00\x12\x13\n\x0fGET_CONFIG_RESP\x10\x01\x12\x16\n\x12GET_CONFIG_ALL_CMD\x10\x02\x12\x17\n\x13GET_CONFIG_ALL_RESP\x10\x03\x12\x14\n\x10GET_PROPERTY_CMD\x10\x04\x12\x15\n\x11GET_PROPERTY_RESP\x10\x05\x12\x18\n\x14GET_PROPERTY_ALL_CMD\x10\x06\x12\x19\n\x15GET_PROPERTY_ALL_RESP\x10\x07\x12\x14\n\x10SET_PROPERTY_CMD\x10\x08\x12\x15\n\x11SET_PROPERTY_RESP\x10\t\x12\x16\n\x12SET_PROPERTY_ASYNC\x10\n*\xfb\x01\n\x06Status\x12\r\n\tRESULT_OK\x10\x00\x12\x11\n\rERROR_UNKNOWN\x10\x01\x12\x1b\n\x17\x45RROR_UNIMPLEMENTED_CMD\x10\x02\x12\x1a\n\x16\x45RROR_INVALID_PROPERTY\x10\x03\x12\x19\n\x15\x45RROR_INVALID_AREA_ID\x10\x04\x12 \n\x1c\x45RROR_PROPERTY_UNINITIALIZED\x10\x05\x12\x1d\n\x19\x45RROR_WRITE_ONLY_PROPERTY\x10\x06\x12\x1d\n\x19\x45RROR_MEMORY_ALLOC_FAILED\x10\x07\x12\x1b\n\x17\x45RROR_INVALID_OPERATION\x10\x08*>\n\x11VehiclePropStatus\x12\r\n\tAVAILABLE\x10\x00\x12\x0f\n\x0bUNAVAILABLE\x10\x01\x12\t\n\x05\x45RROR\x10\x02\x42\x02H\x03')
+  package='vhal_proto',
+  syntax='proto2',
+  serialized_options=None,
+  serialized_pb=_b('\n\x15VehicleHalProto.proto\x12\nvhal_proto\"\xba\x01\n\x11VehicleAreaConfig\x12\x0f\n\x07\x61rea_id\x18\x01 \x02(\x05\x12\x17\n\x0fmin_int32_value\x18\x02 \x01(\x11\x12\x17\n\x0fmax_int32_value\x18\x03 \x01(\x11\x12\x17\n\x0fmin_int64_value\x18\x04 \x01(\x12\x12\x17\n\x0fmax_int64_value\x18\x05 \x01(\x12\x12\x17\n\x0fmin_float_value\x18\x06 \x01(\x02\x12\x17\n\x0fmax_float_value\x18\x07 \x01(\x02\"\x9d\x02\n\x11VehiclePropConfig\x12\x0c\n\x04prop\x18\x01 \x02(\x05\x12\x0e\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x05\x12\x13\n\x0b\x63hange_mode\x18\x03 \x01(\x05\x12\x12\n\nvalue_type\x18\x04 \x01(\x05\x12\x17\n\x0fsupported_areas\x18\x05 \x01(\x05\x12\x33\n\x0c\x61rea_configs\x18\x06 \x03(\x0b\x32\x1d.vhal_proto.VehicleAreaConfig\x12\x14\n\x0c\x63onfig_flags\x18\x07 \x01(\x05\x12\x14\n\x0c\x63onfig_array\x18\x08 \x03(\x05\x12\x15\n\rconfig_string\x18\t \x01(\t\x12\x17\n\x0fmin_sample_rate\x18\n \x01(\x02\x12\x17\n\x0fmax_sample_rate\x18\x0b \x01(\x02\"\xf4\x01\n\x10VehiclePropValue\x12\x0c\n\x04prop\x18\x01 \x02(\x05\x12\x12\n\nvalue_type\x18\x02 \x01(\x05\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\x12-\n\x06status\x18\n \x01(\x0e\x32\x1d.vhal_proto.VehiclePropStatus\x12\x0f\n\x07\x61rea_id\x18\x04 \x01(\x05\x12\x14\n\x0cint32_values\x18\x05 \x03(\x11\x12\x14\n\x0cint64_values\x18\x06 \x03(\x12\x12\x14\n\x0c\x66loat_values\x18\x07 \x03(\x02\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\x12\x13\n\x0b\x62ytes_value\x18\t \x01(\x0c\"/\n\x0eVehiclePropGet\x12\x0c\n\x04prop\x18\x01 \x02(\x05\x12\x0f\n\x07\x61rea_id\x18\x02 \x01(\x05\"\xe2\x01\n\x0f\x45mulatorMessage\x12%\n\x08msg_type\x18\x01 \x02(\x0e\x32\x13.vhal_proto.MsgType\x12\"\n\x06status\x18\x02 \x01(\x0e\x32\x12.vhal_proto.Status\x12(\n\x04prop\x18\x03 \x03(\x0b\x32\x1a.vhal_proto.VehiclePropGet\x12-\n\x06\x63onfig\x18\x04 \x03(\x0b\x32\x1d.vhal_proto.VehiclePropConfig\x12+\n\x05value\x18\x05 \x03(\x0b\x32\x1c.vhal_proto.VehiclePropValue*\x8a\x02\n\x07MsgType\x12\x12\n\x0eGET_CONFIG_CMD\x10\x00\x12\x13\n\x0fGET_CONFIG_RESP\x10\x01\x12\x16\n\x12GET_CONFIG_ALL_CMD\x10\x02\x12\x17\n\x13GET_CONFIG_ALL_RESP\x10\x03\x12\x14\n\x10GET_PROPERTY_CMD\x10\x04\x12\x15\n\x11GET_PROPERTY_RESP\x10\x05\x12\x18\n\x14GET_PROPERTY_ALL_CMD\x10\x06\x12\x19\n\x15GET_PROPERTY_ALL_RESP\x10\x07\x12\x14\n\x10SET_PROPERTY_CMD\x10\x08\x12\x15\n\x11SET_PROPERTY_RESP\x10\t\x12\x16\n\x12SET_PROPERTY_ASYNC\x10\n*\xfb\x01\n\x06Status\x12\r\n\tRESULT_OK\x10\x00\x12\x11\n\rERROR_UNKNOWN\x10\x01\x12\x1b\n\x17\x45RROR_UNIMPLEMENTED_CMD\x10\x02\x12\x1a\n\x16\x45RROR_INVALID_PROPERTY\x10\x03\x12\x19\n\x15\x45RROR_INVALID_AREA_ID\x10\x04\x12 \n\x1c\x45RROR_PROPERTY_UNINITIALIZED\x10\x05\x12\x1d\n\x19\x45RROR_WRITE_ONLY_PROPERTY\x10\x06\x12\x1d\n\x19\x45RROR_MEMORY_ALLOC_FAILED\x10\x07\x12\x1b\n\x17\x45RROR_INVALID_OPERATION\x10\x08*>\n\x11VehiclePropStatus\x12\r\n\tAVAILABLE\x10\x00\x12\x0f\n\x0bUNAVAILABLE\x10\x01\x12\t\n\x05\x45RROR\x10\x02')
+)
 
 _MSGTYPE = _descriptor.EnumDescriptor(
   name='MsgType',
-  full_name='emulator.MsgType',
+  full_name='vhal_proto.MsgType',
   filename=None,
   file=DESCRIPTOR,
   values=[
     _descriptor.EnumValueDescriptor(
       name='GET_CONFIG_CMD', index=0, number=0,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='GET_CONFIG_RESP', index=1, number=1,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='GET_CONFIG_ALL_CMD', index=2, number=2,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='GET_CONFIG_ALL_RESP', index=3, number=3,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='GET_PROPERTY_CMD', index=4, number=4,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='GET_PROPERTY_RESP', index=5, number=5,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='GET_PROPERTY_ALL_CMD', index=6, number=6,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='GET_PROPERTY_ALL_RESP', index=7, number=7,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='SET_PROPERTY_CMD', index=8, number=8,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='SET_PROPERTY_RESP', index=9, number=9,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='SET_PROPERTY_ASYNC', index=10, number=10,
-      options=None,
+      serialized_options=None,
       type=None),
   ],
   containing_type=None,
-  options=None,
-  serialized_start=1024,
-  serialized_end=1290,
+  serialized_options=None,
+  serialized_start=1040,
+  serialized_end=1306,
 )
+_sym_db.RegisterEnumDescriptor(_MSGTYPE)
 
 MsgType = enum_type_wrapper.EnumTypeWrapper(_MSGTYPE)
 _STATUS = _descriptor.EnumDescriptor(
   name='Status',
-  full_name='emulator.Status',
+  full_name='vhal_proto.Status',
   filename=None,
   file=DESCRIPTOR,
   values=[
     _descriptor.EnumValueDescriptor(
       name='RESULT_OK', index=0, number=0,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_UNKNOWN', index=1, number=1,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_UNIMPLEMENTED_CMD', index=2, number=2,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_INVALID_PROPERTY', index=3, number=3,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_INVALID_AREA_ID', index=4, number=4,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_PROPERTY_UNINITIALIZED', index=5, number=5,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_WRITE_ONLY_PROPERTY', index=6, number=6,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_MEMORY_ALLOC_FAILED', index=7, number=7,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR_INVALID_OPERATION', index=8, number=8,
-      options=None,
+      serialized_options=None,
       type=None),
   ],
   containing_type=None,
-  options=None,
-  serialized_start=1293,
-  serialized_end=1544,
+  serialized_options=None,
+  serialized_start=1309,
+  serialized_end=1560,
 )
+_sym_db.RegisterEnumDescriptor(_STATUS)
 
 Status = enum_type_wrapper.EnumTypeWrapper(_STATUS)
 _VEHICLEPROPSTATUS = _descriptor.EnumDescriptor(
   name='VehiclePropStatus',
-  full_name='emulator.VehiclePropStatus',
+  full_name='vhal_proto.VehiclePropStatus',
   filename=None,
   file=DESCRIPTOR,
   values=[
     _descriptor.EnumValueDescriptor(
       name='AVAILABLE', index=0, number=0,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='UNAVAILABLE', index=1, number=1,
-      options=None,
+      serialized_options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
       name='ERROR', index=2, number=2,
-      options=None,
+      serialized_options=None,
       type=None),
   ],
   containing_type=None,
-  options=None,
-  serialized_start=1546,
-  serialized_end=1608,
+  serialized_options=None,
+  serialized_start=1562,
+  serialized_end=1624,
 )
+_sym_db.RegisterEnumDescriptor(_VEHICLEPROPSTATUS)
 
 VehiclePropStatus = enum_type_wrapper.EnumTypeWrapper(_VEHICLEPROPSTATUS)
 GET_CONFIG_CMD = 0
@@ -178,351 +189,366 @@
 
 _VEHICLEAREACONFIG = _descriptor.Descriptor(
   name='VehicleAreaConfig',
-  full_name='emulator.VehicleAreaConfig',
+  full_name='vhal_proto.VehicleAreaConfig',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='area_id', full_name='emulator.VehicleAreaConfig.area_id', index=0,
+      name='area_id', full_name='vhal_proto.VehicleAreaConfig.area_id', index=0,
       number=1, type=5, cpp_type=1, label=2,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='min_int32_value', full_name='emulator.VehicleAreaConfig.min_int32_value', index=1,
+      name='min_int32_value', full_name='vhal_proto.VehicleAreaConfig.min_int32_value', index=1,
       number=2, type=17, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='max_int32_value', full_name='emulator.VehicleAreaConfig.max_int32_value', index=2,
+      name='max_int32_value', full_name='vhal_proto.VehicleAreaConfig.max_int32_value', index=2,
       number=3, type=17, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='min_int64_value', full_name='emulator.VehicleAreaConfig.min_int64_value', index=3,
+      name='min_int64_value', full_name='vhal_proto.VehicleAreaConfig.min_int64_value', index=3,
       number=4, type=18, cpp_type=2, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='max_int64_value', full_name='emulator.VehicleAreaConfig.max_int64_value', index=4,
+      name='max_int64_value', full_name='vhal_proto.VehicleAreaConfig.max_int64_value', index=4,
       number=5, type=18, cpp_type=2, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='min_float_value', full_name='emulator.VehicleAreaConfig.min_float_value', index=5,
+      name='min_float_value', full_name='vhal_proto.VehicleAreaConfig.min_float_value', index=5,
       number=6, type=2, cpp_type=6, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='max_float_value', full_name='emulator.VehicleAreaConfig.max_float_value', index=6,
+      name='max_float_value', full_name='vhal_proto.VehicleAreaConfig.max_float_value', index=6,
       number=7, type=2, cpp_type=6, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
   nested_types=[],
   enum_types=[
   ],
-  options=None,
+  serialized_options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=36,
-  serialized_end=222,
+  oneofs=[
+  ],
+  serialized_start=38,
+  serialized_end=224,
 )
 
 
 _VEHICLEPROPCONFIG = _descriptor.Descriptor(
   name='VehiclePropConfig',
-  full_name='emulator.VehiclePropConfig',
+  full_name='vhal_proto.VehiclePropConfig',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='prop', full_name='emulator.VehiclePropConfig.prop', index=0,
+      name='prop', full_name='vhal_proto.VehiclePropConfig.prop', index=0,
       number=1, type=5, cpp_type=1, label=2,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='access', full_name='emulator.VehiclePropConfig.access', index=1,
+      name='access', full_name='vhal_proto.VehiclePropConfig.access', index=1,
       number=2, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='change_mode', full_name='emulator.VehiclePropConfig.change_mode', index=2,
+      name='change_mode', full_name='vhal_proto.VehiclePropConfig.change_mode', index=2,
       number=3, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='value_type', full_name='emulator.VehiclePropConfig.value_type', index=3,
+      name='value_type', full_name='vhal_proto.VehiclePropConfig.value_type', index=3,
       number=4, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='supported_areas', full_name='emulator.VehiclePropConfig.supported_areas', index=4,
+      name='supported_areas', full_name='vhal_proto.VehiclePropConfig.supported_areas', index=4,
       number=5, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='area_configs', full_name='emulator.VehiclePropConfig.area_configs', index=5,
+      name='area_configs', full_name='vhal_proto.VehiclePropConfig.area_configs', index=5,
       number=6, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='config_flags', full_name='emulator.VehiclePropConfig.config_flags', index=6,
+      name='config_flags', full_name='vhal_proto.VehiclePropConfig.config_flags', index=6,
       number=7, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='config_array', full_name='emulator.VehiclePropConfig.config_array', index=7,
+      name='config_array', full_name='vhal_proto.VehiclePropConfig.config_array', index=7,
       number=8, type=5, cpp_type=1, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='config_string', full_name='emulator.VehiclePropConfig.config_string', index=8,
+      name='config_string', full_name='vhal_proto.VehiclePropConfig.config_string', index=8,
       number=9, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='min_sample_rate', full_name='emulator.VehiclePropConfig.min_sample_rate', index=9,
+      name='min_sample_rate', full_name='vhal_proto.VehiclePropConfig.min_sample_rate', index=9,
       number=10, type=2, cpp_type=6, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='max_sample_rate', full_name='emulator.VehiclePropConfig.max_sample_rate', index=10,
+      name='max_sample_rate', full_name='vhal_proto.VehiclePropConfig.max_sample_rate', index=10,
       number=11, type=2, cpp_type=6, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
   nested_types=[],
   enum_types=[
   ],
-  options=None,
+  serialized_options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=225,
-  serialized_end=508,
+  oneofs=[
+  ],
+  serialized_start=227,
+  serialized_end=512,
 )
 
 
 _VEHICLEPROPVALUE = _descriptor.Descriptor(
   name='VehiclePropValue',
-  full_name='emulator.VehiclePropValue',
+  full_name='vhal_proto.VehiclePropValue',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='prop', full_name='emulator.VehiclePropValue.prop', index=0,
+      name='prop', full_name='vhal_proto.VehiclePropValue.prop', index=0,
       number=1, type=5, cpp_type=1, label=2,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='value_type', full_name='emulator.VehiclePropValue.value_type', index=1,
+      name='value_type', full_name='vhal_proto.VehiclePropValue.value_type', index=1,
       number=2, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='timestamp', full_name='emulator.VehiclePropValue.timestamp', index=2,
+      name='timestamp', full_name='vhal_proto.VehiclePropValue.timestamp', index=2,
       number=3, type=3, cpp_type=2, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='status', full_name='emulator.VehiclePropValue.status', index=3,
+      name='status', full_name='vhal_proto.VehiclePropValue.status', index=3,
       number=10, type=14, cpp_type=8, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='area_id', full_name='emulator.VehiclePropValue.area_id', index=4,
+      name='area_id', full_name='vhal_proto.VehiclePropValue.area_id', index=4,
       number=4, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='int32_values', full_name='emulator.VehiclePropValue.int32_values', index=5,
+      name='int32_values', full_name='vhal_proto.VehiclePropValue.int32_values', index=5,
       number=5, type=17, cpp_type=1, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='int64_values', full_name='emulator.VehiclePropValue.int64_values', index=6,
+      name='int64_values', full_name='vhal_proto.VehiclePropValue.int64_values', index=6,
       number=6, type=18, cpp_type=2, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='float_values', full_name='emulator.VehiclePropValue.float_values', index=7,
+      name='float_values', full_name='vhal_proto.VehiclePropValue.float_values', index=7,
       number=7, type=2, cpp_type=6, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='string_value', full_name='emulator.VehiclePropValue.string_value', index=8,
+      name='string_value', full_name='vhal_proto.VehiclePropValue.string_value', index=8,
       number=8, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='bytes_value', full_name='emulator.VehiclePropValue.bytes_value', index=9,
+      name='bytes_value', full_name='vhal_proto.VehiclePropValue.bytes_value', index=9,
       number=9, type=12, cpp_type=9, label=1,
-      has_default_value=False, default_value="",
+      has_default_value=False, default_value=_b(""),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
   nested_types=[],
   enum_types=[
   ],
-  options=None,
+  serialized_options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=511,
-  serialized_end=753,
+  oneofs=[
+  ],
+  serialized_start=515,
+  serialized_end=759,
 )
 
 
 _VEHICLEPROPGET = _descriptor.Descriptor(
   name='VehiclePropGet',
-  full_name='emulator.VehiclePropGet',
+  full_name='vhal_proto.VehiclePropGet',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='prop', full_name='emulator.VehiclePropGet.prop', index=0,
+      name='prop', full_name='vhal_proto.VehiclePropGet.prop', index=0,
       number=1, type=5, cpp_type=1, label=2,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='area_id', full_name='emulator.VehiclePropGet.area_id', index=1,
+      name='area_id', full_name='vhal_proto.VehiclePropGet.area_id', index=1,
       number=2, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
   nested_types=[],
   enum_types=[
   ],
-  options=None,
+  serialized_options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=755,
-  serialized_end=802,
+  oneofs=[
+  ],
+  serialized_start=761,
+  serialized_end=808,
 )
 
 
 _EMULATORMESSAGE = _descriptor.Descriptor(
   name='EmulatorMessage',
-  full_name='emulator.EmulatorMessage',
+  full_name='vhal_proto.EmulatorMessage',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='msg_type', full_name='emulator.EmulatorMessage.msg_type', index=0,
+      name='msg_type', full_name='vhal_proto.EmulatorMessage.msg_type', index=0,
       number=1, type=14, cpp_type=8, label=2,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='status', full_name='emulator.EmulatorMessage.status', index=1,
+      name='status', full_name='vhal_proto.EmulatorMessage.status', index=1,
       number=2, type=14, cpp_type=8, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='prop', full_name='emulator.EmulatorMessage.prop', index=2,
+      name='prop', full_name='vhal_proto.EmulatorMessage.prop', index=2,
       number=3, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='config', full_name='emulator.EmulatorMessage.config', index=3,
+      name='config', full_name='vhal_proto.EmulatorMessage.config', index=3,
       number=4, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='value', full_name='emulator.EmulatorMessage.value', index=4,
+      name='value', full_name='vhal_proto.EmulatorMessage.value', index=4,
       number=5, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      options=None),
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
   nested_types=[],
   enum_types=[
   ],
-  options=None,
+  serialized_options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=805,
-  serialized_end=1021,
+  oneofs=[
+  ],
+  serialized_start=811,
+  serialized_end=1037,
 )
 
 _VEHICLEPROPCONFIG.fields_by_name['area_configs'].message_type = _VEHICLEAREACONFIG
@@ -537,38 +563,45 @@
 DESCRIPTOR.message_types_by_name['VehiclePropValue'] = _VEHICLEPROPVALUE
 DESCRIPTOR.message_types_by_name['VehiclePropGet'] = _VEHICLEPROPGET
 DESCRIPTOR.message_types_by_name['EmulatorMessage'] = _EMULATORMESSAGE
+DESCRIPTOR.enum_types_by_name['MsgType'] = _MSGTYPE
+DESCRIPTOR.enum_types_by_name['Status'] = _STATUS
+DESCRIPTOR.enum_types_by_name['VehiclePropStatus'] = _VEHICLEPROPSTATUS
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-class VehicleAreaConfig(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _VEHICLEAREACONFIG
+VehicleAreaConfig = _reflection.GeneratedProtocolMessageType('VehicleAreaConfig', (_message.Message,), {
+  'DESCRIPTOR' : _VEHICLEAREACONFIG,
+  '__module__' : 'VehicleHalProto_pb2'
+  # @@protoc_insertion_point(class_scope:vhal_proto.VehicleAreaConfig)
+  })
+_sym_db.RegisterMessage(VehicleAreaConfig)
 
-  # @@protoc_insertion_point(class_scope:emulator.VehicleAreaConfig)
+VehiclePropConfig = _reflection.GeneratedProtocolMessageType('VehiclePropConfig', (_message.Message,), {
+  'DESCRIPTOR' : _VEHICLEPROPCONFIG,
+  '__module__' : 'VehicleHalProto_pb2'
+  # @@protoc_insertion_point(class_scope:vhal_proto.VehiclePropConfig)
+  })
+_sym_db.RegisterMessage(VehiclePropConfig)
 
-class VehiclePropConfig(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _VEHICLEPROPCONFIG
+VehiclePropValue = _reflection.GeneratedProtocolMessageType('VehiclePropValue', (_message.Message,), {
+  'DESCRIPTOR' : _VEHICLEPROPVALUE,
+  '__module__' : 'VehicleHalProto_pb2'
+  # @@protoc_insertion_point(class_scope:vhal_proto.VehiclePropValue)
+  })
+_sym_db.RegisterMessage(VehiclePropValue)
 
-  # @@protoc_insertion_point(class_scope:emulator.VehiclePropConfig)
+VehiclePropGet = _reflection.GeneratedProtocolMessageType('VehiclePropGet', (_message.Message,), {
+  'DESCRIPTOR' : _VEHICLEPROPGET,
+  '__module__' : 'VehicleHalProto_pb2'
+  # @@protoc_insertion_point(class_scope:vhal_proto.VehiclePropGet)
+  })
+_sym_db.RegisterMessage(VehiclePropGet)
 
-class VehiclePropValue(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _VEHICLEPROPVALUE
-
-  # @@protoc_insertion_point(class_scope:emulator.VehiclePropValue)
-
-class VehiclePropGet(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _VEHICLEPROPGET
-
-  # @@protoc_insertion_point(class_scope:emulator.VehiclePropGet)
-
-class EmulatorMessage(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _EMULATORMESSAGE
-
-  # @@protoc_insertion_point(class_scope:emulator.EmulatorMessage)
+EmulatorMessage = _reflection.GeneratedProtocolMessageType('EmulatorMessage', (_message.Message,), {
+  'DESCRIPTOR' : _EMULATORMESSAGE,
+  '__module__' : 'VehicleHalProto_pb2'
+  # @@protoc_insertion_point(class_scope:vhal_proto.EmulatorMessage)
+  })
+_sym_db.RegisterMessage(EmulatorMessage)
 
 
-DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), 'H\003')
 # @@protoc_insertion_point(module_scope)