Snap for 5645017 from 5570f2c2a1c11fed1d83caf5b3bf065c3942736e to qt-release

Change-Id: I7fe7078692d24478880c36a46c9dc7f56f1363dd
diff --git a/car-lib/src/android/car/CarBugreportManager.java b/car-lib/src/android/car/CarBugreportManager.java
index 7fca8ba..b0f7a03 100644
--- a/car-lib/src/android/car/CarBugreportManager.java
+++ b/car-lib/src/android/car/CarBugreportManager.java
@@ -16,6 +16,7 @@
 
 package android.car;
 
+import android.annotation.FloatRange;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
@@ -74,6 +75,16 @@
         public static final int CAR_BUGREPORT_SERVICE_NOT_AVAILABLE = 4;
 
         /**
+         * Called when bugreport progress changes.
+         *
+         * <p>It's never called after {@link #onError} or {@link #onFinished}.
+         *
+         * @param progress - a number in [0.0, 100.0].
+         */
+        public void onProgress(@FloatRange(from = 0f, to = 100f) float progress) {
+        }
+
+        /**
          * Called on an error condition with one of the error codes listed above.
          *
          * @param errorCode the error code that defines failure reason.
@@ -110,6 +121,15 @@
         }
 
         @Override
+        public void onProgress(@FloatRange(from = 0f, to = 100f) float progress) {
+            CarBugreportManagerCallback callback = mWeakCallback.get();
+            Handler handler = mWeakHandler.get();
+            if (handler != null && callback != null) {
+                handler.post(() -> callback.onProgress(progress));
+            }
+        }
+
+        @Override
         public void onError(@CarBugreportManagerCallback.CarBugreportErrorCode int errorCode) {
             CarBugreportManagerCallback callback = mWeakCallback.get();
             Handler handler = mWeakHandler.get();
@@ -123,7 +143,7 @@
             CarBugreportManagerCallback callback = mWeakCallback.get();
             Handler handler = mWeakHandler.get();
             if (handler != null && callback != null) {
-                handler.post(() -> callback.onFinished());
+                handler.post(callback::onFinished);
             }
         }
     }
@@ -139,37 +159,30 @@
     }
 
     /**
-     * Request a bug report. An zipped bugreport is generated in the background.
-     * The file descriptors are closed when bugreport is written or if an exception happens.
-     * The progress protocol is described
-     * <a href="https://android.googlesource.com/platform/frameworks/native/+/master/cmds/bugreportz/readme.md">
-     *     here</a>
+     * Request a bug report. A zipped bugreport is generated in the background.
+     *
+     * <p>The file descriptor is closed when bugreport is written or if an exception happens.
      *
      * @param output the zipped bugreport file
-     * @param progress the progress information that includes failure/success status.
      * @param callback  the callback for reporting dump status
      */
     @RequiresPermission(android.Manifest.permission.DUMP)
-    public void requestZippedBugreport(@NonNull ParcelFileDescriptor output,
-            @NonNull ParcelFileDescriptor progress,
-            @NonNull CarBugreportManagerCallback callback) {
+    public void requestZippedBugreport(
+            @NonNull ParcelFileDescriptor output, @NonNull CarBugreportManagerCallback callback) {
         Preconditions.checkNotNull(output);
-        Preconditions.checkNotNull(progress);
         Preconditions.checkNotNull(callback);
         try {
             CarBugreportManagerCallbackWrapper wrapper =
                     new CarBugreportManagerCallbackWrapper(callback, mHandler);
-            mService.requestZippedBugreport(output, progress, wrapper);
+            mService.requestZippedBugreport(output, wrapper);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } finally {
             IoUtils.closeQuietly(output);
-            IoUtils.closeQuietly(progress);
         }
     }
 
     @Override
     public void onCarDisconnected() {
     }
-
 }
diff --git a/car-lib/src/android/car/ICarBugreportCallback.aidl b/car-lib/src/android/car/ICarBugreportCallback.aidl
index e254d4c..0384d43 100644
--- a/car-lib/src/android/car/ICarBugreportCallback.aidl
+++ b/car-lib/src/android/car/ICarBugreportCallback.aidl
@@ -29,8 +29,15 @@
     void onError(int errorCode);
 
     /**
+     * Called when the bugreport progress changes. Progress value is a number between 0.0 and 100.0.
+     *
+     * <p>Never called after {@link #onError()} or {@link onFinished()}.
+     */
+    void onProgress(float progress);
+
+    /**
      * Called when taking bugreport finishes successfully.
      */
     void onFinished();
 
-}
\ No newline at end of file
+}
diff --git a/car-lib/src/android/car/ICarBugreportService.aidl b/car-lib/src/android/car/ICarBugreportService.aidl
index 2d713da..1ec4e91 100644
--- a/car-lib/src/android/car/ICarBugreportService.aidl
+++ b/car-lib/src/android/car/ICarBugreportService.aidl
@@ -28,14 +28,7 @@
     /**
      * Starts bugreport service to capture a zipped bugreport. The caller needs to provide
      * two file descriptors. The "output" file descriptor will be used to provide the actual
-     * zip file and the "progress" descriptor will be used to provide the progress information.
-     * Both of these descriptors are written by the service and will be read by the client.
-     *
-     * The progress protocol is described
-     * <a href="https://android.googlesource.com/platform/frameworks/native/+/master/cmds/bugreportz/readme.md">
-     *     here</a>
+     * zip file. The file descriptor is written by the service and will be read by the client.
      */
-    void requestZippedBugreport(in ParcelFileDescriptor output, in ParcelFileDescriptor progress,
-        ICarBugreportCallback callback) = 1;
+    void requestZippedBugreport(in ParcelFileDescriptor output, ICarBugreportCallback callback) = 1;
  }
-
diff --git a/car-lib/src/android/car/ICarUserService.aidl b/car-lib/src/android/car/ICarUserService.aidl
index 1c7211c..82eab72 100644
--- a/car-lib/src/android/car/ICarUserService.aidl
+++ b/car-lib/src/android/car/ICarUserService.aidl
@@ -16,8 +16,10 @@
 
 package android.car;
 import android.car.ICarBluetoothUserService;
+import android.car.ILocationManagerProxy;
 
 /** @hide */
 interface ICarUserService {
     ICarBluetoothUserService getBluetoothUserService();
+    ILocationManagerProxy getLocationManagerProxy();
 }
diff --git a/car-lib/src/android/car/ILocationManagerProxy.aidl b/car-lib/src/android/car/ILocationManagerProxy.aidl
new file mode 100644
index 0000000..5fef542
--- /dev/null
+++ b/car-lib/src/android/car/ILocationManagerProxy.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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;
+import android.location.Location;
+
+/** @hide */
+interface ILocationManagerProxy {
+    boolean isLocationEnabled();
+    boolean injectLocation(in Location location);
+    Location getLastKnownLocation(in String provider);
+}
\ No newline at end of file
diff --git a/car-lib/src/android/car/hardware/property/CarPropertyEvent.java b/car-lib/src/android/car/hardware/property/CarPropertyEvent.java
index 260d5fa..4cb7e92 100644
--- a/car-lib/src/android/car/hardware/property/CarPropertyEvent.java
+++ b/car-lib/src/android/car/hardware/property/CarPropertyEvent.java
@@ -32,7 +32,8 @@
     private final int mEventType;
     private final CarPropertyValue<?> mCarPropertyValue;
 
-    // Getters.
+    // Use it as default value for error events.
+    private static final int ERROR_EVENT_VALUE = -1;
 
     /**
      * @return EventType field
@@ -69,11 +70,24 @@
     /**
      * Constructor for {@link CarPropertyEvent}.
      */
