diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 41b6815..6f5975a 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -47,10 +47,17 @@
           blocked in a UX restricted state.
           Format of each entry is either to specify package name to whitelist the whole package or
           use format of "packagename/activity_classname" for tagging each activities.
+          For general guidelines to design distraction optimized apps, please refer
+          to Android Auto Driver Distraction Guidelines. -->
+    <string name="activityWhitelist"></string>
+    <!--  Comma separated list of activities that need to be exempted from getting
+          blocked in a UX restricted state.
+          Format of each entry is either to specify package name to whitelist the whole package or
+          use format of "packagename/activity_classname" for tagging each activities.
           The current implementations expects the following system packages/activities to be
           whitelisted. For general guidelines to design distraction optimized apps, please refer
           to Android Auto Driver Distraction Guidelines. -->
-    <string name="activityWhitelist">com.android.systemui,com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity,android/com.android.internal.app.ResolverActivity</string>
+    <string name="systemActivityWhitelist">com.android.systemui,com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity,android/com.android.internal.app.ResolverActivity</string>
     <!--  Comma separated list of activities that will be blocked during restricted state.
           Format of each entry is either to specify package name to whitelist the whole package
           or use format of "packagename/activity_classname" for tagging each activities.-->
diff --git a/service/src/com/android/car/SystemActivityMonitoringService.java b/service/src/com/android/car/SystemActivityMonitoringService.java
index a20e7fc..c2abdc6 100644
--- a/service/src/com/android/car/SystemActivityMonitoringService.java
+++ b/service/src/com/android/car/SystemActivityMonitoringService.java
@@ -57,13 +57,15 @@
         public final ComponentName topActivity;
         public final int taskId;
         public final int displayId;
+        public final int position;
         public final StackInfo stackInfo;
 
-        private TopTaskInfoContainer(ComponentName topActivity, int taskId, int displayId,
-                StackInfo stackInfo) {
+        private TopTaskInfoContainer(ComponentName topActivity, int taskId,
+                int displayId, int position, StackInfo stackInfo) {
             this.topActivity = topActivity;
             this.taskId = taskId;
             this.displayId = displayId;
+            this.position = position;
             this.stackInfo = stackInfo;
         }
 
@@ -72,15 +74,16 @@
                     && Objects.equals(this.topActivity, taskInfo.topActivity)
                     && this.taskId == taskInfo.taskId
                     && this.displayId == taskInfo.displayId
+                    && this.position == taskInfo.position
                     && this.stackInfo.userId == taskInfo.stackInfo.userId;
         }
 
         @Override
         public String toString() {
             return String.format(
-                    "TaskInfoContainer [topActivity=%s, taskId=%d, stackId=%d, userId=%d,"
-                    + " displayId=%d]",
-                    topActivity, taskId, stackInfo.stackId, stackInfo.userId, displayId);
+                    "TaskInfoContainer [topActivity=%s, taskId=%d, stackId=%d, userId=%d, "
+                    + "displayId=%d, position=%d",
+                  topActivity, taskId, stackInfo.stackId, stackInfo.userId, displayId, position);
         }
     }
 