-    public CarPropertyEvent(@NonNull int eventType, @NonNull CarPropertyValue<?> carPropertyValue) {
+    public CarPropertyEvent(int eventType, @NonNull CarPropertyValue<?> carPropertyValue) {
         mEventType  = eventType;
         mCarPropertyValue = carPropertyValue;
     }
 
+    /**
+     * Constructor for {@link CarPropertyEvent} when it is an error event.
+     *
+     * The status of {@link CarPropertyValue} should be {@link CarPropertyValue#STATUS_ERROR}.
+     * In {@link CarPropertyManager}, the value of {@link CarPropertyValue} will be dropped.
+     */
+    public static CarPropertyEvent createErrorEvent(int propertyId, int areaId) {
+        // valueWithErrorCode will not be propagated to listeners
+        CarPropertyValue<Integer> valueWithErrorCode = new CarPropertyValue<>(propertyId, areaId,
+                    CarPropertyValue.STATUS_ERROR, 0, ERROR_EVENT_VALUE);
+        return new CarPropertyEvent(PROPERTY_EVENT_ERROR, valueWithErrorCode);
+    }
+
     private CarPropertyEvent(Parcel in) {
         mEventType  = in.readInt();
         mCarPropertyValue = in.readParcelable(CarPropertyValue.class.getClassLoader());
diff --git a/car-lib/src/android/car/hardware/property/CarPropertyManager.java b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
index 85ffd34..3f7da1d 100644
--- a/car-lib/src/android/car/hardware/property/CarPropertyManager.java
+++ b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
@@ -562,6 +562,12 @@
             listeners.forEach(new Consumer<CarPropertyEventCallback>() {
                 @Override
                 public void accept(CarPropertyEventCallback listener) {
+                    if (DBG) {
+                        Log.d(TAG, new StringBuilder().append("onErrorEvent for ")
+                                        .append("property: ").append(value.getPropertyId())
+                                        .append(" areaId: ").append(value.getAreaId())
+                                        .toString());
+                    }
                     listener.onErrorEvent(value.getPropertyId(), value.getAreaId());
                 }
             });
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 6db7961..62ff41c 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
@@ -84,5 +84,8 @@
     <!-- True if the device supports split screen as a form of multi-window. -->
     <bool name="config_supportsSplitScreenMultiWindow">false</bool>
 
+    <!-- True if the device supports system decorations on secondary displays. -->
+    <bool name="config_supportsSystemDecorsOnSecondaryDisplays">false</bool>
+
     <string name="config_dataUsageSummaryComponent">com.android.car.settings/com.android.car.settings.datausage.DataWarningAndLimitActivity</string>
 </resources>
diff --git a/service/src/com/android/car/CarBugreportManagerService.java b/service/src/com/android/car/CarBugreportManagerService.java
index 338ca43..572f17d 100644
--- a/service/src/com/android/car/CarBugreportManagerService.java
+++ b/service/src/com/android/car/CarBugreportManagerService.java
@@ -16,6 +16,11 @@
 
 package com.android.car;
 
+import static android.car.CarBugreportManager.CarBugreportManagerCallback.CAR_BUGREPORT_DUMPSTATE_CONNECTION_FAILED;
+import static android.car.CarBugreportManager.CarBugreportManagerCallback.CAR_BUGREPORT_DUMPSTATE_FAILED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.car.CarBugreportManager.CarBugreportManagerCallback;
 import android.car.ICarBugreportCallback;
@@ -37,14 +42,15 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 
-
 /**
  * Bugreport service for cars. Should *only* be used on userdebug or eng builds.
  */
@@ -52,17 +58,19 @@
         CarServiceBase {
 
     private static final String TAG = "CarBugreportMgrService";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private final Context mContext;
-    private final Object mLock = new Object();
+    /**
+     * {@code dumpstate} progress prefixes.
+     *
+     * <p>The protocol is described in {@code frameworks/native/cmds/bugreportz/readme.md}.
+     */
+    private static final String BEGIN_PREFIX = "BEGIN:";
+    private static final String PROGRESS_PREFIX = "PROGRESS:";
+    private static final String OK_PREFIX = "OK:";
+    private static final String FAIL_PREFIX = "FAIL:";
 
-    private HandlerThread mHandlerThread = null;
-    private Handler mHandler;
-    private boolean mIsServiceRunning;
+    private static final String BUGREPORTD_SERVICE = "car-bugreportd";
 
-    // The socket at /dev/socket/dumpstate to communicate with dumpstate.
-    private static final String DUMPSTATE_SOCKET = "dumpstate";
     // The socket definitions must match the actual socket names defined in car_bugreportd service
     // definition.
     private static final String BUGREPORT_PROGRESS_SOCKET = "car_br_progress_socket";
@@ -70,6 +78,13 @@
 
     private static final int SOCKET_CONNECTION_MAX_RETRY = 10;
 
+    private final Context mContext;
+    private final Object mLock = new Object();
+
+    private HandlerThread mHandlerThread;
+    private Handler mHandler;
+    private boolean mIsServiceRunning;
+
     /**
      * Create a CarBugreportManagerService instance.
      *
@@ -93,8 +108,7 @@
 
     @Override
     @RequiresPermission(android.Manifest.permission.DUMP)
-    public void requestZippedBugreport(ParcelFileDescriptor data, ParcelFileDescriptor progress,
-            ICarBugreportCallback callback) {
+    public void requestZippedBugreport(ParcelFileDescriptor data, ICarBugreportCallback callback) {
 
         // Check the caller has proper permission
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
@@ -124,84 +138,134 @@
         }
 
         synchronized (mLock) {
-            requestZippedBugReportLocked(data, progress, callback);
+            requestZippedBugReportLocked(data, callback);
         }
     }
 
     @GuardedBy("mLock")
-    private void requestZippedBugReportLocked(ParcelFileDescriptor data,
-            ParcelFileDescriptor progress, ICarBugreportCallback callback) {
+    private void requestZippedBugReportLocked(
+            ParcelFileDescriptor data, ICarBugreportCallback callback) {
         if (mIsServiceRunning) {
             Slog.w(TAG, "Bugreport Service already running");
             reportError(callback, CarBugreportManagerCallback.CAR_BUGREPORT_IN_PROGRESS);
             return;
         }
         mIsServiceRunning = true;
-        mHandler.post(() -> startBugreportd(data, progress, callback));
+        mHandler.post(() -> startBugreportd(data, callback));
     }
 
-    private void startBugreportd(ParcelFileDescriptor data, ParcelFileDescriptor progress,
-            ICarBugreportCallback callback) {
-        readBugreport(data, progress, callback);
+    private void startBugreportd(ParcelFileDescriptor data, ICarBugreportCallback callback) {
+        Slog.i(TAG, "Starting " + BUGREPORTD_SERVICE);
+        try {
+            SystemProperties.set("ctl.start", BUGREPORTD_SERVICE);
+        } catch (RuntimeException e) {
+            Slog.e(TAG, "Failed to start " + BUGREPORTD_SERVICE, e);
+            reportError(callback, CAR_BUGREPORT_DUMPSTATE_FAILED);
+            return;
+        }
+        processBugreportSockets(data, callback);
         synchronized (mLock) {
             mIsServiceRunning = false;
         }
     }
 
-    private void readBugreport(ParcelFileDescriptor output, ParcelFileDescriptor progress,
-            ICarBugreportCallback callback) {
-        Slog.i(TAG, "Starting car-bugreportd");
+    private void handleProgress(String line, ICarBugreportCallback callback) {
+        String progressOverTotal = line.substring(PROGRESS_PREFIX.length());
+        String[] parts = progressOverTotal.split("/");
+        if (parts.length != 2) {
+            Slog.w(TAG, "Invalid progress line from bugreportz: " + line);
+            return;
+        }
+        float progress;
+        float total;
         try {
-            SystemProperties.set("ctl.start", "car-bugreportd");
-        } catch (RuntimeException e) {
-            Slog.e(TAG, "Failed to start car-bugreportd", e);
-            reportError(callback, CarBugreportManagerCallback.CAR_BUGREPORT_DUMPSTATE_FAILED);
+            progress = Float.parseFloat(parts[0]);
+            total = Float.parseFloat(parts[1]);
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Invalid progress value: " + line, e);
             return;
         }
-        // The native service first generates the progress data. Once it writes the progress
-        // data fully, it closes the socket and writes the zip file. So we read both files
-        // sequentially here.
-        if (!readSocket(BUGREPORT_PROGRESS_SOCKET, progress, callback)) {
-            Slog.e(TAG, "failed reading bugreport progress socket");
-            reportError(callback, CarBugreportManagerCallback.CAR_BUGREPORT_DUMPSTATE_FAILED);
+        if (total == 0) {
+            Slog.w(TAG, "Invalid progress total value: " + line);
             return;
         }
-        if (!readSocket(BUGREPORT_OUTPUT_SOCKET, output, callback)) {
-            Slog.i(TAG, "failed reading bugreport output socket");
-            reportError(callback, CarBugreportManagerCallback.CAR_BUGREPORT_DUMPSTATE_FAILED);
-            return;
-        }
-        Slog.i(TAG, "finished reading bugreport");
         try {
-            callback.onFinished();
+            callback.onProgress(100f * progress / total);
         } catch (RemoteException e) {
-            Slog.e(TAG, "onFinished() failed: " + e.getMessage());
+            Slog.e(TAG, "Failed to call onProgress callback", e);
         }
     }
 
-    private boolean readSocket(String name, ParcelFileDescriptor pfd,
-            ICarBugreportCallback callback) {
-        LocalSocket localSocket;
-
+    private void handleFinished(ParcelFileDescriptor output, ICarBugreportCallback callback) {
+        Slog.i(TAG, "Finished reading bugreport");
+        if (!copySocketToPfd(output, callback)) {
+            return;
+        }
         try {
-            localSocket = connectSocket(name);
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed connecting to socket " + name, e);
-            reportError(callback,
-                    CarBugreportManagerCallback.CAR_BUGREPORT_DUMPSTATE_CONNECTION_FAILED);
-            // Early out if connection to socket fails.
+            callback.onFinished();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to call onFinished callback", e);
+        }
+    }
+
+    /**
+     * Reads from dumpstate progress and output sockets and invokes appropriate callbacks.
+     *
+     * <p>dumpstate prints {@code BEGIN:} right away, then prints {@code PROGRESS:} as it
+     * progresses. When it finishes or fails it prints {@code OK:pathToTheZipFile} or
+     * {@code FAIL:message} accordingly.
+     */
+    private void processBugreportSockets(
+            ParcelFileDescriptor output, ICarBugreportCallback callback) {
+        LocalSocket localSocket = connectSocket(BUGREPORT_PROGRESS_SOCKET);
+        if (localSocket == null) {
+            reportError(callback, CAR_BUGREPORT_DUMPSTATE_CONNECTION_FAILED);
+            return;
+        }
+
+        try (BufferedReader reader =
+                new BufferedReader(new InputStreamReader(localSocket.getInputStream()))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (line.startsWith(PROGRESS_PREFIX)) {
+                    handleProgress(line, callback);
+                } else if (line.startsWith(FAIL_PREFIX)) {
+                    String errorMessage = line.substring(FAIL_PREFIX.length());
+                    Slog.e(TAG, "Failed to dumpstate: " + errorMessage);
+                    reportError(callback, CAR_BUGREPORT_DUMPSTATE_FAILED);
+                    return;
+                } else if (line.startsWith(OK_PREFIX)) {
+                    handleFinished(output, callback);
+                    return;
+                } else if (!line.startsWith(BEGIN_PREFIX)) {
+                    Slog.w(TAG, "Received unknown progress line from dumpstate: " + line);
+                }
+            }
+            Slog.e(TAG, "dumpstate progress unexpectedly ended");
+            reportError(callback, CAR_BUGREPORT_DUMPSTATE_FAILED);
+        } catch (IOException | RuntimeException e) {
+            Slog.i(TAG, "Failed to read from progress socket", e);
+            reportError(callback, CAR_BUGREPORT_DUMPSTATE_CONNECTION_FAILED);
+        }
+    }
+
+    private boolean copySocketToPfd(
+            ParcelFileDescriptor pfd, ICarBugreportCallback callback) {
+        LocalSocket localSocket = connectSocket(BUGREPORT_OUTPUT_SOCKET);
+        if (localSocket == null) {
+            reportError(callback, CAR_BUGREPORT_DUMPSTATE_CONNECTION_FAILED);
             return false;
         }
 
         try (
             DataInputStream in = new DataInputStream(localSocket.getInputStream());
             DataOutputStream out =
-                    new DataOutputStream(new ParcelFileDescriptor.AutoCloseOutputStream(pfd));
+                    new DataOutputStream(new ParcelFileDescriptor.AutoCloseOutputStream(pfd))
         ) {
             rawCopyStream(out, in);
         } catch (IOException | RuntimeException e) {
-            Slog.e(TAG, "Failed to grab dump state " + name, e);
-            reportError(callback, CarBugreportManagerCallback.CAR_BUGREPORT_DUMPSTATE_FAILED);
+            Slog.e(TAG, "Failed to grab dump state from " + BUGREPORT_OUTPUT_SOCKET, e);
+            reportError(callback, CAR_BUGREPORT_DUMPSTATE_FAILED);
             return false;
         }
         return true;
@@ -220,15 +284,15 @@
         // TODO(sgurun) implement
     }
 
-    private LocalSocket connectSocket(String socketName) throws IOException {
+    @Nullable
+    private LocalSocket connectSocket(@NonNull String socketName) {
         LocalSocket socket = new LocalSocket();
         // The dumpstate socket will be created by init upon receiving the
         // service request. It may not be ready by this point. So we will
         // keep retrying until success or reaching timeout.
         int retryCount = 0;
         while (true) {
-            // First connection always fails so we just 1 second before trying to connect for the
-            // first time too.
+            // First connection always fails, so we wait 1 second before trying to connect.
             SystemClock.sleep(/* ms= */ 1000);
             try {
                 socket.connect(new LocalSocketAddress(socketName,
@@ -236,9 +300,11 @@
                 return socket;
             } catch (IOException e) {
                 if (++retryCount >= SOCKET_CONNECTION_MAX_RETRY) {
-                    throw e;
+                    Slog.i(TAG, "Failed to connect to dumpstate socket " + socketName
+                            + " after " + retryCount + " retries", e);
+                    return null;
                 }
-                Log.i(TAG, "Failed to connect to" + socketName + ". will try again"
+                Log.i(TAG, "Failed to connect to" + socketName + ". Will try again "
                         + e.getMessage());
             }
         }
diff --git a/service/src/com/android/car/CarDrivingStateService.java b/service/src/com/android/car/CarDrivingStateService.java
index 48840b7..f75c4e7 100644
--- a/service/src/com/android/car/CarDrivingStateService.java
+++ b/service/src/com/android/car/CarDrivingStateService.java
@@ -36,9 +36,9 @@
 import android.util.Log;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * A service that infers the current driving state of the vehicle.  It computes the driving state
@@ -53,7 +53,7 @@
     private final Context mContext;
     private CarPropertyService mPropertyService;
     // List of clients listening to driving state events.
-    private final List<DrivingStateClient> mDrivingStateClients = new ArrayList<>();
+    private final List<DrivingStateClient> mDrivingStateClients = new CopyOnWriteArrayList<>();
     // Array of properties that the service needs to listen to from CarPropertyService for deriving
     // the driving state.
     private static final int[] REQUIRED_PROPERTIES = {
@@ -154,7 +154,7 @@
         }
         // If a new client is registering, create a new DrivingStateClient and add it to the list
         // of listening clients.
-        DrivingStateClient client = findDrivingStateClientLocked(listener);
+        DrivingStateClient client = findDrivingStateClient(listener);
         if (client == null) {
             client = new DrivingStateClient(listener);
             try {
@@ -175,8 +175,7 @@
      * @return the {@link DrivingStateClient} if found, null if not
      */
     @Nullable
-    private DrivingStateClient findDrivingStateClientLocked(
-            ICarDrivingStateChangeListener listener) {
+    private DrivingStateClient findDrivingStateClient(ICarDrivingStateChangeListener listener) {
         IBinder binder = listener.asBinder();
         // Find the listener by comparing the binder object they host.
         for (DrivingStateClient client : mDrivingStateClients) {
@@ -200,7 +199,7 @@
             throw new IllegalArgumentException("Listener is null");
         }
 
-        DrivingStateClient client = findDrivingStateClientLocked(listener);
+        DrivingStateClient client = findDrivingStateClient(listener);
         if (client == null) {
             Log.e(TAG, "unregisterDrivingStateChangeListener(): listener was not previously "
                     + "registered");
@@ -222,7 +221,7 @@
     }
 
     @Override
-    public synchronized void injectDrivingState(CarDrivingStateEvent event) {
+    public void injectDrivingState(CarDrivingStateEvent event) {
         ICarImpl.assertPermission(mContext, Car.PERMISSION_CONTROL_APP_BLOCKING);
 
         for (DrivingStateClient client : mDrivingStateClients) {
@@ -251,9 +250,7 @@
                 Log.d(TAG, "Binder died " + listenerBinder);
             }
             listenerBinder.unlinkToDeath(this, 0);
-            synchronized (CarDrivingStateService.this) {
-                mDrivingStateClients.remove(this);
-            }
+            mDrivingStateClients.remove(this);
         }
 
         /**
@@ -319,82 +316,80 @@
      * the corresponding UX Restrictions and dispatch the events to the registered clients.
      */
     private synchronized void handlePropertyEvent(CarPropertyEvent event) {
-        switch (event.getEventType()) {
-            case CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE:
-                CarPropertyValue value = event.getCarPropertyValue();
-                int propId = value.getPropertyId();
-                long curTimestamp = value.getTimestamp();
-                Log.d(TAG, "Property Changed: propId=" + propId);
-                switch (propId) {
-                    case VehicleProperty.PERF_VEHICLE_SPEED:
-                        float curSpeed = (Float) value.getValue();
-                        if (DBG) {
-                            Log.d(TAG, "Speed: " + curSpeed + "@" + curTimestamp);
-                        }
-                        if (curTimestamp > mLastSpeedTimestamp) {
-                            mLastSpeedTimestamp = curTimestamp;
-                            mLastSpeed = curSpeed;
-                        } else if (DBG) {
-                            Log.d(TAG, "Ignoring speed with older timestamp:" + curTimestamp);
-                        }
-                        break;
-                    case VehicleProperty.GEAR_SELECTION:
-                        if (mSupportedGears == null) {
-                            mSupportedGears = getSupportedGears();
-                        }
-                        int curGear = (Integer) value.getValue();
-                        if (DBG) {
-                            Log.d(TAG, "Gear: " + curGear + "@" + curTimestamp);
-                        }
-                        if (curTimestamp > mLastGearTimestamp) {
-                            mLastGearTimestamp = curTimestamp;
-                            mLastGear = (Integer) value.getValue();
-                        } else if (DBG) {
-                            Log.d(TAG, "Ignoring Gear with older timestamp:" + curTimestamp);
-                        }
-                        break;
-                    case VehicleProperty.PARKING_BRAKE_ON:
-                        boolean curParkingBrake = (boolean) value.getValue();
-                        if (DBG) {
-                            Log.d(TAG, "Parking Brake: " + curParkingBrake + "@" + curTimestamp);
-                        }
-                        if (curTimestamp > mLastParkingBrakeTimestamp) {
-                            mLastParkingBrakeTimestamp = curTimestamp;
-                            mLastParkingBrakeState = curParkingBrake;
-                        } else if (DBG) {
-                            Log.d(TAG, "Ignoring Parking Brake status with an older timestamp:"
-                                    + curTimestamp);
-                        }
-                        break;
-                    default:
-                        Log.e(TAG, "Received property event for unhandled propId=" + propId);
-                        break;
-                }
-
-                int drivingState = inferDrivingStateLocked();
-                // Check if the driving state has changed.  If it has, update our records and
-                // dispatch the new events to the listeners.
+        if (event.getEventType() != CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE) {
+            return;
+        }
+        CarPropertyValue value = event.getCarPropertyValue();
+        int propId = value.getPropertyId();
+        long curTimestamp = value.getTimestamp();
+        if (DBG) {
+            Log.d(TAG, "Property Changed: propId=" + propId);
+        }
+        switch (propId) {
+            case VehicleProperty.PERF_VEHICLE_SPEED:
+                float curSpeed = (Float) value.getValue();
                 if (DBG) {
-                    Log.d(TAG, "Driving state new->old " + drivingState + "->"
-                            + mCurrentDrivingState.eventValue);
+                    Log.d(TAG, "Speed: " + curSpeed + "@" + curTimestamp);
                 }
-                if (drivingState != mCurrentDrivingState.eventValue) {
-                    addTransitionLog(TAG, mCurrentDrivingState.eventValue, drivingState,
-                            System.currentTimeMillis());
-                    // Update if there is a change in state.
-                    mCurrentDrivingState = createDrivingStateEvent(drivingState);
-                    if (DBG) {
-                        Log.d(TAG, "dispatching to " + mDrivingStateClients.size() + " clients");
-                    }
-                    for (DrivingStateClient client : mDrivingStateClients) {
-                        client.dispatchEventToClients(mCurrentDrivingState);
-                    }
+                if (curTimestamp > mLastSpeedTimestamp) {
+                    mLastSpeedTimestamp = curTimestamp;
+                    mLastSpeed = curSpeed;
+                } else if (DBG) {
+                    Log.d(TAG, "Ignoring speed with older timestamp:" + curTimestamp);
+                }
+                break;
+            case VehicleProperty.GEAR_SELECTION:
+                if (mSupportedGears == null) {
+                    mSupportedGears = getSupportedGears();
+                }
+                int curGear = (Integer) value.getValue();
+                if (DBG) {
+                    Log.d(TAG, "Gear: " + curGear + "@" + curTimestamp);
+                }
+                if (curTimestamp > mLastGearTimestamp) {
+                    mLastGearTimestamp = curTimestamp;
+                    mLastGear = (Integer) value.getValue();
+                } else if (DBG) {
+                    Log.d(TAG, "Ignoring Gear with older timestamp:" + curTimestamp);
+                }
+                break;
+            case VehicleProperty.PARKING_BRAKE_ON:
+                boolean curParkingBrake = (boolean) value.getValue();
+                if (DBG) {
+                    Log.d(TAG, "Parking Brake: " + curParkingBrake + "@" + curTimestamp);
+                }
+                if (curTimestamp > mLastParkingBrakeTimestamp) {
+                    mLastParkingBrakeTimestamp = curTimestamp;
+                    mLastParkingBrakeState = curParkingBrake;
+                } else if (DBG) {
+                    Log.d(TAG, "Ignoring Parking Brake status with an older timestamp:"
+                            + curTimestamp);
                 }
                 break;
             default:
-                // Unhandled event
+                Log.e(TAG, "Received property event for unhandled propId=" + propId);
                 break;
         }
+
+        int drivingState = inferDrivingStateLocked();
+        // Check if the driving state has changed.  If it has, update our records and
+        // dispatch the new events to the listeners.
+        if (DBG) {
+            Log.d(TAG, "Driving state new->old " + drivingState + "->"
+                    + mCurrentDrivingState.eventValue);
+        }
+        if (drivingState != mCurrentDrivingState.eventValue) {
+            addTransitionLog(TAG, mCurrentDrivingState.eventValue, drivingState,
+                    System.currentTimeMillis());
+            // Update if there is a change in state.
+            mCurrentDrivingState = createDrivingStateEvent(drivingState);
+            if (DBG) {
+                Log.d(TAG, "dispatching to " + mDrivingStateClients.size() + " clients");
+            }
+            for (DrivingStateClient client : mDrivingStateClients) {
+                client.dispatchEventToClients(mCurrentDrivingState);
+            }
+        }
     }
 
     private List<Integer> getSupportedGears() {
diff --git a/service/src/com/android/car/CarLocationService.java b/service/src/com/android/car/CarLocationService.java
index cc57856..3827c22 100644
--- a/service/src/com/android/car/CarLocationService.java
+++ b/service/src/com/android/car/CarLocationService.java
@@ -16,6 +16,9 @@
 
 package com.android.car;
 
+import android.app.ActivityManager;
+import android.car.ICarUserService;
+import android.car.ILocationManagerProxy;
 import android.car.drivingstate.CarDrivingStateEvent;
 import android.car.drivingstate.ICarDrivingStateChangeListener;
 import android.car.hardware.power.CarPowerManager;
@@ -30,6 +33,7 @@
 import android.location.LocationManager;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.AtomicFile;
@@ -69,6 +73,9 @@
     // Used internally for mHandlerThread synchronization
     private final Object mLock = new Object();
 
+    // Used internally for mILocationManagerProxy synchronization
+    private final Object mLocationManagerProxyLock = new Object();
+
     private final Context mContext;
     private final CarUserManagerHelper mCarUserManagerHelper;
     private int mTaskCount = 0;
@@ -76,6 +83,69 @@
     private Handler mHandler;
     private CarPowerManager mCarPowerManager;
     private CarDrivingStateService mCarDrivingStateService;
+    private PerUserCarServiceHelper mPerUserCarServiceHelper;
+
+    // Allows us to interact with the {@link LocationManager} as the foreground user.
+    private ILocationManagerProxy mILocationManagerProxy;
+
+    // Maintains mILocationManagerProxy for the current foreground user.
+    private final PerUserCarServiceHelper.ServiceCallback mUserServiceCallback =
+            new PerUserCarServiceHelper.ServiceCallback() {
+                @Override
+                public void onServiceConnected(ICarUserService carUserService) {
+                    logd("Connected to PerUserCarService");
+                    if (carUserService == null) {
+                        logd("ICarUserService is null. Cannot get location manager proxy");
+                        return;
+                    }
+                    synchronized (mLocationManagerProxyLock) {
+                        try {
+                            mILocationManagerProxy = carUserService.getLocationManagerProxy();
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "RemoteException from ICarUserService", e);
+                            return;
+                        }
+                    }
+                    int currentUser = ActivityManager.getCurrentUser();
+                    logd("Current user: " + currentUser);
+                    if (mCarUserManagerHelper.isHeadlessSystemUser()
+                            && currentUser > UserHandle.USER_SYSTEM) {
+                        asyncOperation(() -> loadLocation());
+                    }
+                }
+
+                @Override
+                public void onPreUnbind() {
+                    logd("Before Unbinding from PerCarUserService");
+                    synchronized (mLocationManagerProxyLock) {
+                        mILocationManagerProxy = null;
+                    }
+                }
+
+                @Override
+                public void onServiceDisconnected() {
+                    logd("Disconnected from PerUserCarService");
+                    synchronized (mLocationManagerProxyLock) {
+                        mILocationManagerProxy = null;
+                    }
+                }
+            };
+
+    private final ICarDrivingStateChangeListener mICarDrivingStateChangeEventListener =
+            new ICarDrivingStateChangeListener.Stub() {
+                @Override
+                public void onDrivingStateChanged(CarDrivingStateEvent event) {
+                    logd("onDrivingStateChanged " + event);
+                    if (event != null
+                            && event.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING) {
+                        deleteCacheFile();
+                        if (mCarDrivingStateService != null) {
+                            mCarDrivingStateService.unregisterDrivingStateChangeListener(
+                                    mICarDrivingStateChangeEventListener);
+                        }
+                    }
+                }
+            };
 
     public CarLocationService(Context context, CarUserManagerHelper carUserManagerHelper) {
         logd("constructed");
@@ -87,9 +157,7 @@
     public void init() {
         logd("init");
         IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(LocationManager.MODE_CHANGED_ACTION);
-        filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
         mContext.registerReceiver(this, filter);
         mCarDrivingStateService = CarLocalServices.getService(CarDrivingStateService.class);
         if (mCarDrivingStateService != null) {
@@ -105,6 +173,10 @@
         if (mCarPowerManager != null) { // null case happens for testing.
             mCarPowerManager.setListenerWithCompletion(CarLocationService.this);
         }
+        mPerUserCarServiceHelper = CarLocalServices.getService(PerUserCarServiceHelper.class);
+        if (mPerUserCarServiceHelper != null) {
+            mPerUserCarServiceHelper.registerServiceCallback(mUserServiceCallback);
+        }
     }
 
     @Override
@@ -117,6 +189,9 @@
             mCarDrivingStateService.unregisterDrivingStateChangeListener(
                     mICarDrivingStateChangeEventListener);
         }
+        if (mPerUserCarServiceHelper != null) {
+            mPerUserCarServiceHelper.unregisterServiceCallback(mUserServiceCallback);
+        }
         mContext.unregisterReceiver(this);
     }
 
@@ -158,70 +233,57 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         logd("onReceive " + intent);
-        String action = intent.getAction();
-        if (action == Intent.ACTION_USER_SWITCHED) {
-            int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-            logd("USER_SWITCHED: " + userHandle);
-            if (mCarUserManagerHelper.isHeadlessSystemUser()
-                    && userHandle > UserHandle.USER_SYSTEM) {
-                asyncOperation(() -> loadLocation());
+        // If the system user is headless but the current user is still the system user, then we
+        // should not delete the location cache file due to missing location permissions.
+        if (isCurrentUserHeadlessSystemUser()) {
+            logd("Current user is headless system user.");
+            return;
+        }
+        synchronized (mLocationManagerProxyLock) {
+            if (mILocationManagerProxy == null) {
+                logd("Null location manager.");
+                return;
             }
-        } else if (action == LocationManager.MODE_CHANGED_ACTION
-                && shouldCheckLocationPermissions()) {
-            LocationManager locationManager =
-                    (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-            boolean locationEnabled = locationManager.isLocationEnabled();
-            logd("isLocationEnabled(): " + locationEnabled);
-            if (!locationEnabled) {
-                deleteCacheFile();
-            }
-        } else if (action == LocationManager.PROVIDERS_CHANGED_ACTION
-                && shouldCheckLocationPermissions()) {
-            LocationManager locationManager =
-                    (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-            boolean gpsEnabled =
-                    locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
-            logd("isProviderEnabled('gps'): " + gpsEnabled);
-            if (!gpsEnabled) {
-                deleteCacheFile();
+            String action = intent.getAction();
+            try {
+                if (action == LocationManager.MODE_CHANGED_ACTION) {
+                    boolean locationEnabled = mILocationManagerProxy.isLocationEnabled();
+                    logd("isLocationEnabled(): " + locationEnabled);
+                    if (!locationEnabled) {
+                        deleteCacheFile();
+                    }
+                } else {
+                    logd("Unexpected intent.");
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException from ILocationManagerProxy", e);
             }
         }
     }
 
-    private final ICarDrivingStateChangeListener mICarDrivingStateChangeEventListener =
-            new ICarDrivingStateChangeListener.Stub() {
-                @Override
-                public void onDrivingStateChanged(CarDrivingStateEvent event) {
-                    logd("onDrivingStateChanged " + event);
-                    if (event != null
-                            && event.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING) {
-                        deleteCacheFile();
-                        if (mCarDrivingStateService != null) {
-                            mCarDrivingStateService.unregisterDrivingStateChangeListener(
-                                    mICarDrivingStateChangeEventListener);
-                        }
-                    }
-                }
-            };
-
-    /**
-     * Tells whether or not we should check location permissions for the sake of deleting the
-     * location cache file when permissions are lacking.  If the system user is headless but the
-     * current user is still the system user, then we should not respond to a lack of location
-     * permissions.
-     */
-    private boolean shouldCheckLocationPermissions() {
-        return !(mCarUserManagerHelper.isHeadlessSystemUser()
-                && mCarUserManagerHelper.isCurrentProcessSystemUser());
+    /** Tells whether the current foreground user is the headless system user. */
+    private boolean isCurrentUserHeadlessSystemUser() {
+        int currentUserId = ActivityManager.getCurrentUser();
+        return mCarUserManagerHelper.isHeadlessSystemUser() && currentUserId == 0;
     }
 
     /**
-     * Gets the last known location from the LocationManager and store it in a file.
+     * Gets the last known location from the location manager proxy and store it in a file.
      */
     private void storeLocation() {
-        LocationManager locationManager =
-                (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+        Location location = null;
+        synchronized (mLocationManagerProxyLock) {
+            if (mILocationManagerProxy == null) {
+                logd("Null location manager proxy.");
+                return;
+            }
+            try {
+                location = mILocationManagerProxy.getLastKnownLocation(
+                        LocationManager.GPS_PROVIDER);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException from ILocationManagerProxy", e);
+            }
+        }
         if (location == null) {
             logd("Not storing null location");
         } else {
@@ -277,7 +339,7 @@
     }
 
     /**
-     * Reads a previously stored location and attempts to inject it into the LocationManager.
+     * Reads a previously stored location and attempts to inject it into the location manager proxy.
      */
     private void loadLocation() {
         Location location = readLocationFromCacheFile();
@@ -353,9 +415,18 @@
      * initialized or has not updated its handle to the current user yet.
      */
     private void injectLocation(Location location, int attemptCount) {
-        LocationManager locationManager =
-                (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-        boolean success = locationManager.injectLocation(location);
+        boolean success = false;
+        synchronized (mLocationManagerProxyLock) {
+            if (mILocationManagerProxy == null) {
+                logd("Null location manager proxy.");
+            } else {
+                try {
+                    success = mILocationManagerProxy.injectLocation(location);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException from ILocationManagerProxy", e);
+                }
+            }
+        }
         logd("Injected location " + location + " with result " + success + " on attempt "
                 + attemptCount);
         if (success) {
diff --git a/service/src/com/android/car/CarProjectionService.java b/service/src/com/android/car/CarProjectionService.java
index 144804e..25edc79 100644
--- a/service/src/com/android/car/CarProjectionService.java
+++ b/service/src/com/android/car/CarProjectionService.java
@@ -67,6 +67,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.car.BinderInterfaceContainer.BinderInterface;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
@@ -80,7 +81,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Random;
-import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * Car projection service allows to bound to projected app to boost it prioirity.
@@ -128,8 +128,8 @@
     @GuardedBy("mLock")
     private @Nullable String mCurrentProjectionPackage;
 
-    private final List<ICarProjectionStatusListener> mProjectionStatusListeners =
-            new CopyOnWriteArrayList<>();
+    private final BinderInterfaceContainer<ICarProjectionStatusListener>
+            mProjectionStatusListeners = new BinderInterfaceContainer<>();
 
     @GuardedBy("mLock")
     private final ProjectionKeyEventHandlerContainer mKeyEventHandlers;
@@ -431,7 +431,7 @@
     public void registerProjectionStatusListener(ICarProjectionStatusListener listener)
             throws RemoteException {
         ICarImpl.assertProjectionStatusPermission(mContext);
-        mProjectionStatusListeners.add(listener);
+        mProjectionStatusListeners.addBinder(listener);
 
         // Immediately notify listener with the current status.
         notifyProjectionStatusChanged(listener);
@@ -441,7 +441,7 @@
     public void unregisterProjectionStatusListener(ICarProjectionStatusListener listener)
             throws RemoteException {
         ICarImpl.assertProjectionStatusPermission(mContext);
-        mProjectionStatusListeners.remove(listener);
+        mProjectionStatusListeners.removeBinder(listener);
     }
 
     private ProjectionReceiverClient getOrCreateProjectionReceiverClientLocked(
@@ -488,8 +488,14 @@
         }
 
         if (singleListenerToNotify == null) {
-            for (ICarProjectionStatusListener listener : mProjectionStatusListeners) {
-                listener.onProjectionStatusChanged(currentState, currentPackage, statuses);
+            for (BinderInterface<ICarProjectionStatusListener> listener :
+                    mProjectionStatusListeners.getInterfaces()) {
+                try {
+                    listener.binderInterface.onProjectionStatusChanged(
+                            currentState, currentPackage, statuses);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Error calling to projection status listener", ex);
+                }
             }
         } else {
             singleListenerToNotify.onProjectionStatusChanged(
@@ -793,6 +799,8 @@
             writer.println("Current projection state: " + mCurrentProjectionState);
             writer.println("Current projection package: " + mCurrentProjectionPackage);
             writer.println("Projection status: " + mProjectionReceiverClients);
+            writer.println("Projection status listeners: "
+                    + mProjectionStatusListeners.getInterfaces());
             writer.println("WifiScanner: " + mWifiScanner);
         }
     }
diff --git a/service/src/com/android/car/CarPropertyService.java b/service/src/com/android/car/CarPropertyService.java
index ed24251..3b4e388 100644
--- a/service/src/com/android/car/CarPropertyService.java
+++ b/service/src/com/android/car/CarPropertyService.java
@@ -395,7 +395,7 @@
         List<Client> clients = mPropIdClientMap.get(property);
         if (clients != null) {
             List<CarPropertyEvent> eventList = new LinkedList<>();
-            eventList.add(createErrorEvent(property, area));
+            eventList.add(CarPropertyEvent.createErrorEvent(property, area));
             for (Client c : clients) {
                 try {
                     c.getListener().onEvent(eventList);
@@ -410,9 +410,4 @@
                     + toHexString(property));
         }
     }
-
-    private static CarPropertyEvent createErrorEvent(int property, int area) {
-        return new CarPropertyEvent(CarPropertyEvent.PROPERTY_EVENT_ERROR,
-                new CarPropertyValue<>(property, area, null));
-    }
 }
diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java
index 31627b9..0335186 100644
--- a/service/src/com/android/car/ICarImpl.java
+++ b/service/src/com/android/car/ICarImpl.java
@@ -172,6 +172,7 @@
         CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService);
         CarLocalServices.addService(SystemInterface.class, mSystemInterface);
         CarLocalServices.addService(CarDrivingStateService.class, mCarDrivingStateService);
+        CarLocalServices.addService(PerUserCarServiceHelper.class, mPerUserCarServiceHelper);
 
         // Be careful with order. Service depending on other service should be inited later.
         List<CarServiceBase> allServices = new ArrayList<>();
@@ -504,6 +505,7 @@
         private static final String COMMAND_HELP = "-h";
         private static final String COMMAND_DAY_NIGHT_MODE = "day-night-mode";
         private static final String COMMAND_INJECT_VHAL_EVENT = "inject-vhal-event";
+        private static final String COMMAND_INJECT_ERROR_EVENT = "inject-error-event";
         private static final String COMMAND_ENABLE_UXR = "enable-uxr";
         private static final String COMMAND_GARAGE_MODE = "garage-mode";
         private static final String COMMAND_GET_DO_ACTIVITIES = "get-do-activities";
@@ -532,6 +534,8 @@
             pw.println("\t  Force into day/night mode or restore to auto.");
             pw.println("\tinject-vhal-event property [zone] data(can be comma separated list)");
             pw.println("\t  Inject a vehicle property for testing.");
+            pw.println("\tinject-error-event property zone errorCode");
+            pw.println("\t  Inject an error event from VHAL for testing.");
             pw.println("\tenable-uxr true|false");
             pw.println("\t  Enable/Disable UX restrictions and App blocking.");
             pw.println("\tgarage-mode [on|off|query]");
@@ -584,7 +588,17 @@
                         // Global
                         data = args[2];
                     }
-                    injectVhalEvent(args[1], zone, data, writer);
+                    injectVhalEvent(args[1], zone, data, false, writer);
+                    break;
+                case COMMAND_INJECT_ERROR_EVENT:
+                    if (args.length != 4) {
+                        writer.println("Incorrect number of arguments");
+                        dumpHelp(writer);
+                        break;
+                    }
+                    String errorAreaId = args[2];
+                    String errorCode = args[3];
+                    injectVhalEvent(args[1], errorAreaId, errorCode, true, writer);
                     break;
                 case COMMAND_ENABLE_UXR:
                     if (args.length != 2) {
@@ -722,11 +736,12 @@
          *
          * @param property the Vehicle property Id as defined in the HAL
          * @param zone     Zone that this event services
+         * @param isErrorEvent indicates the type of event
          * @param value    Data value of the event
          * @param writer   PrintWriter
          */
         private void injectVhalEvent(String property, String zone, String value,
-                PrintWriter writer) {
+                boolean isErrorEvent, PrintWriter writer) {
             if (zone != null && (zone.equalsIgnoreCase(PARAM_VEHICLE_PROPERTY_AREA_GLOBAL))) {
                 if (!isPropertyAreaTypeGlobal(property)) {
                     writer.println("Property area type inconsistent with given zone");
@@ -734,7 +749,11 @@
                 }
             }
             try {
-                mHal.injectVhalEvent(property, zone, value);
+                if (isErrorEvent) {
+                    mHal.injectOnPropertySetError(property, zone, value);
+                } else {
+                    mHal.injectVhalEvent(property, zone, value);
+                }
             } catch (NumberFormatException e) {
                 writer.println("Invalid property Id zone Id or value" + e);
                 dumpHelp(writer);
diff --git a/service/src/com/android/car/LocationManagerProxy.java b/service/src/com/android/car/LocationManagerProxy.java
new file mode 100644
index 0000000..8ace92f
--- /dev/null
+++ b/service/src/com/android/car/LocationManagerProxy.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.car.ILocationManagerProxy;
+import android.content.Context;
+import android.location.Location;
+import android.location.LocationManager;
+import android.util.Log;
+
+/** Wraps a {@link LocationManager}. */
+public class LocationManagerProxy extends ILocationManagerProxy.Stub {
+    private static final String TAG = "LocationManagerProxy";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final LocationManager mLocationManager;
+
+    /**
+     * Create a LocationManagerProxy instance given a {@link Context}.
+     */
+    public LocationManagerProxy(Context context) {
+        if (DBG) {
+            Log.d(TAG, "constructed.");
+        }
+        mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+    }
+
+    @Override
+    public boolean isLocationEnabled() {
+        return mLocationManager.isLocationEnabled();
+    }
+
+    @Override
+    public boolean injectLocation(Location location) {
+        return mLocationManager.injectLocation(location);
+    }
+
+    @Override
+    public Location getLastKnownLocation(@NonNull String provider) {
+        if (DBG) {
+            Log.d(TAG, "Getting last known location for provider " + provider);
+        }
+        return mLocationManager.getLastKnownLocation(provider);
+    }
+}
diff --git a/service/src/com/android/car/PerUserCarService.java b/service/src/com/android/car/PerUserCarService.java
index 406456b..dec2b3a 100644
--- a/service/src/com/android/car/PerUserCarService.java
+++ b/service/src/com/android/car/PerUserCarService.java
@@ -18,6 +18,7 @@
 import android.app.Service;
 import android.car.ICarBluetoothUserService;
 import android.car.ICarUserService;
+import android.car.ILocationManagerProxy;
 import android.content.Intent;
 import android.os.IBinder;
 import android.util.Log;
@@ -33,7 +34,8 @@
 public class PerUserCarService extends Service {
     private static final boolean DBG = true;
     private static final String TAG = "CarUserService";
-    private CarBluetoothUserService mCarBluetoothUserService;
+    private volatile CarBluetoothUserService mCarBluetoothUserService;
+    private volatile LocationManagerProxy mLocationManagerProxy;
     private CarUserServiceBinder mCarUserServiceBinder;
 
     @Override
@@ -60,7 +62,9 @@
         if (DBG) {
             Log.d(TAG, "onCreate()");
         }
-        mCarUserServiceBinder = new CarUserServiceBinder(this);
+        mCarUserServiceBinder = new CarUserServiceBinder();
+        mCarBluetoothUserService = new CarBluetoothUserService(this);
+        mLocationManagerProxy = new LocationManagerProxy(this);
         super.onCreate();
     }
 
@@ -69,35 +73,22 @@
         if (DBG) {
             Log.d(TAG, "onDestroy()");
         }
-        mCarBluetoothUserService = null;
         mCarUserServiceBinder = null;
     }
 
-    public void createBluetoothUserService() {
-        if (DBG) {
-            Log.d(TAG, "createBluetoothUserService");
-        }
-        mCarBluetoothUserService = new CarBluetoothUserService(this);
-    }
-
     /**
      * Other Services in CarService can create their own Binder interface and receive that interface
      * through this CarUserService binder.
      */
     private final class CarUserServiceBinder extends ICarUserService.Stub {
-        private PerUserCarService mCarUserService;
-
-        public CarUserServiceBinder(PerUserCarService service) {
-            mCarUserService = service;
+        @Override
+        public ICarBluetoothUserService getBluetoothUserService() {
+            return mCarBluetoothUserService;
         }
 
         @Override
-        public ICarBluetoothUserService getBluetoothUserService() {
-            // Create the bluetoothUserService when needed.
-            if (mCarBluetoothUserService == null) {
-                mCarUserService.createBluetoothUserService();
-            }
-            return mCarBluetoothUserService;
+        public ILocationManagerProxy getLocationManagerProxy() {
+            return mLocationManagerProxy;
         }
     }
 }
diff --git a/service/src/com/android/car/hal/VehicleHal.java b/service/src/com/android/car/hal/VehicleHal.java
index d7faa2b..374ae7b 100644
--- a/service/src/com/android/car/hal/VehicleHal.java
+++ b/service/src/com/android/car/hal/VehicleHal.java
@@ -628,6 +628,23 @@
         onPropertyEvent(Lists.newArrayList(v));
     }
 
+    /**
+     * Inject an error event.
+     *
+     * @param property the Vehicle property Id as defined in the HAL
+     * @param zone Zone for the event to inject
+     * @param errorCode Error code return from HAL
+     */
+    public void injectOnPropertySetError(String property, String zone, String errorCode) {
+        if (zone == null || property == null || errorCode == null) {
+            return;
+        }
+        int propId = Integer.decode(property);
+        int zoneId = Integer.decode(zone);
+        int errorId = Integer.decode(errorCode);
+        onPropertySetError(errorId, propId, zoneId);
+    }
+
     private static class VehiclePropertyEventInfo {
         private int eventCount;
         private VehiclePropValue lastEvent;
diff --git a/tests/BugReportApp/README.md b/tests/BugReportApp/README.md
index 1205ac4..cd0245d 100644
--- a/tests/BugReportApp/README.md
+++ b/tests/BugReportApp/README.md
@@ -1,5 +1,7 @@
 # AAE BugReport App
 
+BugReport App for Android Automotive OS.
+
 ## Flow
 
 1. User long presses Notification icon
@@ -15,3 +17,17 @@
     and when finished it updates MetaBugReport using BugStorageProvider.
 9. BugStorageProvider is running under u0, it schedules UploadJob.
 10. UploadJob runs SimpleUploaderAsyncTask to upload the bugreport.
+
+Bug reports are zipped and uploaded to GCS. GCS enables creating Pub/Sub
+notifications that can be used to track when new  bug reports are uploaded.
+
+## Configuration
+
+UI and upload configs are located in `res/` directory. Resources can be
+[overlayed](https://source.android.com/setup/develop/new-device#use-resource-overlays)
+for specific products.
+
+### Upload configuration
+
+BugReport app uses `res/raw/gcs_credentials.json` for authentication and
+`res/values/configs.xml` for obtaining GCS bucket name.
diff --git a/tests/BugReportApp/res/drawable/item_background.xml b/tests/BugReportApp/res/drawable/item_background.xml
new file mode 100644
index 0000000..d5f33a0
--- /dev/null
+++ b/tests/BugReportApp/res/drawable/item_background.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@*android:color/car_grey_600">
+  <item android:drawable="@color/bugreport_button_background" />
+</ripple>
diff --git a/tests/BugReportApp/res/layout/bug_report_activity.xml b/tests/BugReportApp/res/layout/bug_report_activity.xml
index bd28000..f7e5888 100644
--- a/tests/BugReportApp/res/layout/bug_report_activity.xml
+++ b/tests/BugReportApp/res/layout/bug_report_activity.xml
@@ -30,7 +30,7 @@
         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:textSize="@dimen/bug_report_title_size"
+            android:textAppearance="?android:attr/textAppearanceLarge"
             android:textColor="@color/bugreport_text"
             android:gravity="center"
             android:text="@string/bugreport_dialog_title"/>
@@ -44,30 +44,26 @@
             android:layout_marginTop="@dimen/bug_report_voice_recording_margin_top"
             android:layout_width="match_parent"
             android:layout_height="@dimen/bug_report_voice_recording_height"
-            android:textSize="@dimen/bug_report_text_size"
+            android:textAppearance="?android:attr/textAppearanceMedium"
             android:textColor="@color/bugreport_text"
             android:gravity="center"
             android:visibility="gone"
             android:text="@string/bugreport_dialog_recording_finished"/>
         <Button
             android:id="@+id/button_submit"
+            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_primary_button_padding"
-            android:background="@color/bugreport_button_background"
-            android:textColor="@color/bugreport_button_foreground"
-            android:textSize="@dimen/bug_report_button_text_size"
             android:text="@string/bugreport_dialog_submit"/>
         <Button
             android:id="@+id/button_cancel"
+            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_secondary_button_padding"
-            android:background="@color/bugreport_button_background"
-            android:textColor="@color/bugreport_button_foreground"
-            android:textSize="@dimen/bug_report_button_text_size"
             android:text="@string/bugreport_dialog_cancel"/>
     </LinearLayout>
 
@@ -80,27 +76,34 @@
         android:visibility="gone"
         android:orientation="vertical">
         <TextView
+            android:id="@+id/in_progress_title_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textSize="@dimen/bug_report_title_size"
+            android:textAppearance="?android:attr/textAppearanceLarge"
             android:textColor="@color/bugreport_text"
             android:gravity="center"
             android:text="@string/bugreport_dialog_in_progress_title"/>
         <ProgressBar
-            style="?android:attr/progressBarStyleLarge"
-            android:layout_width="wrap_content"
+            android:id="@+id/progress_bar"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/bug_report_progress_bar_margin_top"
-            android:layout_gravity="center"/>
+            android:max="100"/>
+        <TextView
+            android:id="@+id/progress_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="@color/bugreport_text"
+            android:text="0%"/>
         <Button
             android:id="@+id/button_close"
+            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_secondary_button_padding"
-            android:background="@color/bugreport_button_background"
-            android:textColor="@color/bugreport_button_foreground"
-            android:textSize="@dimen/bug_report_button_text_size"
             android:text="@string/bugreport_dialog_close"/>
     </LinearLayout>
 </LinearLayout>
diff --git a/tests/BugReportApp/res/values/dimens.xml b/tests/BugReportApp/res/values/dimens.xml
index f70b564..e6c1162 100644
--- a/tests/BugReportApp/res/values/dimens.xml
+++ b/tests/BugReportApp/res/values/dimens.xml
@@ -19,10 +19,6 @@
     <!-- Margin between edge of BugReportActivity dialog and content -->
     <dimen name="bug_report_padding">30dp</dimen>
 
-    <dimen name="bug_report_title_size">32sp</dimen>
-    <dimen name="bug_report_text_size">24sp</dimen>
-    <dimen name="bug_report_button_text_size">32sp</dimen>
-
     <!-- VoiceRecordingView dimensions -->
     <dimen name="bug_report_voice_recording_margin_top">20dp</dimen>
     <dimen name="bug_report_voice_recording_height">40dp</dimen>
diff --git a/tests/BugReportApp/res/values/strings.xml b/tests/BugReportApp/res/values/strings.xml
index 3f77ab2..55b2d86 100644
--- a/tests/BugReportApp/res/values/strings.xml
+++ b/tests/BugReportApp/res/values/strings.xml
@@ -26,6 +26,7 @@
     <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="toast_permissions_denied" translatable="false">Please grant permissions</string>
     <string name="toast_bug_report_in_progress" translatable="false">Bug report already being collected</string>
diff --git a/tests/BugReportApp/res/values/styles.xml b/tests/BugReportApp/res/values/styles.xml
index d8dbb02..6d8dd96 100644
--- a/tests/BugReportApp/res/values/styles.xml
+++ b/tests/BugReportApp/res/values/styles.xml
@@ -15,12 +15,11 @@
      limitations under the License.
 -->
 <resources>
-  <style name="Theme.Transparent" parent="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor">
-    <item name="android:windowIsTranslucent">true</item>
-    <item name="android:windowBackground">@android:color/transparent</item>
-    <item name="android:windowContentOverlay">@null</item>
-    <item name="android:windowNoTitle">true</item>
-    <item name="android:windowIsFloating">true</item>
-    <item name="android:backgroundDimEnabled">false</item>
+  <style name="standard_button">
+    <item name="android:gravity">center</item>
+    <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
+    <item name="android:textColor">@color/bugreport_button_foreground</item>
+    <item name="android:clickable">true</item>
+    <item name="android:background">@drawable/item_background</item>
   </style>
 </resources>
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java
index 924bda5..c0b9da3 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java
@@ -16,6 +16,7 @@
 package com.google.android.car.bugreport;
 
 import static com.google.android.car.bugreport.BugReportService.EXTRA_META_BUG_REPORT;
+import static com.google.android.car.bugreport.BugReportService.MAX_PROGRESS_VALUE;
 
 import android.Manifest;
 import android.app.Activity;
@@ -33,6 +34,8 @@
 import android.util.Log;
 import android.view.View;
 import android.view.Window;
+import android.widget.ProgressBar;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import java.io.File;
@@ -63,6 +66,9 @@
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
 
+    private TextView mInProgressTitleText;
+    private ProgressBar mProgressBar;
+    private TextView mProgressText;
     private VoiceRecordingView mVoiceRecordingView;
     private View mVoiceRecordingFinishedView;
     private View mSubmitBugReportLayout;
@@ -99,6 +105,9 @@
         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);
@@ -128,6 +137,9 @@
         if (!mBugReportServiceStarted && mAudioRecordingStarted) {
             cancelAudioMessageRecording();
         }
+        if (mBound) {
+            mService.removeBugReportProgressListener();
+        }
         mAudioRecordingStarted = false;
     }
 
@@ -142,21 +154,20 @@
         }
     }
 
-    private void checkStatus() {
-        if (mBound && mService.isCollectingBugReport()) {
-            scheduleStatusCheck();
-        } else {
-            finish();
+    private void onProgressChanged(float progress) {
+        int progressValue = (int) progress;
+        mProgressBar.setProgress(progressValue);
+        mProgressText.setText(progressValue + "%");
+        if (progressValue == MAX_PROGRESS_VALUE) {
+            mInProgressTitleText.setText(R.string.bugreport_dialog_in_progress_title_finished);
         }
     }
 
-    private void scheduleStatusCheck() {
-        mHandler.postDelayed(this::checkStatus, 1000);
-    }
-
     private void showInProgressUi() {
         mSubmitBugReportLayout.setVisibility(View.GONE);
         mInProgressLayout.setVisibility(View.VISIBLE);
+        mInProgressTitleText.setText(R.string.bugreport_dialog_in_progress_title);
+        onProgressChanged(mService.getBugReportProgress());
     }
 
     private void showSubmitBugReportUi(boolean isRecording) {
@@ -171,11 +182,17 @@
         }
     }
 
+    /**
+     * Initializes MetaBugReport in a local DB and starts audio recording.
+     *
+     * <p>This method expected to be called when the activity is started and bound to the service.
+     */
     private void startAudioMessageRecording() {
+        mService.setBugReportProgressListener(this::onProgressChanged);
+
         if (mService.isCollectingBugReport()) {
             Log.i(TAG, "Bug report is already being collected.");
             showInProgressUi();
-            scheduleStatusCheck();
             return;
         }
 
@@ -263,6 +280,8 @@
                 + Arrays.toString(permissions);
         Log.w(TAG, text);
         Toast.makeText(this, text, Toast.LENGTH_LONG).show();
+        BugStorageUtils.setBugReportStatus(this, mMetaBugReport,
+                Status.STATUS_USER_CANCELLED, text);
         finish();
     }
 
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
index 1b1d030..cce327d 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
@@ -17,6 +17,7 @@
 
 import static com.google.android.car.bugreport.PackageUtils.getPackageVersion;
 
+import android.annotation.FloatRange;
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.app.Notification;
@@ -32,11 +33,14 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 import android.view.Display;
 import android.widget.Toast;
 
+import com.google.common.util.concurrent.AtomicDouble;
+
 import libcore.io.IoUtils;
 
 import java.io.BufferedOutputStream;
@@ -89,27 +93,44 @@
     // http://cs/android/frameworks/base/core/java/android/app/ActivityView.java
     private static final String ACTIVITY_VIEW_VIRTUAL_DISPLAY = "ActivityViewVirtualDisplay";
     private static final String OUTPUT_ZIP_FILE = "output_file.zip";
-    private static final String PROGRESS_FILE = "progress.txt";
 
     private static final String MESSAGE_FAILURE_DUMPSTATE = "Failed to grab dumpstate";
     private static final String MESSAGE_FAILURE_ZIP = "Failed to zip files";
 
-    // Binder given to clients
+    private static final int PROGRESS_HANDLER_EVENT_PROGRESS = 1;
+    private static final String PROGRESS_HANDLER_DATA_PROGRESS = "progress";
+
+    static final float MAX_PROGRESS_VALUE = 100f;
+
+    /** Binder given to clients. */
     private final IBinder mBinder = new ServiceBinder();
 
+    private final AtomicBoolean mIsCollectingBugReport = new AtomicBoolean(false);
+    private final AtomicDouble mBugReportProgress = new AtomicDouble(0);
+
     private MetaBugReport mMetaBugReport;
     private NotificationManager mNotificationManager;
     private NotificationChannel mNotificationChannel;
-    private AtomicBoolean mIsCollectingBugReport = new AtomicBoolean(false);
-    private Handler mHandler;
     private ScheduledExecutorService mSingleThreadExecutor;
+    private BugReportProgressListener mBugReportProgressListener;
     private Car mCar;
     private CarBugreportManager mBugreportManager;
     private CarBugreportManager.CarBugreportManagerCallback mCallback;
 
-    /**
-     * Client binder.
-     */
+    /** A handler on the main thread. */
+    private Handler mHandler;
+
+    /** A listener that's notified when bugreport progress changes. */
+    interface BugReportProgressListener {
+        /**
+         * Called when bug report progress changes.
+         *
+         * @param progress - a bug report progress in [0.0, 100.0].
+         */
+        void onProgress(float progress);
+    }
+
+    /** Client binder. */
     public class ServiceBinder extends Binder {
         BugReportService getService() {
             // Return this instance of LocalService so clients can call public methods
@@ -117,6 +138,23 @@
         }
     }
 
+    /** A handler on a main thread. */
+    private class BugReportHandler extends Handler {
+        @Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case PROGRESS_HANDLER_EVENT_PROGRESS:
+                    if (mBugReportProgressListener != null) {
+                        float progress = message.getData().getFloat(PROGRESS_HANDLER_DATA_PROGRESS);
+                        mBugReportProgressListener.onProgress(progress);
+                    }
+                    break;
+                default:
+                    Log.d(TAG, "Unknown event " + message.what + ", ignoring.");
+            }
+        }
+    }
+
     @Override
     public void onCreate() {
         mNotificationManager = getSystemService(NotificationManager.class);
@@ -125,8 +163,8 @@
                 getString(R.string.notification_bugreport_channel_name),
                 NotificationManager.IMPORTANCE_MIN);
         mNotificationManager.createNotificationChannel(mNotificationChannel);
-        mHandler = new Handler();
         mSingleThreadExecutor = Executors.newSingleThreadScheduledExecutor();
+        mHandler = new BugReportHandler();
         mCar = Car.createCar(this);
         try {
             mBugreportManager = (CarBugreportManager) mCar.getCarManager(Car.CAR_BUGREPORT_SERVICE);
@@ -145,6 +183,7 @@
         Log.i(TAG, String.format("Will start collecting bug report, version=%s",
                 getPackageVersion(this)));
         mIsCollectingBugReport.set(true);
+        mBugReportProgress.set(0);
 
         Notification notification =
                 new Notification.Builder(this, NOTIFICATION_STATUS_CHANNEL_ID)
@@ -162,16 +201,32 @@
         return START_NOT_STICKY;
     }
 
+    /** Returns true if bugreporting is in progress. */
     public boolean isCollectingBugReport() {
         return mIsCollectingBugReport.get();
     }
 
+    /** Returns current bugreport progress. */
+    public float getBugReportProgress() {
+        return (float) mBugReportProgress.get();
+    }
+
+    /** Sets a bugreport progress listener. The listener is called on a main thread. */
+    public void setBugReportProgressListener(BugReportProgressListener listener) {
+        mBugReportProgressListener = listener;
+    }
+
+    /** Removes the bugreport progress listener. */
+    public void removeBugReportProgressListener() {
+        mBugReportProgressListener = null;
+    }
+
     @Override
     public IBinder onBind(Intent intent) {
         return mBinder;
     }
 
-    private void sendStatusInformation(@StringRes int resId) {
+    private void showToast(@StringRes int resId) {
         // run on ui thread.
         mHandler.post(() -> Toast.makeText(this, getText(resId), Toast.LENGTH_LONG).show());
     }
@@ -214,7 +269,7 @@
             return result;
         } catch (IOException | InterruptedException e) {
             Log.e(TAG, "screencap process failed: ", e);
-            sendStatusInformation(R.string.toast_status_screencap_failed);
+            showToast(R.string.toast_status_screencap_failed);
         }
         return null;
     }
@@ -250,31 +305,26 @@
     private void dumpStateToFile() {
         Log.i(TAG, "Dumpstate to file");
         File outputFile = FileUtils.getFile(this, mMetaBugReport.getTimestamp(), OUTPUT_ZIP_FILE);
-        File progressFile = FileUtils.getFile(this, mMetaBugReport.getTimestamp(), PROGRESS_FILE);
 
-        ParcelFileDescriptor outFd = null;
-        ParcelFileDescriptor progressFd = null;
-        try {
-            outFd = ParcelFileDescriptor.open(outputFile,
-                    ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE);
-
-            progressFd = ParcelFileDescriptor.open(progressFile,
-                    ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE);
-
-            requestBugReport(outFd, progressFd);
+        try (ParcelFileDescriptor outFd = ParcelFileDescriptor.open(outputFile,
+                ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE)) {
+            requestBugReport(outFd);
         } catch (IOException | RuntimeException e) {
             Log.e(TAG, "Failed to grab dump state", e);
             BugStorageUtils.setBugReportStatus(this, mMetaBugReport, Status.STATUS_WRITE_FAILED,
                     MESSAGE_FAILURE_DUMPSTATE);
-            sendStatusInformation(R.string.toast_status_dump_state_failed);
-        } finally {
-            IoUtils.closeQuietly(outFd);
-            IoUtils.closeQuietly(progressFd);
+            showToast(R.string.toast_status_dump_state_failed);
         }
     }
 
-    // In Android Q and above, use the CarBugreportManager API
-    private void requestBugReport(ParcelFileDescriptor outFd, ParcelFileDescriptor progressFd) {
+    private void sendProgressEventToHandler(float progress) {
+        Message message = new Message();
+        message.what = PROGRESS_HANDLER_EVENT_PROGRESS;
+        message.getData().putFloat(PROGRESS_HANDLER_DATA_PROGRESS, progress);
+        mHandler.sendMessage(message);
+    }
+
+    private void requestBugReport(ParcelFileDescriptor outFd) {
         if (DEBUG) {
             Log.d(TAG, "Requesting a bug report from CarBugReportManager.");
         }
@@ -282,18 +332,30 @@
             @Override
             public void onError(int errorCode) {
                 Log.e(TAG, "Bugreport failed " + errorCode);
-                sendStatusInformation(R.string.toast_status_failed);
+                showToast(R.string.toast_status_failed);
                 // TODO(b/133520419): show this error on Info page or add to zip file.
                 scheduleZipTask();
+                // 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);
+            }
+
+            @Override
+            public void onProgress(@FloatRange(from = 0f, to = MAX_PROGRESS_VALUE) float progress) {
+                mBugReportProgress.set(progress);
+                sendProgressEventToHandler(progress);
             }
 
             @Override
             public void onFinished() {
                 Log.i(TAG, "Bugreport finished");
                 scheduleZipTask();
+                mBugReportProgress.set(MAX_PROGRESS_VALUE);
+                sendProgressEventToHandler(MAX_PROGRESS_VALUE);
             }
         };
-        mBugreportManager.requestZippedBugreport(outFd, progressFd, mCallback);
+        mBugreportManager.requestZippedBugreport(outFd, mCallback);
     }
 
     private void scheduleZipTask() {
@@ -311,10 +373,10 @@
             Log.e(TAG, "Failed to zip files", e);
             BugStorageUtils.setBugReportStatus(this, mMetaBugReport, Status.STATUS_WRITE_FAILED,
                     MESSAGE_FAILURE_ZIP);
-            sendStatusInformation(R.string.toast_status_failed);
+            showToast(R.string.toast_status_failed);
         }
         mIsCollectingBugReport.set(false);
-        sendStatusInformation(R.string.toast_status_finished);
+        showToast(R.string.toast_status_finished);
     }
 
     @Override
@@ -371,10 +433,6 @@
                     continue;
                 }
                 String filename = file.getName();
-                if (filename.equals(PROGRESS_FILE)) {
-                    // Progress file is already part of zipped bugreport - skip it.
-                    continue;
-                }
                 // only for the OUTPUT_FILE, we add invidiual entries to zip file
                 if (filename.equals(OUTPUT_ZIP_FILE)) {
                     extractZippedFileToOutputStream(file, zipStream);
diff --git a/tests/CarCtsDummyLauncher/res/values-af/strings.xml b/tests/CarCtsDummyLauncher/res/values-af/strings.xml
deleted file mode 100644
index ed08816..0000000
--- a/tests/CarCtsDummyLauncher/res/values-af/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Deïnstalleer dit wanneer CTS klaar is\n\n Om dit te deïnstalleer, kan jy Instellings-program of die volgende bevel gebruik:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Skynlanseerder vir CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-am/strings.xml b/tests/CarCtsDummyLauncher/res/values-am/strings.xml
deleted file mode 100644
index a25efc4..0000000
--- a/tests/CarCtsDummyLauncher/res/values-am/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS ከጨረሰ በኋላ ይህን ይጫኑት\n\n ለማራገፍ የቅንብር መተግበሪያውን መጠቀም ወይም የሚከተለውን ትዕዛዝ ማሄድ ይችላሉ፦\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"ለCTS የውሸት ማስጀመሪያ"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ar/strings.xml b/tests/CarCtsDummyLauncher/res/values-ar/strings.xml
deleted file mode 100644
index dd234d9..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ar/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"يمكنك إلغاء تثبيت هذا بعد اكتمال CTS\n\n لإلغاء تثبيته، يمكنك استخدام تطبيق Setting أو تنفيذ الأمر التالي:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-as/strings.xml b/tests/CarCtsDummyLauncher/res/values-as/strings.xml
deleted file mode 100644
index e4a1aec..0000000
--- a/tests/CarCtsDummyLauncher/res/values-as/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS সমাপ্ত হোৱাৰ পাছত এইটো আনইনষ্টল কৰক\n\n আনইনষ্টল কৰিবলৈ আপুনি Setting এপ্‌টো ব্যৱহাৰ কৰিব পাৰে অথবা তলৰ কামাণ্ডটো চলাব পাৰে:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTSৰ বাবে ডামী লঞ্চাৰ"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-az/strings.xml b/tests/CarCtsDummyLauncher/res/values-az/strings.xml
deleted file mode 100644
index 882890f..0000000
--- a/tests/CarCtsDummyLauncher/res/values-az/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS bitdikdən sonra bunun quraşdırılmasını ləğv edin\n\n Quraşdırılmanı ləğv etmək üçün Ayarlama tətbiqini istifadə edə və ya bu əmri tətbiq edə bilərsiniz:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS üçün Şablon Başladıcı"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-b+sr+Latn/strings.xml b/tests/CarCtsDummyLauncher/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 854f4d4..0000000
--- a/tests/CarCtsDummyLauncher/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Deinstalirajte ovo kada se CTS završi\n\n Da biste deinstalirali, možete da koristite aplikaciju Podešavanja ili pokrenete sledeću komandu:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Primer pokretača za CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-be/strings.xml b/tests/CarCtsDummyLauncher/res/values-be/strings.xml
deleted file mode 100644
index 9e15bb2..0000000
--- a/tests/CarCtsDummyLauncher/res/values-be/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Выдаліце гэта пасля завяршэння CTS\n\n Каб выдаліць, можна скарыстаць праграму \"Налады\" ці запусціць наступную каманду:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Праграма тэставага запуску для CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-bg/strings.xml b/tests/CarCtsDummyLauncher/res/values-bg/strings.xml
deleted file mode 100644
index 339f884..0000000
--- a/tests/CarCtsDummyLauncher/res/values-bg/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Деинсталирайте след завършване на CTS\n\n За целта можете да използвате приложението „Настройки“ или да изпълните следната команда:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Фиктивен стартов панел за CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-bn/strings.xml b/tests/CarCtsDummyLauncher/res/values-bn/strings.xml
deleted file mode 100644
index e2a11bd..0000000
--- a/tests/CarCtsDummyLauncher/res/values-bn/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"সিটিএস শেষ হওয়ার পরে এটি আনইনস্টল করুন\n\nআনইনস্টল করতে সেটিং অ্যাপ ব্যবহার করুন অথবা এই কমান্ড ব্যবহার করুন:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"সিটিএসের জন্য ডামি লঞ্চার"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-bs/strings.xml b/tests/CarCtsDummyLauncher/res/values-bs/strings.xml
deleted file mode 100644
index 2ef3845..0000000
--- a/tests/CarCtsDummyLauncher/res/values-bs/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Deinstalirajte ovo nakon što CTS završi\n\n Za deinstaliranje, možete koristiti aplikaciju Postavke ili pokrenuti sljedeću komandu:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Testni pokretač za CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ca/strings.xml b/tests/CarCtsDummyLauncher/res/values-ca/strings.xml
deleted file mode 100644
index 44789d6..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ca/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Desinstal·la quan finalitzi el CTS\n\n Per desinstal·lar, pots utilitzar l\'aplicació Configuració o executar l\'ordre següent:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher per a CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-cs/strings.xml b/tests/CarCtsDummyLauncher/res/values-cs/strings.xml
deleted file mode 100644
index 08ef387..0000000
--- a/tests/CarCtsDummyLauncher/res/values-cs/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Po skončení testu CTS položku odinstalujte\n\n Odinstalovat ji lze pomocí aplikace Nastavení nebo následujícího příkazu:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Zkušební spouštěč pro testy CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-da/strings.xml b/tests/CarCtsDummyLauncher/res/values-da/strings.xml
deleted file mode 100644
index cc485df..0000000
--- a/tests/CarCtsDummyLauncher/res/values-da/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Afinstaller, når CTS er afsluttet \n\n Du kan afinstallere i appen Indstillinger eller ved at køre følgende kommando:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Teststarter til CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-de/strings.xml b/tests/CarCtsDummyLauncher/res/values-de/strings.xml
deleted file mode 100644
index bfc68f0..0000000
--- a/tests/CarCtsDummyLauncher/res/values-de/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Deinstallieren, nachdem die CTS-Tests abgeschlossen sind\n\n Du kannst dies über die App \"Einstellungen\" deinstallieren oder den folgenden Befehl ausführen:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher für CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-el/strings.xml b/tests/CarCtsDummyLauncher/res/values-el/strings.xml
deleted file mode 100644
index ae6482e..0000000
--- a/tests/CarCtsDummyLauncher/res/values-el/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Απεγκατάσταση αυτού του στοιχείου μετά την ολοκλήρωση του CTS\n\n Για να το απεγκαταστήσετε, μπορείτε να χρησιμοποιήσετε την εφαρμογή Ρυθμίσεις ή να εκτελέσετε την ακόλουθη εντολή:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Εικονική εφαρμογή εκκίνησης για CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-en-rAU/strings.xml b/tests/CarCtsDummyLauncher/res/values-en-rAU/strings.xml
deleted file mode 100644
index 623d10a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Uninstall this after CTS finishes\n\n To uninstall, you can use Setting app or run the following command:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-en-rCA/strings.xml b/tests/CarCtsDummyLauncher/res/values-en-rCA/strings.xml
deleted file mode 100644
index 623d10a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Uninstall this after CTS finishes\n\n To uninstall, you can use Setting app or run the following command:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-en-rGB/strings.xml b/tests/CarCtsDummyLauncher/res/values-en-rGB/strings.xml
deleted file mode 100644
index 623d10a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Uninstall this after CTS finishes\n\n To uninstall, you can use Setting app or run the following command:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-en-rIN/strings.xml b/tests/CarCtsDummyLauncher/res/values-en-rIN/strings.xml
deleted file mode 100644
index 623d10a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Uninstall this after CTS finishes\n\n To uninstall, you can use Setting app or run the following command:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-en-rXC/strings.xml b/tests/CarCtsDummyLauncher/res/values-en-rXC/strings.xml
deleted file mode 100644
index a35d467..0000000
--- a/tests/CarCtsDummyLauncher/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎Uninstall this after CTS finishs‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ To uninstall, you can use Setting app or run the following command:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ adb uninstall com.android.car.dummylauncher‎‏‎‎‏‎"</string>
-    <string name="app_name" msgid="1129651585636850259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‎Dummy Launcher for CTS‎‏‎‎‏‎"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-es-rUS/strings.xml b/tests/CarCtsDummyLauncher/res/values-es-rUS/strings.xml
deleted file mode 100644
index ab63dea..0000000
--- a/tests/CarCtsDummyLauncher/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Desinstalar cuando finalice CTS\n\n Para desinstalar, puedes usar la app de Configuración o ejecutar el siguiente comando:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Launcher ficticio para CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-es/strings.xml b/tests/CarCtsDummyLauncher/res/values-es/strings.xml
deleted file mode 100644
index a7623bc..0000000
--- a/tests/CarCtsDummyLauncher/res/values-es/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Desinstala este launcher una vez que CTS termine.\n\n Para ello, usa la aplicación Ajustes o ejecuta el siguiente comando:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher para CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-et/strings.xml b/tests/CarCtsDummyLauncher/res/values-et/strings.xml
deleted file mode 100644
index 1a37e66..0000000
--- a/tests/CarCtsDummyLauncher/res/values-et/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Desinstallige see pärast CTS-i lõppu\n\n Desinstallimiseks võite kasutada rakendust Seaded või käitada järgmise käsu:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS-i fiktiivne käivitusprogramm"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-eu/strings.xml b/tests/CarCtsDummyLauncher/res/values-eu/strings.xml
deleted file mode 100644
index 66f5528..0000000
--- a/tests/CarCtsDummyLauncher/res/values-eu/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTSk amaitzen duenean, desinstalatu hau\n\n Desinstalatzeko, Ezarpenak aplikazioa erabil dezakezu, edo agindu hau exekutatu:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTSrako adibide gisako abiarazlea"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-fa/strings.xml b/tests/CarCtsDummyLauncher/res/values-fa/strings.xml
deleted file mode 100644
index 1d4855a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-fa/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"بعد از پایان CTS، این مورد را حذف نصب کنید\n\n برای حذف نصب، می‌توانید از برنامه «تنظیمات» استفاده کنید و فرمان زیر را اجرا کنید:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"راه‌انداز ساختگی برای CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-fi/strings.xml b/tests/CarCtsDummyLauncher/res/values-fi/strings.xml
deleted file mode 100644
index c28091b..0000000
--- a/tests/CarCtsDummyLauncher/res/values-fi/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Poista tämä, kun CTS on tehty\n\n Voit poistaa tämän asetussovelluksessa tai seuraavalla komennolla:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS:n näköiskäynnistin"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-fr-rCA/strings.xml b/tests/CarCtsDummyLauncher/res/values-fr-rCA/strings.xml
deleted file mode 100644
index b8b162a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Désinstallez le lanceur factice à l\'achèvement de la suite de tests de compatibilité.\n\n Pour le désinstaller, vous pouvez utiliser l\'application Paramètres ou exécuter la commande suivantes :\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Lanceur factice pour suite de tests de compatibilité"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-fr/strings.xml b/tests/CarCtsDummyLauncher/res/values-fr/strings.xml
deleted file mode 100644
index 13017f0..0000000
--- a/tests/CarCtsDummyLauncher/res/values-fr/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Désinstaller à la fin de CTS\n\n Pour désinstaller, utilisez l\'application Paramètres ou exécutez la commande suivante :\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Lanceur factice pour CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-gl/strings.xml b/tests/CarCtsDummyLauncher/res/values-gl/strings.xml
deleted file mode 100644
index 3e1f39b..0000000
--- a/tests/CarCtsDummyLauncher/res/values-gl/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Efectúa a desinstalación despois de que CTS remate\n\n Para facelo podes usar a aplicación Configuración ou ben executar o seguinte comando:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Menú de aplicacións de proba para CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-gu/strings.xml b/tests/CarCtsDummyLauncher/res/values-gu/strings.xml
deleted file mode 100644
index b86e692..0000000
--- a/tests/CarCtsDummyLauncher/res/values-gu/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS સમાપ્ત થાય તે પછી આને અનઇન્સ્ટૉલ કરો\n\n અનઇન્સ્ટૉલ કરવા માટે, તમે સેટિંગ ઍપનો ઉપયોગ કરી શકો છો અથવા નીચે આપેલો આદેશ ચલાવી શકો છો:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS માટે ડમી લૉન્ચર"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-hi/strings.xml b/tests/CarCtsDummyLauncher/res/values-hi/strings.xml
deleted file mode 100644
index 7ef08e7..0000000
--- a/tests/CarCtsDummyLauncher/res/values-hi/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Uninstall this after CTS finishs\n\n To uninstall, you can use Setting app or run the following command:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-hr/strings.xml b/tests/CarCtsDummyLauncher/res/values-hr/strings.xml
deleted file mode 100644
index 4ab9f2c..0000000
--- a/tests/CarCtsDummyLauncher/res/values-hr/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Deinstalirajte ovo nakon što CTS završi\n\n Za deinstalaciju možete upotrijebiti aplikaciju Postavke ili izvršiti naredbu \n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Model pokretača za CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-hu/strings.xml b/tests/CarCtsDummyLauncher/res/values-hu/strings.xml
deleted file mode 100644
index a047d40..0000000
--- a/tests/CarCtsDummyLauncher/res/values-hu/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Távolítsa el ezt, miután a CTS lefutott\n\n Az eltávolításhoz használhatja a Beállítások alkalmazást, vagy futtathatja a következő parancsot:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy indító CTS-hez"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-hy/strings.xml b/tests/CarCtsDummyLauncher/res/values-hy/strings.xml
deleted file mode 100644
index e016afb..0000000
--- a/tests/CarCtsDummyLauncher/res/values-hy/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Ապատեղադրեք սա, երբ CTS-ն ավարտի գործողությունը\n\nԱպատեղադրելու համար դուք կարող եք օգտագործել «Կարգավորումներ» հավելվածը կամ տալ հետևյալ հրահանգը՝\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS-ի գործարկիչի օրինակ"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-in/strings.xml b/tests/CarCtsDummyLauncher/res/values-in/strings.xml
deleted file mode 100644
index f5d64ef..0000000
--- a/tests/CarCtsDummyLauncher/res/values-in/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Uninstal ini setelah CTS selesai\n\n Untuk meng-uninstal, Anda dapat menggunakan aplikasi Setelan atau menjalankan command berikut:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Peluncur Dummy untuk CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-is/strings.xml b/tests/CarCtsDummyLauncher/res/values-is/strings.xml
deleted file mode 100644
index 3c727aa..0000000
--- a/tests/CarCtsDummyLauncher/res/values-is/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Fjarlægja þetta þegar CTS lýkur\n\n Til að fjarlægja geturðu notað stillingarforritið eða keyrt eftirfarandi skipun:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Staðgengilsræsiforrit fyrir CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-it/strings.xml b/tests/CarCtsDummyLauncher/res/values-it/strings.xml
deleted file mode 100644
index 3a59445..0000000
--- a/tests/CarCtsDummyLauncher/res/values-it/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Disinstalla al termine di CTS.\n\n Per la disinstallazione, puoi usare l\'app Impostazioni o eseguire il comando seguente:\n adb uninstall com.android.car.dummylauncher."</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-iw/strings.xml b/tests/CarCtsDummyLauncher/res/values-iw/strings.xml
deleted file mode 100644
index bed29ba..0000000
--- a/tests/CarCtsDummyLauncher/res/values-iw/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"יש להסיר את ההתקנה הזו לאחר סיום ה-CTS\n\n כדי להסיר את ההתקנה, אפשר להשתמש באפליקציית ההגדרות או להריץ את הפקודה הבאה:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"מרכז אפליקציות מדומה ל-CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ja/strings.xml b/tests/CarCtsDummyLauncher/res/values-ja/strings.xml
deleted file mode 100644
index c70d88b..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ja/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS の終了後にこのランチャーをアンインストールしてください\n\nアンインストールするには、設定アプリを使用するか、以下のコマンドを実行してください。\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS のダミー ランチャー"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ka/strings.xml b/tests/CarCtsDummyLauncher/res/values-ka/strings.xml
deleted file mode 100644
index e6005e0..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ka/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS-ის დასრულების შემდეგ მოხდეს ამის დეინსტალაცია\n\n დეინსტალაციისთვის შეგიძლიათ გამოიყენოთ პარამეტრების აპი ან გაუშვათ შემდეგი ბრძანება:\n adb დეინსტალაცია com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"ფიქტიური გამშვები CTS-ისთვის"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-kk/strings.xml b/tests/CarCtsDummyLauncher/res/values-kk/strings.xml
deleted file mode 100644
index ab44d32..0000000
--- a/tests/CarCtsDummyLauncher/res/values-kk/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS біткен соң, мұны жойып тастаңыз.\n\n Жою үшін \"Параметр\" қолданбасын пайдалана аласыз немесе мына пәрменді іске қосыңыз:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS-ке арналған жалған Launcher"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-km/strings.xml b/tests/CarCtsDummyLauncher/res/values-km/strings.xml
deleted file mode 100644
index 47522bf..0000000
--- a/tests/CarCtsDummyLauncher/res/values-km/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"លុបវា បន្ទាប់ពី CTS បញ្ចប់ \n\n ដើម្បីលុប អ្នកអាច​ប្រើ​កម្មវិធី​ការកំណត់ ឬ​ដំណើរការ​ការបញ្ជា​ខាងក្រោម៖\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher សម្រាប់ CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-kn/strings.xml b/tests/CarCtsDummyLauncher/res/values-kn/strings.xml
deleted file mode 100644
index 88dbce0..0000000
--- a/tests/CarCtsDummyLauncher/res/values-kn/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS ಪೂರ್ಣಗೊಂಡ ನಂತರ ಇದನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ\n\n ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು, ನೀವು ಸೆಟ್ಟಿಂಗ್‌ ಆ್ಯಪ್ ಬಳಸಬಹುದು ಅಥವಾ ಈ ಕಮಾಂಡ್ ಅನ್ನು ರನ್ ಮಾಡಬಹುದು:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS ಗಾಗಿ ನಕಲಿ ಲಾಂಚರ್"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ko/strings.xml b/tests/CarCtsDummyLauncher/res/values-ko/strings.xml
deleted file mode 100644
index ff5e7bf..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ko/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS 완료 후 제거\n\n 제거하려면 설정 앱을 사용하거나 다음 명령어를 실행하세요.\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS용 더미 런처"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ky/strings.xml b/tests/CarCtsDummyLauncher/res/values-ky/strings.xml
deleted file mode 100644
index ec18815..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ky/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Муну CTS аяктагандан кийин чыгарып салыңыз\n\n Чыгарып салуу үчүн Жөндөө колдонмосун пайдаланыңыз же төмөнкү буйрукту аткарыңыз:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS үчүн Dummy Launcher"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-lo/strings.xml b/tests/CarCtsDummyLauncher/res/values-lo/strings.xml
deleted file mode 100644
index 9b95d4f..0000000
--- a/tests/CarCtsDummyLauncher/res/values-lo/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"ຖອນການຕິດຕັ້ງສິ່ງນີ້ຫຼັງຈາກ CTS ສຳເລັດ\n\n ເພື່ອຖອນການຕິດຕັ້ງ, ທ່ານສາມາດໃຊ້ແອັບການຕັ້ງຄ່າ ຫຼື ເປີດຄຳສັ່ງຕໍ່ໄປນີ້:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"ຕົວເປີດໃຊ້ຈຳລອງສຳລັບ CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-lt/strings.xml b/tests/CarCtsDummyLauncher/res/values-lt/strings.xml
deleted file mode 100644
index 0f9d084..0000000
--- a/tests/CarCtsDummyLauncher/res/values-lt/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Pašalinkite ją, kai bus baigtas CTS testas\n\n Norėdami pašalinti, galite naudoti Nustatymų programą arba vykdyti nurodytą komandą:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS skirta netikra paleidimo priemonė"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-lv/strings.xml b/tests/CarCtsDummyLauncher/res/values-lv/strings.xml
deleted file mode 100644
index fe31198..0000000
--- a/tests/CarCtsDummyLauncher/res/values-lv/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Atinstalējiet palaišanas programmu, kad ir pabeigts CTS tests\n\n Lai to atinstalētu, varat izmantot lietotni Iestatījumi vai izpildīt tālāk norādīto komandu:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Neīsta CTS palaišanas programma"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-mk/strings.xml b/tests/CarCtsDummyLauncher/res/values-mk/strings.xml
deleted file mode 100644
index c04d67b..0000000
--- a/tests/CarCtsDummyLauncher/res/values-mk/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Деинсталирајте го ова откако CTS ќе заврши\n\n За деинсталирање, може да ја користите апликацијата Setting или да ја извршите следнава наредба:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Лажен стартер за CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ml/strings.xml b/tests/CarCtsDummyLauncher/res/values-ml/strings.xml
deleted file mode 100644
index 53ffaae..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ml/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS കഴിഞ്ഞതിനുശേഷം ഇത് അൺഇൻസ്‌റ്റാൾ ചെയ്യുക\n\n അൺഇൻസ്‌റ്റാൾ ചെയ്യാൻ, ക്രമീകരണ ആപ്പ് ഉപയോഗിക്കുകയോ ഇനിപ്പറയുന്ന കമാൻഡ് പിന്തുടരുകയോ ചെയ്യുക:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS-നുള്ള ഡമ്മി ലോഞ്ചർ"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-mn/strings.xml b/tests/CarCtsDummyLauncher/res/values-mn/strings.xml
deleted file mode 100644
index 605843a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-mn/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Үүнийг CTS-г дууссаны дараа устгана уу\n\n Устгахын тулд та Тохиргооны аппыг ашиглах эсвэл дараах тушаалыг ажиллуулж болно:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS-н хуурмаг хувьсагчийн эхлүүлэгч"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-mr/strings.xml b/tests/CarCtsDummyLauncher/res/values-mr/strings.xml
deleted file mode 100644
index d86f2fc..0000000
--- a/tests/CarCtsDummyLauncher/res/values-mr/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS पूर्ण झाल्यावर हे अनइंस्टॉल करा\n\n अनइंस्टॉल करण्यासाठी, तुम्ही सेटिंग अॅप वापरू शकता किंवा खालील कमांड रन करू शकता:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS साठी बनावटी लाँचर"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ms/strings.xml b/tests/CarCtsDummyLauncher/res/values-ms/strings.xml
deleted file mode 100644
index b6e96d6..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ms/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Nyahpasang item ini setelah CTS selesai\n\n Untuk menyahpasang, anda boleh menggunakan apl Tetapan atau menjalankan perintah berikut:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Pelancar Semu untuk CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-my/strings.xml b/tests/CarCtsDummyLauncher/res/values-my/strings.xml
deleted file mode 100644
index a09826a..0000000
--- a/tests/CarCtsDummyLauncher/res/values-my/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS ပြီးဆုံးပါက ဤအရာကို ပရိုဂရမ်ဖယ်ရှားပါ\n\n ပရိုဂရမ်ဖယ်ရှားရန်အတွက် \'ဆက်တင်\' အက်ပ်ကို အသုံးပြုပါ (သို့) အောက်ပါ ကွန်မန်းကို လုပ်ဆောင်ပါ-\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS အတွက် နမူနာ Launcher"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-nb/strings.xml b/tests/CarCtsDummyLauncher/res/values-nb/strings.xml
deleted file mode 100644
index 5754eac..0000000
--- a/tests/CarCtsDummyLauncher/res/values-nb/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Avinstaller dette etter at CTS er fullført\n\n For å avinstallere kan du bruke Innstillinger-appen eller kjøre denne kommandoen:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy-appoversikt for CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-nl/strings.xml b/tests/CarCtsDummyLauncher/res/values-nl/strings.xml
deleted file mode 100644
index b059708..0000000
--- a/tests/CarCtsDummyLauncher/res/values-nl/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Verwijder dit nadat CTS is voltooid\n\n Je kunt dit verwijderen via de app Instellingen of met de volgende opdracht:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy-launcher voor CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-or/strings.xml b/tests/CarCtsDummyLauncher/res/values-or/strings.xml
deleted file mode 100644
index 46b51b4..0000000
--- a/tests/CarCtsDummyLauncher/res/values-or/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS ସମ୍ପୂର୍ଣ୍ଣ ହେବା ପରେ ଏହାକୁ ଅନ୍‍ଇନ୍‌ଷ୍ଟଲ୍ କରନ୍ତୁ \n\n ଅନ୍‍ଇନ୍‌ଷ୍ଟଲ୍ କରିବା ପାଇଁ, ଆପଣ ସେଟିଂ ଆପ୍ ବ୍ୟବହାର କରିପାରିବେ ବା ନିମ୍ନୋକ୍ତ କମାଣ୍ଡ ଚଲାନ୍ତୁ:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS ପାଇଁ ଲଞ୍ଚର୍‌ର ନକଲ"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-pa/strings.xml b/tests/CarCtsDummyLauncher/res/values-pa/strings.xml
deleted file mode 100644
index 35f0d6d..0000000
--- a/tests/CarCtsDummyLauncher/res/values-pa/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS ਪੂਰਾ ਹੋਮ ਤੋਂ ਬਾਅਦ ਇਸਨੂੰ ਅਣਸਥਾਪਤ ਕਰੋ\n\n ਅਣਸਥਾਪਤ ਕਰਨ ਲਈ, ਤੁਸੀਂ ਸੈਟਿੰਗ ਐਪ ਵਰਤ ਸਕਦੇ ਹੋ ਜਾਂ ਹੇਠਾਂ ਦਿੱਤਾ ਗਿਆ ਆਦੇਸ਼ ਚਲਾ ਸਕਦੇ ਹੋ:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS ਲਈ ਕਲਪਿਤ ਲਾਂਚਰ"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-pl/strings.xml b/tests/CarCtsDummyLauncher/res/values-pl/strings.xml
deleted file mode 100644
index 1dc7789..0000000
--- a/tests/CarCtsDummyLauncher/res/values-pl/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Odinstaluj ten element po zakończeniu działania CTS\n\n Aby to zrobić, możesz użyć aplikacji Ustawienia lub uruchomić polecenie:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Testowy program uruchamiający dla CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-pt-rPT/strings.xml b/tests/CarCtsDummyLauncher/res/values-pt-rPT/strings.xml
deleted file mode 100644
index fa96ef1..0000000
--- a/tests/CarCtsDummyLauncher/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Desinstale após a conclusão do CTS\n\n Para desinstalar, pode utilizar a aplicação Definições ou executar o seguinte comando:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher para CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-pt/strings.xml b/tests/CarCtsDummyLauncher/res/values-pt/strings.xml
deleted file mode 100644
index 0f5060b..0000000
--- a/tests/CarCtsDummyLauncher/res/values-pt/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Desinstale depois que o CTS terminar\n\n Para desinstalar, use o app Config. ou execute o seguinte comando:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Tela de início de teste do CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ro/strings.xml b/tests/CarCtsDummyLauncher/res/values-ro/strings.xml
deleted file mode 100644
index 7edcdf0..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ro/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Dezinstalați după finalizarea CTS\n\n Pentru a dezinstala, puteți să folosiți aplicația Setare sau să rulați următoarea comandă:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Lansator fals pentru CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ru/strings.xml b/tests/CarCtsDummyLauncher/res/values-ru/strings.xml
deleted file mode 100644
index 40d73af..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ru/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Удалите его после завершения CTS.\n\nЭто можно сделать в приложении \"Настройки\" или с помощью следующей команды:\nadb uninstall com.android.car.dummylauncher."</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher для CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-si/strings.xml b/tests/CarCtsDummyLauncher/res/values-si/strings.xml
deleted file mode 100644
index 10a76e9..0000000
--- a/tests/CarCtsDummyLauncher/res/values-si/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS අවසන් වූ පසුව මෙය අස්ථාපනය කරන්න\n\n අස්ථාපනය කිරීමට, ඔබට සැකසීම් යෙදුම භාවිතයට හෝ පහත විධානය ධාවනය කිරීමට හැකිය:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS සඳහා ව්‍යාජ දියත්කරණය"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-sk/strings.xml b/tests/CarCtsDummyLauncher/res/values-sk/strings.xml
deleted file mode 100644
index 318fa54..0000000
--- a/tests/CarCtsDummyLauncher/res/values-sk/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Po dokončení CTS túto položku odinštalujte.\n\n Môžete to urobiť pomocou aplikácie Nastavenia alebo spustením nasledujúceho príkazu:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher pre CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-sl/strings.xml b/tests/CarCtsDummyLauncher/res/values-sl/strings.xml
deleted file mode 100644
index 1be8ce8..0000000
--- a/tests/CarCtsDummyLauncher/res/values-sl/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Odmestite to, ko se CTS dokonča.\n\n Če želite odmestiti, lahko uporabite aplikacijo Nastavitve ali zaženete ta ukaz:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Poskusni zaganjalnik za CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-sq/strings.xml b/tests/CarCtsDummyLauncher/res/values-sq/strings.xml
deleted file mode 100644
index f7a6fa3..0000000
--- a/tests/CarCtsDummyLauncher/res/values-sq/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Çinstaloje këtë pasi CTS të përfundojë\n\n Për ta instaluar, mund të përdorësh aplikacionin \"Cilësimet\" ose ekzekuto komandën e mëposhtme:\n dhe çinstalo com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Nisës fiktiv për CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-sr/strings.xml b/tests/CarCtsDummyLauncher/res/values-sr/strings.xml
deleted file mode 100644
index b7de527..0000000
--- a/tests/CarCtsDummyLauncher/res/values-sr/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Деинсталирајте ово када се CTS заврши\n\n Да бисте деинсталирали, можете да користите апликацију Подешавања или покренете следећу команду:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Пример покретача за CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-sv/strings.xml b/tests/CarCtsDummyLauncher/res/values-sv/strings.xml
deleted file mode 100644
index b66e845..0000000
--- a/tests/CarCtsDummyLauncher/res/values-sv/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Avinstallera detta när CTS-körningen är klar\n\n Du kan avinstallera med inställningsappen eller använda följande kommando:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Översiktsplatshållare för CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-sw/strings.xml b/tests/CarCtsDummyLauncher/res/values-sw/strings.xml
deleted file mode 100644
index d2f6a90..0000000
--- a/tests/CarCtsDummyLauncher/res/values-sw/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Ondoa hii CTS ikishamaliza\n\n Ili uondoe, unaweza kutumia programu ya Mipangilio au utekeleze amri ifuatayo:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Kifungua \"Dummy\" cha CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-te/strings.xml b/tests/CarCtsDummyLauncher/res/values-te/strings.xml
deleted file mode 100644
index 623b71c..0000000
--- a/tests/CarCtsDummyLauncher/res/values-te/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS పూర్తయిన తరువాత దీన్ని అన్‌ఇన్‌స్టాల్ చేయండి \n\n అన్‌ఇన్‌స్టాల్ చేయడానికి , మీరు సెట్టింగ్‌ యాప్‌ను ఉపయోగించవచ్చు లేదా కింది ఆదేశాన్ని అమలు చేయవచ్చు:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS కోసం డమ్మీ లాంచర్"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-th/strings.xml b/tests/CarCtsDummyLauncher/res/values-th/strings.xml
deleted file mode 100644
index c675e1e..0000000
--- a/tests/CarCtsDummyLauncher/res/values-th/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"ถอนการติดตั้งหลังจากที่ CTS ดำเนินการเสร็จเรียบร้อย\n\n หากต้องการถอนการติดตั้ง ให้ใช้แอปการตั้งค่าหรือเรียกใช้คำสั่ง\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Launcher จำลองสำหรับ CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-tl/strings.xml b/tests/CarCtsDummyLauncher/res/values-tl/strings.xml
deleted file mode 100644
index 320c959..0000000
--- a/tests/CarCtsDummyLauncher/res/values-tl/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"I-uninstall ito kapag tapos na ang CTS\n\n Para i-uninstall, puwede mong gamitin ang app na Setting o patakbuhin ang sumusunod na command:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy na Launcher para sa CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-tr/strings.xml b/tests/CarCtsDummyLauncher/res/values-tr/strings.xml
deleted file mode 100644
index e6dd989..0000000
--- a/tests/CarCtsDummyLauncher/res/values-tr/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS tamamlandıktan sonra bunu kaldırın\n\n Kaldırmak için Ayar uygulamasını kullanabilir ve şu komutu çalıştırabilirsiniz:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS için Kukla Başlatıcı"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-uk/strings.xml b/tests/CarCtsDummyLauncher/res/values-uk/strings.xml
deleted file mode 100644
index 2ea9300..0000000
--- a/tests/CarCtsDummyLauncher/res/values-uk/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Видаліть, коли тестування CTS завершиться\n\n Для цього перейдіть у додаток Налаштування або запустіть таку команду:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Dummy Launcher для CTS"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-ur/strings.xml b/tests/CarCtsDummyLauncher/res/values-ur/strings.xml
deleted file mode 100644
index 518da33..0000000
--- a/tests/CarCtsDummyLauncher/res/values-ur/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS مکمل ہونے کے بعد اَن انسٹال کریں\n\n اَن انسٹال کرنے کیلئے، آپ ایپ کی ترتیب کا استعمال کر سکتے ہیں یا مندرجہ ذیل کمانڈ چلا سکتے ہیں:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS کیلئے ڈمی لانچر"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-uz/strings.xml b/tests/CarCtsDummyLauncher/res/values-uz/strings.xml
deleted file mode 100644
index 1639a4c..0000000
--- a/tests/CarCtsDummyLauncher/res/values-uz/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"CTS tamomlangach buni oʻchirib tashlang\n\nSozlamalar ilovasi orqali yoki quyidagi buyruq yordamida oʻchirib tashlash mumkin:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS uchun namunaviy launcher"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-vi/strings.xml b/tests/CarCtsDummyLauncher/res/values-vi/strings.xml
deleted file mode 100644
index e866ed2..0000000
--- a/tests/CarCtsDummyLauncher/res/values-vi/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Gỡ cài đặt trình chạy này sau khi Gói thử nghiệm khả năng tương thích (CTS) hoàn tất\n\n Để gỡ cài đặt, bạn có thể dùng ứng dụng Cài đặt hoặc chạy lệnh sau:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Trình chạy giả cho Gói thử nghiệm khả năng tương thích (CTS)"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-zh-rCN/strings.xml b/tests/CarCtsDummyLauncher/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 08560a3..0000000
--- a/tests/CarCtsDummyLauncher/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"在 CTS 完成后卸载虚拟启动器\n\n要卸载虚拟启动器,您可以使用“设置”应用或运行以下命令:\nadb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"适用于 CTS 的虚拟启动器"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-zh-rHK/strings.xml b/tests/CarCtsDummyLauncher/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 7d654ab..0000000
--- a/tests/CarCtsDummyLauncher/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"在完成 CTS 後解除安裝\n\n如要解除安裝,您可以使用「設定」應用程式或執行以下指令:\n adb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"CTS 虛擬啟動器"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-zh-rTW/strings.xml b/tests/CarCtsDummyLauncher/res/values-zh-rTW/strings.xml
deleted file mode 100644
index fa00adc..0000000
--- a/tests/CarCtsDummyLauncher/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"請在 CTS 完成後解除安裝 Dummy Launcher\n\n你可以透過「設定」應用程式或執行以下命令來解除安裝:\nadb uninstall com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"適用於 CTS 的 Dummy Launcher"</string>
-</resources>
diff --git a/tests/CarCtsDummyLauncher/res/values-zu/strings.xml b/tests/CarCtsDummyLauncher/res/values-zu/strings.xml
deleted file mode 100644
index d3be9cd..0000000
--- a/tests/CarCtsDummyLauncher/res/values-zu/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="launcher_activity_message" msgid="6204844030446459585">"Khipha lokhu ngemuva kokuthi i-CTS iqede\n\n Ukuze ukhiphe, ungasebenzisa uhlelo lokusebenza lwesilungiselelo noma uqalise umyalo olandelayo:\n i-adb ikhipha i-com.android.car.dummylauncher"</string>
-    <string name="app_name" msgid="1129651585636850259">"Isiqalisi se-dummy se-CTS"</string>
-</resources>
diff --git a/tests/MultiDisplaySecondaryHomeTestLauncher/AndroidManifest.xml b/tests/MultiDisplaySecondaryHomeTestLauncher/AndroidManifest.xml
index d336672..e4d48ab 100644
--- a/tests/MultiDisplaySecondaryHomeTestLauncher/AndroidManifest.xml
+++ b/tests/MultiDisplaySecondaryHomeTestLauncher/AndroidManifest.xml
@@ -36,6 +36,4 @@
             </intent-filter>
         </activity>
     </application>
-
-
 </manifest>
diff --git a/tests/MultiDisplaySecondaryHomeTestLauncher/res/layout/app_picker_layout.xml b/tests/MultiDisplaySecondaryHomeTestLauncher/res/layout/app_picker_layout.xml
index e6c6b1e..bdc7b62 100644
--- a/tests/MultiDisplaySecondaryHomeTestLauncher/res/layout/app_picker_layout.xml
+++ b/tests/MultiDisplaySecondaryHomeTestLauncher/res/layout/app_picker_layout.xml
@@ -27,8 +27,10 @@
         android:visibility="invisible">
 
         <LinearLayout
+            android:id="@+id/FloatingSheetHeader"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
+            android:layout_marginTop = "@dimen/app_grid_margin_top"
             android:layout_marginStart="@dimen/app_grid_margin_left"
             android:layout_marginEnd="@dimen/app_grid_margin_right"
             android:orientation="vertical">
diff --git a/tests/MultiDisplaySecondaryHomeTestLauncher/src/com/android/car/multidisplay/launcher/LauncherActivity.java b/tests/MultiDisplaySecondaryHomeTestLauncher/src/com/android/car/multidisplay/launcher/LauncherActivity.java
index d106343..5f51817 100644
--- a/tests/MultiDisplaySecondaryHomeTestLauncher/src/com/android/car/multidisplay/launcher/LauncherActivity.java
+++ b/tests/MultiDisplaySecondaryHomeTestLauncher/src/com/android/car/multidisplay/launcher/LauncherActivity.java
@@ -67,7 +67,9 @@
     private Spinner mDisplaySpinner;
     private ArrayAdapter<DisplayItem> mDisplayAdapter;
     private int mSelectedDisplayId = Display.INVALID_DISPLAY;
+    private View mRootView;
     private View mScrimView;
+    private View mAppDrawerHeader;
     private AppListAdapter mAppListAdapter;
     private AppListAdapter mPinnedAppListAdapter;
     private CircularRevealCardView mAppDrawerView;
@@ -81,10 +83,21 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
 
+        mRootView = findViewById(R.id.RootView);
         mScrimView = findViewById(R.id.Scrim);
         mAppDrawerView = findViewById(R.id.FloatingSheet);
-        mFab = findViewById(R.id.FloatingActionButton);
 
+        // get system insets and apply padding accordingly to the content view
+        mRootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        mRootView.setOnApplyWindowInsetsListener((v, insets) -> {
+            mRootView.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
+            mAppDrawerHeader = findViewById(R.id.FloatingSheetHeader);
+            mAppDrawerHeader.setPadding(0, insets.getSystemWindowInsetTop(), 0, 0);
+            return insets.consumeSystemWindowInsets();
+        });
+
+        mFab = findViewById(R.id.FloatingActionButton);
         mFab.setOnClickListener((View v) -> {
             showAppDrawer(true);
         });
diff --git a/tests/MultiDisplayTest/Android.mk b/tests/MultiDisplayTest/Android.mk
new file mode 100644
index 0000000..c5c7ce0
--- /dev/null
+++ b/tests/MultiDisplayTest/Android.mk
@@ -0,0 +1,39 @@
+#
+# 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_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := MultiDisplayTest
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_STATIC_ANDROID_LIBRARIES += \
+    androidx.lifecycle_lifecycle-livedata \
+    androidx.lifecycle_lifecycle-viewmodel \
+    androidx.car_car-cluster
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/MultiDisplayTest/AndroidManifest.xml b/tests/MultiDisplayTest/AndroidManifest.xml
new file mode 100644
index 0000000..cb294b3
--- /dev/null
+++ b/tests/MultiDisplayTest/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     to come from a domain that you own or have control over. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.car.multidisplaytest">
+    <application android:label="MD Test">
+        <activity android:name="MDTest"
+            android:label="@string/app_title_always"
+            android:documentLaunchMode="always"
+            android:theme="@style/MainActivityTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+
diff --git a/tests/MultiDisplayTest/res/drawable/border.xml b/tests/MultiDisplayTest/res/drawable/border.xml
new file mode 100644
index 0000000..088c31b
--- /dev/null
+++ b/tests/MultiDisplayTest/res/drawable/border.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+  <corners
+      android:bottomRightRadius="5dp"
+      android:bottomLeftRadius="5dp"
+      android:topLeftRadius="5dp"
+      android:topRightRadius="5dp"/>
+  <stroke
+      android:width="2dip"
+      android:color="#212121" />
+</shape>
\ No newline at end of file
diff --git a/tests/MultiDisplayTest/res/drawable/ic_close_white.xml b/tests/MultiDisplayTest/res/drawable/ic_close_white.xml
new file mode 100644
index 0000000..4187755
--- /dev/null
+++ b/tests/MultiDisplayTest/res/drawable/ic_close_white.xml
@@ -0,0 +1,24 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M19.000000,6.400000l-1.400000,-1.400000 -5.600000,5.600000 -5.600000,-5.600000 -1.400000,1.400000 5.600000,5.600000 -5.600000,5.600000 1.400000,1.400000 5.600000,-5.600000 5.600000,5.600000 1.400000,-1.400000 -5.600000,-5.600000z"
+        android:fillColor="#FFFFFFFF"/>
+</vector>
\ No newline at end of file
diff --git a/tests/MultiDisplayTest/res/layout/activity_main.xml b/tests/MultiDisplayTest/res/layout/activity_main.xml
new file mode 100644
index 0000000..e741c32
--- /dev/null
+++ b/tests/MultiDisplayTest/res/layout/activity_main.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+
+<!-- We use this container to place kitchen app fragments. It insets the fragment contents -->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <Button
+        android:id="@+id/menu_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="10dp"
+        android:background="@android:color/background_light"
+        android:text="Hide Test Menu"
+        android:textSize="30sp"
+        android:padding="15dp"/>
+
+    <FrameLayout
+        android:id="@+id/menu_content"
+        android:layout_alignParentStart="true"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@id/menu_button"
+        android:visibility="gone"/>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/menu"
+        android:layout_below="@id/menu_button"
+        android:layout_alignParentStart="true"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</RelativeLayout>
diff --git a/tests/MultiDisplayTest/res/layout/draw.xml b/tests/MultiDisplayTest/res/layout/draw.xml
new file mode 100644
index 0000000..4bb1fa9
--- /dev/null
+++ b/tests/MultiDisplayTest/res/layout/draw.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#000000"
+        android:orientation="vertical" >
+
+  <com.google.android.car.multidisplaytest.draw.CanvasView
+          android:id="@+id/drawCanvas"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"/>
+
+  <Button
+          android:id="@+id/clearButton"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_gravity="bottom|center"
+          android:text="Clear Canvas" />
+</FrameLayout>
diff --git a/tests/MultiDisplayTest/res/layout/input_type_test.xml b/tests/MultiDisplayTest/res/layout/input_type_test.xml
new file mode 100644
index 0000000..c23926f
--- /dev/null
+++ b/tests/MultiDisplayTest/res/layout/input_type_test.xml
@@ -0,0 +1,613 @@
+<?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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:weightSum="2">
+        <Button
+            style="@style/Button"
+            android:id="@+id/clearButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="clear"/>
+    </LinearLayout>
+
+    <LinearLayout
+        style="@style/SectionContainer"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:layout_weight="1">
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:fillViewport="true">
+            <TextView
+                android:id="@+id/ime_watchdog"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textSize="18sp"
+                android:text="@string/no_results"/>
+        </ScrollView>
+    </LinearLayout>
+
+    <ScrollView
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:layout_weight="1">
+
+        <LinearLayout
+            android:id="@+id/inputViewGroup"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Test Input Focus:"/>
+
+                <EditText
+                    android:id="@+id/testEditText"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="text"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Plain Text:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="text"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Date:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="date"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Date Time:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="datetime"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Number:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="number"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Number Decimal:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="numberDecimal"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Number Password:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="numberPassword"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Number Signed:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="numberSigned"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Auto Complete:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textAutoComplete"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Auto Correct:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textAutoCorrect"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Cap Characters:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textCapCharacters"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Cap Sentences:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textCapSentences"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Cap Words:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textCapWords"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Email Address:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textEmailAddress"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Email Subject:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textEmailSubject"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Filter:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textFilter"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="IME Multiline:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textImeMultiLine"
+                    android:singleLine="false"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Long Message:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textLongMessage"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="MultiLine:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textMultiLine"
+                    android:singleLine="false"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="No Suggestions:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textNoSuggestions"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Password:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textPassword"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Person Name:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textPersonName"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Phonetic:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textPhonetic"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Postal Address:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textPostalAddress"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Short Message:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textShortMessage"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="URI:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textUri"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Visible Password:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textVisiblePassword"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Web Edit Text:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textWebEditText"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Web Email Address:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textWebEmailAddress"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_marginLeft="@dimen/inputTypeMarginLeft"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Web Password:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="textWebPassword"
+                    android:singleLine="true"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Phone:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:inputType="phone"
+                    android:singleLine="true"/>
+
+                <TextView
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:textSize="@dimen/inputTypeTextSize"
+                    android:text="Time:"/>
+
+                <EditText
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="6"
+                    android:inputType="time"
+                    android:singleLine="true"/>
+            </LinearLayout>
+        </LinearLayout>
+    </ScrollView>
+</LinearLayout>
diff --git a/tests/MultiDisplayTest/res/layout/list_item.xml b/tests/MultiDisplayTest/res/layout/list_item.xml
new file mode 100644
index 0000000..4f97c2c
--- /dev/null
+++ b/tests/MultiDisplayTest/res/layout/list_item.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@android:id/text1"
+          android:paddingTop="2dip"
+          android:paddingBottom="3dip"
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content"
+          android:textSize="24sp" />
diff --git a/tests/MultiDisplayTest/res/layout/menu_item.xml b/tests/MultiDisplayTest/res/layout/menu_item.xml
new file mode 100644
index 0000000..be681b6
--- /dev/null
+++ b/tests/MultiDisplayTest/res/layout/menu_item.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:paddingBottom="5dp">
+
+    <Button
+        android:id="@+id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="30sp"/>
+</LinearLayout>
diff --git a/tests/MultiDisplayTest/res/layout/present_fragment.xml b/tests/MultiDisplayTest/res/layout/present_fragment.xml
new file mode 100644
index 0000000..7f64456
--- /dev/null
+++ b/tests/MultiDisplayTest/res/layout/present_fragment.xml
@@ -0,0 +1,47 @@
+<?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.
+-->
+
+<!-- Demonstrates an activity that shows content on secondary displays using
+     the android.app.Presentation class.
+     See corresponding Java code PresentationActivity.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+  <!-- Message to show to use. -->
+  <TextView android:id="@+id/text"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_weight="0"
+      android:gravity="center_vertical|center_horizontal"
+      android:textAppearance="?android:attr/textAppearanceMedium"
+      android:text="@string/presentation_introduction"/>
+
+  <!-- A checkbox to toggle between showing all displays or only presentation displays. -->
+  <CheckBox android:id="@+id/show_all_displays"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_weight="0"
+      android:text="@string/presentation_show_all_displays" />
+
+  <!-- List that will show information about all connected displays. -->
+  <ListView android:id="@+id/display_list"
+      android:layout_width="match_parent"
+      android:layout_height="0dip"
+      android:layout_weight="1" />
+</LinearLayout>
diff --git a/tests/MultiDisplayTest/res/layout/touch_points.xml b/tests/MultiDisplayTest/res/layout/touch_points.xml
new file mode 100644
index 0000000..f2b2e1f
--- /dev/null
+++ b/tests/MultiDisplayTest/res/layout/touch_points.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    <com.google.android.car.multidisplaytest.touch.TouchPointView
+        android:id="@+id/touch_point_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+</RelativeLayout>
diff --git a/tests/MultiDisplayTest/res/values/dimens.xml b/tests/MultiDisplayTest/res/values/dimens.xml
new file mode 100644
index 0000000..99a2f85
--- /dev/null
+++ b/tests/MultiDisplayTest/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+    <dimen name="inputTypeMarginLeft">50dp</dimen>
+    <dimen name="inputTypeTextSize">24sp</dimen>
+    <dimen name="overview_icon_size">72dp</dimen>
+</resources>
diff --git a/tests/MultiDisplayTest/res/values/strings.xml b/tests/MultiDisplayTest/res/values/strings.xml
new file mode 100644
index 0000000..24fb4f9
--- /dev/null
+++ b/tests/MultiDisplayTest/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+
+<resources>
+    <string name="app_title_always" translatable="false">MDTest</string>
+    <string name="section_header_watchdog" translatable="false">Watchdog</string>
+    <string name="no_results" translatable="false">No Results</string>
+    <string name="presentation_introduction" translatable="false">Fragment that uses a
+        Presentation and the DisplayManager to show content on other Displays.\n
+        Selecting a Display will open a Presentation on it</string>
+    <string name="presentation_show_all_displays" translatable="false">Show all displays</string>
+</resources>
diff --git a/tests/MultiDisplayTest/res/values/styles.xml b/tests/MultiDisplayTest/res/values/styles.xml
new file mode 100644
index 0000000..c15c870
--- /dev/null
+++ b/tests/MultiDisplayTest/res/values/styles.xml
@@ -0,0 +1,41 @@
+<?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.
+*/
+-->
+<resources>
+    <style name="OverviewButton">
+        <item name="android:layout_width">@dimen/overview_icon_size</item>
+        <item name="android:layout_height">@dimen/overview_icon_size</item>
+        <item name="android:padding">6dp</item>
+        <item name="android:scaleType">fitCenter</item>
+        <item name="android:clickable">true</item>
+    </style>
+
+    <style name="MainActivityTheme" parent="android:Theme.DeviceDefault.NoActionBar">
+    </style>
+
+    <style name="SectionContainer">
+        <!-- Customize your theme here. -->
+        <item name="android:background">@drawable/border</item>
+        <item name="android:padding">3dp</item>
+        <item name="android:layout_margin">5dp</item>
+    </style>
+
+    <style name="Button">
+        <item name="android:layout_margin">5dp</item>
+    </style>
+
+</resources>
diff --git a/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/MDTest.java b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/MDTest.java
new file mode 100644
index 0000000..57e2834
--- /dev/null
+++ b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/MDTest.java
@@ -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.
+ */
+package com.google.android.car.multidisplaytest;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.google.android.car.multidisplaytest.draw.DrawTestFragment;
+import com.google.android.car.multidisplaytest.ime.InputTestFragment;
+import com.google.android.car.multidisplaytest.touch.TouchTestFragment;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Mostly copied from EmbeddedKitchenSinkApp with modifications on Fragments
+ */
+public class MDTest extends FragmentActivity {
+    private static final String TAG = MDTest.class.getSimpleName();
+    private FragmentManager mFragmentManager;
+    private Button mMenuButton;
+    private RecyclerView mMenu;
+    private View mMenuContent;
+
+    private interface ClickHandler {
+        void onClick();
+    }
+
+    private abstract class MenuEntry implements ClickHandler {
+        abstract String getText();
+    }
+
+    private final class FragmentMenuEntry<T extends Fragment> extends MenuEntry {
+        private final class MenuFragment<T extends Fragment> {
+            private final Class<T> mClazz;
+            private T mMenuFragment = null;
+
+            MenuFragment(Class<T> clazz) {
+                mClazz = clazz;
+            }
+
+            T getFragment() {
+                if (mMenuFragment == null) {
+                    try {
+                        mMenuFragment = mClazz.newInstance();
+                    } catch (InstantiationException | IllegalAccessException e) {
+                        Log.e(TAG, "unable to create fragment", e);
+                    }
+                }
+                return mMenuFragment;
+            }
+        }
+
+        private final String mText;
+        private final MenuFragment<T> mFragment;
+
+        FragmentMenuEntry(String text, Class<T> clazz) {
+            mText = text;
+            mFragment = new MenuFragment<>(clazz);
+        }
+
+        @Override
+        String getText() {
+            return mText;
+        }
+
+        @Override
+        public void onClick() {
+            Fragment fragment = mFragment.getFragment();
+            if (fragment != null) {
+                mFragmentManager.beginTransaction()
+                    .replace(R.id.menu_content, fragment)
+                    .commit();
+                // MDTest.this.showFragment(fragment);
+                toggleMenuVisibility();
+            } else {
+                Log.e(TAG, "cannot show fragment for " + getText());
+            }
+        }
+    }
+
+    // list of test fragments
+    private final List<MenuEntry> mMenuEntries = Arrays.asList(
+            new FragmentMenuEntry("Touch test", TouchTestFragment.class),
+            new FragmentMenuEntry("IME test", InputTestFragment.class),
+            new FragmentMenuEntry("Draw test", DrawTestFragment.class)
+    );
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        mMenuContent = findViewById(R.id.menu_content);
+
+        mMenu = findViewById(R.id.menu);
+        mMenu.setAdapter(new MenuAdapter(this));
+        mMenu.setLayoutManager(new GridLayoutManager(this, 3));
+
+        mMenuButton = findViewById(R.id.menu_button);
+        mMenuButton.setOnClickListener(view -> toggleMenuVisibility());
+        Log.i(TAG, "Creating MDTest activity view");
+        mFragmentManager = MDTest.this.getSupportFragmentManager();
+        onNewIntent(getIntent());
+    }
+
+    private void toggleMenuVisibility() {
+        boolean menuVisible = mMenu.getVisibility() == View.VISIBLE;
+        mMenu.setVisibility(menuVisible ? View.GONE : View.VISIBLE);
+        mMenuContent.setVisibility(menuVisible ? View.VISIBLE : View.GONE);
+        mMenuButton.setText(menuVisible ? "Show Test Menu" : "Hide Test Menu");
+    }
+
+    private final class MenuAdapter extends RecyclerView.Adapter<ItemViewHolder> {
+        private final LayoutInflater mLayoutInflator;
+
+        MenuAdapter(Context context) {
+            mLayoutInflator = LayoutInflater.from(context);
+        }
+
+        @Override
+        public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+            View view = mLayoutInflator.inflate(R.layout.menu_item, parent, false);
+            return new ItemViewHolder(view);
+        }
+
+        @Override
+        public void onBindViewHolder(ItemViewHolder holder, int position) {
+            holder.mTitle.setText(mMenuEntries.get(position).getText());
+            holder.mTitle.setOnClickListener(v -> mMenuEntries.get(position).onClick());
+        }
+
+        @Override
+        public int getItemCount() {
+            return mMenuEntries.size();
+        }
+    }
+
+    private final class ItemViewHolder extends RecyclerView.ViewHolder {
+        private TextView mTitle;
+
+        ItemViewHolder(View itemView) {
+            super(itemView);
+            mTitle = itemView.findViewById(R.id.title);
+        }
+    }
+}
diff --git a/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/draw/CanvasView.java b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/draw/CanvasView.java
new file mode 100644
index 0000000..594f654
--- /dev/null
+++ b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/draw/CanvasView.java
@@ -0,0 +1,101 @@
+/*
+ * 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.google.android.car.multidisplaytest.draw;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class CanvasView extends View {
+    private static final float TOLERANCE = 5.0f;
+
+    private final Paint mPaint;
+    private final Path mPath;
+    private float mX;
+    private float mY;
+
+    public CanvasView(Context c, AttributeSet attrs) {
+        super(c, attrs);
+
+        mPath = new Path();
+        mPaint = new Paint();
+        mPaint.setStyle(Paint.Style.STROKE);
+        mPaint.setStrokeJoin(Paint.Join.ROUND);
+        mPaint.setStrokeWidth(4f);
+        mPaint.setColor(Color.WHITE);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        canvas.drawPath(mPath, mPaint);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        float x = event.getX();
+        float y = event.getY();
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                downTouch(x, y);
+                invalidate();
+                break;
+            case MotionEvent.ACTION_MOVE:
+                moveTouch(x, y);
+                invalidate();
+                break;
+            case MotionEvent.ACTION_UP:
+                upTouch();
+                invalidate();
+                break;
+        }
+        return true;
+    }
+
+    public void clearCanvas() {
+        mPath.reset();
+        invalidate();
+    }
+
+    private void moveTouch(float x, float y) {
+        float dx = Math.abs(x - mX);
+        float dy = Math.abs(y - mY);
+        if (dx >= TOLERANCE || dy >= TOLERANCE) {
+            // use mid-point as the control point of the bezier curve to make a smooth line
+            // eg. when forming curve between three non-aligned consecutive points
+            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
+            mX = x;
+            mY = y;
+        }
+    }
+
+    private void downTouch(float x, float y) {
+        mPath.moveTo(x, y);
+        mX = x;
+        mY = y;
+    }
+
+    private void upTouch() {
+        mPath.lineTo(mX, mY);
+    }
+}
diff --git a/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/draw/DrawTestFragment.java b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/draw/DrawTestFragment.java
new file mode 100644
index 0000000..b6c322a
--- /dev/null
+++ b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/draw/DrawTestFragment.java
@@ -0,0 +1,47 @@
+/*
+ * 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.google.android.car.multidisplaytest.draw;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+import androidx.fragment.app.Fragment;
+
+import com.google.android.car.multidisplaytest.R;
+
+public class DrawTestFragment extends Fragment {
+    private CanvasView mCanvas;
+    private Button mClearButton;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
+        View view = inflater.inflate(R.layout.draw, container, false);
+
+        mCanvas = view.findViewById(R.id.drawCanvas);
+        mClearButton = view.findViewById(R.id.clearButton);
+        setClearButtonListener();
+
+        return view;
+    }
+
+    private void setClearButtonListener() {
+        mClearButton.setOnClickListener(view -> mCanvas.clearCanvas());
+    }
+}
diff --git a/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/ime/InputTestFragment.java b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/ime/InputTestFragment.java
new file mode 100644
index 0000000..05751d6
--- /dev/null
+++ b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/ime/InputTestFragment.java
@@ -0,0 +1,124 @@
+/*
+ * 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.google.android.car.multidisplaytest.ime;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import androidx.fragment.app.Fragment;
+
+import com.google.android.car.multidisplaytest.R;
+
+/**
+ * Modified from GarageModeTestApp;
+ * Including coping Watchdog.java and Logger.java
+ */
+public class InputTestFragment extends Fragment {
+    private static final String TAG = InputTestFragment.class.getSimpleName();
+
+    private Button mClearButton;
+    private EditText mTestEditText;
+    private InputMethodManager mInputManager;
+    private InputConnection mInputConnection;
+    private TextView mWatchdogTextView;
+    private ViewGroup mInputViewGroup;
+    private Watchdog mWatchdog;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
+        View view = inflater.inflate(R.layout.input_type_test, container, false);
+        setViewsFromFragment(view);
+        setListners();
+
+        return view;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        Log.d(TAG, "Resuming watchdog");
+
+        mWatchdog = new Watchdog(mWatchdogTextView);
+        mWatchdog.start();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        Log.d(TAG, "Pausing watchdog");
+
+        if (mWatchdog != null) {
+            mWatchdog.stop();
+            mWatchdog = null;
+        }
+    }
+
+    private void setViewsFromFragment(View view) {
+        mWatchdogTextView = view.findViewById(R.id.ime_watchdog);
+        mInputManager = (InputMethodManager) getActivity()
+            .getSystemService(Context.INPUT_METHOD_SERVICE);
+        mInputViewGroup = view.findViewById(R.id.inputViewGroup);
+        mClearButton = view.findViewById(R.id.clearButton);
+        // Log this EditText view's input focus to test for input connection with IME
+        mTestEditText = view.findViewById(R.id.testEditText);
+    }
+
+    private void setListners() {
+        mClearButton.setOnClickListener(view -> onClearButtonClick());
+        mInputViewGroup.setOnTouchListener((view, event) -> {
+            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+                if (mWatchdog != null) {
+                    boolean activeState = mInputManager.isActive();
+                    boolean acceptingState = mInputManager.isAcceptingText();
+                    String logMessage = String.format("IME states: Active - %b, AcceptingText - %b",
+                            activeState, acceptingState);
+                    mWatchdog.logEvent(logMessage);
+                }
+            }
+            return true;
+        });
+
+        mTestEditText.setOnFocusChangeListener((view, hasFocus) -> {
+            if (mWatchdog != null) {
+                if (hasFocus) {
+                    mWatchdog.logEvent("EditText view has input connection with IME");
+                } else {
+                    mWatchdog.logEvent("EditText view doesn't have input connection with IME");
+                }
+            }
+        });
+    }
+
+    private void onClearButtonClick() {
+        if (mWatchdog != null) {
+            mWatchdog.logEvent("Clear botton test...");
+            mWatchdog.start();
+        }
+    }
+}
diff --git a/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/ime/Watchdog.java b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/ime/Watchdog.java
new file mode 100644
index 0000000..80d63ee
--- /dev/null
+++ b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/ime/Watchdog.java
@@ -0,0 +1,79 @@
+/*
+ * 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.google.android.car.multidisplaytest.ime;
+
+import android.os.Handler;
+import android.util.Log;
+import android.widget.TextView;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+/**
+ * Copied from GarageModeTestApp
+ * Use Handler to send and process messages in a queue
+ * Potentially use for multi-thread
+ */
+public final class Watchdog {
+    private static final String TAG = Watchdog.class.getSimpleName();
+    // wait before trying to get new message from the queue and post it
+    private static final Integer DELAY = 500; // in millisecond
+    private static final Integer MAXQSIZE = 10000;
+
+    private final TextView mView;
+    private final ArrayList<String> mEvents;
+
+    private Handler mWatchdogHandler;
+    private Runnable mRefreshLoop;
+
+    Watchdog(TextView view) {
+        mView = view;
+        mEvents = new ArrayList<>();
+    }
+
+    public void logEvent(String s) {
+        Date date = new Date();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("[yyyy-MM-dd hh:mm:ss]");
+        mEvents.add(0, dateFormat.format(date) + " " + s);
+
+        if (mEvents.size() > MAXQSIZE) {
+            mEvents.remove(mEvents.size() - 1);
+        }
+    }
+
+    public synchronized void refresh() {
+        mView.setText(String.join("\n", mEvents));
+    }
+
+    public void start() {
+        Log.d(TAG, "Starting Watchdog");
+        mEvents.clear();
+        mWatchdogHandler = new Handler();
+        mRefreshLoop = () -> {
+            refresh();
+            mWatchdogHandler.postDelayed(mRefreshLoop, DELAY);
+        };
+        mWatchdogHandler.postDelayed(mRefreshLoop, DELAY);
+    }
+
+    public void stop() {
+        Log.d(TAG, "Stopping Watchdog");
+        mWatchdogHandler.removeCallbacks(mRefreshLoop);
+        mWatchdogHandler = null;
+        mRefreshLoop = null;
+    }
+}
diff --git a/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/touch/TouchPointView.java b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/touch/TouchPointView.java
new file mode 100644
index 0000000..77980d0
--- /dev/null
+++ b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/touch/TouchPointView.java
@@ -0,0 +1,124 @@
+/*
+ * 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.google.android.car.multidisplaytest.touch;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Copied from EmbeddedKitchenSinkApp
+ * Show touch points as circles; allow multiple touch points
+ * Set LOG_ONLY = false to test on physical device.
+ */
+public class TouchPointView extends View {
+    private static final String TAG = TouchPointView.class.getSimpleName();
+    private static final boolean LOG_ONLY = false;
+    private static final int[] COLORS = {
+        Color.RED,
+        Color.GREEN,
+        Color.BLUE,
+        Color.YELLOW,
+        Color.MAGENTA,
+        Color.BLACK,
+        Color.DKGRAY
+    };
+
+    private final List<Finger> mFingers;
+    private final Paint mPaint;
+
+    public TouchPointView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TouchPointView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mFingers = new ArrayList<Finger>();
+
+        mPaint = new Paint();
+        mPaint.setStyle(Paint.Style.FILL);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (LOG_ONLY) {
+            logTouchEvents(event);
+            return true;
+        }
+        mFingers.clear();
+        if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+            invalidate();
+            return true;
+        }
+        for (int i = 0; i < event.getPointerCount(); i++) {
+            int pointerId = event.getPointerId(i);
+            int pointerIndex = event.findPointerIndex(pointerId);
+            Finger finger = new Finger();
+            finger.point =  new Point((int) event.getX(pointerIndex),
+                    (int) event.getY(pointerIndex));
+            finger.pointerId = pointerId;
+
+            mFingers.add(finger);
+        }
+        invalidate();
+        return true;
+    }
+
+    private void logTouchEvents(MotionEvent event) {
+        if (event.getActionMasked() != MotionEvent.ACTION_UP) {
+            return;
+        }
+
+        for (int i = 0; i < event.getPointerCount(); i++) {
+            int pointerId = event.getPointerId(i);
+            int pointerIndex = event.findPointerIndex(pointerId);
+            long downTime = event.getDownTime();
+            long eventTime = event.getEventTime();
+            Log.d(TAG, "TouchUp [x=" + event.getX(pointerIndex) + ", y=" + event.getY(pointerIndex)
+                    + " , pointerId=" + pointerId + ", pointerIndex=" + pointerIndex + ", duration="
+                    + (eventTime - downTime) + "]");
+        }
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        if (LOG_ONLY) {
+            return;
+        }
+        int radius = canvas.getWidth() / 100;
+        for (Finger finger: mFingers) {
+            Point point = finger.point;
+            int color = COLORS[finger.pointerId % COLORS.length];
+            mPaint.setColor(color);
+            canvas.drawCircle(point.x, point.y, radius, mPaint);
+        }
+    }
+
+    private static final class Finger {
+        public Point point;
+        public int pointerId;
+    }
+}
diff --git a/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/touch/TouchTestFragment.java b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/touch/TouchTestFragment.java
new file mode 100644
index 0000000..5341435
--- /dev/null
+++ b/tests/MultiDisplayTest/src/com/google/android/car/multidisplaytest/touch/TouchTestFragment.java
@@ -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.
+ */
+
+package com.google.android.car.multidisplaytest.touch;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.fragment.app.Fragment;
+
+import com.google.android.car.multidisplaytest.R;
+
+public class TouchTestFragment extends Fragment {
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
+        View view = inflater.inflate(R.layout.touch_points, container, false);
+
+        return view;
+    }
+}
diff --git a/tests/carservice_test/src/com/android/car/garagemode/GarageModeServiceTest.java b/tests/carservice_test/src/com/android/car/garagemode/GarageModeServiceTest.java
index 91059fc..83f2c87 100644
--- a/tests/carservice_test/src/com/android/car/garagemode/GarageModeServiceTest.java
+++ b/tests/carservice_test/src/com/android/car/garagemode/GarageModeServiceTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -61,7 +62,7 @@
         when(mMockController.isGarageModeActive()).thenReturn(true);
 
         mService.dump(mMockPrintWriter);
-        verify(mMockPrintWriter).println(mCaptorString.capture());
+        verify(mMockPrintWriter, atLeastOnce()).println(mCaptorString.capture());
         List<String> strings = mCaptorString.getAllValues();
         assertThat(strings.get(0)).isEqualTo("GarageModeInProgress true");
     }
diff --git a/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java
index d08d32a..c9e85e0 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java
@@ -16,6 +16,8 @@
 
 package com.android.car;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -23,11 +25,13 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.car.ICarUserService;
 import android.car.drivingstate.CarDrivingStateEvent;
 import android.car.drivingstate.ICarDrivingStateChangeListener;
 import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
@@ -45,7 +49,6 @@
 
 import com.android.car.systeminterface.SystemInterface;
 import com.android.car.test.utils.TemporaryDirectory;
-import com.android.internal.util.ArrayUtils;
 
 import org.junit.After;
 import org.junit.Before;
@@ -67,15 +70,17 @@
 
 /**
  * This class contains unit tests for the {@link CarLocationService}.
- * It tests that {@link LocationManager}'s last known location is stored in and loaded from a JSON
- * file upon appropriate system events.
+ * It tests that {@link LocationManagerProxy}'s last known location is stored in and loaded from a
+ * JSON file upon appropriate system events.
  *
  * The following mocks are used:
- * 1. {@link Context} provides a mocked {@link LocationManager}.
- * 2. {@link LocationManager} provides dummy {@link Location}s.
- * 3. {@link CarUserManagerHelper} tells whether or not the system user is headless.
- * 4. {@link SystemInterface} tells where to store system files.
- * 5. {@link CarDrivingStateService} tells about driving state changes.
+ * 1. {@link Context} registers intent receivers.
+ * 2. {@link CarUserManagerHelper} tells whether or not the system user is headless.
+ * 3. {@link SystemInterface} tells where to store system files.
+ * 4. {@link CarDrivingStateService} tells about driving state changes.
+ * 5. {@link PerUserCarServiceHelper} provides a mocked {@link ICarUserService}.
+ * 6. {@link ICarUserService} provides a mocked {@link LocationManagerProxy}.
+ * 7. {@link LocationManagerProxy} provides dummy {@link Location}s.
  */
 @RunWith(AndroidJUnit4.class)
 public class CarLocationServiceTest {
@@ -85,16 +90,21 @@
     private Context mContext;
     private CountDownLatch mLatch;
     private File mTempDirectory;
+    private PerUserCarServiceHelper.ServiceCallback mUserServiceCallback;
     @Mock
     private Context mMockContext;
     @Mock
-    private LocationManager mMockLocationManager;
+    private LocationManagerProxy mMockLocationManagerProxy;
     @Mock
     private CarUserManagerHelper mMockCarUserManagerHelper;
     @Mock
     private SystemInterface mMockSystemInterface;
     @Mock
     private CarDrivingStateService mMockCarDrivingStateService;
+    @Mock
+    private PerUserCarServiceHelper mMockPerUserCarServiceHelper;
+    @Mock
+    private ICarUserService mMockICarUserService;
 
     /**
      * Initialize all of the objects with the @Mock annotation.
@@ -118,7 +128,24 @@
         CarLocalServices.addService(SystemInterface.class, mMockSystemInterface);
         CarLocalServices.removeServiceForTest(CarDrivingStateService.class);
         CarLocalServices.addService(CarDrivingStateService.class, mMockCarDrivingStateService);
+        CarLocalServices.removeServiceForTest(PerUserCarServiceHelper.class);
+        CarLocalServices.addService(PerUserCarServiceHelper.class, mMockPerUserCarServiceHelper);
         when(mMockSystemInterface.getSystemCarDir()).thenReturn(mTempDirectory);
+        when(mMockICarUserService.getLocationManagerProxy()).thenReturn(mMockLocationManagerProxy);
+
+        // We only support and test the headless system user case.
+        when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
+
+        // Store CarLocationService's user switch callback so we can invoke it in the tests.
+        doAnswer((invocation) -> {
+            Object[] arguments = invocation.getArguments();
+            assertThat(arguments).isNotNull();
+            assertThat(arguments).hasLength(1);
+            assertThat(arguments[0]).isNotNull();
+            mUserServiceCallback = (PerUserCarServiceHelper.ServiceCallback) arguments[0];
+            return null;
+        }).when(mMockPerUserCarServiceHelper).registerServiceCallback(any(
+                PerUserCarServiceHelper.ServiceCallback.class));
     }
 
     @After
@@ -146,23 +173,20 @@
     }
 
     /**
-     * Test that the {@link CarLocationService} registers to receive location and user intents.
+     * Test that the {@link CarLocationService} registers to receive location intents.
      */
     @Test
     public void testRegistersToReceiveEvents() {
+        mCarLocationService.init();
         ArgumentCaptor<IntentFilter> intentFilterArgument = ArgumentCaptor.forClass(
                 IntentFilter.class);
-        mCarLocationService.init();
         verify(mMockContext).registerReceiver(eq(mCarLocationService),
                 intentFilterArgument.capture());
         verify(mMockCarDrivingStateService).registerDrivingStateChangeListener(any());
+        verify(mMockPerUserCarServiceHelper).registerServiceCallback(any());
         IntentFilter intentFilter = intentFilterArgument.getValue();
-        assertEquals(3, intentFilter.countActions());
-        String[] actions = {intentFilter.getAction(0), intentFilter.getAction(1),
-                intentFilter.getAction(2)};
-        assertTrue(ArrayUtils.contains(actions, LocationManager.MODE_CHANGED_ACTION));
-        assertTrue(ArrayUtils.contains(actions, LocationManager.PROVIDERS_CHANGED_ACTION));
-        assertTrue(ArrayUtils.contains(actions, Intent.ACTION_USER_SWITCHED));
+        assertThat(intentFilter.countActions()).isEqualTo(1);
+        assertThat(intentFilter.getAction(0)).isEqualTo(LocationManager.MODE_CHANGED_ACTION);
     }
 
     /**
@@ -174,28 +198,26 @@
         mCarLocationService.release();
         verify(mMockContext).unregisterReceiver(mCarLocationService);
         verify(mMockCarDrivingStateService).unregisterDrivingStateChangeListener(any());
+        verify(mMockPerUserCarServiceHelper).unregisterServiceCallback(any());
     }
 
     /**
      * Test that the {@link CarLocationService} parses a location from a JSON serialization and then
-     * injects it into the {@link LocationManager} upon user switch.
+     * injects it into the {@link LocationManagerProxy} upon onServiceConnected.
      */
     @Test
     public void testLoadsLocationWithHeadlessSystemUser() throws Exception {
+        mCarLocationService.init();
+        assertThat(mUserServiceCallback).isNotNull();
         long currentTime = System.currentTimeMillis();
         long elapsedTime = SystemClock.elapsedRealtimeNanos();
         long pastTime = currentTime - 60000;
         writeCacheFile("{\"provider\": \"gps\", \"latitude\": 16.7666, \"longitude\": 3.0026,"
                 + "\"accuracy\":12.3, \"captureTime\": " + pastTime + "}");
         ArgumentCaptor<Location> argument = ArgumentCaptor.forClass(Location.class);
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.injectLocation(argument.capture())).thenReturn(true);
-        when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
+        when(mMockLocationManagerProxy.injectLocation(argument.capture())).thenReturn(true);
 
-        Intent userSwitchedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
-        userSwitchedIntent.putExtra(Intent.EXTRA_USER_HANDLE, 11);
-        mCarLocationService.onReceive(mMockContext, userSwitchedIntent);
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
         mLatch.await();
 
         Location location = argument.getValue();
@@ -213,16 +235,14 @@
      */
     @Test
     public void testDoesNotLoadLocationWhenNoFileExists() throws Exception {
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
-                .thenReturn(null);
-        when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
-        Intent userSwitchedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
-        userSwitchedIntent.putExtra(Intent.EXTRA_USER_HANDLE, 11);
-        mCarLocationService.onReceive(mMockContext, userSwitchedIntent);
+        mCarLocationService.init();
+        assertThat(mUserServiceCallback).isNotNull();
+        assertThat(getLocationCacheFile().exists()).isFalse();
+
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
         mLatch.await();
-        verify(mMockLocationManager, never()).injectLocation(any());
+
+        verify(mMockLocationManagerProxy, never()).injectLocation(any());
     }
 
     /**
@@ -230,17 +250,14 @@
      */
     @Test
     public void testDoesNotLoadLocationFromIncompleteFile() throws Exception {
+        mCarLocationService.init();
+        assertThat(mUserServiceCallback).isNotNull();
         writeCacheFile("{\"provider\": \"gps\", \"latitude\": 16.7666, \"longitude\": 3.0026,");
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
-                .thenReturn(null);
-        when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
-        Intent userSwitchedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
-        userSwitchedIntent.putExtra(Intent.EXTRA_USER_HANDLE, 11);
-        mCarLocationService.onReceive(mMockContext, userSwitchedIntent);
+
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
         mLatch.await();
-        verify(mMockLocationManager, never()).injectLocation(any());
+
+        verify(mMockLocationManagerProxy, never()).injectLocation(any());
     }
 
     /**
@@ -248,17 +265,14 @@
      */
     @Test
     public void testDoesNotLoadLocationFromCorruptFile() throws Exception {
+        mCarLocationService.init();
+        assertThat(mUserServiceCallback).isNotNull();
         writeCacheFile("{\"provider\":\"latitude\":16.7666,\"longitude\": \"accuracy\":1.0}");
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
-                .thenReturn(null);
-        when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
-        Intent userSwitchedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
-        userSwitchedIntent.putExtra(Intent.EXTRA_USER_HANDLE, 11);
-        mCarLocationService.onReceive(mMockContext, userSwitchedIntent);
+
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
         mLatch.await();
-        verify(mMockLocationManager, never()).injectLocation(any());
+
+        verify(mMockLocationManagerProxy, never()).injectLocation(any());
     }
 
     /**
@@ -267,17 +281,14 @@
      */
     @Test
     public void testDoesNotLoadIncompleteLocation() throws Exception {
+        mCarLocationService.init();
+        assertThat(mUserServiceCallback).isNotNull();
         writeCacheFile("{\"provider\": \"gps\", \"latitude\": 16.7666, \"longitude\": 3.0026}");
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
-                .thenReturn(null);
-        when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
-        Intent userSwitchedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
-        userSwitchedIntent.putExtra(Intent.EXTRA_USER_HANDLE, 11);
-        mCarLocationService.onReceive(mMockContext, userSwitchedIntent);
+
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
         mLatch.await();
-        verify(mMockLocationManager, never()).injectLocation(any());
+
+        verify(mMockLocationManagerProxy, never()).injectLocation(any());
     }
 
     /**
@@ -286,20 +297,17 @@
      */
     @Test
     public void testDoesNotLoadOldLocation() throws Exception {
+        mCarLocationService.init();
+        assertThat(mUserServiceCallback).isNotNull();
         long thirtyThreeDaysMs = 33 * 24 * 60 * 60 * 1000L;
         long oldTime = System.currentTimeMillis() - thirtyThreeDaysMs;
         writeCacheFile("{\"provider\": \"gps\", \"latitude\": 16.7666, \"longitude\": 3.0026,"
                 + "\"accuracy\":12.3, \"captureTime\": " + oldTime + "}");
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
-                .thenReturn(null);
-        when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
-        Intent userSwitchedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
-        userSwitchedIntent.putExtra(Intent.EXTRA_USER_HANDLE, 11);
-        mCarLocationService.onReceive(mMockContext, userSwitchedIntent);
+
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
         mLatch.await();
-        verify(mMockLocationManager, never()).injectLocation(any());
+
+        verify(mMockLocationManagerProxy, never()).injectLocation(any());
     }
 
     /**
@@ -308,6 +316,13 @@
      */
     @Test
     public void testStoresLocationUponShutdownPrepare() throws Exception {
+        // We must have a LocationManagerProxy for the current user in order to get a location
+        // during shutdown-prepare.
+        mCarLocationService.init();
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
+        mLatch.await();
+        mLatch = new CountDownLatch(1);
+
         long currentTime = System.currentTimeMillis();
         long elapsedTime = SystemClock.elapsedRealtimeNanos();
         Location timbuktu = new Location(LocationManager.GPS_PROVIDER);
@@ -316,14 +331,14 @@
         timbuktu.setAccuracy(13.75f);
         timbuktu.setTime(currentTime);
         timbuktu.setElapsedRealtimeNanos(elapsedTime);
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
+        when(mMockLocationManagerProxy.getLastKnownLocation(LocationManager.GPS_PROVIDER))
                 .thenReturn(timbuktu);
         CompletableFuture<Void> future = new CompletableFuture<>();
+
         mCarLocationService.onStateChanged(CarPowerStateListener.SHUTDOWN_PREPARE, future);
         mLatch.await();
-        verify(mMockLocationManager).getLastKnownLocation(LocationManager.GPS_PROVIDER);
+
+        verify(mMockLocationManagerProxy).getLastKnownLocation(LocationManager.GPS_PROVIDER);
         assertTrue(future.isDone());
         String actualContents = readCacheFile();
         long oneDayMs = 24 * 60 * 60 * 1000;
@@ -355,14 +370,22 @@
      */
     @Test
     public void testDoesNotStoreNullLocation() throws Exception {
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
+        // We must have a LocationManagerProxy for the current user in order to get a location
+        // during shutdown-prepare.
+        mCarLocationService.init();
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
+        mLatch.await();
+        mLatch = new CountDownLatch(1);
+
+        when(mMockLocationManagerProxy.getLastKnownLocation(LocationManager.GPS_PROVIDER))
                 .thenReturn(null);
         CompletableFuture<Void> future = new CompletableFuture<>();
+
         mCarLocationService.onStateChanged(CarPowerStateListener.SHUTDOWN_PREPARE, future);
         mLatch.await();
-        verify(mMockLocationManager).getLastKnownLocation(LocationManager.GPS_PROVIDER);
+
+        assertTrue(future.isDone());
+        verify(mMockLocationManagerProxy).getLastKnownLocation(LocationManager.GPS_PROVIDER);
         assertFalse(getLocationCacheFile().exists());
     }
 
@@ -372,17 +395,21 @@
      */
     @Test
     public void testDeletesCacheFileWhenLocationIsDisabled() throws Exception {
-        writeCacheFile("{\"provider\":\"latitude\":16.7666,\"longitude\": \"accuracy\":1.0}");
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.isLocationEnabled()).thenReturn(false);
+        // We must have a LocationManagerProxy for the current user in order to check whether or
+        // not location is enabled.
         mCarLocationService.init();
+        mUserServiceCallback.onServiceConnected(mMockICarUserService);
+        mLatch.await();
+        mLatch = new CountDownLatch(1);
+
+        writeCacheFile("{\"provider\":\"latitude\":16.7666,\"longitude\": \"accuracy\":1.0}");
+        when(mMockLocationManagerProxy.isLocationEnabled()).thenReturn(false);
         assertTrue(getLocationCacheFile().exists());
 
         mCarLocationService.onReceive(mMockContext,
                 new Intent(LocationManager.MODE_CHANGED_ACTION));
 
-        verify(mMockLocationManager, times(1)).isLocationEnabled();
+        verify(mMockLocationManagerProxy, times(1)).isLocationEnabled();
         assertFalse(getLocationCacheFile().exists());
     }
 
@@ -392,36 +419,14 @@
      */
     @Test
     public void testDeletesCacheFileUponSuspendExit() throws Exception {
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.isLocationEnabled()).thenReturn(false);
         mCarLocationService.init();
+        when(mMockLocationManagerProxy.isLocationEnabled()).thenReturn(false);
         CompletableFuture<Void> future = new CompletableFuture<>();
+
         mCarLocationService.onStateChanged(CarPowerStateListener.SUSPEND_EXIT, future);
+
         assertTrue(future.isDone());
-        verify(mMockLocationManager, times(0)).isLocationEnabled();
-        assertFalse(getLocationCacheFile().exists());
-    }
-
-    /**
-     * Test that the {@link CarLocationService} deletes location_cache.json when the GPS location
-     * provider is disabled.
-     */
-    @Test
-    public void testDeletesCacheFileWhenTheGPSProviderIsDisabled() throws Exception {
-        writeCacheFile("{\"provider\":\"latitude\":16.7666,\"longitude\": \"accuracy\":1.0}");
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)).thenReturn(
-                false);
-        mCarLocationService.init();
-        assertTrue(getLocationCacheFile().exists());
-
-        mCarLocationService.onReceive(mMockContext,
-                new Intent(LocationManager.PROVIDERS_CHANGED_ACTION));
-
-        verify(mMockLocationManager, times(1))
-                .isProviderEnabled(LocationManager.GPS_PROVIDER);
+        verify(mMockLocationManagerProxy, times(0)).isLocationEnabled();
         assertFalse(getLocationCacheFile().exists());
     }
 
@@ -431,11 +436,9 @@
      */
     @Test
     public void testDeletesCacheFileWhenDrivingStateBecomesMoving() throws Exception {
-        writeCacheFile("{\"provider\":\"latitude\":16.7666,\"longitude\": \"accuracy\":1.0}");
-        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
-                .thenReturn(mMockLocationManager);
-        when(mMockLocationManager.isLocationEnabled()).thenReturn(false);
         mCarLocationService.init();
+        writeCacheFile("{\"provider\":\"latitude\":16.7666,\"longitude\": \"accuracy\":1.0}");
+        when(mMockLocationManagerProxy.isLocationEnabled()).thenReturn(false);
         ArgumentCaptor<ICarDrivingStateChangeListener> changeListenerArgument =
                 ArgumentCaptor.forClass(ICarDrivingStateChangeListener.class);
         verify(mMockCarDrivingStateService).registerDrivingStateChangeListener(
@@ -447,7 +450,7 @@
                 new CarDrivingStateEvent(CarDrivingStateEvent.DRIVING_STATE_MOVING,
                         SystemClock.elapsedRealtimeNanos()));
 
-        verify(mMockLocationManager, times(0)).isLocationEnabled();
+        verify(mMockLocationManagerProxy, times(0)).isLocationEnabled();
         verify(mMockCarDrivingStateService, times(1)).unregisterDrivingStateChangeListener(any());
         assertFalse(getLocationCacheFile().exists());
     }
diff --git a/tests/carservice_unit_test/src/com/android/car/LocationManagerProxyTest.java b/tests/carservice_unit_test/src/com/android/car/LocationManagerProxyTest.java
new file mode 100644
index 0000000..6fa4e3b
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/LocationManagerProxyTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.location.Location;
+import android.location.LocationManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * This class contains unit tests for {@link LocationManagerProxy}.
+ *
+ * Mocks are used for {@link Context} and {@link LocationManager}.
+ */
+public class LocationManagerProxyTest {
+    private static final String TAG = "LocationManagerProxyTest";
+    private LocationManagerProxy mLocationManagerProxy;
+    @Mock
+    private Context mMockContext;
+    @Mock
+    private LocationManager mMockLocationManager;
+
+    /** Initialize all of the objects with the @Mock annotation. */
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
+                .thenReturn(mMockLocationManager);
+        mLocationManagerProxy = new LocationManagerProxy(mMockContext);
+    }
+
+    @Test
+    public void testLocationManagerProxyCanInjectLocation() {
+        Location location = new Location(LocationManager.GPS_PROVIDER);
+        mLocationManagerProxy.injectLocation(location);
+        verify(mMockLocationManager).injectLocation(location);
+    }
+
+    @Test
+    public void testLocationManagerProxyCanGetLastKnownLocation() {
+        Location location = new Location(LocationManager.GPS_PROVIDER);
+        when(mMockLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
+                .thenReturn(location);
+        Location locationFromProxy = mLocationManagerProxy
+                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
+        assertThat(locationFromProxy).isEqualTo(location);
+    }
+
+    @Test
+    public void testLocationManagerProxyCanCheckIfLocationIsEnabled() {
+        when(mMockLocationManager.isLocationEnabled()).thenReturn(true);
+        assertThat(mLocationManagerProxy.isLocationEnabled()).isTrue();
+
+        when(mMockLocationManager.isLocationEnabled()).thenReturn(false);
+        assertThat(mLocationManagerProxy.isLocationEnabled()).isFalse();
+    }
+}