@@ -144,15 +147,16 @@
     @Override
     public void dump(PrintWriter writer) {
         writer.println("*SystemActivityMonitoringService*");
-        writer.println(" Top Tasks:");
+        writer.println(" Top Tasks per display:");
         synchronized (this) {
             for (int i = 0; i < mTopTasks.size(); i++) {
+                int displayId = mTopTasks.keyAt(i);
                 TopTaskInfoContainer info = mTopTasks.valueAt(i);
                 if (info != null) {
-                    writer.println(info);
+                    writer.println("display id " + displayId + ": " + info);
                 }
             }
-            writer.println(" Foregroud uid-pids:");
+            writer.println(" Foreground uid-pids:");
             for (Integer key : mForegroundUidPids.keySet()) {
                 Set<Integer> pids = mForegroundUidPids.get(key);
                 if (pids == null) {
@@ -274,48 +278,39 @@
             return;
         }
         mTasksToDispatch.clear();
+
+        SparseArray<TopTaskInfoContainer> topTasks = new SparseArray<>();
         ActivityLaunchListener listener;
         synchronized (this) {
             listener = mActivityLaunchListener;
-            Set<Integer> allStackIds = new ArraySet<>(infos.size());
-            Set<Integer> stackIdsToRemove = new ArraySet<>(infos.size());
             for (StackInfo info : infos) {
-                int stackId = info.stackId;
-                allStackIds.add(info.stackId);
+                int displayId = info.displayId;
                 if (info.taskNames.length == 0 || !info.visible) { // empty stack or not shown
-                    stackIdsToRemove.add(stackId);
                     continue;
                 }
                 TopTaskInfoContainer newTopTaskInfo = new TopTaskInfoContainer(
-                        info.topActivity, info.taskIds[info.taskIds.length - 1], info.displayId,
-                        info);
-                TopTaskInfoContainer currentTopTaskInfo = mTopTasks.get(stackId);
+                        info.topActivity, info.taskIds[info.taskIds.length - 1],
+                        info.displayId, info.position, info);
+                TopTaskInfoContainer currentTopTaskInfo = topTasks.get(displayId);
 
-                // if a new task is added to stack or focused stack changes, should notify
                 if (currentTopTaskInfo == null ||
-                        !currentTopTaskInfo.isMatching(newTopTaskInfo) ||
-                        (focusedStackId == stackId && focusedStackId != mFocusedStackId)) {
-                    mTopTasks.put(stackId, newTopTaskInfo);
-                    mTasksToDispatch.add(newTopTaskInfo);
+                        newTopTaskInfo.position > currentTopTaskInfo.position) {
+                    topTasks.put(displayId, newTopTaskInfo);
                     if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
-                        Log.i(CarLog.TAG_AM, "New top task: " + newTopTaskInfo);
+                        Log.i(CarLog.TAG_AM, "Current top task " + newTopTaskInfo);
                     }
                 }
             }
-            for (int i = 0; i < mTopTasks.size(); i++) {
-                TopTaskInfoContainer topTask = mTopTasks.valueAt(i);
-                if (topTask == null) {
-                    Log.wtf(CarLog.TAG_AM, "unexpected null value in sparse array");
-                    continue;
-                }
-                if (!allStackIds.contains(mTopTasks.keyAt(i))) {
-                    stackIdsToRemove.add(mTopTasks.keyAt(i));
+            // Assuming displays remains the same.
+            for (int i = 0; i < topTasks.size(); i++) {
+                int displayId = topTasks.keyAt(i);
+                TopTaskInfoContainer current = topTasks.get(displayId);
+                TopTaskInfoContainer previous = mTopTasks.get(displayId);
+                if (!current.isMatching(previous)) {
+                    mTasksToDispatch.add(current);
+                    mTopTasks.put(displayId, current);
                 }
             }
-            for (int stackIdToRemove : stackIdsToRemove) {
-                mTopTasks.remove(stackIdToRemove);
-            }
-            mFocusedStackId = focusedStackId;
         }
         if (listener != null) {
             for (TopTaskInfoContainer topTask : mTasksToDispatch) {
diff --git a/service/src/com/android/car/pm/CarPackageManagerService.java b/service/src/com/android/car/pm/CarPackageManagerService.java
index 781b9ef..136b3e3 100644
--- a/service/src/com/android/car/pm/CarPackageManagerService.java
+++ b/service/src/com/android/car/pm/CarPackageManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.car.pm;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager.StackInfo;
 import android.car.Car;
@@ -94,6 +95,7 @@
 
     // Store the white list and black list strings from the resource file.
     private String mConfiguredWhitelist;
+    private String mConfiguredSystemWhitelist;
     private String mConfiguredBlacklist;
     private final List<String> mAllowedAppInstallSources;
 
@@ -487,7 +489,7 @@
     }
 
     boolean isInstalledPackageMatching(AppBlockingPackageInfo info) {
-        PackageInfo packageInfo = null;
+        PackageInfo packageInfo;
         try {
             packageInfo = mPackageManager.getPackageInfo(info.packageName,
                     PackageManager.GET_SIGNATURES);
@@ -501,8 +503,8 @@
         if ((info.flags & AppBlockingPackageInfo.FLAG_SYSTEM_APP) == 0 ||
                 (!packageInfo.applicationInfo.isSystemApp() &&
                         !packageInfo.applicationInfo.isUpdatedSystemApp())) {
-            Signature[] signatires = packageInfo.signatures;
-            if (!isAnySignatureMatching(signatires, info.signatures)) {
+            Signature[] signatures = packageInfo.signatures;
+            if (!isAnySignatureMatching(signatures, info.signatures)) {
                 return false;
             }
         }
@@ -551,15 +553,24 @@
      */
     private void generateActivityWhitelistMap() {
         HashMap<String, AppBlockingPackageInfoWrapper> activityWhitelist = new HashMap<>();
+
+        // Get the apps/activities that are whitelisted in the configuration XML resources.
+        HashMap<String, Set<String>> configWhitelist = new HashMap<>();
         mConfiguredWhitelist = mContext.getString(R.string.activityWhitelist);
-        // Get the apps/activities that are whitelisted in the configuration XML resource
-        HashMap<String, Set<String>> configWhitelist = parseConfigList(mConfiguredWhitelist);
-        if (configWhitelist == null) {
+        if (mConfiguredWhitelist == null) {
             if (DBG_POLICY_CHECK) {
-                Log.w(CarLog.TAG_PACKAGE, "White list null.  No apps whitelisted");
+                Log.w(CarLog.TAG_PACKAGE, "White list is null.");
             }
-            return;
         }
+        parseConfigList(mConfiguredWhitelist, configWhitelist);
+        mConfiguredSystemWhitelist = mContext.getString(R.string.systemActivityWhitelist);
+        if (mConfiguredSystemWhitelist == null) {
+            if (DBG_POLICY_CHECK) {
+                Log.w(CarLog.TAG_PACKAGE, "System white list is null.");
+            }
+        }
+        parseConfigList(mConfiguredSystemWhitelist, configWhitelist);
+
         // Add the blocking overlay activity to the whitelist, since that needs to run in a
         // restricted state to communicate the reason an app was blocked.
         Set<String> defaultActivity = new ArraySet<>();
@@ -690,20 +701,16 @@
      */
     private void generateActivityBlacklistMap() {
         HashMap<String, AppBlockingPackageInfoWrapper> activityBlacklist = new HashMap<>();
+
+        // Parse blacklisted activities.
+        Map<String, Set<String>> configBlacklist = new HashMap<>();
         mConfiguredBlacklist = mContext.getString(R.string.activityBlacklist);
         if (mConfiguredBlacklist == null) {
             if (DBG_POLICY_CHECK) {
                 Log.d(CarLog.TAG_PACKAGE, "Null blacklist in config");
             }
-            return;
         }
-        Map<String, Set<String>> configBlacklist = parseConfigList(mConfiguredBlacklist);
-        if (configBlacklist == null) {
-            if (DBG_POLICY_CHECK) {
-                Log.w(CarLog.TAG_PACKAGE, "Black list null.  No apps blacklisted");
-            }
-            return;
-        }
+        parseConfigList(mConfiguredBlacklist, configBlacklist);
 
         for (String pkg : configBlacklist.keySet()) {
             if (TextUtils.isEmpty(pkg)) {
@@ -757,16 +764,22 @@
     }
 
     /**
-     * Parses the given resource and returns a map of packages and activities.
-     * Key is package name and value is list of activities. Empty list implies whole package is
+     * Parses the given resource and updates the input map of packages and activities.
+     *
+     * Key is package name and value is list of activities. Empty set implies whole package is
      * included.
+     *
+     * When there are multiple entries regarding one package, the entry with
+     * greater scope wins. Namely if there were 2 entires such that one whitelists
+     * an activity, and the other whitelists the entire package of the activity,
+     * the package is whitelisted, regardless of input order.
      */
-    @Nullable
-    private HashMap<String, Set<String>> parseConfigList(String configList) {
+    @VisibleForTesting
+    /* package */ void parseConfigList(String configList,
+            @NonNull Map<String, Set<String>> packageToActivityMap) {
         if (configList == null) {
-            return null;
+            return;
         }
-        HashMap<String, Set<String>> packageToActivityMap = new HashMap<>();
         String[] entries = configList.split(PACKAGE_DELIMITER);
         for (String entry : entries) {
             String[] packageActivityPair = entry.split(PACKAGE_ACTIVITY_DELIMITER);
@@ -786,7 +799,6 @@
                 }
             }
         }
-        return packageToActivityMap;
     }
 
     @Nullable
@@ -961,7 +973,7 @@
                 return;
             }
         }
-        if (DBG_POLICY_CHECK) {
+        if (DBG_POLICY_ENFORCEMENT) {
             Log.i(CarLog.TAG_PACKAGE, "Current activity " + topTask.topActivity +
                     " not allowed, will block, number of tasks in stack:" +
                     topTask.stackInfo.taskIds.length);
@@ -1273,7 +1285,7 @@
 
         @Override
         public void onUxRestrictionsChanged(CarUxRestrictions restrictions) {
-            if (DBG_POLICY_CHECK) {
+            if (DBG_POLICY_ENFORCEMENT) {
                 Log.d(CarLog.TAG_PACKAGE, "Received uxr restrictions: "
                         + restrictions.isRequiresDistractionOptimization()
                         + " : " + restrictions.getActiveRestrictions());
@@ -1299,7 +1311,7 @@
                     shouldCheck = true;
                 }
             }
-            if (DBG_POLICY_CHECK) {
+            if (DBG_POLICY_ENFORCEMENT) {
                 Log.d(CarLog.TAG_PACKAGE, "block?: " + shouldCheck);
             }
             if (shouldCheck) {
diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
index 398ae94..8176e0b 100644
--- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
+++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
@@ -68,16 +68,9 @@
             android:name="android.car.application"
             android:resource="@xml/automotive_app_desc" />
 
-        <activity android:name=".setting.CarServiceSettingsActivity"
-            android:label="@string/car_settings">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-            </intent-filter>
-        </activity>
-
         <activity android:name=".orientation.LandscapeActivity"
-            android:label="@string/landscpae_activity"
-            android:screenOrientation="landscape">
+                  android:label="@string/landscpae_activity"
+                  android:screenOrientation="landscape">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
@@ -91,11 +84,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".setting.UsbHostManagementActivity"
-                  android:theme="@android:style/Theme.Material.Light.Dialog"
-                  android:launchMode="singleTop">
-        </activity>
-
         <activity android:name=".cluster.FakeClusterNavigationActivity"
                   android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
                   android:launchMode="singleInstance"
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
index 38c5bc2..f4e7799 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
@@ -57,7 +57,6 @@
 import com.google.android.car.kitchensink.power.PowerTestFragment;
 import com.google.android.car.kitchensink.property.PropertyTestFragment;
 import com.google.android.car.kitchensink.sensor.SensorsTestFragment;
-import com.google.android.car.kitchensink.setting.CarServiceSettingsActivity;
 import com.google.android.car.kitchensink.storagelifetime.StorageLifetimeFragment;
 import com.google.android.car.kitchensink.touch.TouchTestFragment;
 import com.google.android.car.kitchensink.users.UsersFragment;
@@ -152,11 +151,6 @@
             new FragmentMenuEntry("audio", AudioTestFragment.class),
             new FragmentMenuEntry("bluetooth headset", BluetoothHeadsetFragment.class),
             new FragmentMenuEntry("bluetooth messaging test", MapMceTestFragment.class),
-            new OnClickMenuEntry("car service settings", () -> {
-                Intent intent = new Intent(KitchenSinkActivity.this,
-                        CarServiceSettingsActivity.class);
-                startActivity(intent);
-            }),
             new FragmentMenuEntry("carboard", KeyboardTestFragment.class),
             new FragmentMenuEntry("connectivity", ConnectivityFragment.class),
             new FragmentMenuEntry("cubes test", CubesTestFragment.class),
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/CarServiceSettingsActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/CarServiceSettingsActivity.java
deleted file mode 100644
index d5f2cf2..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/CarServiceSettingsActivity.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- */
-
-package com.google.android.car.kitchensink.setting;
-
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-import android.widget.Button;
-
-import com.google.android.car.kitchensink.R;
-
-import java.util.List;
-
-public class CarServiceSettingsActivity extends PreferenceActivity {
-    private static final String TAG = CarServiceSettingsActivity.class.getSimpleName();
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Button button = new Button(this);
-        button.setText("Finish");
-        button.setOnClickListener(view -> finish());
-        setListFooter(button);
-    }
-
-    @Override
-    public void onBuildHeaders(List<Header> target) {
-        loadHeadersFromResource(R.xml.preference_header, target);
-    }
-
-    @Override
-    protected boolean isValidFragment(String fragmentName) {
-        if (UsbManagerFragment.class.getName().equals(fragmentName)) {
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/UsbHostManagementActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/UsbHostManagementActivity.java
deleted file mode 100644
index e025f0d..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/UsbHostManagementActivity.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.google.android.car.kitchensink.R;
-import com.google.android.car.kitchensink.setting.usb.UsbDeviceSettings;
-import com.google.android.car.kitchensink.setting.usb.UsbHostController;
-
-import java.util.List;
-
-/**
- * Activity to handle USB device attached.
- * <p>
- * When user plugs in USB device:
- *    a) Device was used before and user selected handler for it.
- *       In this case handler will be launched.
- *    b) Device has not handler assigned. In this case supported handlers will be captured,
- *       and user will be presented with choice to assign default handler.
- *       After that handler will be lauched.
- */
-public class UsbHostManagementActivity extends Activity
-        implements UsbHostController.UsbHostControllerCallbacks {
-    private static final String TAG = UsbHostManagementActivity.class.getSimpleName();
-    private static final boolean LOCAL_LOGD = true;
-    private static final boolean LOCAL_LOGV = true;
-
-    private HandlersAdapter mListAdapter;
-    private ListView mHandlersList;
-    private LinearLayout mProgressInfo;
-    private UsbHostController mController;
-    private PackageManager mPackageManager;
-
-    private final AdapterView.OnItemClickListener mHandlerClickListener =
-            new AdapterView.OnItemClickListener() {
-        @Override
-        public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
-            UsbDeviceSettings settings = (UsbDeviceSettings) parent.getItemAtPosition(position);
-            mController.applyDeviceSettings(settings);
-        }
-    };
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.usb_host);
-        mHandlersList = (ListView) findViewById(R.id.usb_handlers_list);
-        mProgressInfo = (LinearLayout) findViewById(R.id.usb_handlers_progress);
-        mListAdapter = new HandlersAdapter(this);
-        mHandlersList.setAdapter(mListAdapter);
-        mHandlersList.setOnItemClickListener(mHandlerClickListener);
-        mController = new UsbHostController(this, this);
-        mPackageManager = getPackageManager();
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        mController.release();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        UsbDevice connectedDevice = getDevice();
-        if (connectedDevice != null) {
-            mController.processDevice(connectedDevice);
-        } else {
-            finish();
-        }
-    }
-
-    @Override
-    public void shutdown() {
-        runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                finish();
-            }
-        });
-    }
-
-    @Override
-    public void processingStateChanged(final boolean processing) {
-        runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mProgressInfo.setVisibility(processing ? View.VISIBLE : View.GONE);
-            }
-        });
-    }
-
-    @Override
-    public void titleChanged(String title) {
-        runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                setTitle(title);
-            }
-        });
-    }
-
-    @Override
-    public void optionsUpdated(List<UsbDeviceSettings> options) {
-        runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mListAdapter.clear();
-                mListAdapter.addAll(options);
-            }
-        });
-    }
-
-
-    @Override
-    public void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        setIntent(intent);
-    }
-
-    @Nullable
-    private UsbDevice getDevice() {
-        if (!UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(getIntent().getAction())) {
-            return null;
-        }
-        return (UsbDevice) getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE);
-    }
-
-    private static Intent createDeviceAttachedIntent(UsbDevice device) {
-        Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
-        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    private class HandlersAdapter extends ArrayAdapter<UsbDeviceSettings> {
-        class HandlerHolder {
-            public TextView mAppName;
-            public ImageView mAppIcon;
-        }
-
-        HandlersAdapter(Context context) {
-            super(context, R.layout.usb_handler_row);
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            View rowView = convertView;
-            if (rowView == null) {
-                rowView = getLayoutInflater().inflate(R.layout.usb_handler_row, null);
-                HandlerHolder holder = new HandlerHolder();
-                holder.mAppName = (TextView) rowView.findViewById(R.id.usb_handler_title);
-                holder.mAppIcon = (ImageView) rowView.findViewById(R.id.usb_handler_icon);
-                rowView.setTag(holder);
-            }
-
-            HandlerHolder holder = (HandlerHolder) rowView.getTag();
-            ComponentName handler = getItem(position).getHandler();
-
-            try {
-                ApplicationInfo appInfo =
-                        mPackageManager.getApplicationInfo(handler.getPackageName(), 0);
-                holder.mAppName.setText(appInfo.loadLabel(mPackageManager));
-                holder.mAppIcon.setImageDrawable(appInfo.loadIcon(mPackageManager));
-            } catch (NameNotFoundException e) {
-                Log.e(TAG, "Handling package not found: " + handler.getPackageName());
-                holder.mAppName.setText(handler.flattenToShortString());
-                holder.mAppIcon.setImageResource(android.R.color.transparent);
-            }
-            return rowView;
-        }
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/UsbManagerFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/UsbManagerFragment.java
deleted file mode 100644
index c5656e8..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/UsbManagerFragment.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbManager;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceCategory;
-import android.preference.PreferenceFragment;
-import android.preference.PreferenceGroup;
-import android.util.Log;
-
-import com.google.android.car.kitchensink.R;
-import com.google.android.car.kitchensink.setting.usb.UsbDevicePreference;
-import com.google.android.car.kitchensink.setting.usb.UsbDeviceSettings;
-import com.google.android.car.kitchensink.setting.usb.UsbSettingsStorage;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Usb manager handles management for USB device settings.
- */
-public class UsbManagerFragment extends PreferenceFragment
-        implements UsbDevicePreference.UsbDevicePreferenceCallback {
-
-    // TODO: for produciton settings version we need to handle detach through broadcast.
-
-    private static final String TAG = UsbManagerFragment.class.getSimpleName();
-    private static final boolean LOCAL_LOGD = true;
-    private static final boolean LOCAL_LOGV = true;
-
-    private UsbSettingsStorage mUsbSettingsStorage;
-    private UsbManager mUsbManager;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.usb_manager_prefs);
-        mUsbSettingsStorage = new UsbSettingsStorage(getContext());
-        mUsbManager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        populateSettings();
-    }
-
-    private void populateSettings() {
-        getPreferenceScreen().removeAll();
-        HashMap<String, UsbDevice> attachedDevices = mUsbManager.getDeviceList();
-        List<UsbDeviceSettings> allSavedSettings = mUsbSettingsStorage.getAllSettings();
-        PreferenceGroup availableDevicesCategory =
-                createPreferenceCategory(1, R.string.usb_available_devices);
-        getPreferenceScreen().addPreference(availableDevicesCategory);
-
-        PreferenceGroup savedDevicesCategory =
-                createPreferenceCategory(2, R.string.usb_saved_devices);
-        getPreferenceScreen().addPreference(savedDevicesCategory);
-
-        for (UsbDevice attachedDevice : attachedDevices.values()) {
-            if (LOCAL_LOGD) {
-                Log.d(TAG, "Attached device: " + attachedDevice);
-            }
-            if (attachedDevice.getSerialNumber() == null) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "Attached device: " + attachedDevice + " misseshave serial number");
-                }
-                continue;
-            }
-            UsbDeviceSettings deviceSettings = getSavedSetting(allSavedSettings, attachedDevice);
-            if (deviceSettings != null) {
-                // This might be slow if there are a lot of settings.
-                allSavedSettings.remove(deviceSettings);
-            } else {
-                deviceSettings = UsbDeviceSettings.constructSettings(attachedDevice);
-            }
-            UsbDevicePreference preference = new UsbDevicePreference(
-                    getContext(), deviceSettings, this);
-            availableDevicesCategory.addPreference(preference);
-        }
-        availableDevicesCategory.setEnabled(availableDevicesCategory.getPreferenceCount() > 0);
-
-        for (UsbDeviceSettings savedSettings : allSavedSettings) {
-            UsbDevicePreference preference = new UsbDevicePreference(
-                    getContext(), savedSettings, this);
-            savedDevicesCategory.addPreference(preference);
-        }
-        savedDevicesCategory.setEnabled(savedDevicesCategory.getPreferenceCount() > 0);
-    }
-
-    private PreferenceGroup createPreferenceCategory(int order, int titleId) {
-        PreferenceGroup preferenceGroup = new PreferenceCategory(getContext());
-        preferenceGroup.setTitle(titleId);
-        preferenceGroup.setOrder(order);
-        preferenceGroup.setSelectable(false);
-        return preferenceGroup;
-    }
-
-    @Nullable
-    private UsbDeviceSettings getSavedSetting(List<UsbDeviceSettings> settings, UsbDevice device) {
-        for (UsbDeviceSettings savedSetting : settings) {
-            if (savedSetting.matchesDevice(device)) {
-                return savedSetting;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public void onUsbDevicePreferenceDelete(Preference preference, UsbDeviceSettings settings) {
-        mUsbSettingsStorage.deleteSettings(
-                settings.getSerialNumber(), settings.getVid(), settings.getPid());
-        populateSettings();
-    }
-
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/AoapInterface.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/AoapInterface.java
deleted file mode 100644
index 8907dc6..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/AoapInterface.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.hardware.usb.UsbConstants;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbDeviceConnection;
-import android.util.Log;
-
-import java.io.IOException;
-
-final class AoapInterface {
-    /**
-     * Use Google Vendor ID when in accessory mode
-     */
-    public static final int USB_ACCESSORY_VENDOR_ID = 0x18D1;
-
-    /**
-     * Product ID to use when in accessory mode
-     */
-    public static final int USB_ACCESSORY_PRODUCT_ID = 0x2D00;
-
-    /**
-     * Product ID to use when in accessory mode and adb is enabled
-     */
-    public static final int USB_ACCESSORY_ADB_PRODUCT_ID = 0x2D01;
-
-    /**
-     * Indexes for strings sent by the host via ACCESSORY_SEND_STRING
-     */
-    public static final int ACCESSORY_STRING_MANUFACTURER = 0;
-    public static final int ACCESSORY_STRING_MODEL = 1;
-    public static final int ACCESSORY_STRING_DESCRIPTION = 2;
-    public static final int ACCESSORY_STRING_VERSION = 3;
-    public static final int ACCESSORY_STRING_URI = 4;
-    public static final int ACCESSORY_STRING_SERIAL = 5;
-
-    /**
-     * Control request for retrieving device's protocol version
-     *
-     *  requestType:    USB_DIR_IN | USB_TYPE_VENDOR
-     *  request:        ACCESSORY_GET_PROTOCOL
-     *  value:          0
-     *  index:          0
-     *  data            version number (16 bits little endian)
-     *                     1 for original accessory support
-     *                     2 adds HID and device to host audio support
-     */
-    public static final int ACCESSORY_GET_PROTOCOL = 51;
-
-    /**
-     * Control request for host to send a string to the device
-     *
-     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
-     *  request:        ACCESSORY_SEND_STRING
-     *  value:          0
-     *  index:          string ID
-     *  data            zero terminated UTF8 string
-     *
-     *  The device can later retrieve these strings via the
-     *  ACCESSORY_GET_STRING_* ioctls
-     */
-    public static final int ACCESSORY_SEND_STRING = 52;
-
-    /**
-     * Control request for starting device in accessory mode.
-     * The host sends this after setting all its strings to the device.
-     *
-     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
-     *  request:        ACCESSORY_START
-     *  value:          0
-     *  index:          0
-     *  data            none
-     */
-    public static final int ACCESSORY_START = 53;
-
-    /**
-     * Max payload size for AOAP. Limited by driver.
-     */
-    public static final int MAX_PAYLOAD_SIZE = 16384;
-
-    /**
-     * Accessory write timeout.
-     */
-    public static final int AOAP_TIMEOUT_MS = 2000;
-
-    private static final String TAG = AoapInterface.class.getSimpleName();
-
-    public static int getProtocol(UsbDeviceConnection conn) {
-        byte[] buffer = new byte[2];
-        int len = conn.controlTransfer(
-                UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_VENDOR,
-                ACCESSORY_GET_PROTOCOL, 0, 0, buffer, 2, AOAP_TIMEOUT_MS);
-        if (len != 2) {
-            return -1;
-        }
-        return (buffer[1] << 8) | buffer[0];
-    }
-
-    public static void sendString(UsbDeviceConnection conn, int index, String string)
-            throws IOException {
-        byte[] buffer = (string + "\0").getBytes();
-        int len = conn.controlTransfer(
-                UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
-                ACCESSORY_SEND_STRING, 0, index,
-                buffer, buffer.length, AOAP_TIMEOUT_MS);
-        if (len != buffer.length) {
-            throw new IOException("Failed to send string " + index + ": \"" + string + "\"");
-        } else {
-            Log.i(TAG, "Sent string " + index + ": \"" + string + "\"");
-        }
-    }
-
-    public static void sendAoapStart(UsbDeviceConnection conn) throws IOException {
-        int len = conn.controlTransfer(
-                UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
-                ACCESSORY_START, 0, 0, null, 0, AOAP_TIMEOUT_MS);
-        if (len < 0) {
-            throw new IOException("Control transfer for accessory start failed:" + len);
-        }
-    }
-
-    public static boolean isDeviceInAoapMode(UsbDevice device) {
-        if (device == null) {
-            return false;
-        }
-        final int vid = device.getVendorId();
-        final int pid = device.getProductId();
-        return vid == USB_ACCESSORY_VENDOR_ID
-                && (pid == USB_ACCESSORY_PRODUCT_ID || pid == USB_ACCESSORY_ADB_PRODUCT_ID);
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceHandlerResolver.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceHandlerResolver.java
deleted file mode 100644
index c66fd2f..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceHandlerResolver.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.car.IUsbAoapSupportCheckService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.res.XmlResourceParser;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbInterface;
-import android.hardware.usb.UsbManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-
-/**
- * Resolves supported handlers for USB device.
- */
-public final class UsbDeviceHandlerResolver
-        implements UsbDeviceStateController.UsbDeviceStateListener {
-    private static final String TAG = UsbDeviceHandlerResolver.class.getSimpleName();
-    private static final boolean LOCAL_LOGD = true;
-
-    private static final int MODE_OFF = 0;
-    private static final int MODE_PROBE = 1;
-    private static final int MODE_PROBE_AOAP = 2;
-    private static final int MODE_DISPATCH = 3;
-
-    /**
-     * Callbacks for device reolver.
-     */
-    public interface UsbDeviceHandlerResolverCallback {
-        /** Handlers are reolved */
-        void onHandlersResolveCompleted(
-                UsbDevice device, List<UsbDeviceSettings> availableSettings);
-        /** Device was dispatched */
-        void onDeviceDispatched();
-    }
-
-    private final UsbManager mUsbManager;
-    private final PackageManager mPackageManager;
-    private final UsbDeviceHandlerResolverCallback mDeviceCallback;
-    private final Context mContext;
-    private final HandlerThread mHandlerThread;
-    private final UsbDeviceResolverHandler mHandler;
-    private final UsbDeviceStateController mStateController;
-    private final Queue<Pair<ResolveInfo, DeviceFilter>> mActiveDeviceOptions = new LinkedList<>();
-    private final List<UsbDeviceSettings> mActiveDeviceSettings = new ArrayList<>();
-
-    private String mActiveDeviceSerial;
-    private UsbDevice mActiveUsbDevice;
-    private UsbDeviceSettings mBaseSettings;
-    private int mDeviceMode = MODE_OFF;
-    private Intent mDispatchIntent;
-    private int mDispatchUid;
-    private IUsbAoapSupportCheckService mIUsbAoapSupportCheckService;
-    private boolean mBound;
-
-    // This class is used to describe a USB device.
-    // When used in HashMaps all values must be specified,
-    // but wildcards can be used for any of the fields in
-    // the package meta-data.
-    private static class DeviceFilter {
-        // USB Vendor ID (or -1 for unspecified)
-        public final int mVendorId;
-        // USB Product ID (or -1 for unspecified)
-        public final int mProductId;
-        // USB device or interface class (or -1 for unspecified)
-        public final int mClass;
-        // USB device subclass (or -1 for unspecified)
-        public final int mSubclass;
-        // USB device protocol (or -1 for unspecified)
-        public final int mProtocol;
-        // USB device manufacturer name string (or null for unspecified)
-        public final String mManufacturerName;
-        // USB device product name string (or null for unspecified)
-        public final String mProductName;
-        // USB device serial number string (or null for unspecified)
-        public final String mSerialNumber;
-
-        // USB device in AOAP mode manufacturer
-        public final String mAoapManufacturer;
-        // USB device in AOAP mode modeal
-        public final String mAoapModel;
-        // USB device in AOAP mode description string
-        public final String mAoapDescription;
-        // USB device in AOAP mode version
-        public final String mAoapVersion;
-        // USB device in AOAP mode URI
-        public final String mAoapUri;
-        // USB device in AOAP mode serial
-        public final String mAoapSerial;
-        // USB device in AOAP mode verification service
-        public final String mAoapService;
-
-        DeviceFilter(int vid, int pid, int clasz, int subclass, int protocol,
-                            String manufacturer, String product, String serialnum,
-                            String aoapManufacturer, String aoapModel, String aoapDescription,
-                            String aoapVersion, String aoapUri, String aoapSerial,
-                            String aoapService) {
-            mVendorId = vid;
-            mProductId = pid;
-            mClass = clasz;
-            mSubclass = subclass;
-            mProtocol = protocol;
-            mManufacturerName = manufacturer;
-            mProductName = product;
-            mSerialNumber = serialnum;
-
-            mAoapManufacturer = aoapManufacturer;
-            mAoapModel = aoapModel;
-            mAoapDescription = aoapDescription;
-            mAoapVersion = aoapVersion;
-            mAoapUri = aoapUri;
-            mAoapSerial = aoapSerial;
-            mAoapService = aoapService;
-        }
-
-        DeviceFilter(UsbDevice device) {
-            mVendorId = device.getVendorId();
-            mProductId = device.getProductId();
-            mClass = device.getDeviceClass();
-            mSubclass = device.getDeviceSubclass();
-            mProtocol = device.getDeviceProtocol();
-            mManufacturerName = device.getManufacturerName();
-            mProductName = device.getProductName();
-            mSerialNumber = device.getSerialNumber();
-            mAoapManufacturer = null;
-            mAoapModel = null;
-            mAoapDescription = null;
-            mAoapVersion = null;
-            mAoapUri = null;
-            mAoapSerial = null;
-            mAoapService = null;
-        }
-
-        public static DeviceFilter read(XmlPullParser parser, boolean aoapData)
-                throws XmlPullParserException, IOException {
-            int vendorId = -1;
-            int productId = -1;
-            int deviceClass = -1;
-            int deviceSubclass = -1;
-            int deviceProtocol = -1;
-            String manufacturerName = null;
-            String productName = null;
-            String serialNumber = null;
-
-            String aoapManufacturer = null;
-            String aoapModel = null;
-            String aoapDescription = null;
-            String aoapVersion = null;
-            String aoapUri = null;
-            String aoapSerial = null;
-            String aoapService = null;
-
-            int count = parser.getAttributeCount();
-            for (int i = 0; i < count; i++) {
-                String name = parser.getAttributeName(i);
-                String value = parser.getAttributeValue(i);
-                // Attribute values are ints or strings
-                if (!aoapData && "manufacturer-name".equals(name)) {
-                    manufacturerName = value;
-                } else if (!aoapData && "product-name".equals(name)) {
-                    productName = value;
-                } else if (!aoapData && "serial-number".equals(name)) {
-                    serialNumber = value;
-                } else if (aoapData && "manufacturer".equals(name)) {
-                    aoapManufacturer = value;
-                } else if (aoapData && "model".equals(name)) {
-                    aoapModel = value;
-                } else if (aoapData && "description".equals(name)) {
-                    aoapDescription = value;
-                } else if (aoapData && "version".equals(name)) {
-                    aoapVersion = value;
-                } else if (aoapData && "uri".equals(name)) {
-                    aoapUri = value;
-                } else if (aoapData && "serial".equals(name)) {
-                    aoapSerial = value;
-                } else if (aoapData && "service".equals(name)) {
-                    aoapService = value;
-                } else if (!aoapData) {
-                    int intValue = -1;
-                    int radix = 10;
-                    if (value != null && value.length() > 2 && value.charAt(0) == '0'
-                            && (value.charAt(1) == 'x' || value.charAt(1) == 'X')) {
-                        // allow hex values starting with 0x or 0X
-                        radix = 16;
-                        value = value.substring(2);
-                    }
-                    try {
-                        intValue = Integer.parseInt(value, radix);
-                    } catch (NumberFormatException e) {
-                        Log.e(TAG, "invalid number for field " + name, e);
-                        continue;
-                    }
-                    if ("vendor-id".equals(name)) {
-                        vendorId = intValue;
-                    } else if ("product-id".equals(name)) {
-                        productId = intValue;
-                    } else if ("class".equals(name)) {
-                        deviceClass = intValue;
-                    } else if ("subclass".equals(name)) {
-                        deviceSubclass = intValue;
-                    } else if ("protocol".equals(name)) {
-                        deviceProtocol = intValue;
-                    }
-                }
-            }
-            return new DeviceFilter(vendorId, productId,
-                                    deviceClass, deviceSubclass, deviceProtocol,
-                                    manufacturerName, productName, serialNumber, aoapManufacturer,
-                                    aoapModel, aoapDescription, aoapVersion, aoapUri, aoapSerial,
-                                    aoapService);
-        }
-
-        private boolean matches(int clasz, int subclass, int protocol) {
-            return ((mClass == -1 || clasz == mClass)
-                    && (mSubclass == -1 || subclass == mSubclass)
-                    && (mProtocol == -1 || protocol == mProtocol));
-        }
-
-        public boolean isAoap() {
-            return (mVendorId == AoapInterface.USB_ACCESSORY_VENDOR_ID
-                    && mProductId == AoapInterface.USB_ACCESSORY_PRODUCT_ID);
-        }
-
-        public boolean matches(UsbDevice device) {
-            if (mVendorId != -1 && device.getVendorId() != mVendorId) {
-                return false;
-            }
-            if (mProductId != -1 && device.getProductId() != mProductId) {
-                return false;
-            }
-            if (mManufacturerName != null && device.getManufacturerName() == null) {
-                return false;
-            }
-            if (mProductName != null && device.getProductName() == null) {
-                return false;
-            }
-            if (mSerialNumber != null && device.getSerialNumber() == null) {
-                return false;
-            }
-            if (mManufacturerName != null && device.getManufacturerName() != null
-                    && !mManufacturerName.equals(device.getManufacturerName())) {
-                return false;
-            }
-            if (mProductName != null && device.getProductName() != null
-                    && !mProductName.equals(device.getProductName())) {
-                return false;
-            }
-            if (mSerialNumber != null && device.getSerialNumber() != null
-                    && !mSerialNumber.equals(device.getSerialNumber())) {
-                return false;
-            }
-
-            // check device class/subclass/protocol
-            if (matches(device.getDeviceClass(), device.getDeviceSubclass(),
-                        device.getDeviceProtocol())) {
-                return true;
-            }
-
-            // if device doesn't match, check the interfaces
-            int count = device.getInterfaceCount();
-            for (int i = 0; i < count; i++) {
-                UsbInterface intf = device.getInterface(i);
-                if (matches(intf.getInterfaceClass(), intf.getInterfaceSubclass(),
-                            intf.getInterfaceProtocol())) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            // can't compare if we have wildcard strings
-            if (mVendorId == -1 || mProductId == -1
-                    || mClass == -1 || mSubclass == -1 || mProtocol == -1) {
-                return false;
-            }
-            if (obj instanceof DeviceFilter) {
-                DeviceFilter filter = (DeviceFilter) obj;
-
-                if (filter.mVendorId != mVendorId
-                        || filter.mProductId != mProductId
-                        || filter.mClass != mClass
-                        || filter.mSubclass != mSubclass
-                        || filter.mProtocol != mProtocol) {
-                    return false;
-                }
-                if ((filter.mManufacturerName != null && mManufacturerName == null)
-                        || (filter.mManufacturerName == null && mManufacturerName != null)
-                        || (filter.mProductName != null && mProductName == null)
-                        || (filter.mProductName == null && mProductName != null)
-                        || (filter.mSerialNumber != null && mSerialNumber == null)
-                        || (filter.mSerialNumber == null && mSerialNumber != null)) {
-                    return false;
-                }
-                if  ((filter.mManufacturerName != null && mManufacturerName != null
-                          && !mManufacturerName.equals(filter.mManufacturerName))
-                          || (filter.mProductName != null && mProductName != null
-                          && !mProductName.equals(filter.mProductName))
-                          || (filter.mSerialNumber != null && mSerialNumber != null
-                          && !mSerialNumber.equals(filter.mSerialNumber))) {
-                    return false;
-                }
-                return true;
-            }
-            if (obj instanceof UsbDevice) {
-                UsbDevice device = (UsbDevice) obj;
-                if (device.getVendorId() != mVendorId
-                        || device.getProductId() != mProductId
-                        || device.getDeviceClass() != mClass
-                        || device.getDeviceSubclass() != mSubclass
-                        || device.getDeviceProtocol() != mProtocol) {
-                    return false;
-                }
-                if ((mManufacturerName != null && device.getManufacturerName() == null)
-                        || (mManufacturerName == null && device.getManufacturerName() != null)
-                        || (mProductName != null && device.getProductName() == null)
-                        || (mProductName == null && device.getProductName() != null)
-                        || (mSerialNumber != null && device.getSerialNumber() == null)
-                        || (mSerialNumber == null && device.getSerialNumber() != null)) {
-                    return false;
-                }
-                if ((device.getManufacturerName() != null
-                        && !mManufacturerName.equals(device.getManufacturerName()))
-                        || (device.getProductName() != null
-                        && !mProductName.equals(device.getProductName()))
-                        || (device.getSerialNumber() != null
-                        && !mSerialNumber.equals(device.getSerialNumber()))) {
-                    return false;
-                }
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return (((mVendorId << 16) | mProductId)
-                    ^ ((mClass << 16) | (mSubclass << 8) | mProtocol));
-        }
-
-        @Override
-        public String toString() {
-            return "DeviceFilter[mVendorId=" + mVendorId + ",mProductId=" + mProductId
-                    + ",mClass=" + mClass + ",mSubclass=" + mSubclass
-                    + ",mProtocol=" + mProtocol + ",mManufacturerName=" + mManufacturerName
-                    + ",mProductName=" + mProductName + ",mSerialNumber=" + mSerialNumber + "]";
-        }
-    }
-
-    private final ServiceConnection mConnection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            Log.i(TAG, "onServiceConnected: " + className);
-            mHandler.requestOnServiceConnectionStateChanged(
-                    IUsbAoapSupportCheckService.Stub.asInterface(service));
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName className) {
-            Log.i(TAG, "onServiceDisconnected: " + className);
-            mHandler.requestOnServiceConnectionStateChanged(null);
-        }
-    };
-
-    public UsbDeviceHandlerResolver(UsbManager manager, Context context,
-            UsbDeviceHandlerResolverCallback deviceListener) {
-        mUsbManager = manager;
-        mContext = context;
-        mDeviceCallback = deviceListener;
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new UsbDeviceResolverHandler(mHandlerThread.getLooper());
-        mPackageManager = context.getPackageManager();
-        mStateController = new UsbDeviceStateController(context, this, manager);
-        mStateController.init();
-    }
-
-    /**
-     * Releases current object.
-     */
-    public void release() {
-        if (mHandlerThread != null) {
-            mHandlerThread.quitSafely();
-        }
-        if (mStateController != null) {
-            mStateController.release();
-        }
-    }
-
-    /**
-     * Resolves handlers for USB device.
-     */
-    public void resolve(UsbDevice device) {
-        mHandler.requestResolveHandlers(device);
-    }
-
-    /**
-     * Dispatches device to component.
-     */
-    public boolean dispatch(UsbDevice device, ComponentName component, boolean inAoap) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "dispatch: " + device + " component: " + component + " inAoap:" + inAoap);
-        }
-
-        mActiveUsbDevice = device;
-        mDeviceMode = MODE_DISPATCH;
-        ActivityInfo activityInfo;
-        try {
-            activityInfo = mPackageManager.getActivityInfo(component, PackageManager.GET_META_DATA);
-        } catch (NameNotFoundException e) {
-            Log.e(TAG, "Activity not found: " + component);
-            return false;
-        }
-
-        Intent intent = createDeviceAttachedIntent(device);
-        if (inAoap) {
-            DeviceFilter filter = packageMatches(activityInfo, intent.getAction(), device, true);
-            intent.setComponent(component);
-            mDispatchIntent = intent;
-            mDispatchUid = activityInfo.applicationInfo.uid;
-            if (filter != null) {
-                requestAoapSwitch(filter);
-                return true;
-            }
-        }
-
-        intent.setComponent(component);
-        mUsbManager.grantPermission(device, activityInfo.applicationInfo.uid);
-
-        mContext.startActivity(intent);
-        mHandler.requestCompleteDeviceDispatch();
-        return true;
-    }
-
-    private static Intent createDeviceAttachedIntent(UsbDevice device) {
-        Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
-        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    private void doHandleResolveHandlers(
-            UsbDevice device) {
-        mActiveDeviceSettings.clear();
-        mActiveDeviceOptions.clear();
-        mActiveUsbDevice = device;
-        mDeviceMode = MODE_PROBE;
-
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "doHandleResolveHandlers: " + device);
-        }
-        boolean maySupportAoap = UsbUtil.possiblyAndroid(device);
-        boolean isInAoap = AoapInterface.isDeviceInAoapMode(device);
-
-        Intent intent = createDeviceAttachedIntent(device);
-        List<Pair<ResolveInfo, DeviceFilter>> matches = getDeviceMatches(device, intent, false);
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "matches size: " + matches.size());
-        }
-        for (Pair<ResolveInfo, DeviceFilter> info : matches) {
-            UsbDeviceSettings setting = UsbDeviceSettings.constructSettings(mActiveUsbDevice);
-            setting.setHandler(
-                    new ComponentName(
-                            info.first.activityInfo.packageName, info.first.activityInfo.name));
-            mActiveDeviceSettings.add(setting);
-        }
-        mBaseSettings = UsbDeviceSettings.constructSettings(mActiveUsbDevice);
-        if (!AoapInterface.isDeviceInAoapMode(device) && maySupportAoap) {
-            mActiveDeviceOptions.addAll(getDeviceMatches(device, intent, true));
-            handleTryNextAoapMode();
-        } else {
-            doHandleCompleteDeviceProbing();
-        }
-    }
-
-    private void handleTryNextAoapMode() {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "handleTryNextAoapMode");
-        }
-        Pair<ResolveInfo, DeviceFilter> option = mActiveDeviceOptions.peek();
-        if (option == null) {
-            mHandler.requestCompleteDeviceProbing();
-            return;
-        }
-        requestAoapSwitch(option.second);
-    }
-
-    private void requestAoapSwitch(DeviceFilter filter) {
-        UsbDeviceStateController.AoapSwitchRequest request =
-                new UsbDeviceStateController.AoapSwitchRequest(
-                        mActiveUsbDevice,
-                        filter.mAoapManufacturer,
-                        filter.mAoapModel,
-                        filter.mAoapDescription,
-                        filter.mAoapVersion,
-                        filter.mAoapUri,
-                        filter.mAoapSerial);
-        mStateController.startAoap(request);
-    }
-
-    private void doHandleCompleteDeviceProbing() {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "doHandleCompleteDeviceProbing");
-        }
-        mDeviceCallback.onHandlersResolveCompleted(mActiveUsbDevice, mActiveDeviceSettings);
-        stopDeviceProcessing(mActiveUsbDevice);
-        mActiveUsbDevice = null;
-        mBaseSettings = null;
-        mDeviceMode = MODE_OFF;
-    }
-
-    private void doHandleAoapStartComplete(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "doHandleAoapStartComplete:" + device + " mode: " + MODE_DISPATCH);
-        }
-        if (mDeviceMode == MODE_DISPATCH && mDispatchIntent != null) {
-            mDispatchIntent.putExtra(UsbManager.EXTRA_DEVICE, device);
-            mUsbManager.grantPermission(device, mDispatchUid);
-            mContext.startActivity(mDispatchIntent);
-            mDispatchIntent = null;
-            mDispatchUid = 0;
-            mDeviceMode = MODE_OFF;
-            mDeviceCallback.onDeviceDispatched();
-            return;
-        }
-        mActiveUsbDevice = device;
-        mDeviceMode = MODE_PROBE_AOAP;
-        if (device == null) {
-            mActiveDeviceOptions.poll();
-            handleTryNextAoapMode();
-        }
-
-        Pair<ResolveInfo, DeviceFilter> option = mActiveDeviceOptions.peek();
-        if (option == null) {
-            Log.w(TAG, "No more options left.");
-            mStateController.startDeviceReset(mActiveUsbDevice);
-            return;
-        }
-        DeviceFilter filter = option.second;
-        Intent serviceIntent = new Intent();
-        serviceIntent.setComponent(ComponentName.unflattenFromString(option.second.mAoapService));
-        boolean bound = mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
-        if (bound) {
-            mHandler.requestServiceConnectionTimeout();
-        } else {
-            if (LOCAL_LOGD) {
-                Log.d(TAG, "Failed to bind to the service");
-            }
-            mStateController.startDeviceReset(mActiveUsbDevice);
-        }
-    }
-
-    private void doHandleDeviceResetComplete(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "doHandleDeviceResetComplete:" + device);
-        }
-        mActiveDeviceOptions.poll();
-        mActiveUsbDevice = device;
-        mDeviceMode = MODE_PROBE;
-        handleTryNextAoapMode();
-    }
-
-    private void doHandleServiceConnectionStateChanged(IUsbAoapSupportCheckService service) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "doHandleServiceConnectionStateChanged: " + service);
-        }
-        mBound = service != null;
-        mIUsbAoapSupportCheckService = service;
-        if (mBound && mActiveUsbDevice != null && mDeviceMode == MODE_PROBE_AOAP) {
-            boolean deviceSupported = false;
-            try {
-                deviceSupported =
-                        mIUsbAoapSupportCheckService.isDeviceSupported(mActiveUsbDevice);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Call to remote service failed", e);
-            }
-            if (deviceSupported) {
-                Pair<ResolveInfo, DeviceFilter> option = mActiveDeviceOptions.peek();
-
-                UsbDeviceSettings setting = UsbDeviceSettings.constructSettings(mBaseSettings);
-                setting.setHandler(
-                        new ComponentName(
-                            option.first.activityInfo.packageName, option.first.activityInfo.name));
-                setting.setAoap(true);
-                mActiveDeviceSettings.add(setting);
-            }
-            mContext.unbindService(mConnection);
-            mBound = false;
-            mIUsbAoapSupportCheckService = null;
-            mStateController.startDeviceReset(mActiveUsbDevice);
-        } else if (mActiveUsbDevice != null && mDeviceMode == MODE_PROBE_AOAP) {
-            mStateController.startDeviceReset(mActiveUsbDevice);
-        } else {
-            handleTryNextAoapMode();
-        }
-    }
-
-    private List<Pair<ResolveInfo, DeviceFilter>> getDeviceMatches(
-            UsbDevice device, Intent intent, boolean forAoap) {
-        List<Pair<ResolveInfo, DeviceFilter>> matches = new ArrayList<>();
-        List<ResolveInfo> resolveInfos =
-                mPackageManager.queryIntentActivities(intent, PackageManager.GET_META_DATA);
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            DeviceFilter filter = packageMatches(resolveInfo.activityInfo,
-                    intent.getAction(), device, forAoap);
-            if (filter != null) {
-                matches.add(Pair.create(resolveInfo, filter));
-            }
-        }
-        return matches;
-    }
-
-    private DeviceFilter packageMatches(ActivityInfo ai, String metaDataName, UsbDevice device,
-            boolean forAoap) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "packageMatches ai: " + ai + "metaDataName: " + metaDataName + " forAoap: "
-                    + forAoap);
-        }
-        String filterTagName = forAoap ? "usb-aoap-accessory" : "usb-device";
-        XmlResourceParser parser = null;
-        try {
-            parser = ai.loadXmlMetaData(mPackageManager, metaDataName);
-            if (parser == null) {
-                Log.w(TAG, "no meta-data for " + ai);
-                return null;
-            }
-
-            XmlUtils.nextElement(parser);
-            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
-                String tagName = parser.getName();
-                if (device != null && filterTagName.equals(tagName)) {
-                    DeviceFilter filter = DeviceFilter.read(parser, forAoap);
-                    if (forAoap || filter.matches(device)) {
-                        return filter;
-                    }
-                }
-                XmlUtils.nextElement(parser);
-            }
-        } catch (Exception e) {
-            Log.w(TAG, "Unable to load component info " + ai.toString(), e);
-        } finally {
-            if (parser != null) parser.close();
-        }
-        return null;
-    }
-
-    @Override
-    public void onDeviceResetComplete(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "onDeviceResetComplete: " + device);
-        }
-        mHandler.requestOnDeviceResetComplete(device);
-    }
-
-    @Override
-    public void onAoapStartComplete(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "onAoapStartComplete: " + device);
-        }
-        mHandler.requestOnAoapStartComplete(device);
-    }
-
-    @Override
-    public void onAoapStartFailed(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "onAoapStartFailed: " + device);
-        }
-        mActiveDeviceOptions.poll();
-        handleTryNextAoapMode();
-    }
-
-    private boolean isDeviceProcessing(UsbDevice device) {
-        return mActiveDeviceSerial != null
-                && mActiveDeviceSerial.equals(device.getSerialNumber());
-    }
-
-    private boolean stopDeviceProcessing(UsbDevice device) {
-        if (device == null || device.getSerialNumber().equals(mActiveDeviceSerial)) {
-            mActiveDeviceSerial = null;
-            return true;
-        }
-        return false;
-    }
-
-    private boolean startDeviceProcessing(UsbDevice device) {
-        if (mActiveDeviceSerial != null) {
-            return false;
-        } else {
-            mActiveDeviceSerial = device.getSerialNumber();
-            return true;
-        }
-    }
-
-    private class UsbDeviceResolverHandler extends Handler {
-        private static final int MSG_RESOLVE_HANDLERS = 0;
-        private static final int MSG_DEVICE_RESET_COMPLETE = 1;
-        private static final int MSG_AOAP_START_COMPLETE = 2;
-        private static final int MSG_SERVICE_CONNECTION_STATE_CHANGE = 3;
-        private static final int MSG_SERVICE_CONNECTION_TIMEOUT = 4;
-        private static final int MSG_COMPLETE_PROBING = 5;
-        private static final int MSG_COMPLETE_DISPATCH = 6;
-
-        private static final long RESCHEDULE_TIMEOUT_MS = 100;
-        private static final long CONNECT_TIMEOUT_MS = 5000;
-        private static final long FINISH_PROBING_TIMEOUT_MS = 200;
-
-        private UsbDeviceResolverHandler(Looper looper) {
-            super(looper);
-        }
-
-        public void requestResolveHandlers(UsbDevice device) {
-            Message msg = obtainMessage(MSG_RESOLVE_HANDLERS, device);
-            sendMessage(msg);
-        }
-
-        public void requestOnAoapStartComplete(UsbDevice device) {
-            sendMessage(obtainMessage(MSG_AOAP_START_COMPLETE, device));
-        }
-
-        public void requestOnDeviceResetComplete(UsbDevice device) {
-            sendMessage(obtainMessage(MSG_DEVICE_RESET_COMPLETE, device));
-        }
-
-        public void requestOnServiceConnectionStateChanged(IUsbAoapSupportCheckService service) {
-            sendMessage(obtainMessage(MSG_SERVICE_CONNECTION_STATE_CHANGE, service));
-        }
-
-        public void requestServiceConnectionTimeout() {
-            sendEmptyMessageDelayed(MSG_SERVICE_CONNECTION_TIMEOUT, CONNECT_TIMEOUT_MS);
-        }
-
-        public void requestCompleteDeviceProbing() {
-            sendEmptyMessageDelayed(MSG_COMPLETE_PROBING, FINISH_PROBING_TIMEOUT_MS);
-        }
-
-        public void requestCompleteDeviceDispatch() {
-            sendEmptyMessage(MSG_COMPLETE_DISPATCH);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_RESOLVE_HANDLERS:
-                    UsbDevice device = (UsbDevice) msg.obj;
-                    // if this device is already being processed - drop the request.
-                    if (!isDeviceProcessing(device)) {
-                        if (startDeviceProcessing(device)) {
-                            doHandleResolveHandlers(device);
-                        } else {
-                            // Reschedule this device for processing at later time.
-                            sendMessageDelayed(msg, RESCHEDULE_TIMEOUT_MS);
-                        }
-                    } else {
-                        Log.i(TAG, "Device is already being processed: " + device);
-                    }
-                    break;
-                case MSG_AOAP_START_COMPLETE:
-                    doHandleAoapStartComplete((UsbDevice) msg.obj);
-                    break;
-                case MSG_DEVICE_RESET_COMPLETE:
-                    doHandleDeviceResetComplete((UsbDevice) msg.obj);
-                    break;
-                case MSG_SERVICE_CONNECTION_STATE_CHANGE:
-                    removeMessages(MSG_SERVICE_CONNECTION_TIMEOUT);
-                    doHandleServiceConnectionStateChanged((IUsbAoapSupportCheckService) msg.obj);
-                    break;
-                case MSG_SERVICE_CONNECTION_TIMEOUT:
-                    Log.i(TAG, "Service connection timeout");
-                    doHandleServiceConnectionStateChanged(null);
-                    break;
-                case MSG_COMPLETE_PROBING:
-                    doHandleCompleteDeviceProbing();
-                    break;
-                case MSG_COMPLETE_DISPATCH:
-                    mDeviceCallback.onDeviceDispatched();
-                    break;
-                default:
-                    Log.w(TAG, "Unsupported message: " + msg);
-            }
-        }
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDevicePreference.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDevicePreference.java
deleted file mode 100644
index 62f624e..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDevicePreference.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.preference.Preference;
-
-import com.google.android.car.kitchensink.R;
-
-/**
- * Setting preferabce used for USB devices.
- */
-public final class UsbDevicePreference extends Preference
-        implements Preference.OnPreferenceClickListener {
-
-    /**
-     * Callbacks to handle preference changes.
-     */
-    public interface UsbDevicePreferenceCallback {
-        /** Preference deleted */
-        void onUsbDevicePreferenceDelete(Preference preference, UsbDeviceSettings settings);
-    }
-
-    private static final String TAG = UsbDevicePreference.class.getSimpleName();
-
-    private final UsbDeviceSettings mUsbDeviceSettings;
-    private final UsbDevicePreferenceCallback mCallback;
-
-    public UsbDevicePreference(Context context, UsbDeviceSettings usbDeviceSettings,
-            UsbDevicePreferenceCallback callback) {
-        super(context);
-        mCallback = callback;
-        mUsbDeviceSettings = usbDeviceSettings;
-        setTitle(usbDeviceSettings.getDeviceName());
-        if (usbDeviceSettings.getHandler() != null) {
-            setSummary(usbDeviceSettings.getHandler().flattenToShortString());
-        }
-        setOnPreferenceClickListener(this);
-    }
-
-    @Override
-    public boolean onPreferenceClick(final Preference preference) {
-        new AlertDialog.Builder(getContext())
-                .setTitle(R.string.usb_pref_delete_title)
-                .setMessage(String.format(
-                        getContext().getResources().getString(R.string.usb_pref_delete_message),
-                        mUsbDeviceSettings.getDeviceName()))
-                .setIcon(android.R.drawable.ic_dialog_alert)
-                .setPositiveButton(R.string.usb_pref_delete_yes,
-                        new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int whichButton) {
-                                mCallback.onUsbDevicePreferenceDelete(
-                                        preference, mUsbDeviceSettings);
-                            }})
-                .setNegativeButton(R.string.usb_pref_delete_cancel, null)
-                .show();
-        return true;
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceSettings.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceSettings.java
deleted file mode 100644
index 7d4dc8a..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceSettings.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.content.ComponentName;
-import android.hardware.usb.UsbDevice;
-
-import com.android.internal.util.Preconditions;
-
-/**
- * Settings for USB device.
- * @hide
- */
-public final class UsbDeviceSettings {
-
-    private final String mSerialNumber;
-    private final int mVid;
-    private final int mPid;
-    private String mDeviceName;
-    private ComponentName mHandler;
-    private boolean mAoap;
-
-    UsbDeviceSettings(String serialNumber, int vid, int pid) {
-        Preconditions.checkNotNull(serialNumber);
-
-        mSerialNumber = serialNumber;
-        mVid = vid;
-        mPid = pid;
-    }
-
-    public String getSerialNumber() {
-        return mSerialNumber;
-    }
-
-    public int getVid() {
-        return mVid;
-    }
-
-    public int getPid() {
-        return mPid;
-    }
-
-    public void setDeviceName(String deviceName) {
-        mDeviceName = deviceName;
-    }
-
-    public String getDeviceName() {
-        return mDeviceName;
-    }
-
-    public void setHandler(ComponentName handler) {
-        mHandler = handler;
-    }
-
-    public ComponentName getHandler() {
-        return mHandler;
-    }
-
-    public void setAoap(boolean aoap) {
-        mAoap = aoap;
-    }
-
-    public boolean getAoap() {
-        return mAoap;
-    }
-
-    @Override
-    public String toString() {
-        return "UsbDeviceSettings{serial=" + getSerialNumber() + ", vid=" + mVid + "pid=" + mPid
-                + "name=" + getDeviceName() + ", handler=" + getHandler().toString()
-                + "aoap=" + getAoap() + "}";
-    }
-
-    /**
-     * Checks if setting matches {@code UsbDevice}.
-     */
-    public boolean matchesDevice(UsbDevice device) {
-        return (getSerialNumber().equals(device.getSerialNumber())
-                && getVid() == device.getVendorId()
-                && getPid() == device.getProductId());
-    }
-
-    /**
-     * Creates settings from {@code UsbDevice}.
-     */
-    public static UsbDeviceSettings constructSettings(UsbDevice device) {
-        UsbDeviceSettings settings = new UsbDeviceSettings(
-                device.getSerialNumber(), device.getVendorId(), device.getProductId());
-        settings.setDeviceName(device.getProductName());
-        return settings;
-    }
-
-    /**
-     * Creates settings from other settings.
-     * <p>
-     * Only basic properties are inherited.
-     */
-    public static UsbDeviceSettings constructSettings(UsbDeviceSettings origSettings) {
-        UsbDeviceSettings settings = new UsbDeviceSettings(
-                origSettings.getSerialNumber(), origSettings.getVid(), origSettings.getPid());
-        settings.setDeviceName(origSettings.getDeviceName());
-        return settings;
-    }
-
-    /**
-     * Creates settings.
-     */
-    public static UsbDeviceSettings constructSettings(String serialNumber, int vid, int pid,
-            String deviceName, ComponentName handler, boolean aoap) {
-        UsbDeviceSettings settings = new UsbDeviceSettings(serialNumber, vid, pid);
-        settings.setDeviceName(deviceName);
-        settings.setHandler(handler);
-        settings.setAoap(aoap);
-        return settings;
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceStateController.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceStateController.java
deleted file mode 100644
index 438fbaf..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbDeviceStateController.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbDeviceConnection;
-import android.hardware.usb.UsbManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import dalvik.system.CloseGuard;
-
-import java.io.IOException;
-import java.util.LinkedList;
-
-/**
- * Controller to change device into AOAP mode and back.
- */
-class UsbDeviceStateController {
-    /**
-     * Listener for USB device mode controller.
-     */
-    public interface UsbDeviceStateListener {
-        void onDeviceResetComplete(UsbDevice device);
-        void onAoapStartComplete(UsbDevice device);
-        void onAoapStartFailed(UsbDevice device);
-    }
-
-    private static final String TAG = UsbDeviceStateController.class.getSimpleName();
-    private static final boolean LOCAL_LOGD = true;
-
-    // Because of the bug in UsbDeviceManager total time for AOAP reset should be >10s.
-    // 21*500 = 10.5 s.
-    private static final int MAX_USB_DETACH_CHANGE_WAIT = 21;
-    private static final int MAX_USB_ATTACH_CHANGE_WAIT = 21;
-    private static final long USB_STATE_DETACH_WAIT_TIMEOUT_MS = 500;
-    private static final long USB_STATE_ATTACH_WAIT_TIMEOUT_MS = 500;
-
-    private final Context mContext;
-    private final UsbDeviceStateListener mListener;
-    private final UsbManager mUsbManager;
-    private final HandlerThread mHandlerThread;
-    private final UsbStateHandler mHandler;
-    private final UsbDeviceBroadcastReceiver mUsbStateBroadcastReceiver;
-    private final CloseGuard mCloseGuard = CloseGuard.get();
-
-    private final Object mUsbConnectionChangeWait = new Object();
-    private final LinkedList<UsbDevice> mDevicesRemoved = new LinkedList<>();
-    private final LinkedList<UsbDevice> mDevicesAdded = new LinkedList<>();
-    private boolean mShouldQuit = false;
-
-    UsbDeviceStateController(Context context, UsbDeviceStateListener listener,
-                                    UsbManager usbManager) {
-        mContext = context;
-        mListener = listener;
-        mUsbManager = usbManager;
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mCloseGuard.open("release");
-        mHandler = new UsbStateHandler(mHandlerThread.getLooper());
-        mUsbStateBroadcastReceiver = new UsbDeviceBroadcastReceiver();
-    }
-
-    public void init() {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
-        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
-        mContext.registerReceiver(mUsbStateBroadcastReceiver, filter);
-    }
-
-    public void release() {
-        mCloseGuard.close();
-        mContext.unregisterReceiver(mUsbStateBroadcastReceiver);
-        synchronized (mUsbConnectionChangeWait) {
-            mShouldQuit = true;
-            mUsbConnectionChangeWait.notifyAll();
-        }
-        mHandlerThread.quit();
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            mCloseGuard.warnIfOpen();
-            boolean release = false;
-            synchronized (mUsbConnectionChangeWait) {
-                release = !mShouldQuit;
-            }
-            if (release) {
-                release();
-            }
-        } finally {
-            super.finalize();
-        }
-    }
-
-    public void startDeviceReset(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "startDeviceReset: " + device);
-        }
-        mHandler.requestDeviceReset(device);
-    }
-
-    public void startAoap(AoapSwitchRequest request) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "startAoap: " + request.device);
-        }
-        mHandler.requestAoap(request);
-    }
-
-    private void doHandleDeviceReset(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "doHandleDeviceReset: " + device);
-        }
-        synchronized (mUsbConnectionChangeWait) {
-            mDevicesRemoved.clear();
-            mDevicesAdded.clear();
-        }
-        boolean isInAoap = AoapInterface.isDeviceInAoapMode(device);
-        UsbDevice completedDevice = null;
-        if (isInAoap) {
-            completedDevice = resetUsbDeviceAndConfirmModeChange(device);
-        } else {
-            UsbDeviceConnection conn = openConnection(device);
-            if (conn == null) {
-                throw new RuntimeException("cannot open conneciton for device: " + device);
-            } else {
-                try {
-                    if (!conn.resetDevice()) {
-                        throw new RuntimeException("resetDevice failed for device: " + device);
-                    } else {
-                        completedDevice = device;
-                    }
-                } finally {
-                    conn.close();
-                }
-            }
-        }
-        mListener.onDeviceResetComplete(completedDevice);
-    }
-
-    private void doHandleAoapStart(AoapSwitchRequest request) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "doHandleAoapStart: " + request.device);
-        }
-        UsbDevice device = request.device;
-        boolean isInAoap = AoapInterface.isDeviceInAoapMode(device);
-        if (isInAoap) {
-            device = resetUsbDeviceAndConfirmModeChange(device);
-            if (device == null) {
-                mListener.onAoapStartComplete(null);
-                return;
-            }
-        }
-        synchronized (mUsbConnectionChangeWait) {
-            mDevicesRemoved.clear();
-            mDevicesAdded.clear();
-        }
-        UsbDeviceConnection connection = openConnection(device);
-        try {
-            AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_MANUFACTURER,
-                                     request.manufacturer);
-            AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_MODEL,
-                                     request.model);
-            AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_DESCRIPTION,
-                                     request.description);
-            AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_VERSION,
-                                     request.version);
-            AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_URI, request.uri);
-            AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_SERIAL,
-                    request.serial);
-            AoapInterface.sendAoapStart(connection);
-            device = resetUsbDeviceAndConfirmModeChange(device);
-        } catch (IOException e) {
-            Log.w(TAG, "Failed to switch device into AOSP mode", e);
-        }
-        if (device == null) {
-            mListener.onAoapStartComplete(null);
-            connection.close();
-            return;
-        }
-        if (AoapInterface.isDeviceInAoapMode(device)) {
-            mListener.onAoapStartComplete(device);
-        } else {
-            Log.w(TAG, "Device not in AOAP mode after switching: " + device);
-            mListener.onAoapStartFailed(device);
-        }
-        connection.close();
-    }
-
-    private UsbDevice resetUsbDeviceAndConfirmModeChange(UsbDevice device) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "resetUsbDeviceAndConfirmModeChange: " + device);
-        }
-        int retry = 0;
-        boolean removalDetected = false;
-        while (retry < MAX_USB_DETACH_CHANGE_WAIT) {
-            UsbDeviceConnection connNow = openConnection(device);
-            if (connNow == null) {
-                removalDetected = true;
-                break;
-            }
-            connNow.resetDevice();
-            connNow.close();
-            synchronized (mUsbConnectionChangeWait) {
-                try {
-                    mUsbConnectionChangeWait.wait(USB_STATE_DETACH_WAIT_TIMEOUT_MS);
-                } catch (InterruptedException e) {
-                    break;
-                }
-                if (mShouldQuit) {
-                    return null;
-                }
-                if (isDeviceRemovedLocked(device)) {
-                    removalDetected = true;
-                    break;
-                }
-            }
-            retry++;
-            connNow = null;
-        }
-        if (!removalDetected) {
-            Log.w(TAG, "resetDevice failed for device, device still in the same mode: " + device);
-            return null;
-        }
-        retry = 0;
-        UsbDevice newlyAttached = null;
-        while (retry < MAX_USB_ATTACH_CHANGE_WAIT) {
-            synchronized (mUsbConnectionChangeWait) {
-                try {
-                    mUsbConnectionChangeWait.wait(USB_STATE_ATTACH_WAIT_TIMEOUT_MS);
-                } catch (InterruptedException e) {
-                    break;
-                }
-                if (mShouldQuit) {
-                    return null;
-                }
-                newlyAttached = checkDeviceAttachedLocked(device);
-            }
-            if (newlyAttached != null) {
-                break;
-            }
-            retry++;
-        }
-        if (newlyAttached == null) {
-            Log.w(TAG, "resetDevice failed for device, device disconnected: " + device);
-            return null;
-        }
-        return newlyAttached;
-    }
-
-    private boolean isDeviceRemovedLocked(UsbDevice device) {
-        for (UsbDevice removed : mDevicesRemoved) {
-            if (UsbUtil.isDevicesMatching(device, removed)) {
-                mDevicesRemoved.clear();
-                return true;
-            }
-        }
-        mDevicesRemoved.clear();
-        return false;
-    }
-
-    private UsbDevice checkDeviceAttachedLocked(UsbDevice device) {
-        for (UsbDevice attached : mDevicesAdded) {
-            if (UsbUtil.isTheSameDevice(device, attached)) {
-                mDevicesAdded.clear();
-                return attached;
-            }
-        }
-        mDevicesAdded.clear();
-        return null;
-    }
-
-    public UsbDeviceConnection openConnection(UsbDevice device) {
-        mUsbManager.grantPermission(device);
-        return mUsbManager.openDevice(device);
-    }
-
-    private void handleUsbDeviceAttached(UsbDevice device) {
-        synchronized (mUsbConnectionChangeWait) {
-            mDevicesAdded.add(device);
-            mUsbConnectionChangeWait.notifyAll();
-        }
-    }
-
-    private void handleUsbDeviceDetached(UsbDevice device) {
-        synchronized (mUsbConnectionChangeWait) {
-            mDevicesRemoved.add(device);
-            mUsbConnectionChangeWait.notifyAll();
-        }
-    }
-
-    private class UsbStateHandler extends Handler {
-        private static final int MSG_RESET_DEVICE = 1;
-        private static final int MSG_AOAP = 2;
-
-        private UsbStateHandler(Looper looper) {
-            super(looper);
-        }
-
-        private void requestDeviceReset(UsbDevice device) {
-            Message msg = obtainMessage(MSG_RESET_DEVICE, device);
-            sendMessage(msg);
-        }
-
-        private void requestAoap(AoapSwitchRequest request) {
-            Message msg = obtainMessage(MSG_AOAP, request);
-            sendMessage(msg);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_RESET_DEVICE:
-                    doHandleDeviceReset((UsbDevice) msg.obj);
-                    break;
-                case MSG_AOAP:
-                    doHandleAoapStart((AoapSwitchRequest) msg.obj);
-                    break;
-            }
-        }
-    }
-
-    private class UsbDeviceBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
-                UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE);
-                handleUsbDeviceDetached(device);
-            } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
-                UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE);
-                handleUsbDeviceAttached(device);
-            }
-        }
-    }
-
-    public static class AoapSwitchRequest {
-        public final UsbDevice device;
-        public final String manufacturer;
-        public final String model;
-        public final String description;
-        public final String version;
-        public final String uri;
-        public final String serial;
-
-        AoapSwitchRequest(UsbDevice device, String manufacturer, String model,
-                String description, String version, String uri, String serial) {
-            this.device = device;
-            this.manufacturer = manufacturer;
-            this.model = model;
-            this.description = description;
-            this.version = version;
-            this.uri = uri;
-            this.serial = serial;
-        }
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbHostController.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbHostController.java
deleted file mode 100644
index fe6bdef..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbHostController.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Controller used to handle USB device connections.
- */
-public final class UsbHostController
-        implements UsbDeviceHandlerResolver.UsbDeviceHandlerResolverCallback {
-
-    /**
-     * Callbacks for controller
-     */
-    public interface UsbHostControllerCallbacks {
-        /** Host controller ready for shutdown*/
-        void shutdown();
-        /** Change of processing state*/
-        void processingStateChanged(boolean processing);
-        /** Title of processing changed */
-        void titleChanged(String title);
-        /** Options for USB device changed */
-        void optionsUpdated(List<UsbDeviceSettings> options);
-    }
-
-    private static final String TAG = UsbHostController.class.getSimpleName();
-    private static final boolean LOCAL_LOGD = true;
-    private static final boolean LOCAL_LOGV = true;
-
-
-    private final List<UsbDeviceSettings> mEmptyList = new ArrayList<>();
-    private final Context mContext;
-    private final UsbHostControllerCallbacks mCallback;
-    private final UsbSettingsStorage mUsbSettingsStorage;
-    private final UsbManager mUsbManager;
-    private final PackageManager mPackageManager;
-    private final UsbDeviceHandlerResolver mUsbReslover;
-    private final UsbHostControllerHandler mHandler;
-
-    private final BroadcastReceiver mUsbBroadcastReceiver = new  BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
-                UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE);
-                unsetActiveDeviceIfSerialMatch(device);
-            } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
-                UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE);
-                setActiveDeviceIfSerialMatch(device);
-            }
-        }
-    };
-
-    @GuardedBy("this")
-    private UsbDevice mActiveDevice;
-
-    @GuardedBy("this")
-    private String mProcessingDeviceSerial;
-
-    public UsbHostController(Context context, UsbHostControllerCallbacks callbacks) {
-        mContext = context;
-        mCallback = callbacks;
-        mHandler = new UsbHostControllerHandler(Looper.myLooper());
-        mUsbSettingsStorage = new UsbSettingsStorage(context);
-        mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
-        mPackageManager = context.getPackageManager();
-        mUsbReslover = new UsbDeviceHandlerResolver(mUsbManager, mContext, this);
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
-        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
-        context.registerReceiver(mUsbBroadcastReceiver, filter);
-
-    }
-
-    private synchronized void setActiveDeviceIfSerialMatch(UsbDevice device) {
-        if (device != null && device.getSerialNumber() != null
-                && device.getSerialNumber().equals(mProcessingDeviceSerial)) {
-            mActiveDevice = device;
-        }
-    }
-
-    private synchronized void unsetActiveDeviceIfSerialMatch(UsbDevice device) {
-        mHandler.requestDeviceRemoved();
-        if (mActiveDevice != null && mActiveDevice.getSerialNumber() != null
-                && mActiveDevice.getSerialNumber().equals(device.getSerialNumber())) {
-            mActiveDevice = null;
-        }
-    }
-
-    private synchronized boolean startDeviceProcessingIfNull(UsbDevice device) {
-        if (mActiveDevice == null) {
-            mActiveDevice = device;
-            mProcessingDeviceSerial = device.getSerialNumber();
-            return true;
-        }
-        return false;
-    }
-
-    private synchronized void stopDeviceProcessing() {
-        mActiveDevice = null;
-        mProcessingDeviceSerial = null;
-    }
-
-    private synchronized UsbDevice getActiveDevice() {
-        return mActiveDevice;
-    }
-
-    private boolean deviceMatchedActiveDevice(UsbDevice device) {
-        UsbDevice activeDevice = getActiveDevice();
-        return activeDevice != null && activeDevice.getSerialNumber() != null
-                && activeDevice.getSerialNumber().equals(device.getSerialNumber());
-    }
-
-    /**
-     * Processes device new device.
-     * <p>
-     * It will load existing settings or resolve supported handlers.
-     */
-    public void processDevice(UsbDevice device) {
-        if (!startDeviceProcessingIfNull(device)) {
-            Log.w(TAG, "Currently, other device is being processed");
-        }
-        mCallback.optionsUpdated(mEmptyList);
-        mCallback.processingStateChanged(true);
-
-        UsbDeviceSettings settings = mUsbSettingsStorage.getSettings(
-                device.getSerialNumber(), device.getVendorId(), device.getProductId());
-        if (settings != null && mUsbReslover.dispatch(
-                    mActiveDevice, settings.getHandler(), settings.getAoap())) {
-            if (LOCAL_LOGV) {
-                Log.v(TAG, "Usb Device: " + device + " was sent to component: "
-                        + settings.getHandler());
-            }
-            return;
-        }
-        mCallback.titleChanged(device.getManufacturerName() + " " + device.getProductName());
-        mUsbReslover.resolve(device);
-    }
-
-    /**
-     * Applies device settings.
-     */
-    public void applyDeviceSettings(UsbDeviceSettings settings) {
-        mUsbSettingsStorage.saveSettings(settings);
-        mUsbReslover.dispatch(getActiveDevice(), settings.getHandler(), settings.getAoap());
-    }
-
-    /**
-     * Release object.
-     */
-    public void release() {
-        mContext.unregisterReceiver(mUsbBroadcastReceiver);
-        mUsbReslover.release();
-    }
-
-    @Override
-    public void onHandlersResolveCompleted(
-            UsbDevice device, List<UsbDeviceSettings> handlers) {
-        if (LOCAL_LOGD) {
-            Log.d(TAG, "onHandlersResolveComplete: " + device);
-        }
-        if (deviceMatchedActiveDevice(device)) {
-            mCallback.processingStateChanged(false);
-            if (handlers.isEmpty()) {
-                onDeviceDispatched();
-            } else {
-                mCallback.optionsUpdated(handlers);
-            }
-        } else {
-            Log.w(TAG, "Handlers ignored as they came for inactive device");
-        }
-    }
-
-    @Override
-    public void onDeviceDispatched() {
-        stopDeviceProcessing();
-        mCallback.shutdown();
-    }
-
-    void doHandleDeviceRemoved() {
-        if (getActiveDevice() == null) {
-            if (LOCAL_LOGD) {
-                Log.d(TAG, "USB device detached");
-            }
-            stopDeviceProcessing();
-            mCallback.shutdown();
-        }
-    }
-
-    private static Intent createDeviceAttachedIntent(UsbDevice device) {
-        Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
-        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    private class UsbHostControllerHandler extends Handler {
-        private static final int MSG_DEVICE_REMOVED = 1;
-
-        private static final int DEVICE_REMOVE_TIMEOUT_MS = 500;
-
-        private UsbHostControllerHandler(Looper looper) {
-            super(looper);
-        }
-
-        private void requestDeviceRemoved() {
-            sendEmptyMessageDelayed(MSG_DEVICE_REMOVED, DEVICE_REMOVE_TIMEOUT_MS);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_DEVICE_REMOVED:
-                    doHandleDeviceRemoved();
-                    break;
-                default:
-                    Log.w(TAG, "Unhandled message: " + msg);
-                    super.handleMessage(msg);
-            }
-        }
-    }
-
-
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbSettingsStorage.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbSettingsStorage.java
deleted file mode 100644
index 1f647c9..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbSettingsStorage.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides API to persist USB device settings.
- */
-public final class UsbSettingsStorage {
-    private static final String TAG = UsbSettingsStorage.class.getSimpleName();
-
-    private static final String TABLE_USB_SETTINGS = "usb_devices";
-    private static final String COLUMN_SERIAL = "serial";
-    private static final String COLUMN_VID = "vid";
-    private static final String COLUMN_PID = "pid";
-    private static final String COLUMN_NAME = "name";
-    private static final String COLUMN_HANDLER = "handler";
-    private static final String COLUMN_AOAP = "aoap";
-
-    private final UsbSettingsDbHelper mDbHelper;
-
-    public UsbSettingsStorage(Context context) {
-        mDbHelper = new UsbSettingsDbHelper(context);
-    }
-
-    /**
-     * Returns settings for {@serialNumber} or null if it doesn't exist.
-     */
-    @Nullable
-    public UsbDeviceSettings getSettings(String serialNumber, int vid, int pid) {
-        try (SQLiteDatabase db = mDbHelper.getReadableDatabase();
-             Cursor resultCursor = db.query(
-                     TABLE_USB_SETTINGS,
-                     null,
-                     COLUMN_SERIAL + " = ? AND " + COLUMN_VID + " = ? AND " + COLUMN_PID + " = ?",
-                     new String[]{serialNumber, Integer.toString(vid), Integer.toString(pid)},
-                     null,
-                     null,
-                     null)) {
-            if (resultCursor.getCount() > 1) {
-                throw new RuntimeException("Quering for serial number: " + serialNumber
-                        + " vid: " + vid + " pid: " + pid + " returned "
-                        + resultCursor.getCount() + " results");
-            }
-            if (resultCursor.getCount() == 0) {
-                Log.w(TAG, "Usb setting missing for device serial: " + serialNumber
-                        + " vid: " + vid + " pid: " + pid);
-                return null;
-            }
-            List<UsbDeviceSettings> settings = constructSettings(resultCursor);
-            return settings.get(0);
-        }
-    }
-
-    /**
-     * Saves or updates settings for USB device.
-     */
-    public void saveSettings(UsbDeviceSettings settings) {
-        try (SQLiteDatabase db = mDbHelper.getWritableDatabase()) {
-            long result = db.replace(
-                    TABLE_USB_SETTINGS,
-                    null,
-                    settingsToContentValues(settings));
-            if (result == -1) {
-                Log.e(TAG, "Failed to save settings: " + settings);
-            }
-        }
-    }
-
-    /**
-     * Delete settings for USB device.
-     */
-    public void deleteSettings(String serialNumber, int vid, int pid) {
-        try (SQLiteDatabase db = mDbHelper.getWritableDatabase()) {
-            int result = db.delete(
-                    TABLE_USB_SETTINGS,
-                    COLUMN_SERIAL + " = ? AND " + COLUMN_VID + " = ? AND " + COLUMN_PID
-                    + " = ?",
-                    new String[]{serialNumber, Integer.toString(vid), Integer.toString(pid)});
-            if (result == 0) {
-                Log.w(TAG, "No settings with serialNumber: " + serialNumber
-                        + " vid: " + vid + " pid: " + pid);
-            }
-            if (result > 1) {
-                Log.e(TAG, "Deleted multiple rows (" + result + ") for serialNumber: "
-                        + serialNumber + " vid: " + vid + " pid: " + pid);
-            }
-        }
-    }
-
-    /**
-     * Returns all saved settings.
-     */
-    public List<UsbDeviceSettings> getAllSettings() {
-        try (SQLiteDatabase db = mDbHelper.getReadableDatabase();
-             Cursor resultCursor = db.query(
-                     TABLE_USB_SETTINGS,
-                     null,
-                     null,
-                     null,
-                     null,
-                     null,
-                     null)) {
-            return constructSettings(resultCursor);
-        }
-    }
-
-    private List<UsbDeviceSettings> constructSettings(Cursor cursor) {
-        if (!cursor.isBeforeFirst()) {
-            throw new RuntimeException("Cursor is not reset to before first element");
-        }
-        int serialNumberColumnId = cursor.getColumnIndex(COLUMN_SERIAL);
-        int vidColumnId = cursor.getColumnIndex(COLUMN_VID);
-        int pidColumnId = cursor.getColumnIndex(COLUMN_PID);
-        int deviceNameColumnId = cursor.getColumnIndex(COLUMN_NAME);
-        int handlerColumnId = cursor.getColumnIndex(COLUMN_HANDLER);
-        int aoapColumnId = cursor.getColumnIndex(COLUMN_AOAP);
-        List<UsbDeviceSettings> results = new ArrayList<>(cursor.getCount());
-        while (cursor.moveToNext()) {
-            results.add(UsbDeviceSettings.constructSettings(
-                                cursor.getString(serialNumberColumnId),
-                                cursor.getInt(vidColumnId),
-                                cursor.getInt(pidColumnId),
-                                cursor.getString(deviceNameColumnId),
-                                ComponentName.unflattenFromString(
-                                        cursor.getString(handlerColumnId)),
-                                cursor.getInt(aoapColumnId) != 0));
-        }
-        return results;
-    }
-
-    /**
-     * Converts {@code UsbDeviceSettings} to {@code ContentValues}.
-     */
-    public ContentValues settingsToContentValues(UsbDeviceSettings settings) {
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(COLUMN_SERIAL, settings.getSerialNumber());
-        contentValues.put(COLUMN_VID, settings.getVid());
-        contentValues.put(COLUMN_PID, settings.getPid());
-        contentValues.put(COLUMN_NAME, settings.getDeviceName());
-        contentValues.put(COLUMN_HANDLER, settings.getHandler().flattenToShortString());
-        contentValues.put(COLUMN_AOAP, settings.getAoap() ? 1 : 0);
-        return contentValues;
-    }
-
-
-    private static class UsbSettingsDbHelper extends SQLiteOpenHelper {
-        private static final int DATABASE_VERSION = 2;
-        private static final String DATABASE_NAME = "usb_devices.db";
-
-        UsbSettingsDbHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-        }
-
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE_USB_SETTINGS + " ("
-                    + COLUMN_SERIAL + " TEXT,"
-                    + COLUMN_VID + " INTEGER,"
-                    + COLUMN_PID + " INTEGER,"
-                    + COLUMN_NAME + " TEXT, "
-                    + COLUMN_HANDLER + " TEXT,"
-                    + COLUMN_AOAP + " INTEGER,"
-                    + "PRIMARY KEY (" + COLUMN_SERIAL + ", " + COLUMN_VID + ", "
-                    + COLUMN_PID + "))");
-        }
-
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            if (oldVersion < 2) {
-                db.execSQL("ALTER TABLE " + TABLE_USB_SETTINGS + " ADD " + COLUMN_AOAP
-                        + " INTEGER");
-            }
-            // Do nothing at this point. Not required for v1 database.
-        }
-    }
-}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbUtil.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbUtil.java
deleted file mode 100644
index e27a86e..0000000
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/setting/usb/UsbUtil.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.car.kitchensink.setting.usb;
-
-import android.hardware.usb.UsbConstants;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbInterface;
-import android.hardware.usb.UsbManager;
-import android.text.TextUtils;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-
-/**
- * Util methods to work with USB devices.
- */
-class UsbUtil {
-    public static final String ADB_INTERFACE_NAME = "ADB Interface";
-    public static final String AOAP_INTERFACE_NAME = "Android Accessory Interface";
-    public static final String MTP_INTERFACE_NAME = "MTP";
-
-    public static LinkedList<UsbDevice> findAllPossibleAndroidDevices(UsbManager usbManager) {
-        HashMap<String, UsbDevice> devices = usbManager.getDeviceList();
-        LinkedList<UsbDevice> androidDevices = null;
-        for (UsbDevice device : devices.values()) {
-            if (possiblyAndroid(device)) {
-                if (androidDevices == null) {
-                    androidDevices = new LinkedList<>();
-                }
-                androidDevices.add(device);
-            }
-        }
-        return androidDevices;
-    }
-
-    public static boolean possiblyAndroid(UsbDevice device) {
-        int numInterfaces = device.getInterfaceCount();
-        for (int i = 0; i < numInterfaces; i++) {
-            UsbInterface usbInterface = device.getInterface(i);
-            String interfaceName = usbInterface.getName();
-            int interfaceClass = usbInterface.getInterfaceClass();
-            // more thorough check can be added, later
-            if (AOAP_INTERFACE_NAME.equals(interfaceName)
-                    || ADB_INTERFACE_NAME.equals(interfaceName)
-                    || MTP_INTERFACE_NAME.equals(interfaceName)
-                    || interfaceClass == UsbConstants.USB_CLASS_MASS_STORAGE) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public static boolean isTheSameDevice(UsbDevice l, UsbDevice r) {
-        if (TextUtils.equals(l.getManufacturerName(), r.getManufacturerName())
-                && TextUtils.equals(l.getProductName(), r.getProductName())
-                && TextUtils.equals(l.getSerialNumber(), r.getSerialNumber())) {
-            return true;
-        }
-        return false;
-    }
-
-    public static boolean isDevicesMatching(UsbDevice l, UsbDevice r) {
-        if (l.getVendorId() == r.getVendorId() && l.getProductId() == r.getProductId()
-                && TextUtils.equals(l.getSerialNumber(), r.getSerialNumber())) {
-            return true;
-        }
-        return false;
-    }
-
-    public static boolean isDeviceConnected(UsbManager usbManager, UsbDevice device) {
-        HashMap<String, UsbDevice> devices = usbManager.getDeviceList();
-        for (UsbDevice dev : devices.values()) {
-            if (isDevicesMatching(dev, device)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/tests/carservice_test/src/com/android/car/pm/CarPackageManagerServiceTest.java b/tests/carservice_test/src/com/android/car/pm/CarPackageManagerServiceTest.java
new file mode 100644
index 0000000..4983bb0
--- /dev/null
+++ b/tests/carservice_test/src/com/android/car/pm/CarPackageManagerServiceTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.pm;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.car.CarUxRestrictionsManagerService;
+import com.android.car.SystemActivityMonitoringService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests for {@link CarPackageManagerService}.
+ */
+@RunWith(AndroidJUnit4.class)
+public class CarPackageManagerServiceTest {
+    CarPackageManagerService mService;
+
+    private Context mContext;
+    @Mock
+    private CarUxRestrictionsManagerService mMockUxrService;
+    @Mock
+    private SystemActivityMonitoringService mMockSamService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = InstrumentationRegistry.getTargetContext();
+
+        mService = new CarPackageManagerService(mContext, mMockUxrService, mMockSamService);
+    }
+
+    @Test
+    public void testParseConfigList_SingleActivity() {
+        String config = "com.android.test/.TestActivity";
+        Map<String, Set<String>> map = new HashMap<>();
+
+        mService.parseConfigList(config, map);
+
+        assertTrue(map.get("com.android.test").size() == 1);
+        assertEquals(".TestActivity", map.get("com.android.test").iterator().next());
+    }
+
+    @Test
+    public void testParseConfigList_Package() {
+        String config = "com.android.test";
+        Map<String, Set<String>> map = new HashMap<>();
+
+        mService.parseConfigList(config, map);
+
+        assertTrue(map.get("com.android.test").size() == 0);
+    }
+
+    @Test
+    public void testParseConfigList_MultipleActivities() {
+        String config = "com.android.test/.TestActivity0,com.android.test/.TestActivity1";
+        Map<String, Set<String>> map = new HashMap<>();
+
+        mService.parseConfigList(config, map);
+
+        assertTrue(map.get("com.android.test").size() == 2);
+        assertTrue(map.get("com.android.test").contains(".TestActivity0"));
+        assertTrue(map.get("com.android.test").contains(".TestActivity1"));
+    }
+
+    @Test
+    public void testParseConfigList_PackageAndActivity() {
+        String config = "com.android.test/.TestActivity0,com.android.test";
+        Map<String, Set<String>> map = new HashMap<>();
+
+        mService.parseConfigList(config, map);
+
+        assertTrue(map.get("com.android.test").size() == 0);
+    }
+}
