Snap for 8426163 from fdacd6c8f39dbd4d8157919a436b7926376838ee to mainline-tzdata2-release

Change-Id: I391cc3b33c955bf7fdafcbe282de0a1a531881e1
diff --git a/androidx-car/Android.bp b/androidx-car/Android.bp
index ec9738f..8d1eee6 100644
--- a/androidx-car/Android.bp
+++ b/androidx-car/Android.bp
@@ -13,10 +13,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library_import {
     name: "androidx.car_car-resources-partially-dejetified-nodeps",
     aars: ["androidx-car-resources.aar"],
diff --git a/car-apps-common/Android.bp b/car-apps-common/Android.bp
index 9518bc0..ef94de8 100644
--- a/car-apps-common/Android.bp
+++ b/car-apps-common/Android.bp
@@ -14,10 +14,6 @@
 //
 
 // Unbundled target (should stay that way).
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-apps-common",
 
@@ -29,10 +25,8 @@
         enabled: false,
     },
 
-    libs: ["android.car-stubs",],
-
+    libs: ["android.car-stubs"],
     sdk_version: "system_current",
-    min_sdk_version: "28",
 
     static_libs: [
         "androidx.annotation_annotation",
diff --git a/car-apps-common/lint-baseline.xml b/car-apps-common/lint-baseline.xml
deleted file mode 100644
index 4567af1..0000000
--- a/car-apps-common/lint-baseline.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.content.res.Resources#getFloat`"
-        errorLine1="                    getResources().getFloat(R.dimen.background_bitmap_blur_percent));"
-        errorLine2="                                   ~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-apps-common/src/com/android/car/apps/common/BackgroundImageView.java"
-            line="64"
-            column="36"/>
-    </issue>
-
-</issues>
diff --git a/car-apps-common/res/color/primary_text_color.xml b/car-apps-common/res/color/primary_text_color.xml
deleted file mode 100644
index d310838..0000000
--- a/car-apps-common/res/color/primary_text_color.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<!-- Copy of ?android:attr/textColorPrimary (frameworks/base/res/res/color/text_color_primary.xml)
-     but with a ux restricted state. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:color="?android:attr/colorForeground"/>
-</selector>
diff --git a/car-apps-common/res/color/secondary_text_color.xml b/car-apps-common/res/color/secondary_text_color.xml
deleted file mode 100644
index 4c9f267..0000000
--- a/car-apps-common/res/color/secondary_text_color.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<!-- Copy of ?android:attr/textColorSecondary (frameworks/base/res/res/color/text_color_secondary.xml)
-     but with a ux restricted state. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:alpha="?android:attr/secondaryContentAlpha"
-          android:color="?android:attr/colorForeground"/>
-</selector>
diff --git a/car-apps-common/res/color/uxr_button_text_color_selector.xml b/car-apps-common/res/color/uxr_button_text_color_selector.xml
new file mode 100644
index 0000000..08b64e1
--- /dev/null
+++ b/car-apps-common/res/color/uxr_button_text_color_selector.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item app:state_ux_restricted="true" android:color="@color/uxr_button_text_disabled_color"/>
+    <item app:state_ux_restricted="false" android:color="@color/uxr_button_text_color"/>
+</selector>
diff --git a/car-apps-common/res/drawable/control_bar_button_background.xml b/car-apps-common/res/drawable/control_bar_button_background.xml
index 09bd38a..7009ecd 100644
--- a/car-apps-common/res/drawable/control_bar_button_background.xml
+++ b/car-apps-common/res/drawable/control_bar_button_background.xml
@@ -17,23 +17,10 @@
   ~
  -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:state_pressed="true">
-        <shape android:shape="oval">
-            <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/>
-            <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width"
-                    android:color="@color/car_ui_rotary_focus_pressed_stroke_color" />
-            <size android:width="@dimen/control_bar_button_background_radius"
-                  android:height="@dimen/control_bar_button_background_radius"/>
-        </shape>
-    </item>
     <item android:state_focused="true">
-        <shape android:shape="oval">
-            <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
-            <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
-                    android:color="@color/car_ui_rotary_focus_stroke_color" />
-            <size android:width="@dimen/control_bar_button_background_radius"
-                  android:height="@dimen/control_bar_button_background_radius"/>
-        </shape>
+        <ripple android:color="@color/car_ui_rotary_focus_color"
+                android:radius="@dimen/control_bar_button_background_radius">
+        </ripple>
     </item>
     <item>
         <ripple android:color="@color/control_bar_button_background_color"
diff --git a/car-apps-common/res/drawable/hero_button_background.xml b/car-apps-common/res/drawable/hero_button_background.xml
index e5aeec5..88177cd 100644
--- a/car-apps-common/res/drawable/hero_button_background.xml
+++ b/car-apps-common/res/drawable/hero_button_background.xml
@@ -13,31 +13,12 @@
 See the License for the specific language governing permissions and
 limitations under the License.
 -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:state_pressed="true">
-        <shape android:shape="rectangle">
-            <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/>
-            <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width"
-                    android:color="@color/car_ui_rotary_focus_pressed_stroke_color" />
-            <corners android:radius="@dimen/hero_button_corner_radius"/>
-        </shape>
-    </item>
-    <item android:state_focused="true">
-        <shape android:shape="rectangle">
-            <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
-            <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
-                    android:color="@color/car_ui_rotary_focus_stroke_color" />
-            <corners android:radius="@dimen/hero_button_corner_radius"/>
-        </shape>
-    </item>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:color="@color/car_card_ripple_background">
     <item>
-        <ripple android:color="@color/car_card_ripple_background">
-            <item>
-                <shape android:shape="rectangle">
-                    <solid android:color="@color/hero_button_background_color" />
-                    <corners android:radius="@dimen/hero_button_corner_radius"/>
-                </shape>
-            </item>
-        </ripple>
+        <shape android:shape="rectangle">
+            <solid android:color="@color/hero_button_background_color" />
+            <corners android:radius="@dimen/hero_button_corner_radius"/>
+        </shape>
     </item>
-</selector>
+</ripple>
diff --git a/car-apps-common/res/values-h600dp/dimens.xml b/car-apps-common/res/values-h600dp/dimens.xml
new file mode 100644
index 0000000..dcbea47
--- /dev/null
+++ b/car-apps-common/res/values-h600dp/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019, The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<resources>
+    <dimen name="control_bar_button_background_radius">48dp</dimen>
+    <dimen name="control_bar_button_size">96dp</dimen>
+    <dimen name="control_bar_button_padding">26dp</dimen>
+    <dimen name="minimized_control_bar_button_size">96dp</dimen>
+</resources>
diff --git a/car-apps-common/res/values-night/colors.xml b/car-apps-common/res/values-night/colors.xml
index a0a9c3a..6a2f4cf 100644
--- a/car-apps-common/res/values-night/colors.xml
+++ b/car-apps-common/res/values-night/colors.xml
@@ -21,6 +21,9 @@
     <color name="scrim_overlay_color">#D6000000</color>
     <color name="minimized_control_bar_background_color">#E00E1013</color>
 
+    <color name="primary_text_color">#E0FFFFFF</color>
+    <color name="secondary_text_color">#99FFFFFF</color>
+
     <color name="primary_app_icon_color">#E0FFFFFF</color>
     <color name="secondary_app_icon_color">#99FFFFFF</color>
 
diff --git a/car-apps-common/res/values-w1280dp/styles.xml b/car-apps-common/res/values-w1280dp/styles.xml
index 71af982..c810097 100644
--- a/car-apps-common/res/values-w1280dp/styles.xml
+++ b/car-apps-common/res/values-w1280dp/styles.xml
@@ -20,9 +20,4 @@
         <item name="android:layout_width">@dimen/control_bar_width</item>
         <item name="android:layout_height">wrap_content</item>
     </style>
-
-    <style name="MinimizedControlBar">
-        <item name="android:layout_width">@dimen/control_bar_width</item>
-        <item name="android:layout_height">@dimen/minimized_control_bar_height</item>
-    </style>
 </resources>
diff --git a/car-apps-common/res/values/colors.xml b/car-apps-common/res/values/colors.xml
index 45a0a18..6cf7ba7 100644
--- a/car-apps-common/res/values/colors.xml
+++ b/car-apps-common/res/values/colors.xml
@@ -38,7 +38,7 @@
     <color name="improper_image_refs_tint_color">#C8FF0000</color>
 
     <color name="control_bar_background_color">@android:color/transparent</color>
-    <color name="minimized_control_bar_background_color">#D60E1013</color>
+    <color name="minimized_control_bar_background_color">#F50E1013</color>
     <color name="scrim_overlay_color">#C7000000</color>
     <color name="app_bar_background_color">#E0000000</color>
     <color name="icon_tint">@color/car_grey_50</color>
@@ -50,6 +50,9 @@
     <color name="car_tab_unselected_color_dark">#80FFFFFF</color>
     <color name="car_tab_unselected_color_light">#90FFFFFF</color>
 
+    <color name="primary_text_color">#FFFFFFFF</color>
+    <color name="secondary_text_color">#B8FFFFFF</color>
+
     <color name="primary_app_icon_color">#FFFFFFFF</color>
     <color name="secondary_app_icon_color">#B8FFFFFF</color>
     <color name="car_card_ripple_background">#17000000</color>
@@ -57,12 +60,14 @@
     <color name="background_image_30p_black">#4D000000</color>
 
     <color name="uxr_button_image_color">@color/primary_app_icon_color</color>
+    <color name="uxr_button_text_color">@color/primary_text_color</color>
     <color name="uxr_button_image_disabled_color">#80FFFFFF</color>
+    <color name="uxr_button_text_disabled_color">#80FFFFFF</color>
 
     <color name="control_bar_button_background_color">#66ffffff</color>
 
     <color name="hero_button_background_color">@color/car_grey_868</color>
-    <color name="hero_button_text_color">@color/primary_text_color</color>
+    <color name="hero_button_text_color">@color/uxr_button_text_color_selector</color>
 
 
 
diff --git a/car-apps-common/res/values/dimens.xml b/car-apps-common/res/values/dimens.xml
index c87fa6b..85f6d90 100644
--- a/car-apps-common/res/values/dimens.xml
+++ b/car-apps-common/res/values/dimens.xml
@@ -26,12 +26,12 @@
     <dimen name="control_bar_height">128dp</dimen>
     <dimen name="control_bar_margin_x">@dimen/car_ui_margin</dimen>
     <dimen name="control_bar_margin_bottom">@dimen/car_ui_padding_2</dimen>
-    <dimen name="control_bar_button_size">104dp</dimen>
+    <dimen name="control_bar_button_size">76dp</dimen>
     <dimen name="control_bar_button_slot_height">@dimen/control_bar_height</dimen>
     <dimen name="control_bar_button_slot_width">@dimen/control_bar_button_size</dimen>
     <dimen name="control_bar_elevation">0dp</dimen>
-    <dimen name="control_bar_button_padding">30dp</dimen>
-    <dimen name="control_bar_button_background_radius">52dp</dimen>
+    <dimen name="control_bar_button_padding">16dp</dimen>
+    <dimen name="control_bar_button_background_radius">38dp</dimen>
 
     <!-- Overflow button in control Bar -->
     <dimen name="overflow_button_icon_size">44dp</dimen>
@@ -46,7 +46,7 @@
     <dimen name="minimized_control_bar_edge_padding">@dimen/car_ui_padding_4</dimen>
     <dimen name="minimized_control_bar_text_padding">@dimen/car_ui_padding_3</dimen>
     <dimen name="minimized_control_bar_button_padding">@dimen/car_ui_padding_5</dimen>
-    <dimen name="minimized_control_bar_button_size">104dp</dimen>
+    <dimen name="minimized_control_bar_button_size">76dp</dimen>
 
     <!-- Tabs -->
     <dimen name="car_tab_width">135dp</dimen>
diff --git a/car-apps-common/src/com/android/car/apps/common/ControlBar.java b/car-apps-common/src/com/android/car/apps/common/ControlBar.java
index 94fb206..5d6d76c 100644
--- a/car-apps-common/src/com/android/car/apps/common/ControlBar.java
+++ b/car-apps-common/src/com/android/car/apps/common/ControlBar.java
@@ -16,8 +16,6 @@
 
 package com.android.car.apps.common;
 
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -31,8 +29,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
 import android.widget.FrameLayout;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
@@ -45,8 +41,6 @@
 import androidx.core.util.Preconditions;
 import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
 
-import com.android.car.apps.common.util.ViewUtils;
-
 import java.util.Locale;
 
 
@@ -94,27 +88,12 @@
     private boolean mExpandEnabled;
     // Callback for the expand/collapse button
     private ExpandCollapseCallback mExpandCollapseCallback;
-    // The root of the transition animation.
-    private ViewGroup mTransitionRoot;
-    // Whether this control bar has focus.
-    private boolean mHasFocus;
 
     // Default number of columns, if unspecified
     private static final int DEFAULT_COLUMNS = 3;
     // Weight for the spacers used between buttons
     private static final float SPACERS_WEIGHT = 1f;
 
-    private final OnGlobalFocusChangeListener mFocusChangeListener =
-            (oldFocus, newFocus) -> {
-                // Collapse the control bar when it is expanded and loses focus.
-                boolean hasFocus = hasFocus();
-                if (mHasFocus && !hasFocus && mIsExpanded) {
-                    onExpandCollapse();
-                }
-                mHasFocus = hasFocus;
-            };
-
-
     public ControlBar(Context context) {
         super(context);
         init(context, null, 0, 0);
@@ -186,18 +165,6 @@
     }
 
     @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        getViewTreeObserver().addOnGlobalFocusChangeListener(mFocusChangeListener);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        getViewTreeObserver().removeOnGlobalFocusChangeListener(mFocusChangeListener);
-        super.onDetachedFromWindow();
-    }
-
-    @Override
     public void setView(@Nullable View view, @SlotPosition int slotPosition) {
         if (view != null) {
             mFixedViews.put(slotPosition, view);
@@ -291,7 +258,7 @@
                 viewToUse = mViews[viewsIndex];
                 viewsIndex++;
             }
-            ViewUtils.setView(viewToUse, mSlots[i]);
+            setView(viewToUse, mSlots[i]);
             if (viewToUse != null) {
                 lastUsedIndex = i;
             }
@@ -323,6 +290,31 @@
         }
     }
 
+    private void setView(@Nullable View view, FrameLayout container) {
+        if (view != null) {
+            // Don't set the view if it stays the same.
+            if (container.getChildCount() == 1 && container.getChildAt(0) == view) {
+                return;
+            }
+
+            ViewGroup parent = (ViewGroup) view.getParent();
+            // As we are removing views (on BT disconnect, for example), some items will be
+            // shifting from expanded to collapsed (like Queue item) - remove those from the
+            // group before adding to the new slot
+            if (view.getParent() != null) {
+                parent.removeView(view);
+            }
+            container.removeAllViews();
+            container.addView(view);
+            container.setVisibility(VISIBLE);
+        } else {
+            if (container.getChildCount() != 0) {
+                container.removeAllViews();
+            }
+            container.setVisibility(INVISIBLE);
+        }
+    }
+
     private void onExpandCollapse() {
         mIsExpanded = !mIsExpanded;
         if (mExpandCollapseView != null) {
@@ -341,34 +333,12 @@
                 .addTransition(new Fade())
                 .setDuration(animationDuration)
                 .setInterpolator(new FastOutSlowInInterpolator());
-        maybeInitTransitionRoot();
-        TransitionManager.beginDelayedTransition(mTransitionRoot, set);
+        TransitionManager.beginDelayedTransition(this, set);
         for (int i = 0; i < mNumExtraRowsInUse; i++) {
             mRowsContainer.getChildAt(i).setVisibility(mIsExpanded ? View.VISIBLE : View.GONE);
         }
     }
 
-    private void maybeInitTransitionRoot() {
-        if (mTransitionRoot != null) {
-            return;
-        }
-        // During the control bar expanding/collapsing animation, the height of the control bar
-        // changes gradually. If the height of its ancestor is WRAP_CONTENT, the height of its
-        // ancestor will not change during the animation, causing janky animation. To fix it the
-        // animation should be played on the highest ancestor that wraps the control bar vertically.
-        mTransitionRoot = this;
-        ViewParent viewParent = getParent();
-        while (viewParent != null && viewParent instanceof ViewGroup) {
-            ViewGroup parent = (ViewGroup) viewParent;
-            if (parent.getLayoutParams().height == WRAP_CONTENT) {
-                mTransitionRoot = parent;
-                viewParent = parent.getParent();
-            } else {
-                break;
-            }
-        }
-    }
-
     /**
      * Returns the view assigned to the given row and column, after layout.
      *
diff --git a/car-apps-common/src/com/android/car/apps/common/LetterTileDrawable.java b/car-apps-common/src/com/android/car/apps/common/LetterTileDrawable.java
index e877e2b..3a698b0 100644
--- a/car-apps-common/src/com/android/car/apps/common/LetterTileDrawable.java
+++ b/car-apps-common/src/com/android/car/apps/common/LetterTileDrawable.java
@@ -45,7 +45,8 @@
     private static Drawable sDefaultVoicemailAvatar;
 
     /** Reusable components to avoid new allocations */
-    private static final Paint sTextPaint = new Paint();
+    private static final Paint sPaint = new Paint();
+    private static final Rect sRect = new Rect();
 
     /** Contact type constants */
     public static final int TYPE_PERSON = 1;
@@ -107,12 +108,11 @@
             sDefaultPersonAvatar = res.getDrawable(R.drawable.ic_person, null /* theme */);
             sDefaultBusinessAvatar = res.getDrawable(R.drawable.ic_person, null /* theme */);
             sDefaultVoicemailAvatar = res.getDrawable(R.drawable.ic_person, null /* theme */);
-            sTextPaint.setTypeface(
+            sPaint.setTypeface(
                     Typeface.create(res.getString(R.string.config_letter_tile_font_family),
                             res.getInteger(R.integer.config_letter_tile_text_style)));
-            sTextPaint.setTextAlign(Align.CENTER);
-            sTextPaint.setAntiAlias(true);
-            sTextPaint.setColor(sTileFontColor);
+            sPaint.setTextAlign(Align.CENTER);
+            sPaint.setAntiAlias(true);
         }
 
         setContactDetails(letters, identifier);
@@ -152,26 +152,31 @@
     }
 
     private void drawLetterTile(final Canvas canvas) {
+        // Draw background color.
+        sPaint.setColor(mColor);
+
+        sPaint.setAlpha(mPaint.getAlpha());
         final Rect bounds = getBounds();
         final int minDimension = Math.min(bounds.width(), bounds.height());
 
-        // Draw background color.
-        mPaint.setColor(mColor);
         if (mIsCircle) {
-            canvas.drawCircle(bounds.centerX(), bounds.centerY(), minDimension / 2, mPaint);
+            canvas.drawCircle(bounds.centerX(), bounds.centerY(), minDimension / 2, sPaint);
         } else {
-            canvas.drawRect(bounds, mPaint);
+            canvas.drawRect(bounds, sPaint);
         }
 
         if (!TextUtils.isEmpty(mLetters)) {
             // Scale text by canvas bounds and user selected scaling factor
-            sTextPaint.setTextSize(mScale * sLetterToTileRatio * minDimension);
-            Paint.FontMetrics fontMetrics = sTextPaint.getFontMetrics();
+            sPaint.setTextSize(mScale * sLetterToTileRatio * minDimension);
+            //sPaint.setTextSize(sTileLetterFontSize);
+            sPaint.getTextBounds(mLetters, 0, mLetters.length(), sRect);
+            sPaint.setColor(sTileFontColor);
 
             // Draw the letter in the canvas, vertically shifted up or down by the user-defined
             // offset
-            canvas.drawText(mLetters, bounds.centerX(), bounds.centerY() + mOffset * bounds.height()
-                    - (fontMetrics.ascent + fontMetrics.descent) / 2f, sTextPaint);
+            canvas.drawText(mLetters, 0, mLetters.length(), bounds.centerX(),
+                    bounds.centerY() + mOffset * bounds.height() + sRect.height() / 2,
+                    sPaint);
         } else {
             // Draw the default image if there is no letter/digit to be drawn
             final Drawable drawable = getDrawablepForContactType(mContactType);
diff --git a/car-apps-common/src/com/android/car/apps/common/MinimizedControlBar.java b/car-apps-common/src/com/android/car/apps/common/MinimizedControlBar.java
index 2eeb1b8..7158f44 100644
--- a/car-apps-common/src/com/android/car/apps/common/MinimizedControlBar.java
+++ b/car-apps-common/src/com/android/car/apps/common/MinimizedControlBar.java
@@ -21,6 +21,7 @@
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.ImageButton;
 import android.widget.ImageView;
@@ -29,8 +30,6 @@
 import androidx.annotation.Nullable;
 import androidx.constraintlayout.widget.ConstraintLayout;
 
-import com.android.car.apps.common.util.ViewUtils;
-
 /**
  * This is a compact CarControlBar that provides a fixed number of controls (with no overflow),
  * along with some metadata (title, subtitle, icon)
@@ -123,7 +122,25 @@
                 viewToUse = mViews[viewIndex];
                 viewIndex++;
             }
-            ViewUtils.setView(viewToUse, mSlots[CarControlBar.getSlotIndex(i, NUM_COLUMNS)]);
+            setView(viewToUse, mSlots[CarControlBar.getSlotIndex(i, NUM_COLUMNS)]);
         }
     }
+
+    private void setView(@Nullable View view, FrameLayout container) {
+        container.removeAllViews();
+        if (view != null) {
+            ViewGroup parent = (ViewGroup) view.getParent();
+            // As we are removing views (on BT disconnect, for example), some items will be
+            // shifting from expanded to collapsed - remove those from the group before adding to
+            // the new slot
+            if (view.getParent() != null) {
+                parent.removeView(view);
+            }
+            container.addView(view);
+            container.setVisibility(VISIBLE);
+        } else {
+            container.setVisibility(INVISIBLE);
+        }
+    }
+
 }
diff --git a/car-apps-common/src/com/android/car/apps/common/util/ViewUtils.java b/car-apps-common/src/com/android/car/apps/common/util/ViewUtils.java
index 0e41a6d..e067573 100644
--- a/car-apps-common/src/com/android/car/apps/common/util/ViewUtils.java
+++ b/car-apps-common/src/com/android/car/apps/common/util/ViewUtils.java
@@ -16,16 +16,11 @@
 
 package com.android.car.apps.common.util;
 
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -39,34 +34,13 @@
  * Utility methods to operate over views.
  */
 public class ViewUtils {
-
-    /** Listener to take action when animations are done. */
-    public interface ViewAnimEndListener {
-        /**
-         * Called when the animation created by {@link #hideViewAnimated} or
-         * {@link #showHideViewAnimated} has reached its end.
-         */
-        void onAnimationEnd(View view);
-    }
-
-    /** Shows the view if show is set to true otherwise hides it. */
-    public static void showHideViewAnimated(boolean show, @NonNull View view, int duration,
-            @Nullable ViewAnimEndListener listener) {
-        if (show) {
-            showViewAnimated(view, duration, listener);
-        } else {
-            hideViewAnimated(view, duration, listener);
-        }
-    }
-
     /**
      * Hides a view using a fade-out animation
      *
      * @param view     {@link View} to be hidden
      * @param duration animation duration in milliseconds.
      */
-    public static void hideViewAnimated(@NonNull View view, int duration,
-            @Nullable ViewAnimEndListener listener) {
+    public static void hideViewAnimated(@NonNull View view, int duration) {
         // Cancel existing animation to avoid race condition
         // if show and hide are called at the same time
         view.animate().cancel();
@@ -77,26 +51,12 @@
             return;
         }
 
-        Animator.AnimatorListener hider = hideViewAfterAnimation(view);
         view.animate()
                 .setDuration(duration)
-                .setListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        hider.onAnimationEnd(animation);
-                        if (listener != null) {
-                            listener.onAnimationEnd(view);
-                        }
-                    }
-                })
+                .setListener(hideViewAfterAnimation(view))
                 .alpha(0f);
     }
 
-    /** Hides a view using a fade-out animation. */
-    public static void hideViewAnimated(@NonNull View view, int duration) {
-        hideViewAnimated(view, duration, null);
-    }
-
     /** Returns an AnimatorListener that hides the view at the end. */
     public static Animator.AnimatorListener hideViewAfterAnimation(View view) {
         return new AnimatorListenerAdapter() {
@@ -114,26 +74,20 @@
      * @param duration animation duration in milliseconds.
      */
     public static void hideViewsAnimated(@Nullable List<View> views, int duration) {
-        if (views == null) {
-            return;
-        }
         for (View view : views) {
             if (view != null) {
-                hideViewAnimated(view, duration, null);
+                hideViewAnimated(view, duration);
             }
         }
     }
 
     /**
-     * Shows a view using a fade-in animation. The view's alpha value isn't changed so that
-     * animating an already visible won't have a visible effect. Therefore, <b>views initialized as
-     * hidden must have their alpha set to 0 prior to calling this method</b>.
+     * Shows a view using a fade-in animation
      *
      * @param view     {@link View} to be shown
      * @param duration animation duration in milliseconds.
      */
-    public static void showViewAnimated(@NonNull View view, int duration,
-            @Nullable ViewAnimEndListener listener) {
+    public static void showViewAnimated(@NonNull View view, int duration) {
         // Cancel existing animation to avoid race condition
         // if show and hide are called at the same time
         view.animate().cancel();
@@ -146,23 +100,12 @@
                 .setListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationStart(Animator animation) {
-                        view.setVisibility(VISIBLE);
-                    }
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        if (listener != null) {
-                            listener.onAnimationEnd(view);
-                        }
+                        view.setVisibility(View.VISIBLE);
                     }
                 })
                 .alpha(1f);
     }
 
-    /** Shows a view using a fade-in animation. */
-    public static void showViewAnimated(@NonNull View view, int duration) {
-        showViewAnimated(view, duration, null);
-    }
-
     /**
      * Shows views using a fade-out animation
      *
@@ -172,7 +115,7 @@
     public static void showViewsAnimated(@Nullable List<View> views, int duration) {
         for (View view : views) {
             if (view != null) {
-                showViewAnimated(view, duration, null);
+                showViewAnimated(view, duration);
             }
         }
     }
@@ -180,7 +123,7 @@
     /** Sets the visibility of the (optional) view to {@link View#VISIBLE} or {@link View#GONE}. */
     public static void setVisible(@Nullable View view, boolean visible) {
         if (view != null) {
-            view.setVisibility(visible ? VISIBLE : View.GONE);
+            view.setVisibility(visible ? View.VISIBLE : View.GONE);
         }
     }
 
@@ -196,7 +139,7 @@
      */
     public static void setInvisible(@Nullable View view, boolean invisible) {
         if (view != null) {
-            view.setVisibility(invisible ? INVISIBLE : VISIBLE);
+            view.setVisibility(invisible ? View.INVISIBLE : View.VISIBLE);
         }
     }
 
@@ -258,38 +201,4 @@
         viewIds.recycle();
         return views;
     }
-
-    /** Removes the view from its parent (if it has one). */
-    public static void removeFromParent(@Nullable View view) {
-        if (view != null) {
-            ViewGroup parent = (ViewGroup) view.getParent();
-            if (parent != null) {
-                parent.removeView(view);
-            }
-        }
-    }
-
-    /** Adds the {@code view} into the {@code container}. */
-    public static void setView(@Nullable View view, FrameLayout container) {
-        if (view != null) {
-            // Don't set the view if it stays the same.
-            if (container.getChildCount() == 1 && container.getChildAt(0) == view) {
-                return;
-            }
-
-            // As we are removing views (on BT disconnect, for example), some items will be
-            // shifting from expanded to collapsed (like Queue item) - remove those from the
-            // group before adding to the new slot
-            removeFromParent(view);
-
-            container.removeAllViews();
-            container.addView(view);
-            container.setVisibility(VISIBLE);
-        } else {
-            if (container.getChildCount() != 0) {
-                container.removeAllViews();
-            }
-            container.setVisibility(INVISIBLE);
-        }
-    }
 }
diff --git a/car-arch-common/Android.bp b/car-arch-common/Android.bp
index 06e7923..6272d40 100644
--- a/car-arch-common/Android.bp
+++ b/car-arch-common/Android.bp
@@ -16,10 +16,6 @@
 
 // This is an unbundled target, sdk_version must be "system_current". If the car library is ever
 // needed, android."car-stubs" or "android.car-system-stubs" must be used.
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-arch-common",
 
diff --git a/car-arch-common/src/com/android/car/arch/common/FutureData.java b/car-arch-common/src/com/android/car/arch/common/FutureData.java
index 8336736..d2ef248 100644
--- a/car-arch-common/src/com/android/car/arch/common/FutureData.java
+++ b/car-arch-common/src/com/android/car/arch/common/FutureData.java
@@ -16,59 +16,19 @@
 
 package com.android.car.arch.common;
 
-import androidx.annotation.Nullable;
-
 /**
- * Class that holds data with a loading state, and optionally the previous version of the data.
+ * Class that holds data with a loading state.
  *
  * @param <T> the output data type
  */
 public class FutureData<T> {
 
     private final boolean mIsLoading;
-    private final T mPastData;
     private final T mData;
 
-    /** Returns an instance with a null data value and loading set to true. */
-    public static <T> FutureData<T> newLoadingData() {
-        return new FutureData<>(true, null);
-    }
-
-    /** Returns a loaded instance with the given data value. */
-    public static <T> FutureData<T> newLoadedData(T data) {
-        return new FutureData<>(false, data);
-    }
-
-    /** Returns a loaded instance with the given previous and current data values. */
-    public static <T> FutureData<T> newLoadedData(T oldData, T newData) {
-        return new FutureData<>(false, oldData, newData);
-    }
-
-    /** Returns the data contained in the future or null (when loading or no future). */
-    @Nullable
-    public static <T> T getData(@Nullable FutureData<T> future) {
-        return (future != null) ? future.getData() : null;
-    }
-
-    /** Returns the past data contained in the future or null (when loading or no future). */
-    @Nullable
-    public static <T> T getPastData(@Nullable FutureData<T> future) {
-        return (future != null) ? future.getPastData() : null;
-    }
-
-    /**
-     * This should become private.
-     * @deprecated Use {@link #newLoadingData}, and {@link #newLoadedData} instead.
-     */
-    @Deprecated
     public FutureData(boolean isLoading, T data) {
-        this(isLoading, null, data);
-    }
-
-    private FutureData(boolean isLoading, T oldData, T newData) {
         mIsLoading = isLoading;
-        mPastData = oldData;
-        mData = newData;
+        mData = data;
     }
 
     /**
@@ -84,9 +44,4 @@
     public T getData() {
         return mData;
     }
-
-    /** If done loading, returns the previous version of the data, otherwise null. */
-    public T getPastData() {
-        return mPastData;
-    }
 }
diff --git a/car-arch-common/tests/robotests/Android.bp b/car-arch-common/tests/robotests/Android.bp
index ff4543c..dbe65bf 100644
--- a/car-arch-common/tests/robotests/Android.bp
+++ b/car-arch-common/tests/robotests/Android.bp
@@ -17,10 +17,6 @@
 //###########################################################
 // CarArchCommon app just for Robolectric test target.     #
 //###########################################################
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_app {
     name: "CarArchCommon",
 
diff --git a/car-arch-common/tests/robotests/src/com/android/car/arch/common/LiveDataFunctionsTest.java b/car-arch-common/tests/robotests/src/com/android/car/arch/common/LiveDataFunctionsTest.java
index 2ab8943..cdcfcb0 100644
--- a/car-arch-common/tests/robotests/src/com/android/car/arch/common/LiveDataFunctionsTest.java
+++ b/car-arch-common/tests/robotests/src/com/android/car/arch/common/LiveDataFunctionsTest.java
@@ -289,7 +289,7 @@
         predicate.setValue(true);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(valueObject);
+        assertThat(observer.getObservedValue()).isSameAs(valueObject);
         observer.reset();
 
         predicate.setValue(null);
@@ -318,13 +318,13 @@
         value.setValue(firstObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(firstObject);
+        assertThat(observer.getObservedValue()).isSameAs(firstObject);
         observer.reset();
 
         value.setValue(new Object());
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isNotSameInstanceAs(firstObject);
+        assertThat(observer.getObservedValue()).isNotSameAs(firstObject);
     }
 
     @Test
@@ -404,13 +404,13 @@
         predicate.setValue(false);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(falseObject);
+        assertThat(observer.getObservedValue()).isSameAs(falseObject);
         observer.reset();
 
         predicate.setValue(true);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(trueObject);
+        assertThat(observer.getObservedValue()).isSameAs(trueObject);
         observer.reset();
 
         predicate.setValue(null);
@@ -444,13 +444,13 @@
         trueObjectData.setValue(trueObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(trueObject);
+        assertThat(observer.getObservedValue()).isSameAs(trueObject);
         observer.reset();
 
         trueObjectData.setValue(new Object());
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isNotSameInstanceAs(trueObject);
+        assertThat(observer.getObservedValue()).isNotSameAs(trueObject);
     }
 
     @Test
@@ -512,13 +512,13 @@
         predicate.setValue(false);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(falseObject);
+        assertThat(observer.getObservedValue()).isSameAs(falseObject);
         observer.reset();
 
         predicate.setValue(true);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(trueObject);
+        assertThat(observer.getObservedValue()).isSameAs(trueObject);
         observer.reset();
 
         predicate.setValue(null);
@@ -566,25 +566,25 @@
         data.observe(mLifecycleOwner, observer);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(fallbackObject);
+        assertThat(observer.getObservedValue()).isSameAs(fallbackObject);
         observer.reset();
 
         sourceData.setValue(firstSourceObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(firstSourceObject);
+        assertThat(observer.getObservedValue()).isSameAs(firstSourceObject);
         observer.reset();
 
         sourceData.setValue(secondSourceObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(secondSourceObject);
+        assertThat(observer.getObservedValue()).isSameAs(secondSourceObject);
         observer.reset();
 
         sourceData.setValue(null);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(fallbackObject);
+        assertThat(observer.getObservedValue()).isSameAs(fallbackObject);
         observer.reset();
     }
 
@@ -608,19 +608,19 @@
         fallbackData.setValue(firstFallbackObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(firstFallbackObject);
+        assertThat(observer.getObservedValue()).isSameAs(firstFallbackObject);
         observer.reset();
 
         fallbackData.setValue(secondFallbackObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(secondFallbackObject);
+        assertThat(observer.getObservedValue()).isSameAs(secondFallbackObject);
         observer.reset();
 
         fallbackData.setValue(null);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(null);
+        assertThat(observer.getObservedValue()).isSameAs(null);
         observer.reset();
     }
 
@@ -685,25 +685,25 @@
         data.observe(mLifecycleOwner, observer);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(fallbackObject);
+        assertThat(observer.getObservedValue()).isSameAs(fallbackObject);
         observer.reset();
 
         sourceData.setValue(firstSourceObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(firstSourceObject);
+        assertThat(observer.getObservedValue()).isSameAs(firstSourceObject);
         observer.reset();
 
         sourceData.setValue(secondSourceObject);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(secondSourceObject);
+        assertThat(observer.getObservedValue()).isSameAs(secondSourceObject);
         observer.reset();
 
         sourceData.setValue(null);
 
         assertThat(observer.hasBeenNotified()).isTrue();
-        assertThat(observer.getObservedValue()).isSameInstanceAs(fallbackObject);
+        assertThat(observer.getObservedValue()).isSameAs(fallbackObject);
         observer.reset();
     }
 
@@ -731,8 +731,8 @@
                                 }));
 
         assertThat(notified[0]).isTrue();
-        assertThat(observedValues[0]).isSameInstanceAs(first);
-        assertThat(observedValues[1]).isSameInstanceAs(second);
+        assertThat(observedValues[0]).isSameAs(first);
+        assertThat(observedValues[1]).isSameAs(second);
     }
 
     @Test
@@ -771,16 +771,16 @@
 
         Pair<Object, Object> observedValue = observer.getObservedValue();
         assertThat(observedValue).isNotNull();
-        assertThat(observedValue.first).isSameInstanceAs(first);
-        assertThat(observedValue.second).isSameInstanceAs(second);
+        assertThat(observedValue.first).isSameAs(first);
+        assertThat(observedValue.second).isSameAs(second);
 
         Object third = new Object();
         firstData.setValue(third);
 
         observedValue = observer.getObservedValue();
         assertThat(observedValue).isNotNull();
-        assertThat(observedValue.first).isSameInstanceAs(third);
-        assertThat(observedValue.second).isSameInstanceAs(second);
+        assertThat(observedValue.first).isSameAs(third);
+        assertThat(observedValue.second).isSameAs(second);
     }
 
     private static class IfThenElseDataParams<T> {
diff --git a/car-assist-client-lib/Android.bp b/car-assist-client-lib/Android.bp
index 465254e..8fe7b32 100644
--- a/car-assist-client-lib/Android.bp
+++ b/car-assist-client-lib/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-assist-client-lib",
 
diff --git a/car-assist-client-lib/OWNERS b/car-assist-client-lib/OWNERS
index 185f5c6..0c113c4 100644
--- a/car-assist-client-lib/OWNERS
+++ b/car-assist-client-lib/OWNERS
@@ -1,3 +1,3 @@
 # People who can approve changes for submission.
 igorr@google.com
-uokoye@google.com
+jiayuzhou@google.com
diff --git a/car-assist-client-lib/res/values-ml/strings.xml b/car-assist-client-lib/res/values-ml/strings.xml
index 641ae11..71bc6ad 100644
--- a/car-assist-client-lib/res/values-ml/strings.xml
+++ b/car-assist-client-lib/res/values-ml/strings.xml
@@ -16,6 +16,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="assist_action_failed_toast" msgid="3250146468076483714">"Assistant-ൽ നിന്ന് പ്രവർത്തനം അഭ്യർത്ഥിക്കാനായില്ല!"</string>
+    <string name="assist_action_failed_toast" msgid="3250146468076483714">"അസിസ്‌റ്റന്റിൽ നിന്ന് പ്രവർത്തനം അഭ്യർത്ഥിക്കാനായില്ല!"</string>
     <string name="says" msgid="8575666015622916107">"പറയുന്നു"</string>
 </resources>
diff --git a/car-assist-client-lib/res/values-te/strings.xml b/car-assist-client-lib/res/values-te/strings.xml
index 4d0ad26..222ddf4 100644
--- a/car-assist-client-lib/res/values-te/strings.xml
+++ b/car-assist-client-lib/res/values-te/strings.xml
@@ -16,6 +16,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="assist_action_failed_toast" msgid="3250146468076483714">"ఈ చర్యను Assistant నుండి రిక్వెస్ట్ చేయడం సాధ్యపడలేదు!"</string>
+    <string name="assist_action_failed_toast" msgid="3250146468076483714">"అసిస్టెంట్ నుండి చర్యను అభ్యర్థించడం సాధ్యపడలేదు!"</string>
     <string name="says" msgid="8575666015622916107">"ఇలా చెప్పారు"</string>
 </resources>
diff --git a/car-assist-client-lib/src/com/android/car/assist/client/CarAssistUtils.java b/car-assist-client-lib/src/com/android/car/assist/client/CarAssistUtils.java
index de2871a..1f9d915 100644
--- a/car-assist-client-lib/src/com/android/car/assist/client/CarAssistUtils.java
+++ b/car-assist-client-lib/src/com/android/car/assist/client/CarAssistUtils.java
@@ -33,7 +33,6 @@
 
 import androidx.annotation.StringDef;
 import androidx.core.app.NotificationCompat;
-import androidx.core.app.NotificationCompat.Action;
 
 import com.android.car.assist.CarVoiceInteractionSession;
 import com.android.internal.app.AssistUtils;
@@ -47,6 +46,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * Util class providing helper methods to interact with the current active voice service,
@@ -69,7 +69,6 @@
 
     private final Context mContext;
     private final AssistUtils mAssistUtils;
-    @Nullable
     private final FallbackAssistant mFallbackAssistant;
     private final String mErrorMessage;
     private final boolean mIsFallbackAssistantEnabled;
@@ -107,11 +106,10 @@
     public CarAssistUtils(Context context) {
         mContext = context;
         mAssistUtils = new AssistUtils(context);
+        mFallbackAssistant = new FallbackAssistant(context);
         mErrorMessage = context.getString(R.string.assist_action_failed_toast);
-
         mIsFallbackAssistantEnabled =
                 context.getResources().getBoolean(R.bool.config_enableFallbackAssistant);
-        mFallbackAssistant = mIsFallbackAssistantEnabled ? new FallbackAssistant(context) : null;
     }
 
     /**
@@ -122,13 +120,6 @@
     }
 
     /**
-     * Returns {@code true} if the fallback assistant is enabled.
-     */
-    public boolean isFallbackAssistantEnabled() {
-        return mIsFallbackAssistantEnabled;
-    }
-
-    /**
      * Returns true if the current active assistant has notification listener permissions.
      */
     public boolean assistantIsNotificationListener() {
@@ -170,12 +161,11 @@
      * @return true if the notification is a car-compatible messaging notification.
      */
     public static boolean isCarCompatibleMessagingNotification(StatusBarNotification sbn) {
-        Notification notification = sbn.getNotification();
-        return hasMessagingStyle(notification)
-                && hasRequiredAssistantCallbacks(notification)
-                && ((getReplyAction(notification) == null)
-                    || replyCallbackHasRemoteInput(notification))
-                && assistantCallbacksShowNoUi(notification);
+        return hasMessagingStyle(sbn)
+                && hasRequiredAssistantCallbacks(sbn)
+                && ((getReplyAction(sbn.getNotification()) == null)
+                    || replyCallbackHasRemoteInput(sbn))
+                && assistantCallbacksShowNoUi(sbn);
     }
 
     /** Returns true if the semantic action provided can be supported. */
@@ -190,9 +180,9 @@
      * {@link Notification.MessagingStyle} (or an instance of
      * {@link NotificationCompat.MessagingStyle} if {@link NotificationCompat} was used).
      */
-    private static boolean hasMessagingStyle(Notification notification) {
+    private static boolean hasMessagingStyle(StatusBarNotification sbn) {
         return NotificationCompat.MessagingStyle
-                .extractMessagingStyleFromNotification(notification) != null;
+                .extractMessagingStyleFromNotification(sbn.getNotification()) != null;
     }
 
     /**
@@ -200,8 +190,8 @@
      * a car-compatible messaging notification. The callbacks must be unambiguous, therefore false
      * is returned if multiple callbacks exist for any semantic action that is supported.
      */
-    private static boolean hasRequiredAssistantCallbacks(Notification notification) {
-        List<Integer> semanticActionList = getAllActions(notification)
+    private static boolean hasRequiredAssistantCallbacks(StatusBarNotification sbn) {
+        List<Integer> semanticActionList = getAllActions(sbn.getNotification())
                 .stream()
                 .map(NotificationCompat.Action::getSemanticAction)
                 .filter(REQUIRED_SEMANTIC_ACTIONS::contains)
@@ -211,13 +201,11 @@
                 && semanticActionSet.containsAll(REQUIRED_SEMANTIC_ACTIONS);
     }
 
-    /** Retrieves visible and invisible {@link Action}s from the {@link Notification}. */
-    public static List<Action> getAllActions(Notification notification) {
-        List<Action> actions = new ArrayList<>(
-                NotificationCompat.getInvisibleActions(notification)
-        );
-        int visibleActionCount = NotificationCompat.getActionCount(notification);
-        for (int i = 0; i < visibleActionCount; i++) {
+    /** Retrieves all visible and invisible {@link Action}s from the {@link #notification}. */
+    public static List<NotificationCompat.Action> getAllActions(Notification notification) {
+        List<NotificationCompat.Action> actions = new ArrayList<>();
+        actions.addAll(NotificationCompat.getInvisibleActions(notification));
+        for (int i = 0; i < NotificationCompat.getActionCount(notification); i++) {
             actions.add(NotificationCompat.getAction(notification, i));
         }
         return actions;
@@ -240,20 +228,6 @@
 
     /**
      * Retrieves the {@link NotificationCompat.Action} containing the
-     * {@link NotificationCompat.Action#SEMANTIC_ACTION_MUTE semantic action.
-     */
-    @Nullable
-    public static NotificationCompat.Action getMuteAction(Notification notification) {
-        for (NotificationCompat.Action action : getAllActions(notification)) {
-            if (action.getSemanticAction() == Action.SEMANTIC_ACTION_MUTE) {
-                return action;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Retrieves the {@link NotificationCompat.Action} containing the
      * {@link NotificationCompat.Action#SEMANTIC_ACTION_REPLY} semantic action.
      */
     @Nullable
@@ -272,19 +246,19 @@
      * <p/>
      * Precondition: There exists only one reply callback.
      */
-    private static boolean replyCallbackHasRemoteInput(Notification notification) {
-        return getAllActions(notification)
-                .stream()
+    private static boolean replyCallbackHasRemoteInput(StatusBarNotification sbn) {
+        return Arrays.stream(sbn.getNotification().actions)
                 .filter(action -> action.getSemanticAction() == SEMANTIC_ACTION_REPLY)
-                .map(NotificationCompat.Action::getRemoteInputs)
+                .map(Notification.Action::getRemoteInputs)
                 .filter(Objects::nonNull)
                 .anyMatch(remoteInputs -> remoteInputs.length > 0);
     }
 
     /** Returns true if all Assistant callbacks indicate that they show no UI, false otherwise. */
-    private static boolean assistantCallbacksShowNoUi(final Notification notification) {
-        return getAllActions(notification)
-                .stream()
+    private static boolean assistantCallbacksShowNoUi(StatusBarNotification sbn) {
+        final Notification notification = sbn.getNotification();
+        return IntStream.range(0, notification.actions.length)
+                .mapToObj(i -> NotificationCompat.getAction(notification, i))
                 .filter(Objects::nonNull)
                 .filter(action -> SUPPORTED_SEMANTIC_ACTIONS.contains(action.getSemanticAction()))
                 .noneMatch(NotificationCompat.Action::getShowsUserInterface);
@@ -410,10 +384,6 @@
 
     private void handleFallback(StatusBarNotification sbn, String action,
             ActionRequestCallback callback) {
-        if (mFallbackAssistant == null) {
-            return;
-        }
-
         FallbackAssistant.Listener listener = new FallbackAssistant.Listener() {
             @Override
             public void onMessageRead(boolean hasError) {
diff --git a/car-assist-lib/Android.bp b/car-assist-lib/Android.bp
index 77d8c26..4f8f578 100644
--- a/car-assist-lib/Android.bp
+++ b/car-assist-lib/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-assist-lib",
 
@@ -30,8 +26,6 @@
     sdk_version: "current",
 
     static_libs: [
-        // ensure unbundled
-        "car-messaging-models",
         "androidx.legacy_legacy-support-v4",
         "androidx.annotation_annotation",
     ],
diff --git a/car-assist-lib/OWNERS b/car-assist-lib/OWNERS
index 185f5c6..0c113c4 100644
--- a/car-assist-lib/OWNERS
+++ b/car-assist-lib/OWNERS
@@ -1,3 +1,3 @@
 # People who can approve changes for submission.
 igorr@google.com
-uokoye@google.com
+jiayuzhou@google.com
diff --git a/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java b/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java
index 8e5fef2..6c16fdc 100644
--- a/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java
+++ b/car-assist-lib/src/com/android/car/assist/CarVoiceInteractionSession.java
@@ -23,10 +23,8 @@
 import android.service.voice.VoiceInteractionSession;
 
 import androidx.annotation.StringDef;
-import androidx.core.app.NotificationManagerCompat;
 
 import com.android.car.assist.payloadhandlers.NotificationPayloadHandler;
-import com.android.car.messenger.common.Conversation;
 
 /**
  * An active voice interaction session on the car, providing additional actions which assistant
@@ -51,120 +49,40 @@
     public static final String KEY_FALLBACK_ASSISTANT_ENABLED = "KEY_FALLBACK_ASSISTANT_ENABLED";
 
     /**
-     * The key used for a substitute package name the Digital Assistant should read out in lieu of
-     * package name associated with the {@link StatusBarNotification}.
-     *
-     * <p>Only system packages which lump together a bunch of unrelated stuff may substitute a
-     * different name to make the purpose of the notification more clear. The correct package label
-     * should always be accessible via SystemUI.
-     */
-    public static final String EXTRA_SUBSTITUTE_APP_NAME = "android.substName";
-
-    /**
      * The key used for the payload {@link Bundle}, if a {@link StatusBarNotification} is used as
      * the payload.
      */
     public static final String KEY_NOTIFICATION = "KEY_NOTIFICATION";
 
-    /**
-     * The key used for the payload {@link Bundle}, if a {@link Conversation} is used as the
-     * payload.
-     */
-    public static final String KEY_CONVERSATION = "KEY_CONVERSATION";
-
     /** Indicates to assistant that no action was specified. */
     public static final String VOICE_ACTION_NO_ACTION = "VOICE_ACTION_NO_ACTION";
 
-    /**
-     * Indicates to assistant that a read action is being requested for a given payload. A {@link
-     * StatusBarNotification} object will be provided in the payload
-     */
+    /** Indicates to assistant that a read action is being requested for a given payload. */
     public static final String VOICE_ACTION_READ_NOTIFICATION = "VOICE_ACTION_READ_NOTIFICATION";
 
-    /**
-     * Indicates to assistant that a reply action is being requested for a given payload. A {@link
-     * StatusBarNotification} object will be provided in the payload
-     */
+    /** Indicates to assistant that a reply action is being requested for a given payload. */
     public static final String VOICE_ACTION_REPLY_NOTIFICATION = "VOICE_ACTION_REPLY_NOTIFICATION";
 
     /**
-     * Indicates to assistant that a read conversation action is being requested. A {@link
-     * Conversation} object will be provided in the payload.
-     */
-    public static final String VOICE_ACTION_READ_CONVERSATION = "VOICE_ACTION_READ_CONVERSATION";
-
-    /**
-     * Indicates to assistant that a reply conversation action is being requested. A {@link
-     * Conversation} object will be provided in the payload.
-     */
-    public static final String VOICE_ACTION_REPLY_CONVERSATION = "VOICE_ACTION_REPLY_CONVERSATION";
-
-    /**
-     * Indicates to digital assistant that it should capture a SMS message from the user,
-     * potentially finding which contact to send the message to and which device to send the message
-     * from (only if the application does not send the digital assistant this information in the
-     * bundle). Once the digital assistant has gathered the information from the user, it should
-     * send back the PendingIntent (provided in the bundle) with the information so the application
-     * can actually send the SMS.
-     */
-    public static final String VOICE_ACTION_SEND_SMS = "VOICE_ACTION_SEND_SMS";
-
-    /* Recipient's phone number. If this and the recipient name are not provided,
-     * by the application, digital assistant must do contact disambiguation
-     * and add the phone number to the pending intent
-     */
-    public static final String KEY_PHONE_NUMBER = "KEY_PHONE_NUMBER";
-
-    /**
-     * Recipient's name. If this and the recipient phone number are not provided by the application,
-     * digital assistant must do contact disambiguation but is not required to add the name to the
-     * PendingIntent.
-     */
-    public static final String KEY_RECIPIENT_NAME = "KEY RECIPIENT NAME";
-
-    /* Recipient's UID in the Contact Provider database. Optionally provided by the application.
-     * Not required to be sent back by the digital assistant.
-     */
-    public static final String KEY_RECIPIENT_UID = "KEY_RECIPIENT_UID";
-
-    /* Friendly name of the device in which to send the message from. If not
-     * provided by the application, digital assistant must do device disambiguation
-     * but is not required to add it to the Pending Intent.
-     */
-    public static final String KEY_DEVICE_NAME = "KEY DEVICE_NAME";
-
-    /* Bluetooth device address of the device of which to send the message from.
-     * If not provided by the application, assistant must do device disambiguation
-     * and add this to the Pendingintent.
-     */
-    public static final String KEY_DEVICE_ADDRESS = "KEY_DEVICE_ADDRESS";
-
-    /* KEY_SEND_PENDING_INTENT is not null and always be provided by the application.
-     * The application must preload the pending intent with any KEYs, it provides the assistant
-     * that is also needed to send the message.
-     * (i.e. if the application passes in the KEY_PHONE_NUMBER in the Bundle,
-     * the assistant can assume the application has already put this in the
-     * PendingIntent and may not re-add it to the PendingIntent).
-     */
-    public static final String KEY_SEND_PENDING_INTENT = "KEY_SEND_PENDING INTENT";
-
-    /**
      * Indicates to assistant that it should resolve the exception in the given payload (found in
      * {@link CarVoiceInteractionSession#KEY_EXCEPTION}'s value).
      */
     public static final String VOICE_ACTION_HANDLE_EXCEPTION = "VOICE_ACTION_HANDLE_EXCEPTION";
 
-    /** The list of exceptions the active voice service must handle. */
+    /**
+     * The list of exceptions the active voice service must handle.
+     */
     @StringDef({EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING})
     public @interface ExceptionValue {}
 
     /**
      * Indicates to assistant that it is missing the Notification Listener permission, and should
      * request this permission from the user.
-     */
+     **/
     public static final String EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING =
             "EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING";
 
+
     private final NotificationPayloadHandler mNotificationPayloadHandler;
 
     public CarVoiceInteractionSession(Context context) {
@@ -188,8 +106,7 @@
     @Override
     public final void onShow(Bundle args, int showFlags) {
         super.onShow(args, showFlags);
-        addNotificationAccessExceptionIfNeeded(args);
-        if (args != null) {
+        if (args != null && isCarNotificationSource(showFlags)) {
             String action = getRequestedVoiceAction(args);
             if (!VOICE_ACTION_NO_ACTION.equals(action)) {
                 onShow(action, args, showFlags);
@@ -200,62 +117,34 @@
     }
 
     /**
-     * Called when the session UI is going to be shown. This is called after {@link
-     * #onCreateContentView} (if the session's content UI needed to be created) and immediately
-     * prior to the window being shown. This may be called while the window is already shown, if a
-     * show request has come in while it is shown, to allow you to update the UI to match the new
-     * show arguments.
+     * Called when the session UI is going to be shown.  This is called after
+     * {@link #onCreateContentView} (if the session's content UI needed to be created) and
+     * immediately prior to the window being shown.  This may be called while the window
+     * is already shown, if a show request has come in while it is shown, to allow you to
+     * update the UI to match the new show arguments.
      *
-     * @param action The action that is being requested for this session (e.g. {@link
-     *     CarVoiceInteractionSession#VOICE_ACTION_READ_NOTIFICATION}, {@link
-     *     CarVoiceInteractionSession#VOICE_ACTION_REPLY_NOTIFICATION}).
-     * @param args The arguments that were supplied to {@link VoiceInteractionService#showSession
-     *     VoiceInteractionService.showSession}.
-     * @param flags The show flags originally provided to {@link VoiceInteractionService#showSession
-     *     VoiceInteractionService.showSession}.
+     * @param action The action that is being requested for this session
+     *               (e.g. {@link CarVoiceInteractionSession#VOICE_ACTION_READ_NOTIFICATION},
+     *               {@link CarVoiceInteractionSession#VOICE_ACTION_REPLY_NOTIFICATION}).
+     * @param args The arguments that were supplied to
+     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
+     * @param flags The show flags originally provided to
+     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
      */
     protected abstract void onShow(String action, Bundle args, int flags);
 
     /**
-     * Transforms bundle to {@link KEY_EXCEPTION} with
-     * value {@link EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING} if
-     * Notification Listener permissions are missing.
+     * Returns true if the request was initiated for a car notification.
      */
-    private void addNotificationAccessExceptionIfNeeded(Bundle args) {
-      if (needsNotificationAccess(args)) {
-              args.putString(KEY_ACTION, VOICE_ACTION_HANDLE_EXCEPTION);
-              args.putString(KEY_EXCEPTION, EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING);
-              args.putBoolean(KEY_FALLBACK_ASSISTANT_ENABLED, false);
-      }
-    }
-
-    private boolean needsNotificationAccess(Bundle args) {
-      return isNotificationAction(args) && !hasNotificationAccess(getContext());
+    private static boolean isCarNotificationSource(int flags) {
+        return (flags & SHOW_SOURCE_NOTIFICATION) != 0;
     }
 
     /**
-     * Returns {@code true} if the given {@code args} is a notification action, {@code false}
-     * otherwise
-     */
-    private static boolean isNotificationAction(Bundle args) {
-        if (args == null) {
-          return false;
-        }
-        String action = args.getString(KEY_ACTION);
-        return VOICE_ACTION_REPLY_NOTIFICATION.equals(action)
-            || VOICE_ACTION_READ_NOTIFICATION.equals(action);
-    }
-
-    private boolean hasNotificationAccess(Context context) {
-        return NotificationManagerCompat
-            .getEnabledListenerPackages(context).contains(context.getPackageName());
-    }
-
-    /**
-     * Returns the action {@link String} provided in the args {@link Bundle}, or {@link
-     * CarVoiceInteractionSession#VOICE_ACTION_NO_ACTION} if no such string was provided.
+     * Returns the action {@link String} provided in the args {@Bundle},
+     * or {@link CarVoiceInteractionSession#VOICE_ACTION_NO_ACTION} if no such string was provided.
      */
     protected static String getRequestedVoiceAction(Bundle args) {
         return args.getString(KEY_ACTION, VOICE_ACTION_NO_ACTION);
     }
-}
\ No newline at end of file
+}
diff --git a/car-assist-lib/src/com/android/car/assist/payloadhandlers/ConversationPayloadHandler.java b/car-assist-lib/src/com/android/car/assist/payloadhandlers/ConversationPayloadHandler.java
deleted file mode 100644
index 5f0ea8a..0000000
--- a/car-assist-lib/src/com/android/car/assist/payloadhandlers/ConversationPayloadHandler.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.assist.payloadhandlers;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.RemoteAction;
-import android.app.RemoteInput;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.app.NotificationCompat;
-import androidx.core.app.NotificationCompat.Action;
-import androidx.core.app.NotificationCompat.Action.SemanticAction;
-import androidx.core.app.NotificationCompat.MessagingStyle;
-import androidx.core.graphics.drawable.IconCompat;
-
-import com.android.car.messenger.common.Conversation;
-import com.android.car.messenger.common.Conversation.ConversationAction.ActionType;
-
-/**
- * Util class that provides a conversion between {@link Conversation} and {@link
- * Notification}
- */
-public class ConversationPayloadHandler {
-
-    private ConversationPayloadHandler() {
-    }
-
-    /**
-     * Returns the package name from the pending intent
-     */
-    @SuppressWarnings("PendingIntentCreator")
-    @NonNull
-    public static String getPackageName(@NonNull PendingIntent pendingIntent) {
-        return pendingIntent.getCreatorPackage();
-    }
-
-    /**
-     * Creates a notification from {@link Conversation}
-     */
-    @NonNull
-    public static Notification createNotificationFromConversation(
-            @NonNull Context context,
-            @NonNull String channelId,
-            @NonNull Conversation conversation,
-            @DrawableRes int iconRes,
-            @Nullable String group) {
-        MessagingStyle messagingStyle = getMessagingStyle(conversation);
-        Action muteAction = getNotificationAction(context, conversation,
-                ActionType.ACTION_TYPE_MUTE);
-        Action markAsReadAction = getNotificationAction(context, conversation,
-                ActionType.ACTION_TYPE_MARK_AS_READ);
-        Action replyAction = getNotificationAction(context, conversation,
-                ActionType.ACTION_TYPE_REPLY);
-
-        return new NotificationCompat.Builder(context, channelId)
-                .setStyle(messagingStyle)
-                .setSmallIcon(iconRes)
-                .setLargeIcon(getBitmap(conversation.getConversationIcon(), context))
-                .addAction(replyAction)
-                .addAction(markAsReadAction)
-                .addAction(muteAction)
-                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
-                .setGroup(group)
-                .build();
-    }
-
-    @Nullable
-    private static Action getNotificationAction(
-            @NonNull Context context,
-            @NonNull Conversation conversation,
-            @ActionType int actionType) {
-        Conversation.ConversationAction conversationAction =
-                getConversationAction(conversation, actionType);
-        Action notificationAction = null;
-        if (conversationAction != null) {
-            RemoteAction remoteAction = conversationAction.getRemoteAction();
-            IconCompat icon =
-                    IconCompat.createFromIcon(context, remoteAction.getIcon());
-            Action.Builder builder =
-                    new Action.Builder(
-                            /* icon= */ icon,
-                            /* charSequence= */ remoteAction.getTitle(),
-                            remoteAction.getActionIntent())
-                            .setShowsUserInterface(false)
-                            .setSemanticAction(getSemanticAction(actionType));
-            if (conversationAction.getRemoteInput() != null) {
-                builder.addRemoteInput(toCompat(conversationAction.getRemoteInput()));
-            }
-            notificationAction = builder.build();
-        }
-        return notificationAction;
-    }
-
-    @SemanticAction
-    private static int getSemanticAction(@ActionType int actionType) {
-        switch (actionType) {
-            case ActionType.ACTION_TYPE_MUTE:
-                return Action.SEMANTIC_ACTION_MUTE;
-            case ActionType.ACTION_TYPE_MARK_AS_READ:
-                return Action.SEMANTIC_ACTION_MARK_AS_READ;
-            case ActionType.ACTION_TYPE_REPLY:
-                return Action.SEMANTIC_ACTION_REPLY;
-            default:
-                return Action.SEMANTIC_ACTION_NONE;
-        }
-    }
-
-    private static MessagingStyle getMessagingStyle(
-            @NonNull Conversation conversation) {
-        MessagingStyle messagingStyle =
-                new MessagingStyle(conversation.getUser());
-        messagingStyle.setGroupConversation(isGroupConversation(conversation));
-        messagingStyle.setConversationTitle(conversation.getConversationTitle());
-        for (Conversation.Message message : conversation.getMessages()) {
-            messagingStyle.addMessage(
-                    new MessagingStyle.Message(
-                            message.getText(), message.getTimestamp(), message.getPerson()));
-        }
-        return messagingStyle;
-    }
-
-    @Nullable
-    private static Bitmap getBitmap(@Nullable IconCompat icon, Context context) {
-        if (icon == null) {
-            return null;
-        }
-        Drawable drawable = icon.loadDrawable(context);
-        if (drawable instanceof BitmapDrawable) {
-            return ((BitmapDrawable) drawable).getBitmap();
-        } else {
-            return null;
-        }
-    }
-
-    private static boolean isGroupConversation(Conversation conversation) {
-        if (conversation.getParticipants().contains(conversation.getUser())) {
-            return conversation.getParticipants().size() > 2;
-        } else {
-            return conversation.getParticipants().size() > 1;
-        }
-    }
-
-    @Nullable
-    private static Conversation.ConversationAction getConversationAction(
-            Conversation conversation, @ActionType int action) {
-        if (conversation.getActions() == null) {
-            return null;
-        }
-        return conversation.getActions().stream()
-                .filter(it -> it.getActionType() == action)
-                .findFirst()
-                .orElse(null);
-    }
-
-    // Conversation classes use android.app.RemoteInput
-    // instead of androidx.core.app.RemoteInput in order to support
-    // being parcelable. While Notification uses androidx.core.app.RemoteInput.
-    // We used these methods to convert between the two.
-    private static androidx.core.app.RemoteInput toCompat(RemoteInput src) {
-        androidx.core.app.RemoteInput.Builder builder =
-                new androidx.core.app.RemoteInput.Builder(src.getResultKey())
-                        .setLabel(src.getLabel())
-                        .addExtras(src.getExtras());
-        return builder.build();
-    }
-}
diff --git a/car-broadcastradio-support/Android.bp b/car-broadcastradio-support/Android.bp
index d0e24e1..cf0b1bb 100644
--- a/car-broadcastradio-support/Android.bp
+++ b/car-broadcastradio-support/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-broadcastradio-support",
 
diff --git a/car-media-common/Android.bp b/car-media-common/Android.bp
index 9ec491f..b85ea3b 100644
--- a/car-media-common/Android.bp
+++ b/car-media-common/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-media-common",
 
diff --git a/car-media-common/res/drawable/fab_empty_foreground.xml b/car-media-common/res/drawable/fab_empty_foreground.xml
new file mode 100644
index 0000000..d9fb901
--- /dev/null
+++ b/car-media-common/res/drawable/fab_empty_foreground.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018, The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<ripple
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:radius="0dp"
+    android:color="@color/car_dark_blue_grey_700" />
diff --git a/car-media-common/res/drawable/seekbar_background.xml b/car-media-common/res/drawable/seekbar_background.xml
new file mode 100644
index 0000000..fcd06a2
--- /dev/null
+++ b/car-media-common/res/drawable/seekbar_background.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018, 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:id="@android:id/background"
+        android:drawable="@android:color/transparent" />
+
+    <item android:id="@android:id/secondaryProgress">
+        <scale android:scaleWidth="100%"
+            android:drawable="@android:color/transparent" />
+    </item>
+
+    <item android:id="@android:id/progress">
+        <scale android:scaleWidth="100%"
+            android:drawable="@drawable/progressbar" />
+    </item>
+
+</layer-list>
diff --git a/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml b/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml
deleted file mode 100644
index 1d70c72..0000000
--- a/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/play_pause_container"
-    android:focusable="false"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
-    <com.android.car.media.common.PlayPauseStopImageView
-        android:id="@+id/play_pause_stop"
-        style="@style/Widget.ActionButton"
-        android:src="@drawable/ic_play_pause_stop_animated"/>
-    <ProgressBar
-        android:id="@+id/circular_progress_bar"
-        android:layout_width="@dimen/fab_spinner_size"
-        android:layout_height="@dimen/fab_spinner_size"
-        android:layout_gravity="center"
-        android:padding="9dp"
-        android:indeterminateDrawable="@drawable/music_buffering"
-        android:indeterminateTint="@color/fab_spinner_indeterminate_color"
-        android:progressDrawable="@drawable/circular_progress_bar"
-        android:progressTint="@color/minimized_progress_bar_highlight"
-        android:progressBackgroundTint="@color/minimized_progress_bar_background"
-        android:focusable="false"
-        android:indeterminateOnly="false"/>
-</FrameLayout>
diff --git a/car-media-common/res/layout/play_pause_stop_button_layout.xml b/car-media-common/res/layout/play_pause_stop_button_layout.xml
index f61a821..f7700fe 100644
--- a/car-media-common/res/layout/play_pause_stop_button_layout.xml
+++ b/car-media-common/res/layout/play_pause_stop_button_layout.xml
@@ -20,9 +20,11 @@
     android:focusable="false"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">
+    <!-- The invisible foreground ripple stops Android O from drawing an ugly square over the play button -->
     <com.android.car.media.common.PlayPauseStopImageView
         android:id="@+id/play_pause_stop"
         style="@style/Widget.ActionButton"
+        android:foreground="@drawable/fab_empty_foreground"
         android:src="@drawable/ic_play_pause_stop_animated"/>
     <ProgressBar
         android:id="@+id/circular_progress_bar"
diff --git a/car-media-common/res/layout/playback_fragment.xml b/car-media-common/res/layout/playback_fragment.xml
index bd77f74..5575087 100644
--- a/car-media-common/res/layout/playback_fragment.xml
+++ b/car-media-common/res/layout/playback_fragment.xml
@@ -14,33 +14,32 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<com.android.car.ui.FocusArea
+<androidx.cardview.widget.CardView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_height="match_parent"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    app:cardElevation="0dp"
+    app:cardCornerRadius="6dp">
 
-    <androidx.cardview.widget.CardView
-        android:layout_height="match_parent"
+    <com.android.car.apps.common.CrossfadeImageView
+        android:id="@+id/album_background"
+        android:foreground="?android:attr/selectableItemBackground"
         android:layout_width="match_parent"
-        app:cardElevation="0dp"
-        app:cardCornerRadius="6dp">
+        android:layout_height="match_parent"
+        android:focusable="false"
+        android:scaleType="fitStart"/>
 
-        <com.android.car.apps.common.CrossfadeImageView
-            android:id="@+id/album_background"
-            android:foreground="?android:attr/selectableItemBackground"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:focusable="false"
-            android:scaleType="fitStart"/>
+    <View
+        android:id="@+id/playback_scrim"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/album_art_scrim"
+        android:alpha="@dimen/album_art_scrim_alpha"/>
 
-        <View
-            android:id="@+id/playback_scrim"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:background="@color/album_art_scrim"
-            android:focusable="true"
-            android:alpha="@dimen/album_art_scrim_alpha"/>
+    <com.android.car.ui.FocusArea
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
 
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/playback_container"
@@ -97,29 +96,6 @@
                 app:layout_constraintEnd_toStartOf="@+id/app_selector_container"
                 app:layout_constraintTop_toBottomOf="@+id/title"/>
 
-            <com.android.car.apps.common.UxrTextView
-                android:id="@+id/error_message"
-                style="@style/FullScreenErrorMessageStyle"
-                android:layout_marginHorizontal="@dimen/playback_fragment_text_margin_x"
-                android:maxLines="@integer/widget_error_text_max_lines"
-                app:layout_constraintVertical_chainStyle="packed"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintTop_toBottomOf="@+id/app_name"
-                app:layout_constraintBottom_toTopOf="@+id/error_button"
-            />
-
-            <com.android.car.apps.common.UxrButton
-                android:id="@+id/error_button"
-                style="@style/FullScreenErrorButtonStyle"
-                android:layout_marginTop="@dimen/playback_fragment_error_button_margin_top"
-                android:layout_marginBottom="@dimen/playback_fragment_error_button_margin_bottom"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintTop_toBottomOf="@+id/error_message"
-                app:layout_constraintBottom_toBottomOf="parent"
-            />
-
             <FrameLayout
                 android:id="@+id/app_selector_container"
                 xmlns:android="http://schemas.android.com/apk/res/android"
@@ -153,6 +129,6 @@
 
         </androidx.constraintlayout.widget.ConstraintLayout>
 
-    </androidx.cardview.widget.CardView>
+    </com.android.car.ui.FocusArea>
 
-</com.android.car.ui.FocusArea>
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/car-media-common/res/values-af/strings.xml b/car-media-common/res/values-af/strings.xml
index 81dc44c..c4efced 100644
--- a/car-media-common/res/values-af/strings.xml
+++ b/car-media-common/res/values-af/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumkunswerk"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Titelloos"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Iets is fout. Probeer later."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Kan dit nie op die oomblik doen nie"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Hierdie program kan dit nie doen nie"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Meld aan om hierdie program te gebruik"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premiumtoegang word vereis"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Luister tans op te veel toestelle"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Daardie inhoud word geblokkeer"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Kan nie daardie inhoud hier kry nie"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Speel reeds daardie inhoud"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Kan nie meer snitte oorslaan nie"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Kon nie voltooi word nie. Probeer weer."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Daar is niks anders op die waglys nie"</string>
 </resources>
diff --git a/car-media-common/res/values-am/strings.xml b/car-media-common/res/values-am/strings.xml
index 1d89404..9888274 100644
--- a/car-media-common/res/values-am/strings.xml
+++ b/car-media-common/res/values-am/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"የአልበም ስነ ጥበብ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"ርዕስ የለም"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"የሆነ ችግር አለ። በኋላ ይሞክሩ።"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"አሁን ይህን ማድረግ አይቻልም"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ይህ መተግበሪያ ይህን ማድረግ አይችልም"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ይህን መተግበሪያ ለመጠቀም በመለያ ይግቡ"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ፕሪሚየም መዳረሻ ያስፈልጋል"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"ከልክ በላይ ብዙ በሆኑ መሣሪያዎች ላይ በማዳመጥ ላይ"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ይዘቱ ታግዷል"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ይዘቱን እዚህ ማግኘት አልተቻለም"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ይዘቱ አስቀድሞ በመጫወት ላይ"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ተጨማሪ ትራኮችን መዝለል አይቻልም"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"መጨረስ አልተቻለም። እንደገና ይሞክሩ።"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"ሌላ ምንም ነገር ወረፋ አልያዘም"</string>
 </resources>
diff --git a/car-media-common/res/values-ar/strings.xml b/car-media-common/res/values-ar/strings.xml
index ca21255..609709e 100644
--- a/car-media-common/res/values-ar/strings.xml
+++ b/car-media-common/res/values-ar/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"صورة الألبوم"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"بلا عنوان"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"حدث خطأ. يُرجى المحاولة لاحقًا."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"يتعذّر على التطبيق تنفيذ هذا الإجراء في الوقت الحالي."</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"يتعذّر على التطبيق تنفيذ هذا الإجراء."</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"سجِّل دخولك لاستخدام هذا التطبيق."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"مطلوب الحصول على إذن وصول بحساب مدفوع."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"يتم الآن الاستماع على أجهزة أكثر من الحدّ المسموح به."</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"تم حظر هذا المحتوى."</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"لا يمكن الحصول على هذا المحتوى من هنا."</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"جارٍ تشغيل هذا المحتوى."</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"لا يمكن تخطّي المزيد من المقاطع الصوتية."</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"تعذَّر الإنهاء. يُرجى إعادة المحاولة."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"لم يتم وضع أي مقطع صوتي آخر في قائمة الانتظار."</string>
 </resources>
diff --git a/car-media-common/res/values-as/strings.xml b/car-media-common/res/values-as/strings.xml
index 6bf03a7..1513a5e 100644
--- a/car-media-common/res/values-as/strings.xml
+++ b/car-media-common/res/values-as/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"এলবাম আৰ্ট"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"কোনো শিৰোনাম নাই"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"কিবা ভুল হ’ল। পাছত চেষ্টা কৰক।"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"সেইটো এই মুহূৰ্তত কৰিব নোৱাৰি"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"এই এপ্‌টোৱে সেইটো কৰিব নোৱাৰে"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"এই এপ্‌টো ব্যৱহাৰ কৰিবলৈ ছাইন ইন কৰক"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium এক্সেছৰ আৱশ্যক"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"বহুকেইটা ডিভাইচত শুনি আছে"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"সেই সমলটো অৱৰোধ কৰা আছে"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"সেই সমলটো ইয়াত পাব নোৱাৰি"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"সেই সমলটো ইতিমধ্যে প্লে’ হৈ আছে"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"আৰু ট্ৰেক এৰি যাব নোৱাৰি"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"সম্পূর্ণ কৰিব পৰা নগ’ল। পুনৰ চেষ্টা কৰক।"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"শাৰীত অন্য একো নাই"</string>
 </resources>
diff --git a/car-media-common/res/values-az/strings.xml b/car-media-common/res/values-az/strings.xml
index 80509ae..9e8a836 100644
--- a/car-media-common/res/values-az/strings.xml
+++ b/car-media-common/res/values-az/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albom təsviri"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Başlıq yoxdur"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Xəta baş verdi. Sonra cəhd edin."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Hazırda onu etmək olmur"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Bu tətbiq onu edə bilmir"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Bu tətbiqi istifadə etmək üçün daxil olun"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium giriş tələb olunur"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Çox cihazda dinləmə aşkarlanıb"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Bu məzmun bloklanıb"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Bu məzmunu əldə etmək mümkün deyil"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Hazırda bu məzmun oxudulur"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Başqa treki keçmək mümkün deyil"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Bitirmək mümkün olmadı. Yenidən cəhd edin."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Növbədə başqa heç nə yoxdur"</string>
 </resources>
diff --git a/car-media-common/res/values-b+sr+Latn/strings.xml b/car-media-common/res/values-b+sr+Latn/strings.xml
index 26310be..60ea824 100644
--- a/car-media-common/res/values-b+sr+Latn/strings.xml
+++ b/car-media-common/res/values-b+sr+Latn/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Omot albuma"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Bez naslova"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Došlo je do greške. Probajte kasnije."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Trenutno ne može to da uradi"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ova aplikacija ne može to da uradi"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Prijavite se da biste koristili ovu aplikaciju"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Potreban je premijum pristup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Slušate na previše uređaja"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Taj sadržaj je blokiran"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Ne možete da dobijete taj sadržaj ovde"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Taj sadržaj se već reprodukuje"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Ne možete više da preskačete pesme"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nismo uspeli da dovršimo radnju. Probajte opet."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ništa drugo nije stavljeno u redosled"</string>
 </resources>
diff --git a/car-media-common/res/values-be/strings.xml b/car-media-common/res/values-be/strings.xml
index d782e53..4a98eab 100644
--- a/car-media-common/res/values-be/strings.xml
+++ b/car-media-common/res/values-be/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Вокладка альбома"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Без назвы"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Узнікла памылка. Паўтарыце спробу пазней."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Не ўдаецца выканаць гэты запыт"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Дзеянне недаступна ў гэтай праграме"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Каб выкарыстоўваць гэту праграму, увайдзіце"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Патрабуецца платны доступ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Праслухоўванне адбываецца на занадта вялікай колькасці прылад"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Гэта змесціва заблакіравана"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"У вашым рэгіёне загрузіць гэта змесціва нельга"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Гэта змесціва ўжо прайграецца"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Прапускаць трэкі больш нельга"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Не ўдалося завяршыць. Паўтарыце спробу."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"У чарзе пуста"</string>
 </resources>
diff --git a/car-media-common/res/values-bg/strings.xml b/car-media-common/res/values-bg/strings.xml
index 980e0fb..f595ed8 100644
--- a/car-media-common/res/values-bg/strings.xml
+++ b/car-media-common/res/values-bg/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Обложка на албума"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Няма заглавие"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Нещо не е наред. Опитайте по-късно."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Понастоящем тази заявка не може да се изпълни"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Приложението не може да изпълни тази заявка"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Влезте в профила си, за да използвате това приложение"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"За достъп се изисква платен профил"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Слуша се на твърде много устройства"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Това съдържание е блокирано"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Това съдържание не е налице за региона ви"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Това съдържание вече се възпроизвежда"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Не могат да се пропускат повече записи"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Не можа да завърши. Опитайте отново."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Няма нищо друго в опашката"</string>
 </resources>
diff --git a/car-media-common/res/values-bn/strings.xml b/car-media-common/res/values-bn/strings.xml
index d02e247..c7366d7 100644
--- a/car-media-common/res/values-bn/strings.xml
+++ b/car-media-common/res/values-bn/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"অ্যালবাম আর্ট"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"কোনও শীর্ষক নেই"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"কোনও সমস্যা হয়েছে। পরে চেষ্টা করুন।"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"এই কাজটি এখন করা যাবে না"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"এই অ্যাপে এই কাজটি করা যাবে না"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"এই অ্যাপ ব্যবহার করতে সাইন-ইন করুন"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium অ্যাক্সেস থাকতে হবে"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"একাধিক ডিভাইসে শোনা হচ্ছে"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ওই কন্টেন্টটি ব্লক করা আছে"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ওই কন্টেন্টটি এখানে পাওয়া যাবে না"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"কন্টেন্টটি আগে থেকেই চলছে"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"আর কোনও ট্র্যাক এড়িয়ে যেতে পারবেন না"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"সম্পূর্ণ করা যায়নি। আবার চেষ্টা করুন।"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"সারিতে আর কিছু নেই"</string>
 </resources>
diff --git a/car-media-common/res/values-bs/strings.xml b/car-media-common/res/values-bs/strings.xml
index 4cdefe8..60ea824 100644
--- a/car-media-common/res/values-bs/strings.xml
+++ b/car-media-common/res/values-bs/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Omot albuma"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Bez naslova"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Nešto nije uredu. Pokušajte kasnije."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Taj zahtjev trenutno nije moguće izvršiti"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ova aplikacija ne može izvršiti taj zahtjev"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Prijavite se da koristite ovu aplikaciju"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Potreban je premijum pristup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Previše je uređaja na kojima se sluša"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Sadržaj je blokiran"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Nije moguće preuzeti taj sadržaj ovdje"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Taj sadržaj se već reproducira"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Ne možete više preskakati numere"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Dovršavanje nije uspjelo. Pokušajte ponovo."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ništa više nije postavljeno u red čekanja"</string>
 </resources>
diff --git a/car-media-common/res/values-ca/strings.xml b/car-media-common/res/values-ca/strings.xml
index 7a44b13..c672d9b 100644
--- a/car-media-common/res/values-ca/strings.xml
+++ b/car-media-common/res/values-ca/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Imatge de l\'àlbum"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Sense títol"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"S\'ha produït un error. Prova-ho més tard."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Ara mateix aquesta acció no es pot dur a terme"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"L\'aplicació no pot dur a terme aquesta acció"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Inicia la sessió per utilitzar aquesta aplicació"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Es requereix accés Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"S\'està escoltant contingut en massa dispositius"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Aquest contingut està bloquejat"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"El contingut no està disponible en aquesta regió"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Aquest contingut ja s\'està reproduint"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"No es poden saltar més cançons"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"No s\'ha pogut acabar. Torna-ho a provar."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"No hi ha res més a la cua"</string>
 </resources>
diff --git a/car-media-common/res/values-cs/strings.xml b/car-media-common/res/values-cs/strings.xml
index 0a45e6d..dfcffe0 100644
--- a/car-media-common/res/values-cs/strings.xml
+++ b/car-media-common/res/values-cs/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Obal alba"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Bez názvu"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Někde se stala chyba. Zkuste to později."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Tuto akci teď nelze provést"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Tuto akci aplikace nedokáže provést"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Chcete-li aplikaci použít, přihlaste se"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Je vyžadován prémiový přístup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Poslech je aktivován v příliš mnoha zařízeních"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Obsah je blokován"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Tento obsah tu nelze načíst"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Tento obsah se už přehrává"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Další skladby nelze přeskočit"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nelze dokončit. Zkuste to znovu."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ve frontě není nic dalšího"</string>
 </resources>
diff --git a/car-media-common/res/values-da/strings.xml b/car-media-common/res/values-da/strings.xml
index a875184..1640516 100644
--- a/car-media-common/res/values-da/strings.xml
+++ b/car-media-common/res/values-da/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumgrafik"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Ingen titel"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Der er noget galt. Prøv senere."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Det er ikke muligt lige nu"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Det kan denne app ikke gøre"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Log ind for at bruge denne app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Dette kræver en Premium-konto"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Du lytter på for mange enheder"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Indholdet er blokeret"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Der er ikke adgang til indholdet her"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Indholdet afspilles allerede"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Du kan ikke springe flere numre over"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Handlingen kunne ikke afsluttes. Prøv igen."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Der er ikke mere i køen"</string>
 </resources>
diff --git a/car-media-common/res/values-de/strings.xml b/car-media-common/res/values-de/strings.xml
index 8af25ed..7bafae6 100644
--- a/car-media-common/res/values-de/strings.xml
+++ b/car-media-common/res/values-de/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumcover"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Kein Titel"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Ein Fehler ist aufgetreten. Versuch es später noch mal."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Das ist gerade nicht möglich"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Diese App kann das nicht"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Melde dich an, um diese App zu verwenden"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premiumzugriff erforderlich"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Es wird auf zu vielen Geräten gleichzeitig gestreamt"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Der Inhalt ist gesperrt"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Der Inhalt kann hier nicht abgerufen werden"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Der Inhalt wird bereits wiedergegeben"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Du kannst keine weiteren Titel überspringen"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Die Aktion konnte nicht abgeschlossen werden. Versuch es noch einmal."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Es ist sonst nichts in der Warteschlange"</string>
 </resources>
diff --git a/car-media-common/res/values-el/strings.xml b/car-media-common/res/values-el/strings.xml
index 9bc13cd..0b5de6d 100644
--- a/car-media-common/res/values-el/strings.xml
+++ b/car-media-common/res/values-el/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Εξώφυλλο άλμπουμ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Χωρίς τίτλο"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε αργότερα."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Δεν είναι δυνατή η εκτέλεση του αιτήματος αυτήν τη στιγμή."</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Δεν είναι δυνατή η εκτέλεση του αιτήματος από αυτήν την εφαρμογή."</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Συνδεθείτε, για να χρησιμοποιήσετε αυτήν την εφαρμογή."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Απαιτείται premium πρόσβαση."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Ακρόαση πάρα πολλών συσκευών"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Αυτό το περιεχόμενο είναι αποκλεισμένο."</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Δεν είναι δυνατή η λήψη αυτού του περιεχομένου εδώ."</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Γίνεται ήδη αναπαραγωγή αυτού του περιεχομένου."</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Δεν είναι δυνατή η παράβλεψη περισσότερων κομματιών."</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Δεν ήταν δυνατή η ολοκλήρωση. Δοκιμάστε ξανά."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Δεν υπάρχει κάτι άλλο στην ουρά."</string>
 </resources>
diff --git a/car-media-common/res/values-en-rAU/strings.xml b/car-media-common/res/values-en-rAU/strings.xml
index b9c3337..98e3148 100644
--- a/car-media-common/res/values-en-rAU/strings.xml
+++ b/car-media-common/res/values-en-rAU/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Album Art"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"No title"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Can’t do that at the moment"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nothing else is queued up"</string>
 </resources>
diff --git a/car-media-common/res/values-en-rCA/strings.xml b/car-media-common/res/values-en-rCA/strings.xml
index b9c3337..98e3148 100644
--- a/car-media-common/res/values-en-rCA/strings.xml
+++ b/car-media-common/res/values-en-rCA/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Album Art"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"No title"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Can’t do that at the moment"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nothing else is queued up"</string>
 </resources>
diff --git a/car-media-common/res/values-en-rGB/strings.xml b/car-media-common/res/values-en-rGB/strings.xml
index b9c3337..98e3148 100644
--- a/car-media-common/res/values-en-rGB/strings.xml
+++ b/car-media-common/res/values-en-rGB/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Album Art"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"No title"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Can’t do that at the moment"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nothing else is queued up"</string>
 </resources>
diff --git a/car-media-common/res/values-en-rIN/strings.xml b/car-media-common/res/values-en-rIN/strings.xml
index b9c3337..98e3148 100644
--- a/car-media-common/res/values-en-rIN/strings.xml
+++ b/car-media-common/res/values-en-rIN/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Album Art"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"No title"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Can’t do that at the moment"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nothing else is queued up"</string>
 </resources>
diff --git a/car-media-common/res/values-en-rXC/strings.xml b/car-media-common/res/values-en-rXC/strings.xml
index 326c0ff..ecdf930 100644
--- a/car-media-common/res/values-en-rXC/strings.xml
+++ b/car-media-common/res/values-en-rXC/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎Album Art‎‏‎‎‏‎"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎No Title‎‏‎‎‏‎"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎Something’s wrong. Try later.‎‏‎‎‏‎"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎Can’t do that right now‎‏‎‎‏‎"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‎This app can’t do that‎‏‎‎‏‎"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎Sign in to use this app‎‏‎‎‏‎"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎Premium access required‎‏‎‎‏‎"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎Listening on too many devices‎‏‎‎‏‎"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎That content is blocked‎‏‎‎‏‎"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎Can’t get that content here‎‏‎‎‏‎"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎Already playing that content‎‏‎‎‏‎"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎Can’t skip any more tracks‎‏‎‎‏‎"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎Couldn’t finish. Try again.‎‏‎‎‏‎"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎Nothing else is queued up‎‏‎‎‏‎"</string>
 </resources>
diff --git a/car-media-common/res/values-es-rUS/strings.xml b/car-media-common/res/values-es-rUS/strings.xml
index 38a7dfd..18ba657 100644
--- a/car-media-common/res/values-es-rUS/strings.xml
+++ b/car-media-common/res/values-es-rUS/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Imagen del álbum"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Sin título"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Se produjo un error. Vuelve a intentarlo más tarde."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"No se puede realizar esa acción en este momento"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Esta app no puede realizar esa acción"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Accede para usar esta app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Se requiere acceso Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Se está escuchando contenido en demasiados dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Ese contenido está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"No se puede acceder a ese contenido en esta región"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Ya se está reproduciendo ese contenido"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"No se pueden omitir más pistas"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"No se pudo completar la acción. Vuelve a intentarlo."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"No hay más contenido en la fila"</string>
 </resources>
diff --git a/car-media-common/res/values-es/strings.xml b/car-media-common/res/values-es/strings.xml
index f70760a..18ba657 100644
--- a/car-media-common/res/values-es/strings.xml
+++ b/car-media-common/res/values-es/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Imagen del álbum"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Sin título"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Se ha producido un error. Inténtalo más tarde."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"No se puede hacer en estos momentos"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"No se puede hacer con esta aplicación"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Inicia sesión para utilizar esta aplicación"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Se necesita acceso premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Se está escuchando en demasiados dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Ese contenido está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Aquí no se puede reproducir ese contenido"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Ya se está reproduciendo ese contenido"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"No se pueden saltar más pistas"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"No se ha podido finalizar. Inténtalo de nuevo."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"No hay nada más en la cola"</string>
 </resources>
diff --git a/car-media-common/res/values-et/strings.xml b/car-media-common/res/values-et/strings.xml
index a5d7fc3..8ca4cf2 100644
--- a/car-media-common/res/values-et/strings.xml
+++ b/car-media-common/res/values-et/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumi kujundus"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Pealkiri puudub"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Midagi on valesti. Proovige hiljem."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Seda ei saa praegu teha"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"See rakendus ei saa seda teha"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Rakenduse kasutamiseks logige sisse"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Vaja on Premium-tasemel juurdepääsu"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Kuulatakse liiga paljudes seadmetes"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"See sisu on blokeeritud"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Seda sisu ei saa siin esitada"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Seda sisu juba esitatakse"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Rohkem lugusid ei saa vahele jätta"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Ei saanud lõpetada. Proovige uuesti."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Midagi muud pole järjekorras"</string>
 </resources>
diff --git a/car-media-common/res/values-eu/strings.xml b/car-media-common/res/values-eu/strings.xml
index c989683..896aa2c 100644
--- a/car-media-common/res/values-eu/strings.xml
+++ b/car-media-common/res/values-eu/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumaren azala"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Izenik gabea"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Arazoren bat izan da. Saiatu geroago."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Ezin da egin halakorik une honetan"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Aplikazio honek ezin du egin halakorik"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Aplikazioa erabiltzeko, hasi saioa"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium-eko sarbidea behar da"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Gailu gehiegitatik jasotzen ari da soinua"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Eduki hori blokeatuta dago"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Ezin da eskuratu eduki hori lurralde honetan"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Dagoeneko ari da erreproduzitzen eduki hori"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Ezin da saltatu pista gehiagorik"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Ezin izan da amaitu ekintza. Saiatu berriro."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ez dago beste ezer ilaran"</string>
 </resources>
diff --git a/car-media-common/res/values-fa/strings.xml b/car-media-common/res/values-fa/strings.xml
index b3168a0..24bac8e 100644
--- a/car-media-common/res/values-fa/strings.xml
+++ b/car-media-common/res/values-fa/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"عکس روی جلد آلبوم"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"بدون عنوان"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"مشکلی رخ داد. بعداً امتحان کنید."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"درحال‌حاضر انجام نمی‌شود"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"این برنامه نمی‌تواند این کار را انجام دهد"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"برای استفاده از این برنامه، به سیستم وارد شوید"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"دسترسی ممتاز لازم است"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"درحال گوش کردن به تعداد زیادی دستگاه"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"این محتوا مسدود شده است"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"نمی‌توان این محتوا را در اینجا دریافت کرد"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"این محتوا از قبل درحال پخش است"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"از هیچ آهنگ دیگری نمی‌توان رد شد"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"تکمیل نشد. دوباره امتحان کنید."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"هیچ مورد دیگری در صف پخش نیست"</string>
 </resources>
diff --git a/car-media-common/res/values-fi/strings.xml b/car-media-common/res/values-fi/strings.xml
index c558794..0fcaaf5 100644
--- a/car-media-common/res/values-fi/strings.xml
+++ b/car-media-common/res/values-fi/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumin kansitaide"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Ei nimeä"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Jotain meni pieleen. Yritä myöhemmin."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Tämä ei juuri nyt onnistu"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Sovellus ei tue pyyntöä"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Kirjaudu sisään käyttääksesi tätä sovellusta"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Edellyttää premium-tilausta"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Kuuntelu käynnissä liian monella laitteella"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Tämä sisältö on estetty"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Sisältö ei ole saatavilla täällä"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Sisältöä toistetaan jo"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Enimmäismäärä kappaleita ohitettu"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Ei onnistunut. Yritä uudelleen."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ei muuta jonossa"</string>
 </resources>
diff --git a/car-media-common/res/values-fr-rCA/strings.xml b/car-media-common/res/values-fr-rCA/strings.xml
index 3f0bff9..66e06e1 100644
--- a/car-media-common/res/values-fr-rCA/strings.xml
+++ b/car-media-common/res/values-fr-rCA/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Image de l\'album"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Aucun titre"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Une erreur s\'est produite. Réessayez plus tard."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Impossible d\'effectuer cette action pour le moment"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Cette application ne peut pas effectuer cette action"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Connectez-vous pour utiliser cette application"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Accès Premium requis"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Écoute en cours sur trop d\'appareils"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Ce contenu est bloqué"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Impossible d\'obtenir ce contenu ici"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Ce contenu est déjà en cours de lecture"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Impossible de passer à d\'autres chansons"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Impossible de terminer l\'action. Réessayez."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Rien d\'autre n\'est dans la file d\'attente"</string>
 </resources>
diff --git a/car-media-common/res/values-fr/strings.xml b/car-media-common/res/values-fr/strings.xml
index 8a86806..dfbc082 100644
--- a/car-media-common/res/values-fr/strings.xml
+++ b/car-media-common/res/values-fr/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Image de l\'album"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Sans titre"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Une erreur s\'est produite. Réessayez plus tard."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Impossible d\'effectuer cette opération pour le moment"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Cette application ne peut pas effectuer cette opération"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Connectez-vous pour utiliser cette application"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Accès Premium requis"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Écoute en cours sur trop d\'appareils"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Ce contenu est bloqué"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Impossible d\'accéder à ce contenu ici"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Ce contenu est déjà en cours de lecture"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Impossible de passer d\'autres titres"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Impossible de terminer l\'opération. Veuillez réessayer."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Aucun autre titre dans la file d\'attente"</string>
 </resources>
diff --git a/car-media-common/res/values-gl/strings.xml b/car-media-common/res/values-gl/strings.xml
index a1a8fc5..6971016 100644
--- a/car-media-common/res/values-gl/strings.xml
+++ b/car-media-common/res/values-gl/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Portada de álbum"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Sen título"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Produciuse un problema. Téntao máis tarde."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Nestes momentos non se pode realizar a acción"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Esta aplicación non pode realizar a acción"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Inicia sesión para utilizar esta aplicación"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Requírese acceso premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Estase escoitando contido en demasiados dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Ese contido está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Aquí non se pode acceder a ese contido"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Xa se está reproducindo ese contido"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Non se poden saltar máis pistas"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Non se puido completar a acción. Téntao de novo."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Non hai nada máis na cola"</string>
 </resources>
diff --git a/car-media-common/res/values-gu/strings.xml b/car-media-common/res/values-gu/strings.xml
index b59fa2a..569394f 100644
--- a/car-media-common/res/values-gu/strings.xml
+++ b/car-media-common/res/values-gu/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"આલ્બમ આર્ટ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"કોઈ શીર્ષક નથી"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"કંઈક ખોટું થયું. થોડા સમય પછી પ્રયાસ કરો."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"તે અત્યારે કરી શકતા નથી"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"આ ઍપ તે કરી શકતી નથી"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"આ ઍપનો ઉપયોગ કરવા માટે સાઇન ઇન કરો"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"પ્રીમિયમ ઍક્સેસ જરૂરી છે"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"ઘણા બધા ડિવાઇસ પર સાંભળી રહ્યાં છે"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"તે કન્ટેન્ટ બ્લૉક કર્યું છે"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"તે કન્ટેન્ટ અહીં મેળવી શકાતું નથી"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"તે કન્ટેન્ટ પહેલાંથી ચલાવી રહ્યાં છે"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"કોઈ વધુ ટ્રૅક છોડી શકાતા નથી"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"સમાપ્ત કરી શક્યાં નથી. ફરી પ્રયાસ કરો."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"બીજું કંઈ કતારમાં નથી"</string>
 </resources>
diff --git a/car-media-common/res/values-hi/strings.xml b/car-media-common/res/values-hi/strings.xml
index 58fed76..f13088f 100644
--- a/car-media-common/res/values-hi/strings.xml
+++ b/car-media-common/res/values-hi/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"एल्‍बम आर्ट"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"कोई शीर्षक नहीं"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"कोई गड़बड़ी हुई. बाद में कोशिश करें."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"अभी नहीं किया जा सकता"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"इस ऐप्लिकेशन पर यह काम नहीं किया जा सकता"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"इस ऐप्लिकेशन का इस्तेमाल करने के लिए साइन इन करें"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"इसके लिए Premium का ऐक्सेस ज़रूरी है"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"आप इसे बहुत सारे डिवाइस पर चला रहे/रही हैं"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"कॉन्टेंट पर रोक लगा दी गई है"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"यह कॉन्टेंट यहां नहीं चलाया जा सकता"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"यह कॉन्टेंट पहले से ही चल रहा है"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"इससे ज़्यादा गाने नहीं छोड़े जा सकते"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"कार्रवाई पूरी नहीं हो सकी. फिर से कोशिश करें."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"सूची में और कुछ नहीं है"</string>
 </resources>
diff --git a/car-media-common/res/values-hr/strings.xml b/car-media-common/res/values-hr/strings.xml
index 007109e..00e19d1 100644
--- a/car-media-common/res/values-hr/strings.xml
+++ b/car-media-common/res/values-hr/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Slika naslovnice albuma"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Bez naslova"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Nešto nije u redu. Pokušajte kasnije."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Trenutačno to ne možemo učiniti"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ova aplikacija nema tu mogućnost"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Prijavite se za upotrebu te aplikacije."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Potreban je pristup uz dodatnu naplatu"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Slušate na previše uređaja"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Taj je sadržaj blokiran"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Taj sadržaj nije dostupan ovdje"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Taj se sadržaj već reproducira"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Ne možete više preskakati pjesme"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Završavanje nije uspjelo. Pokušajte ponovo."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nema više ničeg u redu čekanja"</string>
 </resources>
diff --git a/car-media-common/res/values-hu/strings.xml b/car-media-common/res/values-hu/strings.xml
index a56ebba..8631465 100644
--- a/car-media-common/res/values-hu/strings.xml
+++ b/car-media-common/res/values-hu/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Lemezborító"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Nincs cím"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Hiba történt. Próbálja újra később."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Jelenleg nem lehetséges"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ez az alkalmazás nem képes erre"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Az alkalmazás használatához jelentkezzen be"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Prémium hozzáférés szükséges"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Túl sok eszköz van használatban"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"A tartalom le van tiltva"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Nem lehet betölteni a tartalmat"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"A tartalom lejátszása már folyamatban van"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Nem lehet több számot átugrani"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nem sikerült befejezni. Próbálkozzon újra."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Semmi más nincs a sorban"</string>
 </resources>
diff --git a/car-media-common/res/values-hy/strings.xml b/car-media-common/res/values-hy/strings.xml
index 5fd71be..197a067 100644
--- a/car-media-common/res/values-hy/strings.xml
+++ b/car-media-common/res/values-hy/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Ալբոմի շապիկ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Անանուն"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Սխալ առաջացավ։ Փորձեք ավելի ուշ։"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Այս պահին հնարավոր չէ անել դա"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Հավելվածը չի աջակցում այդ գործողությունը"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Մուտք գործեք՝ հավելվածն օգտագործելու համար"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Անհրաժեշտ է պրեմիում հաշիվ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Չափից շատ սարքերում է բովանդակություն նվագարկվում"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Բովանդակությունն արգելափակված է"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Բովանդակությունն անհասանելի է այս տարածաշրջանում"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Բովանդակությունն արդեն նվագարկվում է"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Այլևս հնարավոր չէ կատարումներ բաց թողնել"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Չհաջողվեց ավարտել։ Նորից փորձեք։"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Հերթացանկը դատարկ է"</string>
 </resources>
diff --git a/car-media-common/res/values-in/strings.xml b/car-media-common/res/values-in/strings.xml
index 3c287f2..e331c0a 100644
--- a/car-media-common/res/values-in/strings.xml
+++ b/car-media-common/res/values-in/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Sampul Album"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Tanpa Judul"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Terjadi masalah. Coba nanti."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Tidak dapat melakukannya saat ini"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Aplikasi ini tidak dapat melakukannya"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Login untuk menggunakan aplikasi ini"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Perlu akses premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Terlalu banyak perangkat digunakan untuk mendengarkan"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Konten tersebut diblokir"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Tidak dapat memuat konten tersebut di sini"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Sedang memutar konten tersebut"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Tidak dapat melewati lagu lagi"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Tidak dapat diselesaikan. Coba lagi."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Tidak ada antrean lagi"</string>
 </resources>
diff --git a/car-media-common/res/values-is/strings.xml b/car-media-common/res/values-is/strings.xml
index 34102e5..b26c4c6 100644
--- a/car-media-common/res/values-is/strings.xml
+++ b/car-media-common/res/values-is/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Plötuumslag"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Enginn titill"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Eitthvað er ekki í lagi. Reyndu síðar."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Ekki er hægt að framkvæma þetta eins og er"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Forritið getur ekki framkvæmt þetta"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Skráðu þig inn til að nota þetta forrit"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium-aðgangur er nauðsynlegur"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Hlustað í of mörgum tækjum"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Þetta efni er á bannlista"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Efnið er ekki tiltækt hér"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Þegar að spila þetta efni"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Ekki er hægt að sleppa fleiri lögum"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Ekki tókst að ljúka aðgerð. Reyndu aftur."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ekkert annað er í röð"</string>
 </resources>
diff --git a/car-media-common/res/values-it/strings.xml b/car-media-common/res/values-it/strings.xml
index d0ef413..bab7f0a 100644
--- a/car-media-common/res/values-it/strings.xml
+++ b/car-media-common/res/values-it/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Copertina dell\'album"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Nessun titolo"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Si è verificato un problema. Prova più tardi."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Al momento non è possibile svolgere l\'operazione"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Questa app non supporta l\'azione richiesta"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Accedi per usare questa app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"È necessario l\'accesso Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Ascolto attivo su troppi dispositivi"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Contenuti bloccati"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Qui non è possibile scaricare questi contenuti"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Contenuti già in riproduzione"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Impossibile saltare altre tracce"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Impossibile completare. Riprova."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nient\'altro in coda"</string>
 </resources>
diff --git a/car-media-common/res/values-iw/strings.xml b/car-media-common/res/values-iw/strings.xml
index a0118e1..9e12f85 100644
--- a/car-media-common/res/values-iw/strings.xml
+++ b/car-media-common/res/values-iw/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"עטיפת אלבום"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"ללא שם"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"משהו השתבש. יש לנסות מאוחר יותר."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"לא ניתן לבצע את הפעולה הזו כרגע"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"אי אפשר לבצע פעולה זו באפליקציה הזו"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"יש להיכנס לחשבון כדי להשתמש באפליקציה הזו"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"נדרשת גישה ל-Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"מתבצעת האזנה ביותר מדי מכשירים"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"התוכן הזה חסום"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"לא ניתן לקבל את התוכן הזה כאן"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"התוכן הזה כבר פועל"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"לא ניתן לדלג יותר על טראקים"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"לא ניתן היה לסיים. יש לנסות שוב."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"אין עוד שירים ברשימת השירים"</string>
 </resources>
diff --git a/car-media-common/res/values-ja/strings.xml b/car-media-common/res/values-ja/strings.xml
index b1a0da3..8d46866 100644
--- a/car-media-common/res/values-ja/strings.xml
+++ b/car-media-common/res/values-ja/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"アルバムアート"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"タイトルなし"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"エラーが発生しました。しばらくしてからお試しください。"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"現在、利用できません"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"このアプリではサポートされていません"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"このアプリを使用するにはログインしてください"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"プレミアム アカウントが必要です"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"再生しているデバイスが多すぎます"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"このコンテンツはブロックされています"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"このコンテンツはこの地域では利用できません"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"このコンテンツはすでに再生中です"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"これ以上トラックをスキップできません"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"完了できません。もう一度お試しください。"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"キューが一杯で追加できません"</string>
 </resources>
diff --git a/car-media-common/res/values-ka/strings.xml b/car-media-common/res/values-ka/strings.xml
index 39b2549..1e467fe 100644
--- a/car-media-common/res/values-ka/strings.xml
+++ b/car-media-common/res/values-ka/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ალბომის გარეკანი"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"უსათაურო"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"წარმოიქმნა შეფერხება. ცადეთ მოგვიანებით."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ამჟამად ამის გაკეთება შეუძლებელია"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ეს აპი ამას ვერ გააკეთებს"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ამ აპით სარგებლობისთვის შედით სისტემაში"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"საჭიროა პრემიუმ ტიპის წვდომა"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"მოსმენა მიმდინარეობს მეტისმეტად ბევრ მოწყობილობაზე"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ეს კონტენტი დაბლოკილია"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ამ კონტენტს აქ ვერ მიიღებთ"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ეს კონტენტი უკვე იკვრება"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"მეტ ჩანაწერს ვერ გამოტოვებთ"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"დასრულება ვერ მოხერხდა. ცადეთ ხელახლა."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"რიგში აღარაფერია"</string>
 </resources>
diff --git a/car-media-common/res/values-kk/strings.xml b/car-media-common/res/values-kk/strings.xml
index 9af1825..ec84f1a 100644
--- a/car-media-common/res/values-kk/strings.xml
+++ b/car-media-common/res/values-kk/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Альбом мұқабасы"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Атауы жоқ"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Бірдеңе дұрыс емес. Кейінірек қайталап көріңіз."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Мұны дәл қазір істеу мүмкін емес."</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Бұл қолданба мұны істей алмайды."</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Бұл қолданбаны пайдалану үшін аккаунтқа кіріңіз."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Премиум рұқсат қажет."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Тым көп құрылғыларда тыңдалып жатыр."</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Бұл мазмұнға тыйым салынған."</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Мазмұнды алу мүмкін емес."</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Әлдеқашан ойнатылып жатыр."</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Басқа тректерді өткізіп жіберу мүмкін емес."</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Аяқталмады. Қайталап көріңіз."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Кезекке басқа ештеңе қойылмаған."</string>
 </resources>
diff --git a/car-media-common/res/values-km/strings.xml b/car-media-common/res/values-km/strings.xml
index 95399ff..a9320b1 100644
--- a/car-media-common/res/values-km/strings.xml
+++ b/car-media-common/res/values-km/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"​ក្រប​អាល់ប៊ុម"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"គ្មាន​ចំណងជើងទេ"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"មានអ្វីមួយ​ខុស​ប្រក្រតី។ សូមព្យាយាម​នៅពេលក្រោយ។"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"មិនអាច​ធ្វើតាមសំណើនោះ​ឥឡូវនេះ​បានទេ"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"កម្មវិធីនេះ​មិនអាចធ្វើ​តាមសំណើនោះ​បានទេ"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ចូលគណនី ដើម្បីប្រើកម្មវិធីនេះ"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"តម្រូវឱ្យមាន​ការចូលប្រើ​លំដាប់ខ្ពស់"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"កំពុងស្ដាប់​នៅលើ​ឧបករណ៍​ច្រើនពេក"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ខ្លឹមសារនោះ​ត្រូវបានទប់ស្កាត់"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"មិនអាច​យក​ខ្លឹមសារនោះ​នៅទីនេះ​បានទេ"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"កំពុងចាក់​ខ្លឹមសារនោះ​ស្រាប់ហើយ"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"មិនអាច​រំលងចម្រៀង​បានទៀតទេ"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"មិនអាច​បញ្ចប់បានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"មិនមានអ្វី​ផ្សេងទៀត​នៅក្នុង​ជួរទេ"</string>
 </resources>
diff --git a/car-media-common/res/values-kn/strings.xml b/car-media-common/res/values-kn/strings.xml
index e690790..4a02cfd 100644
--- a/car-media-common/res/values-kn/strings.xml
+++ b/car-media-common/res/values-kn/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ಆಲ್ಬಮ್ ಕಲೆ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"ಏನೋ ತಪ್ಪಾಗಿದೆ. ನಂತರ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ಸದ್ಯಕ್ಕೆ ಅದನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ಈ ಆ್ಯಪ್‌ನಿಂದ ಅದನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ಈ ಆ್ಯಪ್ ಬಳಸಲು ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ಪ್ರೀಮಿಯಂ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"ಹಲವಾರು ಸಾಧನಗಳಲ್ಲಿ ಆಲಿಸಲಾಗುತ್ತಿದೆ"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ವಿಷಯವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ಆ ವಿಷಯವನ್ನು ಇಲ್ಲಿ ಪಡೆದುಕೊಳ್ಳಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ಈಗಾಗಲೇ ಆ ವಿಷಯವನ್ನು ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ಇನ್ನು ಮುಂದೆ ಟ್ರ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ಕಿಪ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"ಪೂರ್ಣಗೊಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"ಸರದಿಯಲ್ಲಿ ಯಾವುದು ಬಾಕಿ ಉಳಿದಿಲ್ಲ"</string>
 </resources>
diff --git a/car-media-common/res/values-ko/strings.xml b/car-media-common/res/values-ko/strings.xml
index d50fd0f..568f6de 100644
--- a/car-media-common/res/values-ko/strings.xml
+++ b/car-media-common/res/values-ko/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"앨범아트"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"제목 없음"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"문제가 발생했습니다. 나중에 다시 시도해 주세요."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"지금은 요청한 작업을 할 수 없습니다."</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"요청한 작업이 이 앱에서 지원되지 않습니다."</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"이 앱을 사용하려면 로그인하세요."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"프리미엄 액세스 권한이 필요합니다."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"너무 많은 기기에서 스트리밍하고 있습니다."</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"차단된 콘텐츠입니다."</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"이 지역에서 재생할 수 없는 콘텐츠입니다."</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"요청한 콘텐츠가 이미 재생 중입니다."</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"트랙을 더 이상 건너뛸 수 없습니다."</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"완료할 수 없습니다. 다시 시도해 주세요."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"현재 재생목록이 비어있습니다."</string>
 </resources>
diff --git a/car-media-common/res/values-ky/strings.xml b/car-media-common/res/values-ky/strings.xml
index 8ca5ae0..5dd1ccc 100644
--- a/car-media-common/res/values-ky/strings.xml
+++ b/car-media-common/res/values-ky/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Альбом мукабасы"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Аталышы жок"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Бир жерден ката кетти. Бир аздан кийин кайталап көрүңүз."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Аны азыр аткаруу мүмкүн эмес"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Бул колдонмо аны аткара албайт"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Бул колдонмону пайдалануу үчүн аккаунтуңузга кириңиз"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Артыкчылыктуу кирүү мүмкүнчүлүгү талап кылынат"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Өтө көп түзмөк угулууда"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Ал мазмун бөгөттөлгөн"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Ал мазмунду алуу мүмкүн эмес"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Ал мазмун ойнотулууда"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Эми тректерди өткөрүп жиберүүгө болбойт"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Аягына чыккан жок. Кайталап көрүңүз."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Кезекте эч нерсе жок"</string>
 </resources>
diff --git a/car-media-common/res/values-lo/strings.xml b/car-media-common/res/values-lo/strings.xml
index 7e92949..aee4892 100644
--- a/car-media-common/res/values-lo/strings.xml
+++ b/car-media-common/res/values-lo/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ໜ້າປົກອະລະບ້ຳ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"ບໍ່ມີຊື່"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"ມີບ່າງຢ່າງຜິດພາດ. ລອງໃໝ່ພາຍຫຼັງ."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ບໍ່ສາມາດເຮັດໄດ້ຕອນນີ້"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ແອັບນີ້ບໍ່ສາມາດເຮັດສິ່ງນັ້ນໄດ້"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ເຂົ້າສູ່ລະບົບເພື່ອໃຊ້ແອັບນີ້"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ຕ້ອງມີສິດເຂົ້າເຖິງລະດັບພຣີມຽມ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"ກຳລັງຟັງຢູ່ໃນຫຼາຍອຸປະກອນເກີນໄປ"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ເນື້ອຫານັ້ນຖືກບລັອກໄວ້"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ບໍ່ສາມາດຮັບເນື້ອຫານັ້ນຢູ່ບ່ອນນີ້"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ຫຼິ້ນເນື້ອຫານັ້ນແລ້ວ"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ຂ້າມເພງບໍ່ໄດ້ອີກແລ້ວ"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"ບໍ່ສາມາດສຳເລັດໄດ້. ລອງໃໝ່."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"ບໍ່ມີລາຍການອື່ນໃນຄິວ"</string>
 </resources>
diff --git a/car-media-common/res/values-lt/strings.xml b/car-media-common/res/values-lt/strings.xml
index be85d02..b4f1926 100644
--- a/car-media-common/res/values-lt/strings.xml
+++ b/car-media-common/res/values-lt/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumo viršelis"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Nėra pavadinimo"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Kažkas nepavyko. Bandykite vėliau."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Dabar negalima atlikti to veiksmo"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ši programa negali atlikti to veiksmo"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Prisijunkite, kad galėtumėte naudoti šią programą"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Būtina mokama prieiga"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Klausoma naudojant per daug įrenginių"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Tas turinys užblokuotas"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Negalima gauti to turinio čia"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Tas turinys jau leidžiamas"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Daugiau takelių praleisti nebegalima"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nepavyko užbaigti. Bandykite dar kartą."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Eilėje nieko nebėra"</string>
 </resources>
diff --git a/car-media-common/res/values-lv/strings.xml b/car-media-common/res/values-lv/strings.xml
index 754a59d..d4b6044 100644
--- a/car-media-common/res/values-lv/strings.xml
+++ b/car-media-common/res/values-lv/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albuma noformējums"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Bez nosaukuma"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Radās problēma. Mēģiniet vēlāk."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Pašlaik nevar veikt šo darbību."</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Šo darbību nevar veikt šajā lietotnē."</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Pierakstieties, lai izmantotu šo lietotni."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Nepieciešama maksas piekļuve."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Klausīšanās notiek pārāk daudz ierīcēs."</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Šis saturs ir bloķēts."</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Nevar šeit parādīt šo saturu."</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Šis saturs jau tiek atskaņots."</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Vairs nevar izlaist nevienu ierakstu."</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nevarēja pabeigt. Mēģiniet vēlreiz."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Rindā vairs nav nekā cita."</string>
 </resources>
diff --git a/car-media-common/res/values-mk/strings.xml b/car-media-common/res/values-mk/strings.xml
index 5e71b5a..d46c551 100644
--- a/car-media-common/res/values-mk/strings.xml
+++ b/car-media-common/res/values-mk/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Корица на албум"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Без наслов"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Нешто не е во ред. Обидете се подоцна."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Не може да се направи тоа во моментов"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Апликацијава не може да го направи тоа"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Најавете се за да ја користите апликацијава"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Потребен е пристап со Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Се слуша на премногу уреди"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Таа содржина е блокирана"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Не може да се добие таа содржина тука"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Веќе е пуштена таа содржина"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Не може да прескокне повеќе песни"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Не може да заврши. Обидете се повторно."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Веќе ништо не чека на ред"</string>
 </resources>
diff --git a/car-media-common/res/values-ml/strings.xml b/car-media-common/res/values-ml/strings.xml
index edcd0e1..cd1743b 100644
--- a/car-media-common/res/values-ml/strings.xml
+++ b/car-media-common/res/values-ml/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ആൽബം ആർട്ട്"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"പേരില്ല"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"എന്തോ കുഴപ്പമുണ്ട്. പിന്നീട് ശ്രമിക്കുക."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"അത് ഇപ്പോൾ ചെയ്യാനാകില്ല"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ഈ ആപ്പിന് അത് ചെയ്യാനാകില്ല"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ഈ ആപ്പ് ഉപയോഗിക്കാൻ സെെൻ ഇൻ ചെയ്യുക"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"പ്രീമിയം ആക്‌സസ് ആവശ്യമാണ്"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"നിരവധി ഉപകരണങ്ങളിൽ കേൾക്കുന്നു"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ആ ഉള്ളടക്കം ബ്ലോക്ക് ചെയ്‌തിരിക്കുന്നു"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ആ ഉള്ളടക്കം ഇവിടെ ലഭ്യമല്ല"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ആ ഉള്ളടക്കം നിലവിൽ പ്ലേ ചെയ്യുകയാണ്"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ഇനിയും ട്രാക്കുകൾ ഒഴിവാക്കാനാകില്ല"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"പൂർത്തിയാക്കാനായില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"മറ്റൊന്നും ക്യൂവിലില്ല"</string>
 </resources>
diff --git a/car-media-common/res/values-mn/strings.xml b/car-media-common/res/values-mn/strings.xml
index b9cb37c..0cbec6a 100644
--- a/car-media-common/res/values-mn/strings.xml
+++ b/car-media-common/res/values-mn/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Цомгийн зураг"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Гарчиг алга"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Алдаа гарлаа. Дараа оролдоно уу."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Яг одоо үүнийг хийх боломжгүй"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Энэ апп үүнийг хийх боломжгүй"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Энэ аппыг ашиглахын тулд нэвтэрнэ үү"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium хандалт шаардлагатай"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Хэт олон төхөөрөмж дээр сонсож байна"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Энэ контентыг блоклосон байна"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Энэ контентыг энд авах боломжгүй"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Энэ контентыг аль хэдийн тоглуулж байна"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Бичлэг дахин алгасах боломжгүй"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Дуусгаж чадсангүй. Дахин оролдоно уу."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Дараалалд өөр юу ч алга"</string>
 </resources>
diff --git a/car-media-common/res/values-mr/strings.xml b/car-media-common/res/values-mr/strings.xml
index 27547ba..450fddd 100644
--- a/car-media-common/res/values-mr/strings.xml
+++ b/car-media-common/res/values-mr/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"अल्बम कला"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"शीर्षक नाही"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"काहीतरी चूक झाली. नंतर प्रयत्न करा."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ते आता करू शकत नाही"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"हे ॲप ते करू शकत नाही"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"हे ॲप वापरण्यासाठी साइन इन करा"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"प्रीमियम ॲक्सेस आवश्यक आहे"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"खूप जास्‍त डिव्हाइसवर ऐकले जात आहे"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"तो आशय ब्लॉक केलेला आहे"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"तो आशय येथे मिळवू शकत नाही"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"तो आशय आधीपासून प्ले करत आहे"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"आणखी ट्रॅक वगळू शकत नाही"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"पूर्ण करता आले नाही. पुन्हा प्रयत्न करा."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"इतर काहीही क्यू केलेले नाही"</string>
 </resources>
diff --git a/car-media-common/res/values-ms/strings.xml b/car-media-common/res/values-ms/strings.xml
index 3a16397..f5660bf 100644
--- a/car-media-common/res/values-ms/strings.xml
+++ b/car-media-common/res/values-ms/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Seni Album"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Tiada Tajuk"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Ada yang tidak kena. Cuba nanti."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Tidak dapat berbuat demikian sekarang"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Apl ini tidak dapat berbuat demikian"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Log masuk untuk menggunakan apl ini"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Akses premium diperlukan"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Mendengar pada terlalu banyak peranti"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Kandungan itu disekat"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Tidak boleh mendapatkan kandungan itu di sini"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Sudah pun memainkan kandungan itu"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Tidak boleh melangkau apa-apa lagu lagi"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Tidak dapat diselesaikan. Cuba lagi."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Tiada lagu lain dalam baris gilir"</string>
 </resources>
diff --git a/car-media-common/res/values-my/strings.xml b/car-media-common/res/values-my/strings.xml
index f4723b0..e717f45 100644
--- a/car-media-common/res/values-my/strings.xml
+++ b/car-media-common/res/values-my/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"အယ်လ်ဘမ်ပုံ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"ခေါင်းစဉ် မရှိပါ"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"တစ်ခုခု မှားနေသည်။ နောက်မှ စမ်းကြည့်ပါ။"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"၎င်းကို ယခု မပြုလုပ်နိုင်ပါ"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ဤအက်ပ်က ၎င်းကို မပြုလုပ်နိုင်ပါ"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ဤအက်ပ်အသုံးပြုရန် လက်မှတ်ထိုးဝင်ပါ"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ပရီမီယံ အသုံးပြုခွင့် လိုအပ်သည်"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"စက်ပစ္စည်းအများအပြားတွင် နားထောင်နေသည်"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ထိုအကြောင်းအရာကို ပိတ်ထားသည်"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ထိုအကြောင်းအရာကို ဤနေရာတွင် မရရှိနိုင်ပါ"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ထိုအကြောင်းအရာကို ဖွင့်နေပြီဖြစ်သည်"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"နောက်ထပ်သီချင်းပုဒ်များ ကျော်၍မရတော့ပါ"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"အပြီးသတ်၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"အခြားစီထားသည်များ မရှိပါ"</string>
 </resources>
diff --git a/car-media-common/res/values-nb/strings.xml b/car-media-common/res/values-nb/strings.xml
index 878beb2..b01654e 100644
--- a/car-media-common/res/values-nb/strings.xml
+++ b/car-media-common/res/values-nb/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumgrafikk"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Ingen tittel"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Noe gikk galt. Prøv senere."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Kan ikke gjøre det akkurat nå"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Denne appen kan ikke gjøre det"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Logg på for å bruke denne appen"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premiumtilgang kreves"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Du lytter på for mange enheter"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Innholdet er blokkert"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Innholdet er ikke tilgjengelig her"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Du spiller allerede av innholdet"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Kan ikke hoppe over flere spor"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Kunne ikke fullføre. Prøv på nytt."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ingenting annet står i køen"</string>
 </resources>
diff --git a/car-media-common/res/values-ne/strings.xml b/car-media-common/res/values-ne/strings.xml
index 235d2c0..8e2bf79 100644
--- a/car-media-common/res/values-ne/strings.xml
+++ b/car-media-common/res/values-ne/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"एल्बम आर्ट"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"शीर्षक छैन"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"केही चिज गडबड छ। पछि प्रयास गर्नुहोस्।"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"त्यो कार्य अहिले नै गर्न सकिँदैन"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"यस एपले उक्त कार्य गर्न सक्दैन"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"यो एप प्रयोग गर्न साइन इन गर्नुहोस्"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"यसका लागि प्रिमियम खातामाथिको पहुँच आवश्यक हुन्छ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"अत्यधिक यन्त्रहरूबाट सुनिँदै छ"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"उक्त सामग्री ब्लक गरिएको छ"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"उक्त सामग्री यहाँ प्राप्त गर्न सकिँदैन"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"उक्त सामग्री प्ले भइरहेको छ"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"योभन्दा धेरै गीतहरू स्किप गर्न सकिँदैन"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"कार्य पूरा गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"सूचीमा अरू केही पनि छैन"</string>
 </resources>
diff --git a/car-media-common/res/values-nl/strings.xml b/car-media-common/res/values-nl/strings.xml
index e8acdbc..8259676 100644
--- a/car-media-common/res/values-nl/strings.xml
+++ b/car-media-common/res/values-nl/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albumhoes"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Geen titel"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Er is iets misgegaan. Probeer het later opnieuw."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Kan dat nu niet doen"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Deze app kan dat niet doen"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Log in om deze app te gebruiken"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium toegang vereist"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Er wordt op te veel apparaten geluisterd"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Die content is geblokkeerd"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Kan die content hier niet krijgen"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Die content wordt al afgespeeld"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Kan geen nummers meer overslaan"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Kan niet voltooien. Probeer het opnieuw."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Er staat niets anders in de wachtrij"</string>
 </resources>
diff --git a/car-media-common/res/values-or/strings.xml b/car-media-common/res/values-or/strings.xml
index e503cd8..a714293 100644
--- a/car-media-common/res/values-or/strings.xml
+++ b/car-media-common/res/values-or/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ଆଲବମ୍ ଆର୍ଟ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"କୌଣସି ଟାଇଟେଲ୍ ନାହିଁ"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"କିଛି ସମସ୍ୟା ଅଛି। ପରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ବର୍ତ୍ତମାନ ତାହା କରାଯାଇପାରିବ ନାହିଁ"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ଏହି ଆପ୍ ତାହା କରିପାରିବ ନାହିଁ"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ଏହି ଆପ୍ ବ୍ୟବହାର କରିବାକୁ ସାଇନ୍ ଇନ୍ କରନ୍ତୁ"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ପ୍ରିମିୟମ୍ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"ଅନେକ ଡିଭାଇସରେ ଶୁଣାଯାଉଛି"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ସେହି ବିଷୟବସ୍ତୁକୁ ବ୍ଲକ୍ କରାଯାଇଛି"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ଏଠାରେ ସେହି ବିଷୟବସ୍ତୁ ପାଇପାରିବେ ନାହିଁ"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ପୂର୍ବରୁ ସେହି ବିଷୟବସ୍ତୁ ଚଲାଯାଉଛି"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ଆଉ ଅଧିକ ଟ୍ରାକକୁ ବାଦ୍ ଦିଆଯାଇପାରିବ ନାହିଁ"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"ସମାପ୍ତ କରାଯାଇପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"ଧାଡ଼ିରେ ଆଉ କିଛି ନାହିଁ"</string>
 </resources>
diff --git a/car-media-common/res/values-pa/strings.xml b/car-media-common/res/values-pa/strings.xml
index 5d02f20..e3a607b 100644
--- a/car-media-common/res/values-pa/strings.xml
+++ b/car-media-common/res/values-pa/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ਐਲਬਮ ਕਲਾ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"ਕੋਈ ਗੜਬੜ ਹੈ। ਬਾਅਦ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ਫਿਲਹਾਲ ਇਹ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ਇਹ ਐਪ ਇਹ ਨਹੀਂ ਕਰ ਸਕਦੀ"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਲਈ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ਪ੍ਰੀਮੀਅਮ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਡੀਵਾਈਸਾਂ \'ਤੇ ਸੁਣਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ਇੱਥੇ ਇਹ ਸਮੱਗਰੀ ਨਹੀਂ ਮਿਲ ਸਕਦੀ"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ਇਹ ਸਮੱਗਰੀ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਹੀ ਹੈ"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ਕਿਸੇ ਹੋਰ ਟਰੈਕ ਨੂੰ ਛੱਡਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"ਪੂਰਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"ਹੋਰ ਕੁਝ ਵੀ ਕਤਾਰਬੱਧ ਨਹੀਂ ਹੈ"</string>
 </resources>
diff --git a/car-media-common/res/values-pl/strings.xml b/car-media-common/res/values-pl/strings.xml
index 1bdcf9a..fd00ae5 100644
--- a/car-media-common/res/values-pl/strings.xml
+++ b/car-media-common/res/values-pl/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Okładka albumu"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Bez tytułu"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Coś poszło nie tak. Spróbuj później."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Teraz nie można tego zrobić"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ta aplikacja nie ma takiej funkcji"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Zaloguj się, by używać tej aplikacji"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Wymagany jest dostęp na poziomie premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Słuchasz na zbyt wielu urządzeniach"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Te materiały są zablokowane"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Te materiały są niedostępne w tym regionie"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Te materiały są już odtwarzane"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Nie można pominąć większej liczby utworów"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nie udało się dokończyć. Spróbuj ponownie."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nie ma już nic w kolejce"</string>
 </resources>
diff --git a/car-media-common/res/values-pt-rPT/strings.xml b/car-media-common/res/values-pt-rPT/strings.xml
index ab6e0ff..2ae65bf 100644
--- a/car-media-common/res/values-pt-rPT/strings.xml
+++ b/car-media-common/res/values-pt-rPT/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Imagem do álbum"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Sem título"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Ocorreu um problema. Tente mais tarde."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Não é possível responder a esse pedido neste momento."</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Esta app não consegue responder a esse pedido."</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Inicie sessão para utilizar esta app."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Acesso premium necessário."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"A ouvir em demasiados dispositivos."</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Esse conteúdo está bloqueado."</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Não é possível obter esse conteúdo aqui."</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Esse conteúdo já está em reprodução."</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Não é possível ignorar mais faixas."</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Não foi possível terminar. Tente novamente."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Não existem mais elementos em fila."</string>
 </resources>
diff --git a/car-media-common/res/values-pt/strings.xml b/car-media-common/res/values-pt/strings.xml
index b2138e1..1b39a7b 100644
--- a/car-media-common/res/values-pt/strings.xml
+++ b/car-media-common/res/values-pt/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Arte do álbum"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Sem título"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Algo deu errado. Tente mais tarde."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Não é possível fazer isso no momento"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Não é possível fazer isso com este app"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Faça login para usar este app"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"É necessário ter acesso Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Ouvindo em muitos dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Esse conteúdo está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Não é possível acessar esse conteúdo aqui"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Esse conteúdo já está tocando"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Não é possível pular mais faixas"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Não foi possível concluir esta ação. Tente novamente."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Não há mais nada na fila"</string>
 </resources>
diff --git a/car-media-common/res/values-ro/strings.xml b/car-media-common/res/values-ro/strings.xml
index b0a4689..38c53cc 100644
--- a/car-media-common/res/values-ro/strings.xml
+++ b/car-media-common/res/values-ro/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Grafica albumului"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Fără titlu"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"A apărut o problemă. Încercați mai târziu."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Acțiunea nu poate fi realizată momentan"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Aplicația nu poate realiza această acțiune"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Conectați-vă pentru a folosi aplicația"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Este necesar accesul premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Se ascultă pe prea multe dispozitive"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Conținutul este blocat"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Conținutul nu poate fi descărcat aici"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Conținutul se redă deja"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Nu mai pot fi omise melodii"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nu s-a putut finaliza. Reîncercați."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Nu mai există elemente în coadă"</string>
 </resources>
diff --git a/car-media-common/res/values-ru/strings.xml b/car-media-common/res/values-ru/strings.xml
index 6f4a6ba..990650f 100644
--- a/car-media-common/res/values-ru/strings.xml
+++ b/car-media-common/res/values-ru/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Обложка альбома"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Без названия"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Ошибка. Повторите попытку позже."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Сейчас это действие недоступно."</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Действие недоступно в этом приложении."</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Чтобы использовать это приложение, войдите в аккаунт."</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Требуется премиум-доступ."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Слишком много устройств, на которых воспроизводится аудио."</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Контент заблокирован."</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Контент недоступен в вашем регионе."</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Этот контент уже воспроизводится."</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Пропускать треки больше нельзя."</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Произошла ошибка. Повторите попытку."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"В очереди воспроизведения нет других файлов."</string>
 </resources>
diff --git a/car-media-common/res/values-si/strings.xml b/car-media-common/res/values-si/strings.xml
index f748730..7da552b 100644
--- a/car-media-common/res/values-si/strings.xml
+++ b/car-media-common/res/values-si/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ඇල්බම කලාව"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"මාතෘකාවක් නැත"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"යම් දෙයක් වැරදියි. පසුව උත්සාහ කරන්න."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"මේ දැන් එය කළ නොහැක"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"මෙම යෙදුමට එය කළ නොහැක"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"මෙම යෙදුම භාවිත කිරීමට පුරන්න"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"පාරිතෝෂික ප්‍රවේශය අවශ්‍යයි"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"ඕනෑවට වඩා උපාංග මත සවන් දීම"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"එම අන්තර්ගතය අවහිර කර ඇත"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"එම අන්තර්ගතය මෙතැනින් ලබා ගත නොහැක"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"දැනටමත් එම අන්තර්ගතය වාදනය කරයි"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"තවත් ගීත මඟ හැරිය නොහැක"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"අවසන් කිරීමට නොහැකි විය. නැවත උත්සාහ කරන්න."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"වෙන කිසිවක් පෝලිමේ නැත"</string>
 </resources>
diff --git a/car-media-common/res/values-sk/strings.xml b/car-media-common/res/values-sk/strings.xml
index 7a12c96..d94bac4 100644
--- a/car-media-common/res/values-sk/strings.xml
+++ b/car-media-common/res/values-sk/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Obrázok albumu"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Bez názvu"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Vyskytol sa problém. Skúste to znova."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Teraz to nie je možné"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Táto aplikácia to nedokáže"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Ak chcete použiť túto aplikáciu, prihláste sa"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Vyžaduje sa prémiový prístup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Počúva sa na príliš veľa zariadeniach"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Daný obsah je blokovaný"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Daný obsah tu nie je k dispozícii"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Tento obsah sa už prehráva"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Nie je možné preskočiť žiadne ďalšie skladby"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Akciu sa nepodarilo dokončiť. Skúste to znova."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Poradie je prázdne"</string>
 </resources>
diff --git a/car-media-common/res/values-sl/strings.xml b/car-media-common/res/values-sl/strings.xml
index aec70f5..683507c 100644
--- a/car-media-common/res/values-sl/strings.xml
+++ b/car-media-common/res/values-sl/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Slika albuma"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Brez naslova"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Prišlo je do težave. Poskusite pozneje."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Trenutno to ni izvedljivo"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ta aplikacija ne more izvesti tega"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Prijavite se, če želite uporabljati to aplikacijo"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Potrebujete plačljiv dostop"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Poslušanje v preveč napravah"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Ta vsebina je blokirana"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Te vsebine tukaj ni mogoče pridobiti"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Ta vsebina se že predvaja"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Dosegli ste omejitev preskakovanja skladb"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Ni bilo mogoče dokončati. Poskusite znova."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Čakalna vrsta je prazna"</string>
 </resources>
diff --git a/car-media-common/res/values-sq/strings.xml b/car-media-common/res/values-sq/strings.xml
index d4d02e1..354b5ed 100644
--- a/car-media-common/res/values-sq/strings.xml
+++ b/car-media-common/res/values-sq/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Kopertina e albumit"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Pa titull"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Ndodhi një gabim. Provo më vonë."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Këtë nuk mund ta bësh në këtë moment"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ky aplikacion nuk mund ta bëjë këtë"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Identifikohu për të përdorur këtë aplikacion"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Kërkohet qasje Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Po dëgjon në shumë pajisje"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Kjo përmbajtje është bllokuar"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Ajo përmbajtje nuk mund të merret këtu"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Ajo përmbajtje po luhet tashmë"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Nuk mund të kapërcejë këngë të tjera"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Nuk mundi të përfundojë. Provo sërish."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Asgjë tjetër nuk është në radhë"</string>
 </resources>
diff --git a/car-media-common/res/values-sr/strings.xml b/car-media-common/res/values-sr/strings.xml
index 69c898d..e6173ba 100644
--- a/car-media-common/res/values-sr/strings.xml
+++ b/car-media-common/res/values-sr/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Омот албума"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Без наслова"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Дошло је до грешке. Пробајте касније."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Тренутно не може то да уради"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ова апликација не може то да уради"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Пријавите се да бисте користили ову апликацију"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Потребан је премијум приступ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Слушате на превише уређаја"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Тај садржај је блокиран"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Не можете да добијете тај садржај овде"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Тај садржај се већ репродукује"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Не можете више да прескачете песме"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Нисмо успели да довршимо радњу. Пробајте опет."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ништа друго није стављено у редослед"</string>
 </resources>
diff --git a/car-media-common/res/values-sv/strings.xml b/car-media-common/res/values-sv/strings.xml
index 05a0d28..ce52ecf 100644
--- a/car-media-common/res/values-sv/strings.xml
+++ b/car-media-common/res/values-sv/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Skivomslag"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Ingen titel"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Något är fel. Försök igen senare."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Det går inte just nu"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Det går inte med den här appen"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Logga in om du vill använda appen"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium-konto krävs"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"För många enheter streamas"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Det innehållet har blockerats"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Det innehållet är inte tillgängligt här"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Det innehållet spelas redan"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Det går inte att hoppa över fler låtar"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Det gick inte att slutföra. Försök igen."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Inget annat har lagts i uppspelningskön"</string>
 </resources>
diff --git a/car-media-common/res/values-sw/strings.xml b/car-media-common/res/values-sw/strings.xml
index 30937ac..282555c 100644
--- a/car-media-common/res/values-sw/strings.xml
+++ b/car-media-common/res/values-sw/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Sanaa ya Albamu"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Hakuna Jina"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Hitilafu fulani imetokea. Jaribu baadaye."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Imeshindwa kutekeleza ombi kwa sasa"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Programu hii imeshindwa kutekeleza ombi lako"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Ingia katika akaunti ili utumie programu hii"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Unahitaji kutumia akaunti ya kulipia"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Unasikiliza kwenye vifaa vingi mno"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Maudhui hayo yamezuiwa"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Imeshindwa kupata maudhui haya hapa"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Tayari inacheza wimbo huo"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Imeshindwa kuruka nyimbo zaidi"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Imeshindwa kumaliza. Jaribu tena."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Hakuna wimbo mwingine kwenye foleni"</string>
 </resources>
diff --git a/car-media-common/res/values-ta/strings.xml b/car-media-common/res/values-ta/strings.xml
index 6fc14ba..dd522b8 100644
--- a/car-media-common/res/values-ta/strings.xml
+++ b/car-media-common/res/values-ta/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ஆல்பம் ஆர்ட்"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"தலைப்பு இல்லை"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"ஏதோ தவறாகிவிட்டது. பிறகு முயலவும்."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"தற்சமயம் இதைச் செய்ய இயலாது"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"இந்த ஆப்ஸால் அதைச் செய்ய இயலாது"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"இந்த ஆப்ஸை உபயோகிக்க உள்நுழைய வேண்டும்"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium அணுகல் தேவை"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"நிறைய சாதனங்களைக் கவனிக்கிறது"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"அந்த உள்ளடக்கம் தடுக்கப்பட்டுள்ளது"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"அந்த உள்ளடக்கத்தை இங்கே பெற முடியவில்லை"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"அந்த உள்ளடக்கம் ஏற்கெனவே பிளே செய்யப்பட்டுக் கொண்டிருக்கிறது"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"இதற்கு மேல் டிராக்குகளைத் தவிர்க்க முடியாது"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"நிறைவடையவில்லை. மீண்டும் முயலவும்."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"வேறு எதுவும் வரிசையில் இல்லை"</string>
 </resources>
diff --git a/car-media-common/res/values-te/strings.xml b/car-media-common/res/values-te/strings.xml
index f3dec11..62a7464 100644
--- a/car-media-common/res/values-te/strings.xml
+++ b/car-media-common/res/values-te/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ఆల్బమ్ ఆర్ట్"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"శీర్షిక లేదు"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"ఏదో తప్పు జరిగింది. తర్వాత ట్రై చేయండి."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"దానిని ఇప్పుడు చేయడం సాధ్యపడదు"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"ఈ యాప్ దానిని చేయలేదు"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ఈ యాప్‌ను ఉపయోగించడానికి సైన్ ఇన్ చేయండి"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ప్రీమియం యాక్సెస్ అవసరం"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"అనేక పరికరాలలో వింటున్నారు"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"ఆ కంటెంట్ బ్లాక్ చేయబడింది"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"ఆ కంటెంట్‌ను ఇక్కడ పొందడం సాధ్యపడదు"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"ఇప్పటికే ఆ కంటెంట్ ప్లే అవుతోంది"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ఇంక ఏ ట్రాక్‌లనూ స్కిప్ చేయడం సాధ్యపడదు"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"పూర్తి చేయడం సాధ్యపడలేదు. మళ్లీ ట్రై చేయండి."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"క్రమ వరుసలో ఏమీ లేదు"</string>
 </resources>
diff --git a/car-media-common/res/values-th/strings.xml b/car-media-common/res/values-th/strings.xml
index 3e3aa59..f642719 100644
--- a/car-media-common/res/values-th/strings.xml
+++ b/car-media-common/res/values-th/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"ปกอัลบั้ม"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"ไม่มีชื่อ"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"มีข้อผิดพลาดเกิดขึ้น ลองอีกครั้งในภายหลัง"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ดำเนินการดังกล่าวไม่ได้ในขณะนี้"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"แอปนี้ดำเนินการดังกล่าวไม่ได้"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"ลงชื่อเข้าใช้เพื่อใช้แอปนี้"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"ต้องมีสิทธิ์เข้าถึงระดับพรีเมียม"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"กำลังเปิดฟังจากหลายอุปกรณ์เกินไป"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"เนื้อหาดังกล่าวถูกบล็อก"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"เปิดเนื้อหาดังกล่าวไม่ได้ที่นี่"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"กำลังเล่นเนื้อหาดังกล่าวอยู่แล้ว"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"ข้ามแทร็กอื่นอีกไม่ได้แล้ว"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"ดำเนินการไม่สำเร็จ ลองใหม่"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"ไม่มีรายการอื่นในคิว"</string>
 </resources>
diff --git a/car-media-common/res/values-tl/strings.xml b/car-media-common/res/values-tl/strings.xml
index 39bc081..a2da896 100644
--- a/car-media-common/res/values-tl/strings.xml
+++ b/car-media-common/res/values-tl/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Album Art"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Walang Pamagat"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"May problema. Subukan sa ibang pagkakataon."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Hindi iyon magagawa ngayon"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Hindi iyon magagawa ng app na ito"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Mag-sign in para gamitin ang app na ito"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Kailangan ng premium na access"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Nakikinig sa masyadong maraming device"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Naka-block ang content na iyon"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Hindi makukuha ang content na iyon dito"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Pine-play na ang content na iyon"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Hindi na makakalaktaw pa ng track"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Hindi matapos. Subukan ulit."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Wala nang naka-queue"</string>
 </resources>
diff --git a/car-media-common/res/values-tr/strings.xml b/car-media-common/res/values-tr/strings.xml
index 7fc645e..6f717ac 100644
--- a/car-media-common/res/values-tr/strings.xml
+++ b/car-media-common/res/values-tr/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albüm Kapağı"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Başlıksız"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Bir şeyler ters gitti. Daha sonra tekrar deneyin."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"İşlem şu anda gerçekleştirilemiyor"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Uygulama bu işlemi gerçekleştiremiyor"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Bu uygulamayı kullanmak için oturum açın"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Premium erişim gerekli"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Çok fazla cihazda dinleme yapılıyor"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Bu içerik engellendi"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"İçeriğe buradan erişilemiyor"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Bu içerik zaten oynatılıyor"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Daha fazla parça atlanamıyor"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Tamamlanamadı. Tekrar deneyin."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Sıraya eklenmiş başka bir şey yok"</string>
 </resources>
diff --git a/car-media-common/res/values-uk/strings.xml b/car-media-common/res/values-uk/strings.xml
index e377c98..0661490 100644
--- a/car-media-common/res/values-uk/strings.xml
+++ b/car-media-common/res/values-uk/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Обкладинка альбому"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Без назви"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Сталася помилка. Повторіть спробу пізніше."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Наразі ця дія недоступна"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Додаток не підтримує цю дію"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Увійдіть, щоб використовувати цей додаток"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Потрібен преміум-доступ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Забагато пристроїв, на яких відтворюється контент"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Цей контент заблоковано"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Цей контент недоступний у вашому регіоні"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Цей контент уже відтворюється"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Більше не можна пропускати композиції"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Не вдалося закінчити. Повторіть спробу."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Черга порожня"</string>
 </resources>
diff --git a/car-media-common/res/values-ur/strings.xml b/car-media-common/res/values-ur/strings.xml
index 19dfce7..ccf505c 100644
--- a/car-media-common/res/values-ur/strings.xml
+++ b/car-media-common/res/values-ur/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"البم آرٹ"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"کوئی عنوان نہیں ہے"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"کچھ غلط ہو گیا۔ بعد میں کوشش کریں۔"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"ابھی وہ ایسا نہیں کر سکتا"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"یہ ایپ ایسا نہیں کر سکتی"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"اس ایپ کا استعمال کرنے کے لیے سائن ان کریں"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"پریمیم رسائی درکار ہے"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"بہت سے آلات پر سنا جا رہا ہے"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"وہ مواد مسدود ہے"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"یہاں وہ مواد حاصل نہیں کر سکتے"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"وہ مواد پہلے سے ہی چلایا جا رہا ہے"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"مزید کسی اور ٹریکس کو نظر انداز نہیں کر سکتے"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"پورا نہیں ہو سکا۔ پھر آزمائيں۔"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"مزید کچھ اور کی قطار نہیں ہے"</string>
 </resources>
diff --git a/car-media-common/res/values-uz/strings.xml b/car-media-common/res/values-uz/strings.xml
index b2bfd1e..f3e8826 100644
--- a/car-media-common/res/values-uz/strings.xml
+++ b/car-media-common/res/values-uz/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Albom muqovasi"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Nomsiz"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Nimadir xato ketdi Keyinroq qayta urining."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Buni hozir amalga oshira olmaydi"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Bu ilova bu amalni bajara olmaydi"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Bu ilovadan foydalanish uchun hisobingizga kiring"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Ishonchli ruxsat kerak"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Koʻplab qurilmalar tinglanmoqda"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Bu kontent bloklangan"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Bu kontentni bu yerga olish imkonsiz"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Bu kontent allaqachon ijro etilmoqda"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Boshqa treklarni qoldirib ketish imkonsiz"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Tugallanmadi. Qayta urining."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Ijro navbatida boshqa fayllar mavjud emas"</string>
 </resources>
diff --git a/car-media-common/res/values-vi/strings.xml b/car-media-common/res/values-vi/strings.xml
index f75fe5a..2a99840 100644
--- a/car-media-common/res/values-vi/strings.xml
+++ b/car-media-common/res/values-vi/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Ảnh bìa album"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Không có tiêu đề"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Đã xảy ra lỗi. Hãy thử lại sau."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Không thể thực hiện yêu cầu đó ngay bây giờ"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Ứng dụng này không thể thực hiện yêu cầu đó"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Hãy đăng nhập để dùng ứng dụng này"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Yêu cầu quyền truy cập đặc biệt"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Đang nghe trên quá nhiều thiết bị"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Nội dung đó đã bị chặn"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Không thể xem nội dung đó tại đây"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Đang phát nội dung đó rồi"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Không thể bỏ qua bản nhạc nào nữa"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Không thể hoàn tất. Hãy thử lại."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Không có nội dung nào khác trong hàng đợi"</string>
 </resources>
diff --git a/car-media-common/res/values-zh-rCN/strings.xml b/car-media-common/res/values-zh-rCN/strings.xml
index 9688f0e..b3ddef1 100644
--- a/car-media-common/res/values-zh-rCN/strings.xml
+++ b/car-media-common/res/values-zh-rCN/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"专辑封面"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"无标题"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"出了点问题。请稍后重试。"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"目前无法执行该操作"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"此应用无法执行该操作"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"登录才能使用此应用"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"需要有付费帐号才能访问"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"同时使用太多设备聆听"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"该内容已遭到屏蔽"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"所在地区不提供这项内容"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"系统已在播放这项内容"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"无法再跳过更多曲目"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"无法完成操作。请重试。"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"队列中没有任何其他内容"</string>
 </resources>
diff --git a/car-media-common/res/values-zh-rHK/strings.xml b/car-media-common/res/values-zh-rHK/strings.xml
index 1e84ca7..6ce371a 100644
--- a/car-media-common/res/values-zh-rHK/strings.xml
+++ b/car-media-common/res/values-zh-rHK/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"專輯封面"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"無標題"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"發生錯誤,請稍後再試。"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"目前無法執行此操作"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"應用程式不支援此操作"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"登入帳戶才能使用此應用程式"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"必須付費才能存取"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"同時使用太多裝置聆聽音樂"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"內容已被封鎖"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"所在地區不提供該內容"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"系統已開始播放該內容"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"無法再略過曲目"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"無法完成此操作,請再試一次。"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"序列上沒有其他項目"</string>
 </resources>
diff --git a/car-media-common/res/values-zh-rTW/strings.xml b/car-media-common/res/values-zh-rTW/strings.xml
index 47a62ca..6ce371a 100644
--- a/car-media-common/res/values-zh-rTW/strings.xml
+++ b/car-media-common/res/values-zh-rTW/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"專輯封面"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"無標題"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"發生錯誤,請稍後再試。"</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"目前無法執行這項操作"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"應用程式不支援這項操作"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"必須登入帳戶,才能使用這個應用程式"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"必須付費才能使用"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"同時使用太多裝置聆聽音樂"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"內容已遭到封鎖"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"所在地區不提供該內容"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"系統已開始播放該內容"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"無法再略過曲目"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"無法完成這項操作,請再試一次。"</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"待播清單上沒有其他項目"</string>
 </resources>
diff --git a/car-media-common/res/values-zu/strings.xml b/car-media-common/res/values-zu/strings.xml
index 6f06f6d..cde3b48 100644
--- a/car-media-common/res/values-zu/strings.xml
+++ b/car-media-common/res/values-zu/strings.xml
@@ -19,16 +19,4 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="album_art" msgid="3392647029019061691">"Ubuciko be-albhamu"</string>
     <string name="metadata_default_title" msgid="5902775732281325081">"Asikho isihloko"</string>
-    <string name="default_error_message" msgid="4044331619453864482">"Kukhona okungalungile. Zama emuva kwesikhathi."</string>
-    <string name="error_code_app_error" msgid="3608680401453743688">"Ayikwazi ukwenza lokho khona manje"</string>
-    <string name="error_code_not_supported" msgid="8004310657548193089">"Lolu hlelo lokusebenza alukwazi ukwenza lokho"</string>
-    <string name="error_code_authentication_expired" msgid="1727285213286610186">"Ngena ngemvume ukuze usebenzise lolu hlelo lokusebenza"</string>
-    <string name="error_code_premium_account_required" msgid="2328664287270814966">"Ukufinyelela kwe-premium kuyadingeka"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="493048763425570552">"Ilalele kumadivayisi amaningi kakhulu"</string>
-    <string name="error_code_parental_control_restricted" msgid="325145513462419399">"Lokho okuqukethwe kuvinjelwe"</string>
-    <string name="error_code_not_available_in_region" msgid="5840935836875073145">"Ayikwazi ukuletha lokho okuqukethwe lapha"</string>
-    <string name="error_code_content_already_playing" msgid="1306236349553004461">"Isivele idlala lokho okuqukethwe"</string>
-    <string name="error_code_skip_limit_reached" msgid="4203743406433151146">"Ayikwazi ukweqa amanye amathrekhi amaningi"</string>
-    <string name="error_code_action_aborted" msgid="8611777981356536501">"Ayikwazanga ukuqeda. Zama futhi."</string>
-    <string name="error_code_end_of_queue" msgid="6935022448319288887">"Akukho okunye okufakwe kulayini"</string>
 </resources>
diff --git a/car-media-common/res/values/bools.xml b/car-media-common/res/values/bools.xml
index fee9fec..85fce20 100644
--- a/car-media-common/res/values/bools.xml
+++ b/car-media-common/res/values/bools.xml
@@ -22,9 +22,4 @@
     <!-- Whether to show a circular progress bar in control bar and minimized control bar or not. -->
     <bool name="show_circular_progress_bar">false</bool>
 
-    <!-- Whether the media source logo should be used for the app selector button. If the flag is
-        set to 'true', the main logo (which by default appears on the left hand side on toolbar)
-        will be hidden. -->
-    <bool name="use_media_source_logo_for_app_selector">false</bool>
-
 </resources>
diff --git a/car-media-common/res/values/config.xml b/car-media-common/res/values/config.xml
index 5f8aab1..34c1eb6 100644
--- a/car-media-common/res/values/config.xml
+++ b/car-media-common/res/values/config.xml
@@ -16,16 +16,14 @@
   -->
 
 <resources>
-    <!-- Intent used to launch the app selector as popup.
-        This should be overlaid to match the actual launcher included in the car. -->
+    <!-- Intent used to launch the app selector as popup -->
     <string name="launcher_popup_intent" translatable="false">
-        intent:#Intent;action=com.android.car.carlauncher.ACTION_APP_GRID;launchFlags=0x24000000;S.com.android.car.carlauncher.mode=MEDIA_POPUP;end
+        intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;S.com.android.car.carlauncher.mode=MEDIA_POPUP;end
     </string>
 
-    <!-- Intent used to launch the app selector full screen.
-        This should be overlaid to match the actual launcher included in the car. -->
+    <!-- Intent used to launch the app selector -->
     <string name="launcher_intent" translatable="false">
-        intent:#Intent;action=com.android.car.carlauncher.ACTION_APP_GRID;launchFlags=0x24000000;S.com.android.car.carlauncher.mode=MEDIA_ONLY;end
+        intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;S.com.android.car.carlauncher.mode=MEDIA_ONLY;end
     </string>
 
     <!-- A list of custom media component names, which are created by calling
diff --git a/car-media-common/res/values/dimens.xml b/car-media-common/res/values/dimens.xml
index 058ec8e..d888e4b 100644
--- a/car-media-common/res/values/dimens.xml
+++ b/car-media-common/res/values/dimens.xml
@@ -24,8 +24,6 @@
     <!-- playback_fragment.xml -->
     <dimen name="playback_fragment_text_margin_top">@dimen/car_ui_padding_4</dimen>
     <dimen name="playback_fragment_text_margin_x">@dimen/car_ui_padding_4</dimen>
-    <dimen name="playback_fragment_error_button_margin_top">@dimen/car_ui_padding_5</dimen>
-    <dimen name="playback_fragment_error_button_margin_bottom">@dimen/car_ui_padding_4</dimen>
 
     <dimen name="playback_fragment_app_icon_margin_right">@dimen/car_ui_padding_4</dimen>
     <dimen name="playback_fragment_controls_margin_bottom">@dimen/car_ui_padding_4</dimen>
diff --git a/car-media-common/res/values/integers.xml b/car-media-common/res/values/integers.xml
index cda2e06..2c6177d 100644
--- a/car-media-common/res/values/integers.xml
+++ b/car-media-common/res/values/integers.xml
@@ -36,7 +36,4 @@
     -->
     <integer name="media_items_bitmap_max_size_px">256</integer>
 
-    <!-- The maximum number of lines for the error message in the media widget. -->
-    <integer name="widget_error_text_max_lines">3</integer>
-
 </resources>
diff --git a/car-media-common/res/values/strings.xml b/car-media-common/res/values/strings.xml
index 424e9f7..e5831bc 100644
--- a/car-media-common/res/values/strings.xml
+++ b/car-media-common/res/values/strings.xml
@@ -19,29 +19,4 @@
     <string name="album_art">Album Art</string>
     <!-- Default title of current track's metadata. [CHAR LIMIT=50] -->
     <string name="metadata_default_title">No Title</string>
-
-    <!-- Default error message [CHAR LIMIT=100] -->
-    <string name="default_error_message">Something’s wrong. Try later.</string>
-    <!-- Error message set when the application state is invalid to fulfill the request. [CHAR LIMIT=100] -->
-    <string name="error_code_app_error">Can’t do that right now</string>
-    <!-- Error message set when the request is not supported by the application. [CHAR LIMIT=100] -->
-    <string name="error_code_not_supported">This app can’t do that</string>
-    <!-- Error message set when the request cannot be performed because authentication has expired. [CHAR LIMIT=100] -->
-    <string name="error_code_authentication_expired">Sign in to use this app</string>
-    <!-- Error message set when a premium account is required for the request to succeed. [CHAR LIMIT=100] -->
-    <string name="error_code_premium_account_required">Premium access required</string>
-    <!-- Error message set when too many concurrent streams are detected. [CHAR LIMIT=100] -->
-    <string name="error_code_concurrent_stream_limit">Listening on too many devices</string>
-    <!-- Error message set when the content is blocked due to parental controls. [CHAR LIMIT=100] -->
-    <string name="error_code_parental_control_restricted">That content is blocked</string>
-    <!-- Error message set when the content is blocked due to being regionally unavailable. [CHAR LIMIT=100] -->
-    <string name="error_code_not_available_in_region">Can’t get that content here</string>
-    <!-- Error message set when the requested content is already playing. [CHAR LIMIT=100] -->
-    <string name="error_code_content_already_playing">Already playing that content</string>
-    <!-- Error message set when the application cannot skip any more songs because skip limit is reached. [CHAR LIMIT=100] -->
-    <string name="error_code_skip_limit_reached">Can’t skip any more tracks</string>
-    <!-- Error message set when the action is interrupted due to some external event. [CHAR LIMIT=100] -->
-    <string name="error_code_action_aborted">Couldn’t finish. Try again.</string>
-    <!-- Error message set when the playback navigation (previous, next) is not possible because the queue was exhausted. [CHAR LIMIT=100] -->
-    <string name="error_code_end_of_queue">Nothing else is queued up</string>
 </resources>
diff --git a/car-media-common/src/com/android/car/media/common/ControlBarHelper.java b/car-media-common/src/com/android/car/media/common/ControlBarHelper.java
index 4e3b7b9..0f011fd 100644
--- a/car-media-common/src/com/android/car/media/common/ControlBarHelper.java
+++ b/car-media-common/src/com/android/car/media/common/ControlBarHelper.java
@@ -64,8 +64,8 @@
 
         model.getProgress().observe(owner,
                 progress -> {
-                    progressBar.setMax((int) progress.getMaxProgress());
                     progressBar.setProgress((int) progress.getProgress());
+                    progressBar.setMax((int) progress.getMaxProgress());
                 });
     }
 }
diff --git a/car-media-common/src/com/android/car/media/common/MediaButtonController.java b/car-media-common/src/com/android/car/media/common/MediaButtonController.java
index 1db7a31..48e0406 100644
--- a/car-media-common/src/com/android/car/media/common/MediaButtonController.java
+++ b/car-media-common/src/com/android/car/media/common/MediaButtonController.java
@@ -41,9 +41,7 @@
 import com.android.car.media.common.source.MediaSourceColors;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -56,8 +54,6 @@
 
     private static final String TAG = "MediaButton";
 
-    private final Map<String, ImageButton> mImageButtons = new HashMap<>();
-
     private Context mContext;
     private PlayPauseStopImageView mPlayPauseStopImageView;
     private View mPlayPauseStopImageContainer;
@@ -84,13 +80,11 @@
         mPlayPauseStopImageContainer.setOnClickListener(this::onPlayPauseStopClicked);
         mPlayPauseStopImageView = mPlayPauseStopImageContainer.findViewById(R.id.play_pause_stop);
         mPlayPauseStopImageView.setVisibility(View.INVISIBLE);
+        mPlayPauseStopImageView.setFocusedByDefault(true);
         mCircularProgressBar = mPlayPauseStopImageContainer.findViewById(
                 R.id.circular_progress_bar);
         mPlayPauseStopImageView.setAction(PlayPauseStopImageView.ACTION_DISABLED);
         mPlayPauseStopImageView.setOnClickListener(this::onPlayPauseStopClicked);
-        // In non-touch mode, a browse list will request focus explicitly and its first element
-        // will get focused instead of this button
-        mPlayPauseStopImageView.setFocusedByDefault(true);
 
         mShowCircularProgressBar = context.getResources().getBoolean(
                 R.bool.show_circular_progress_bar);
@@ -140,7 +134,6 @@
         mControlBar.setView(null, ControlBar.SLOT_RIGHT);
         mSkipNextAdded = false;
         mSkipPrevAdded = false;
-        mImageButtons.clear();
     }
 
     private ImageButton createIconButton(Drawable icon) {
@@ -235,7 +228,12 @@
             imageButtons.addAll(state.getCustomActions()
                     .stream()
                     .map(rawAction -> rawAction.fetchDrawable(mContext))
-                    .map(action -> getOrCreateIconButton(action))
+                    .map(action -> {
+                        ImageButton button = createIconButton(action.mIcon);
+                        button.setOnClickListener(view ->
+                                mController.doCustomAction(action.mAction, action.mExtras));
+                        return button;
+                    })
                     .collect(Collectors.toList()));
         }
         if (!mSkipPrevAdded && !imageButtons.isEmpty()) {
@@ -247,21 +245,6 @@
         mControlBar.setViews(imageButtons.toArray(new ImageButton[0]));
     }
 
-    private ImageButton getOrCreateIconButton(CustomPlaybackAction action) {
-        // Reuse the ImageButton with the same action identifier if it exists, because if the
-        // ImageButton is focused, replacing it with a new one will make it lose focus.
-        ImageButton button = mImageButtons.get(action.mAction);
-        if (button != null) {
-            button.setImageDrawable(action.mIcon);
-        } else {
-            button = createIconButton(action.mIcon);
-            mImageButtons.put(action.mAction, button);
-        }
-        button.setOnClickListener(view ->
-                mController.doCustomAction(action.mAction, action.mExtras));
-        return button;
-    }
-
     private void onPlayPauseStopClicked(View view) {
         if (mController == null) {
             return;
diff --git a/car-media-common/src/com/android/car/media/common/MetadataController.java b/car-media-common/src/com/android/car/media/common/MetadataController.java
index e43753f..baeca11 100644
--- a/car-media-common/src/com/android/car/media/common/MetadataController.java
+++ b/car-media-common/src/com/android/car/media/common/MetadataController.java
@@ -47,12 +47,7 @@
             new SeekBar.OnSeekBarChangeListener() {
                 @Override
                 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-                    // Allow to set the progress via the rotary controller. It will do nothing
-                    // when the user uses touch screen because no view will be focused in touch
-                    // mode.
-                    if (mController != null && fromUser && seekBar.isFocused()) {
-                        mController.seekTo(seekBar.getProgress());
-                    }
+                    // Do nothing.
                 }
 
                 @Override
diff --git a/car-media-common/src/com/android/car/media/common/MinimizedPlaybackControlBar.java b/car-media-common/src/com/android/car/media/common/MinimizedPlaybackControlBar.java
index 17a37b2..9cfda34 100644
--- a/car-media-common/src/com/android/car/media/common/MinimizedPlaybackControlBar.java
+++ b/car-media-common/src/com/android/car/media/common/MinimizedPlaybackControlBar.java
@@ -62,7 +62,7 @@
 
     private void init(Context context) {
         mMediaButtonController = new MediaButtonController(context, this,
-                R.color.playback_control_color, R.layout.minimized_play_pause_stop_button_layout,
+                R.color.playback_control_color, R.layout.play_pause_stop_button_layout,
                 R.drawable.ic_skip_previous, R.drawable.ic_skip_next);
 
         mShowLinearProgressBar = context.getResources().getBoolean(R.bool.show_linear_progress_bar);
diff --git a/car-media-common/src/com/android/car/media/common/PlaybackErrorViewController.java b/car-media-common/src/com/android/car/media/common/PlaybackErrorViewController.java
deleted file mode 100644
index 2d4c7c8..0000000
--- a/car-media-common/src/com/android/car/media/common/PlaybackErrorViewController.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.media.common;
-
-import android.app.PendingIntent;
-import android.car.drivingstate.CarUxRestrictions;
-import android.content.res.Resources;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import com.android.car.apps.common.UxrButton;
-import com.android.car.apps.common.UxrTextView;
-import com.android.car.apps.common.util.ViewUtils;
-
-
-/** Simple controller for the error message and the error button. */
-public class PlaybackErrorViewController {
-
-    private static final String TAG = "PlaybckErrViewCtrlr";
-
-    // mErrorMessageView is defined explicitly as a UxrTextView instead of a TextView to
-    // provide clarity as it may be misleading to assume that mErrorMessageView extends all TextView
-    // methods. In addition, it increases discoverability of runtime issues that may occur.
-    private final UxrTextView mErrorMessageView;
-    private final UxrButton mErrorButton;
-
-    private final int mFadeDuration;
-
-    public PlaybackErrorViewController(View content) {
-        mErrorMessageView = content.findViewById(R.id.error_message);
-        mErrorButton = content.findViewById(R.id.error_button);
-
-        Resources res = content.getContext().getResources();
-        mFadeDuration = res.getInteger(R.integer.new_album_art_fade_in_duration);
-    }
-
-    /** Animates away the error views. */
-    public void hideError() {
-        ViewUtils.hideViewAnimated(mErrorMessageView, mFadeDuration);
-        ViewUtils.hideViewAnimated(mErrorButton, mFadeDuration);
-    }
-
-    /** Hides the error views without animation. */
-    public void hideErrorNoAnim() {
-        ViewUtils.hideViewAnimated(mErrorMessageView, 0);
-        ViewUtils.hideViewAnimated(mErrorButton, 0);
-    }
-
-    /** Sets the error message and optionally the error button. */
-    public void setError(String message, @Nullable String label,
-            @Nullable PendingIntent pendingIntent, boolean isDistractionOptimized) {
-        mErrorMessageView.setText(message);
-        ViewUtils.showViewAnimated(mErrorMessageView, mFadeDuration);
-
-        // Only show the error button if the error is actionable.
-        if (label != null && pendingIntent != null) {
-            mErrorButton.setText(label);
-
-            mErrorButton.setUxRestrictions(isDistractionOptimized
-                    ? CarUxRestrictions.UX_RESTRICTIONS_BASELINE
-                    : CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP);
-
-            mErrorButton.setOnClickListener(v -> {
-                try {
-                    pendingIntent.send();
-                } catch (PendingIntent.CanceledException e) {
-                    if (Log.isLoggable(TAG, Log.ERROR)) {
-                        Log.e(TAG, "Pending intent canceled");
-                    }
-                }
-            });
-            ViewUtils.showViewAnimated(mErrorButton, mFadeDuration);
-        } else {
-            ViewUtils.hideViewAnimated(mErrorButton, mFadeDuration);
-        }
-    }
-}
diff --git a/car-media-common/src/com/android/car/media/common/PlaybackErrorsHelper.java b/car-media-common/src/com/android/car/media/common/PlaybackErrorsHelper.java
deleted file mode 100644
index 475346d..0000000
--- a/car-media-common/src/com/android/car/media/common/PlaybackErrorsHelper.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.media.common;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.media.common.playback.PlaybackViewModel.PlaybackStateWrapper;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Abstract class to factorize most of the error handling logic.
- */
-public abstract class PlaybackErrorsHelper {
-
-    private static final Map<Integer, Integer> ERROR_CODE_MESSAGES_MAP;
-
-    static {
-        Map<Integer, Integer> map = new HashMap<>();
-        map.put(PlaybackStateCompat.ERROR_CODE_APP_ERROR, R.string.error_code_app_error);
-        map.put(PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED, R.string.error_code_not_supported);
-        map.put(PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
-                R.string.error_code_authentication_expired);
-        map.put(PlaybackStateCompat.ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED,
-                R.string.error_code_premium_account_required);
-        map.put(PlaybackStateCompat.ERROR_CODE_CONCURRENT_STREAM_LIMIT,
-                R.string.error_code_concurrent_stream_limit);
-        map.put(PlaybackStateCompat.ERROR_CODE_PARENTAL_CONTROL_RESTRICTED,
-                R.string.error_code_parental_control_restricted);
-        map.put(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION,
-                R.string.error_code_not_available_in_region);
-        map.put(PlaybackStateCompat.ERROR_CODE_CONTENT_ALREADY_PLAYING,
-                R.string.error_code_content_already_playing);
-        map.put(PlaybackStateCompat.ERROR_CODE_SKIP_LIMIT_REACHED,
-                R.string.error_code_skip_limit_reached);
-        map.put(PlaybackStateCompat.ERROR_CODE_ACTION_ABORTED, R.string.error_code_action_aborted);
-        map.put(PlaybackStateCompat.ERROR_CODE_END_OF_QUEUE, R.string.error_code_end_of_queue);
-        ERROR_CODE_MESSAGES_MAP = Collections.unmodifiableMap(map);
-    }
-
-    private final Context mContext;
-    private PlaybackStateWrapper mCurrentPlaybackStateWrapper;
-
-    public PlaybackErrorsHelper(Context context) {
-        mContext = context;
-    }
-
-    protected abstract void handleNewPlaybackState(String displayedMessage, PendingIntent intent,
-            String label);
-
-    /**
-     * Triggers updates of the error state.
-     * Must be called when the children list of the root of the browse tree changes AND when
-     * the playback state changes.
-     */
-    public void handlePlaybackState(@NonNull String tag, PlaybackStateWrapper state,
-            boolean ignoreSameState) {
-        if (Log.isLoggable(tag, Log.DEBUG)) {
-            Log.d(tag,
-                    "handlePlaybackState(); state change: " + (mCurrentPlaybackStateWrapper != null
-                            ? mCurrentPlaybackStateWrapper.getState() : null) + " -> " + (
-                            state != null ? state.getState() : null));
-        }
-
-        if (state == null) {
-            mCurrentPlaybackStateWrapper = null;
-            return;
-        }
-
-        String displayedMessage = getDisplayedMessage(mContext, state);
-        if (Log.isLoggable(tag, Log.DEBUG)) {
-            Log.d(tag, "Displayed error message: [" + displayedMessage + "]");
-        }
-        if (ignoreSameState && mCurrentPlaybackStateWrapper != null
-                && mCurrentPlaybackStateWrapper.getState() == state.getState()
-                && TextUtils.equals(displayedMessage,
-                getDisplayedMessage(mContext, mCurrentPlaybackStateWrapper))) {
-            if (Log.isLoggable(tag, Log.DEBUG)) {
-                Log.d(tag, "Ignore same playback state.");
-            }
-            return;
-        }
-
-        mCurrentPlaybackStateWrapper = state;
-
-        PendingIntent intent = getErrorResolutionIntent(state);
-        String label = getErrorResolutionLabel(state);
-        handleNewPlaybackState(displayedMessage, intent, label);
-    }
-
-
-    @Nullable
-    private String getDisplayedMessage(Context ctx, @Nullable PlaybackStateWrapper state) {
-        if (state == null) {
-            return null;
-        }
-        if (!TextUtils.isEmpty(state.getErrorMessage())) {
-            return state.getErrorMessage().toString();
-        }
-        // ERROR_CODE_UNKNOWN_ERROR means there is no error in PlaybackState.
-        if (state.getErrorCode() != PlaybackStateCompat.ERROR_CODE_UNKNOWN_ERROR) {
-            Integer messageId = ERROR_CODE_MESSAGES_MAP.get(state.getErrorCode());
-            return messageId != null ? ctx.getString(messageId) : ctx.getString(
-                    R.string.default_error_message);
-        }
-        if (state.getState() == PlaybackStateCompat.STATE_ERROR) {
-            return ctx.getString(R.string.default_error_message);
-        }
-        return null;
-    }
-
-    @Nullable
-    private PendingIntent getErrorResolutionIntent(@NonNull PlaybackStateWrapper state) {
-        Bundle extras = state.getExtras();
-        return extras == null ? null : extras.getParcelable(
-                MediaConstants.ERROR_RESOLUTION_ACTION_INTENT);
-    }
-
-    @Nullable
-    private String getErrorResolutionLabel(@NonNull PlaybackStateWrapper state) {
-        Bundle extras = state.getExtras();
-        return extras == null ? null : extras.getString(
-                MediaConstants.ERROR_RESOLUTION_ACTION_LABEL);
-    }
-
-}
diff --git a/car-media-common/src/com/android/car/media/common/PlaybackFragment.java b/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
index d9ff4b1..a9285ba 100644
--- a/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
+++ b/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
@@ -21,13 +21,10 @@
 import static com.android.car.arch.common.LiveDataFunctions.mapNonNull;
 
 import android.app.Application;
-import android.app.PendingIntent;
 import android.car.Car;
-import android.car.content.pm.CarPackageManager;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.os.Bundle;
-import android.text.TextUtils;
 import android.util.Size;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -41,119 +38,66 @@
 import androidx.fragment.app.FragmentActivity;
 import androidx.lifecycle.AndroidViewModel;
 import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.ViewModelProviders;
 
 import com.android.car.apps.common.BitmapUtils;
 import com.android.car.apps.common.CrossfadeImageView;
 import com.android.car.apps.common.imaging.ImageBinder;
 import com.android.car.apps.common.imaging.ImageBinder.PlaceholderType;
-import com.android.car.apps.common.util.CarPackageManagerUtils;
 import com.android.car.apps.common.util.ViewUtils;
-import com.android.car.arch.common.FutureData;
-import com.android.car.media.common.browse.MediaBrowserViewModelImpl;
-import com.android.car.media.common.browse.MediaItemsRepository;
 import com.android.car.media.common.playback.PlaybackViewModel;
-import com.android.car.media.common.playback.PlaybackViewModel.PlaybackStateWrapper;
 import com.android.car.media.common.source.MediaSource;
 import com.android.car.media.common.source.MediaSourceViewModel;
 
-import java.util.List;
-
 /**
  * {@link Fragment} that can be used to display and control the currently playing media item. Its
  * requires the android.Manifest.permission.MEDIA_CONTENT_CONTROL permission be held by the hosting
  * application.
  */
 public class PlaybackFragment extends Fragment {
-    private static final String TAG = "PlaybackFragmentWidget";
-
-    private Car mCar;
-    private CarPackageManager mCarPackageManager;
     private Intent mAppSelectorIntent;
     private MediaSourceViewModel mMediaSourceViewModel;
-    private PlaybackViewModel mPlaybackViewModel;
     private ImageBinder<MediaItemMetadata.ArtworkRef> mAlbumArtBinder;
-    private ViewModel mInnerViewModel;
-
-    private PlaybackErrorViewController mPlaybackErrorViewController;
-    private PlaybackErrorsHelper mErrorsHelper;
-    private boolean mIsFatalError;
 
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
             Bundle savedInstanceState) {
         FragmentActivity activity = requireActivity();
-        mCar = Car.createCar(activity);
-        mCarPackageManager = (CarPackageManager) mCar.getCarManager(Car.PACKAGE_SERVICE);
-
-        Application application = activity.getApplication();
-        mPlaybackViewModel = PlaybackViewModel.get(application, MEDIA_SOURCE_MODE_PLAYBACK);
-        mMediaSourceViewModel = MediaSourceViewModel.get(application, MEDIA_SOURCE_MODE_PLAYBACK);
+        PlaybackViewModel playbackViewModel = PlaybackViewModel.get(activity.getApplication(),
+                MEDIA_SOURCE_MODE_PLAYBACK);
+        mMediaSourceViewModel = MediaSourceViewModel.get(activity.getApplication(),
+                MEDIA_SOURCE_MODE_PLAYBACK);
         mAppSelectorIntent = MediaSource.getSourceSelectorIntent(getContext(), true);
 
-        mInnerViewModel = ViewModelProviders.of(activity).get(ViewModel.class);
-        mInnerViewModel.init(activity, mMediaSourceViewModel, mPlaybackViewModel,
-                MediaItemsRepository.get(application, MEDIA_SOURCE_MODE_PLAYBACK));
+        ViewModel innerViewModel = ViewModelProviders.of(activity).get(ViewModel.class);
+        innerViewModel.init(mMediaSourceViewModel, playbackViewModel);
 
         View view = inflater.inflate(R.layout.playback_fragment, container, false);
 
-        mPlaybackErrorViewController = new PlaybackErrorViewController(view);
-
         PlaybackControlsActionBar playbackControls = view.findViewById(R.id.playback_controls);
-        playbackControls.setModel(mPlaybackViewModel, getViewLifecycleOwner());
-        mPlaybackViewModel.getPlaybackStateWrapper().observe(getViewLifecycleOwner(),
-                state -> {
-                    ViewUtils.setVisible(playbackControls,
-                            (state != null) && state.shouldDisplay());
-                    if (mErrorsHelper != null) {
-                        mErrorsHelper.handlePlaybackState(TAG, state, /*ignoreSameState*/ true);
-                    }
-                });
+        playbackControls.setModel(playbackViewModel, getViewLifecycleOwner());
+        playbackViewModel.getPlaybackStateWrapper().observe(getViewLifecycleOwner(),
+                state -> ViewUtils.setVisible(playbackControls,
+                        (state != null) && state.shouldDisplay()));
 
         TextView appName = view.findViewById(R.id.app_name);
-        mInnerViewModel.getAppName().observe(getViewLifecycleOwner(), appName::setText);
+        innerViewModel.getAppName().observe(getViewLifecycleOwner(), appName::setText);
 
         TextView title = view.findViewById(R.id.title);
-        mInnerViewModel.getTitle().observe(getViewLifecycleOwner(), title::setText);
+        innerViewModel.getTitle().observe(getViewLifecycleOwner(), title::setText);
 
         TextView subtitle = view.findViewById(R.id.subtitle);
-        mInnerViewModel.getSubtitle().observe(getViewLifecycleOwner(), subtitle::setText);
-
-        boolean useSourceLogoForAppSelector =
-                getResources().getBoolean(R.bool.use_media_source_logo_for_app_selector);
+        innerViewModel.getSubtitle().observe(getViewLifecycleOwner(), subtitle::setText);
 
         ImageView appIcon = view.findViewById(R.id.app_icon);
-        View appSelector = view.findViewById(R.id.app_selector_container);
-        mInnerViewModel.getAppIcon().observe(getViewLifecycleOwner(), bitmap -> {
-            if (useSourceLogoForAppSelector) {
-                ImageView appSelectorIcon = appSelector.findViewById(R.id.app_selector);
-                appSelectorIcon.setImageBitmap(bitmap);
-                appSelectorIcon.setImageTintList(null);
-
-                appIcon.setVisibility(View.GONE);
-            } else {
-                appIcon.setImageBitmap(bitmap);
-            }
-        });
-
-        mInnerViewModel.getBrowseTreeHasChildren().observe(getViewLifecycleOwner(),
-                this::onBrowseTreeHasChildrenChanged);
-
-        mMediaSourceViewModel.getPrimaryMediaSource().observe(getViewLifecycleOwner(),
-                this::onMediaSourceChanged);
-
-        View playbackScrim = view.findViewById(R.id.playback_scrim);
-        playbackScrim.setOnClickListener(
-                // Let the Media center trampoline figure out what to open.
-                v -> {
-                    if (!mIsFatalError) {
-                        startActivity(new Intent(Car.CAR_INTENT_ACTION_MEDIA_TEMPLATE));
-                    }
-                });
+        innerViewModel.getAppIcon().observe(getViewLifecycleOwner(), appIcon::setImageBitmap);
 
         CrossfadeImageView albumBackground = view.findViewById(R.id.album_background);
+        albumBackground.setOnClickListener(
+                // Let the Media center trampoline figure out what to open.
+                v -> startActivity(new Intent(Car.CAR_INTENT_ACTION_MEDIA_TEMPLATE)));
+
         int max = activity.getResources().getInteger(R.integer.media_items_bitmap_max_size_px);
         Size maxArtSize = new Size(max, max);
         mAlbumArtBinder = new ImageBinder<>(PlaceholderType.FOREGROUND, maxArtSize,
@@ -163,57 +107,16 @@
                     albumBackground.setImageBitmap(bitmap, true);
                 });
 
-        mPlaybackViewModel.getMetadata().observe(getViewLifecycleOwner(),
+        playbackViewModel.getMetadata().observe(getViewLifecycleOwner(),
                 item -> mAlbumArtBinder.setImage(PlaybackFragment.this.getContext(),
                         item != null ? item.getArtworkKey() : null));
+        View appSelector = view.findViewById(R.id.app_selector_container);
         appSelector.setVisibility(mAppSelectorIntent != null ? View.VISIBLE : View.GONE);
         appSelector.setOnClickListener(e -> getContext().startActivity(mAppSelectorIntent));
 
-        mErrorsHelper = new PlaybackErrorsHelper(activity) {
-
-            @Override
-            public void handleNewPlaybackState(String displayedMessage, PendingIntent intent,
-                    String label) {
-                mIsFatalError = false;
-                if (!TextUtils.isEmpty(displayedMessage)) {
-                    Boolean hasChildren = mInnerViewModel.getBrowseTreeHasChildren().getValue();
-                    if (hasChildren != null && !hasChildren) {
-                        boolean isDistractionOptimized =
-                                intent != null && CarPackageManagerUtils.isDistractionOptimized(
-                                        mCarPackageManager, intent);
-                        mPlaybackErrorViewController.setError(displayedMessage, label, intent,
-                                isDistractionOptimized);
-                        mIsFatalError = true;
-                    }
-                }
-
-                if (!mIsFatalError) {
-                    mPlaybackErrorViewController.hideError();
-                }
-            }
-        };
-
         return view;
     }
 
-    @Override
-    public void onDestroyView() {
-        super.onDestroyView();
-        mCar.disconnect();
-        mErrorsHelper = null;
-    }
-
-    private void onBrowseTreeHasChildrenChanged(@Nullable Boolean hasChildren) {
-        if (hasChildren != null && mErrorsHelper != null) {
-            PlaybackStateWrapper state = mPlaybackViewModel.getPlaybackStateWrapper().getValue();
-            mErrorsHelper.handlePlaybackState(TAG, state, /*ignoreSameState*/ false);
-        }
-    }
-
-    private void onMediaSourceChanged(MediaSource source) {
-        mPlaybackErrorViewController.hideErrorNoAnim();
-    }
-
     /**
      * ViewModel for the PlaybackFragment
      */
@@ -224,9 +127,7 @@
         private LiveData<Bitmap> mAppIcon;
         private LiveData<CharSequence> mTitle;
         private LiveData<CharSequence> mSubtitle;
-        private MutableLiveData<Boolean> mBrowseTreeHasChildren = new MutableLiveData<>();
 
-        private MediaItemsRepository mMediaItemsRepository;
         private PlaybackViewModel mPlaybackViewModel;
         private MediaSourceViewModel mMediaSourceViewModel;
 
@@ -234,24 +135,18 @@
             super(application);
         }
 
-        void init(FragmentActivity activity, MediaSourceViewModel mediaSourceViewModel,
-                PlaybackViewModel playbackViewModel, MediaItemsRepository mediaItemsRepository) {
+        void init(MediaSourceViewModel mediaSourceViewModel, PlaybackViewModel playbackViewModel) {
             if (mMediaSourceViewModel == mediaSourceViewModel
-                    && mPlaybackViewModel == playbackViewModel
-                    && mMediaItemsRepository == mediaItemsRepository) {
+                    && mPlaybackViewModel == playbackViewModel) {
                 return;
             }
             mPlaybackViewModel = playbackViewModel;
             mMediaSourceViewModel = mediaSourceViewModel;
-            mMediaItemsRepository = mediaItemsRepository;
             mMediaSource = mMediaSourceViewModel.getPrimaryMediaSource();
             mAppName = mapNonNull(mMediaSource, MediaSource::getDisplayName);
             mAppIcon = mapNonNull(mMediaSource, MediaSource::getCroppedPackageIcon);
             mTitle = mapNonNull(playbackViewModel.getMetadata(), MediaItemMetadata::getTitle);
             mSubtitle = mapNonNull(playbackViewModel.getMetadata(), MediaItemMetadata::getArtist);
-
-            mMediaItemsRepository.getRootMediaItems()
-                    .observe(activity, this::onRootMediaItemsUpdate);
         }
 
         LiveData<CharSequence> getAppName() {
@@ -269,22 +164,5 @@
         LiveData<CharSequence> getSubtitle() {
             return mSubtitle;
         }
-
-        LiveData<Boolean> getBrowseTreeHasChildren() {
-            return mBrowseTreeHasChildren;
-        }
-
-        private void onRootMediaItemsUpdate(FutureData<List<MediaItemMetadata>> data) {
-            if (data.isLoading()) {
-                mBrowseTreeHasChildren.setValue(null);
-                return;
-            }
-
-            List<MediaItemMetadata> items =
-                    MediaBrowserViewModelImpl.filterItems(/*forRoot*/ true, data.getData());
-
-            boolean browseTreeHasChildren = items != null && !items.isEmpty();
-            mBrowseTreeHasChildren.setValue(browseTreeHasChildren);
-        }
     }
 }
diff --git a/car-media-common/src/com/android/car/media/common/browse/BrowsedMediaItems.java b/car-media-common/src/com/android/car/media/common/browse/BrowsedMediaItems.java
new file mode 100644
index 0000000..f93be0a
--- /dev/null
+++ b/car-media-common/src/com/android/car/media/common/browse/BrowsedMediaItems.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2018 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.media.common.browse;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.media.MediaBrowserCompat;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LiveData;
+
+import com.android.car.media.common.MediaItemMetadata;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * A LiveData that provides access the a MediaBrowser's children
+ */
+
+class BrowsedMediaItems extends LiveData<List<MediaItemMetadata>> {
+
+    /**
+     * Number of times we will retry obtaining the list of children of a certain node
+     */
+    private static final int CHILDREN_SUBSCRIPTION_RETRIES = 1;
+    /**
+     * Time between retries while trying to obtain the list of children of a certain node
+     */
+    private static final int CHILDREN_SUBSCRIPTION_RETRY_TIME_MS = 5000;
+
+    /** Whether to send an error after the last timeout. The subscription stays active regardless.*/
+    private static final boolean LAST_RETRY_TIMEOUT_SENDS_ERROR = false;
+
+    private final MediaBrowserCompat mBrowser;
+    private final String mParentId;
+    private final Handler mHandler = new Handler();
+
+    private ChildrenSubscription mSubscription;
+
+    BrowsedMediaItems(@NonNull MediaBrowserCompat mediaBrowser, @NonNull String parentId) {
+        mBrowser = mediaBrowser;
+        mParentId = parentId;
+    }
+
+    @Override
+    protected void onActive() {
+        super.onActive();
+        mSubscription = new ChildrenSubscription(mParentId);
+        mSubscription.start(CHILDREN_SUBSCRIPTION_RETRIES, CHILDREN_SUBSCRIPTION_RETRY_TIME_MS);
+    }
+
+    @Override
+    protected void onInactive() {
+        super.onInactive();
+        mSubscription.stop();
+        mSubscription = null;
+        mHandler.removeCallbacksAndMessages(null);
+    }
+
+    /**
+     * {@link MediaBrowserCompat.SubscriptionCallback} wrapper used to overcome the lack of a
+     * reliable method to obtain the initial list of children of a given node.
+     * <p>
+     * When some 3rd party apps go through configuration changes (i.e., in the case of user-switch),
+     * they leave subscriptions in an intermediate state where neither {@link
+     * MediaBrowserCompat.SubscriptionCallback#onChildrenLoaded(String, List)} nor {@link
+     * MediaBrowserCompat.SubscriptionCallback#onError(String)} are invoked.
+     * <p>
+     * This wrapper works around this problem by retrying the subscription a given number of times
+     * if no data is received after a certain amount of time. This process is started by calling
+     * {@link #start(int, int)}, passing the number of retries and delay between them as
+     * parameters.
+     * TODO: remove all this code if it's indeed not needed anymore (using retry=1 to be sure).
+     */
+    private class ChildrenSubscription extends MediaBrowserCompat.SubscriptionCallback {
+        private final String mItemId;
+
+        private boolean mIsDataLoaded;
+        private int mRetries;
+        private int mRetryDelay;
+
+        ChildrenSubscription(String itemId) {
+            mItemId = itemId;
+        }
+
+        private Runnable mRetryRunnable = new Runnable() {
+            @Override
+            public void run() {
+                if (!mIsDataLoaded) {
+                    if (mRetries > 0) {
+                        mRetries--;
+                        mBrowser.unsubscribe(mItemId);
+                        mBrowser.subscribe(mItemId, ChildrenSubscription.this);
+                        mHandler.postDelayed(this, mRetryDelay);
+                    } else if (LAST_RETRY_TIMEOUT_SENDS_ERROR) {
+                        mIsDataLoaded = true;
+                        setValue(null);
+                    }
+                }
+            }
+        };
+
+        /**
+         * Starts trying to obtain the list of children
+         *
+         * @param retries    number of times to retry. If children are not obtained in this time
+         *                   then the LiveData's value will be set to {@code null}
+         * @param retryDelay time between retries in milliseconds
+         */
+        void start(int retries, int retryDelay) {
+            if (mIsDataLoaded) {
+                mBrowser.subscribe(mItemId, this);
+            } else {
+                mRetries = retries;
+                mRetryDelay = retryDelay;
+                mHandler.post(mRetryRunnable);
+            }
+        }
+
+        /**
+         * Stops retrying
+         */
+        void stop() {
+            mHandler.removeCallbacks(mRetryRunnable);
+            mBrowser.unsubscribe(mItemId);
+        }
+
+        @Override
+        public void onChildrenLoaded(@NonNull String parentId,
+                @NonNull List<MediaBrowserCompat.MediaItem> children) {
+            mHandler.removeCallbacks(mRetryRunnable);
+            mIsDataLoaded = true;
+            setValue(children.stream()
+                    .filter(Objects::nonNull)
+                    .map(MediaItemMetadata::new)
+                    .collect(Collectors.toList()));
+        }
+
+        @Override
+        public void onChildrenLoaded(@NonNull String parentId,
+                @NonNull List<MediaBrowserCompat.MediaItem> children,
+                @NonNull Bundle options) {
+            onChildrenLoaded(parentId, children);
+        }
+
+        @Override
+        public void onError(@NonNull String parentId) {
+            mHandler.removeCallbacks(mRetryRunnable);
+            mIsDataLoaded = true;
+            setValue(null);
+        }
+
+        @Override
+        public void onError(@NonNull String parentId, @NonNull Bundle options) {
+            onError(parentId);
+        }
+    }
+}
diff --git a/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModel.java b/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModel.java
new file mode 100644
index 0000000..323b4ce
--- /dev/null
+++ b/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModel.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 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.media.common.browse;
+
+import android.support.v4.media.MediaBrowserCompat;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.android.car.arch.common.FutureData;
+import com.android.car.media.common.MediaItemMetadata;
+import com.android.car.media.common.source.MediaSourceViewModel;
+
+import java.util.List;
+
+/**
+ * Contains observable data needed for displaying playback and browse UI. Instances can be obtained
+ * via {@link MediaBrowserViewModel.Factory}
+ */
+public interface MediaBrowserViewModel {
+
+    /**
+     * Returns a LiveData that emits the current package name of the browser's service component.
+     */
+    LiveData<String> getPackageName();
+
+    /**
+     * Fetches the MediaItemMetadatas for the current browsed id, and the loading status of the
+     * fetch operation.
+     *
+     * This LiveData will never emit {@code null}. If the data is loading, the data component of the
+     * {@link FutureData} will be null
+     * A MediaSource must be selected and its MediaBrowser connected, otherwise the FutureData will
+     * always contain a {@code null} data value.
+     *
+     * @return a LiveData that emits a FutureData that contains the loading status and the
+     * MediaItemMetadatas for the current browsed id
+     */
+    LiveData<FutureData<List<MediaItemMetadata>>> getBrowsedMediaItems();
+
+    /**
+     * Fetches the MediaItemMetadatas for the current search query, and the loading status of the
+     * fetch operation.
+     *
+     * See {@link #getBrowsedMediaItems()}
+     */
+    LiveData<FutureData<List<MediaItemMetadata>>> getSearchedMediaItems();
+
+
+    /**
+     * Returns a LiveData that emits whether the media browser supports search. This wil never emit
+     * {@code null}
+     */
+    LiveData<Boolean> supportsSearch();
+
+    /**
+     * Gets the content style display type of browsable elements in this media browser, set at the
+     * browse root
+     */
+    LiveData<Integer> rootBrowsableHint();
+
+    /**
+     * Gets the content style display type of playable elements in this media browser, set at the
+     * browse root
+     */
+    LiveData<Integer> rootPlayableHint();
+
+    /**
+     * A {@link MediaBrowserViewModel} whose selected browse ID may be changed.
+     */
+    interface WithMutableBrowseId extends MediaBrowserViewModel {
+
+        /**
+         * Set the current item to be browsed. If available, the list of items will be emitted by
+         * {@link #getBrowsedMediaItems()}.
+         */
+        @UiThread
+        void setCurrentBrowseId(@NonNull String browseId);
+
+        /**
+         * Set the current item to be searched for. If available, the list of items will be emitted
+         * by {@link #getBrowsedMediaItems()}.
+         */
+        @UiThread
+        void search(@Nullable String query);
+    }
+
+    /**
+     * Creates and/or fetches {@link MediaBrowserViewModel} instances.
+     */
+    class Factory {
+
+        private static final String KEY_BROWSER_ROOT =
+                "com.android.car.media.common.browse.MediaBrowserViewModel.Factory.browserRoot";
+
+        /**
+         * Returns an initialized {@link MediaBrowserViewModel.WithMutableBrowseId} with the
+         * provided connected media browser. The provided {@code mediaBrowser} does not need to be
+         * from the same scope as {@code viewModelProvider}.
+         */
+        @NonNull
+        public static MediaBrowserViewModel.WithMutableBrowseId getInstanceWithMediaBrowser(
+                @NonNull String key,
+                @NonNull ViewModelProvider viewModelProvider,
+                @NonNull LiveData<MediaBrowserCompat> mediaBrowser) {
+            MutableMediaBrowserViewModel viewModel =
+                    viewModelProvider.get(key, MutableMediaBrowserViewModel.class);
+            initMediaBrowser(mediaBrowser, viewModel);
+            return viewModel;
+        }
+
+        /**
+         * Fetch an initialized {@link MediaBrowserViewModel}. It will get its media browser from
+         * the {@link MediaSourceViewModel} provided by {@code viewModelProvider}. It will already
+         * be configured to browse the root of the browser.
+         *
+         * @param mediaSourceVM     the {@link MediaSourceViewModel} singleton.
+         * @param viewModelProvider the ViewModelProvider to load ViewModels from.
+         * @return an initialized MediaBrowserViewModel configured to browse the specified browseId.
+         */
+        @NonNull
+        public static MediaBrowserViewModel getInstanceForBrowseRoot(
+                MediaSourceViewModel mediaSourceVM, @NonNull ViewModelProvider viewModelProvider) {
+            RootMediaBrowserViewModel viewModel =
+                    viewModelProvider.get(KEY_BROWSER_ROOT, RootMediaBrowserViewModel.class);
+            initMediaBrowser(mediaSourceVM.getConnectedMediaBrowser(), viewModel);
+            return viewModel;
+        }
+
+        private static void initMediaBrowser(
+                @NonNull LiveData<MediaBrowserCompat> connectedMediaBrowser,
+                MediaBrowserViewModelImpl viewModel) {
+            if (viewModel.getMediaBrowserSource() != connectedMediaBrowser) {
+                viewModel.setConnectedMediaBrowser(connectedMediaBrowser);
+            }
+        }
+    }
+}
diff --git a/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModelImpl.java b/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModelImpl.java
index d740667..949c81d 100644
--- a/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModelImpl.java
+++ b/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModelImpl.java
@@ -16,124 +16,177 @@
 
 package com.android.car.media.common.browse;
 
+import static androidx.lifecycle.Transformations.map;
+
+import static com.android.car.arch.common.LiveDataFunctions.dataOf;
+import static com.android.car.arch.common.LiveDataFunctions.loadingSwitchMap;
+import static com.android.car.arch.common.LiveDataFunctions.pair;
+import static com.android.car.arch.common.LiveDataFunctions.split;
+
+import android.app.Application;
 import android.os.Bundle;
 import android.support.v4.media.MediaBrowserCompat;
+import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.lifecycle.AndroidViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
 
+import com.android.car.arch.common.FutureData;
+import com.android.car.arch.common.switching.SwitchingLiveData;
 import com.android.car.media.common.MediaConstants;
 import com.android.car.media.common.MediaItemMetadata;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 /**
- * TODO: rename to MediaBrowserUtils.
- * Provides utility methods for {@link MediaBrowserCompat}.
+ * Contains observable data needed for displaying playback and browse/search UI. Instances can be
+ * obtained via {@link MediaBrowserViewModel.Factory}
  */
-public class MediaBrowserViewModelImpl {
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+class MediaBrowserViewModelImpl extends AndroidViewModel implements MediaBrowserViewModel {
 
-    private MediaBrowserViewModelImpl() {
+    private final boolean mIsRoot;
+
+    private final SwitchingLiveData<MediaBrowserCompat> mMediaBrowserSwitch =
+            SwitchingLiveData.newInstance();
+
+    final MutableLiveData<String> mCurrentBrowseId = dataOf(null);
+    final MutableLiveData<String> mCurrentSearchQuery = dataOf(null);
+    private final LiveData<MediaBrowserCompat> mConnectedMediaBrowser =
+            map(mMediaBrowserSwitch.asLiveData(), MediaBrowserViewModelImpl::requireConnected);
+
+    private final LiveData<FutureData<List<MediaItemMetadata>>> mSearchedMediaItems;
+    private final LiveData<FutureData<List<MediaItemMetadata>>> mBrowsedMediaItems;
+    private final LiveData<String> mPackageName;
+
+    MediaBrowserViewModelImpl(@NonNull Application application, boolean isRoot) {
+        super(application);
+
+        mIsRoot = isRoot;
+
+        mPackageName = map(mConnectedMediaBrowser,
+                mediaBrowser -> {
+                    if (mediaBrowser == null) return null;
+                    return mediaBrowser.getServiceComponent().getPackageName();
+                });
+
+        mBrowsedMediaItems =
+                loadingSwitchMap(pair(mConnectedMediaBrowser, mCurrentBrowseId),
+                        split((mediaBrowser, browseId) -> {
+                            if (mediaBrowser == null || (!mIsRoot && browseId == null)) {
+                                return null;
+                            }
+
+                            String parentId = (mIsRoot) ? mediaBrowser.getRoot() : browseId;
+                            return new BrowsedMediaItems(mediaBrowser, parentId);
+                        }));
+        mSearchedMediaItems =
+                loadingSwitchMap(pair(mConnectedMediaBrowser, mCurrentSearchQuery),
+                        split((mediaBrowser, query) ->
+                                (mediaBrowser == null || TextUtils.isEmpty(query))
+                                        ? null
+                                        : new SearchedMediaItems(mediaBrowser, query)));
+    }
+
+    private static MediaBrowserCompat requireConnected(@Nullable MediaBrowserCompat mediaBrowser) {
+        if (mediaBrowser != null && !mediaBrowser.isConnected()) {
+            throw new IllegalStateException(
+                    "Only connected MediaBrowsers may be provided to MediaBrowserViewModel.");
+        }
+        return mediaBrowser;
     }
 
     /**
-     * Filters the items that are valid for the root (tabs) or the current node. Returns null when
-     * the given list is null to preserve its error signal.
+     * Set the source {@link MediaBrowserCompat} to use for browsing. If {@code mediaBrowser} emits
+     * non-null, the MediaBrowser emitted must already be in a connected state.
      */
-    @Nullable
-    public static List<MediaItemMetadata> filterItems(boolean forRoot,
-            @Nullable List<MediaItemMetadata> items) {
-        if (items == null) return null;
-        Predicate<MediaItemMetadata> predicate = forRoot ? MediaItemMetadata::isBrowsable
-                : item -> (item.isPlayable() || item.isBrowsable());
-        return items.stream().filter(predicate).collect(Collectors.toList());
+    void setConnectedMediaBrowser(@Nullable LiveData<MediaBrowserCompat> mediaBrowser) {
+        mMediaBrowserSwitch.setSource(mediaBrowser);
     }
 
-    /** Returns only the browse-able items from the given list. */
-    @Nullable
-    public static List<MediaItemMetadata> selectBrowseableItems(
-            @Nullable List<MediaItemMetadata> items) {
-        if (items == null) return null;
-        Predicate<MediaItemMetadata> predicate = MediaItemMetadata::isBrowsable;
-        return items.stream().filter(predicate).collect(Collectors.toList());
+    LiveData<? extends MediaBrowserCompat> getMediaBrowserSource() {
+        return mMediaBrowserSwitch.getSource();
     }
 
+    @Override
+    public LiveData<String> getPackageName() {
+        return mPackageName;
+    }
+
+    @Override
+    public LiveData<FutureData<List<MediaItemMetadata>>> getBrowsedMediaItems() {
+        return mBrowsedMediaItems;
+    }
+
+    @Override
+    public LiveData<FutureData<List<MediaItemMetadata>>> getSearchedMediaItems() {
+        return mSearchedMediaItems;
+    }
 
     @SuppressWarnings("deprecation")
-    public static boolean getSupportsSearch(@Nullable MediaBrowserCompat mediaBrowserCompat) {
-        if (mediaBrowserCompat == null) {
+    @Override
+    public LiveData<Boolean> supportsSearch() {
+        return map(mConnectedMediaBrowser, mediaBrowserCompat -> {
+            if (mediaBrowserCompat == null) {
+                return false;
+            }
+            Bundle extras = mediaBrowserCompat.getExtras();
+            if (extras == null) {
+                return false;
+            }
+            if (extras.containsKey(MediaConstants.MEDIA_SEARCH_SUPPORTED)) {
+                return extras.getBoolean(MediaConstants.MEDIA_SEARCH_SUPPORTED);
+            }
+            if (extras.containsKey(MediaConstants.MEDIA_SEARCH_SUPPORTED_PRERELEASE)) {
+                return extras.getBoolean(MediaConstants.MEDIA_SEARCH_SUPPORTED_PRERELEASE);
+            }
             return false;
-        }
-        Bundle extras = mediaBrowserCompat.getExtras();
-        if (extras == null) {
-            return false;
-        }
-        if (extras.containsKey(MediaConstants.MEDIA_SEARCH_SUPPORTED)) {
-            return extras.getBoolean(MediaConstants.MEDIA_SEARCH_SUPPORTED);
-        }
-        if (extras.containsKey(MediaConstants.MEDIA_SEARCH_SUPPORTED_PRERELEASE)) {
-            return extras.getBoolean(MediaConstants.MEDIA_SEARCH_SUPPORTED_PRERELEASE);
-        }
-        return false;
+        });
     }
 
     @SuppressWarnings("deprecation")
-    public static int getRootBrowsableHint(@Nullable MediaBrowserCompat mediaBrowserCompat) {
-        if (mediaBrowserCompat == null) {
+    @Override
+    public LiveData<Integer> rootBrowsableHint() {
+        return map(mConnectedMediaBrowser, mediaBrowserCompat -> {
+            if (mediaBrowserCompat == null) {
+                return 0;
+            }
+            Bundle extras = mediaBrowserCompat.getExtras();
+            if (extras == null) {
+                return 0;
+            }
+            if (extras.containsKey(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT)) {
+                return extras.getInt(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT, 0);
+            }
+            if (extras.containsKey(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT_PRERELEASE)) {
+                return extras.getInt(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT_PRERELEASE, 0);
+            }
             return 0;
-        }
-        Bundle extras = mediaBrowserCompat.getExtras();
-        if (extras == null) {
-            return 0;
-        }
-        if (extras.containsKey(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT)) {
-            return extras.getInt(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT, 0);
-        }
-        if (extras.containsKey(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT_PRERELEASE)) {
-            return extras.getInt(MediaConstants.CONTENT_STYLE_BROWSABLE_HINT_PRERELEASE, 0);
-        }
-        return 0;
+        });
     }
 
     @SuppressWarnings("deprecation")
-    public static int getRootPlayableHint(@Nullable MediaBrowserCompat mediaBrowserCompat) {
-        if (mediaBrowserCompat == null) {
+    @Override
+    public LiveData<Integer> rootPlayableHint() {
+        return map(mConnectedMediaBrowser, mediaBrowserCompat -> {
+            if (mediaBrowserCompat == null) {
+                return 0;
+            }
+            Bundle extras = mediaBrowserCompat.getExtras();
+            if (extras == null) {
+                return 0;
+            }
+            if (extras.containsKey(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT)) {
+                return extras.getInt(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT, 0);
+            }
+            if (extras.containsKey(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT_PRERELEASE)) {
+                return extras.getInt(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT_PRERELEASE, 0);
+            }
             return 0;
-        }
-        Bundle extras = mediaBrowserCompat.getExtras();
-        if (extras == null) {
-            return 0;
-        }
-        if (extras.containsKey(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT)) {
-            return extras.getInt(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT, 0);
-        }
-        if (extras.containsKey(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT_PRERELEASE)) {
-            return extras.getInt(MediaConstants.CONTENT_STYLE_PLAYABLE_HINT_PRERELEASE, 0);
-        }
-        return 0;
-    }
-
-    /** Returns the elements of oldList that do NOT appear in newList. */
-    public static @NonNull Collection<MediaItemMetadata> computeRemovedItems(
-            @Nullable List<MediaItemMetadata> oldList, @Nullable List<MediaItemMetadata> newList) {
-        if (oldList == null || oldList.isEmpty()) {
-            // Nothing was removed
-            return Collections.emptyList();
-        }
-
-        if (newList == null || newList.isEmpty()) {
-            // Everything was removed
-            return new ArrayList<>(oldList);
-        }
-
-        HashSet<MediaItemMetadata> itemsById = new HashSet<>(oldList);
-        itemsById.removeAll(newList);
-        return itemsById;
+        });
     }
 }
diff --git a/car-media-common/src/com/android/car/media/common/browse/MediaItemsRepository.java b/car-media-common/src/com/android/car/media/common/browse/MediaItemsRepository.java
deleted file mode 100644
index e01cb96..0000000
--- a/car-media-common/src/com/android/car/media/common/browse/MediaItemsRepository.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.media.common.browse;
-
-import static com.android.car.arch.common.LiveDataFunctions.dataOf;
-
-import static java.util.stream.Collectors.toList;
-
-import android.app.Application;
-import android.os.Bundle;
-import android.support.v4.media.MediaBrowserCompat;
-import android.support.v4.media.MediaBrowserCompat.SearchCallback;
-import android.support.v4.media.MediaBrowserCompat.SubscriptionCallback;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-
-import com.android.car.arch.common.FutureData;
-import com.android.car.media.common.MediaItemMetadata;
-import com.android.car.media.common.source.MediaBrowserConnector.BrowsingState;
-import com.android.car.media.common.source.MediaSource;
-import com.android.car.media.common.source.MediaSourceViewModel;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-
-/**
- * Fulfills media items search and children queries. The latter also provides the last list of
- * results alongside the new list so that differences can be calculated and acted upon.
- */
-public class MediaItemsRepository {
-    private static final String TAG = "MediaItemsRepository";
-
-    /** One instance per MEDIA_SOURCE_MODE. */
-    private static MediaItemsRepository[] sInstances = new MediaItemsRepository[2];
-
-    /** Returns the MediaItemsRepository "singleton" tied to the application for the given mode. */
-    public static MediaItemsRepository get(@NonNull Application application, int mode) {
-        if (sInstances[mode] == null) {
-            sInstances[mode] = new MediaItemsRepository(
-                    MediaSourceViewModel.get(application, mode).getBrowsingState());
-        }
-        return sInstances[mode];
-    }
-
-    /** The live data providing the updates for a query. */
-    public static class MediaItemsLiveData
-            extends LiveData<FutureData<List<MediaItemMetadata>>> {
-
-        private MediaItemsLiveData() {
-            this(true);
-        }
-
-        private MediaItemsLiveData(boolean initAsLoading) {
-            if (initAsLoading) {
-                setLoading();
-            } else {
-                clear();
-            }
-        }
-
-        private void onDataLoaded(List<MediaItemMetadata> old, List<MediaItemMetadata> list) {
-            setValue(FutureData.newLoadedData(old, list));
-        }
-
-        private void setLoading() {
-            setValue(FutureData.newLoadingData());
-        }
-
-        private void clear() {
-            setValue(null);
-        }
-    }
-
-    private static class MediaChildren {
-        final String mNodeId;
-        final MediaItemsLiveData mLiveData = new MediaItemsLiveData();
-        List<MediaItemMetadata> mPreviousValue = Collections.emptyList();
-
-        MediaChildren(String nodeId) {
-            mNodeId = nodeId;
-        }
-    }
-
-    private static class PerMediaSourceCache {
-        String mRootId;
-        Map<String, MediaChildren> mChildrenByNodeId = new HashMap<>();
-    }
-
-    private BrowsingState mBrowsingState;
-    private final Map<MediaSource, PerMediaSourceCache> mCaches = new HashMap<>();
-    private final MutableLiveData<BrowsingState> mBrowsingStateLiveData = dataOf(null);
-    private final MediaItemsLiveData mRootMediaItems = new MediaItemsLiveData();
-    private final MediaItemsLiveData mSearchMediaItems = new MediaItemsLiveData(/*loading*/ false);
-
-    private String mSearchQuery;
-
-    @VisibleForTesting
-    public MediaItemsRepository(LiveData<BrowsingState> browsingState) {
-        browsingState.observeForever(this::onMediaBrowsingStateChanged);
-    }
-
-    /**
-     * Rebroadcasts browsing state changes before the repository takes any action on them.
-     */
-    public LiveData<BrowsingState> getBrowsingState() {
-        return mBrowsingStateLiveData;
-    }
-
-    /**
-     * Convenience wrapper for root media items. The live data is the same instance for all
-     * media sources.
-     */
-    public MediaItemsLiveData getRootMediaItems() {
-        return mRootMediaItems;
-    }
-
-    /**
-     * Returns the results from the current search query. The live data is the same instance
-     * for all media sources.
-     */
-    public MediaItemsLiveData getSearchMediaItems() {
-        return mSearchMediaItems;
-    }
-
-    /** Returns the children of the given node. */
-    public MediaItemsLiveData getMediaChildren(String nodeId) {
-        PerMediaSourceCache cache = getCache();
-        MediaChildren items = cache.mChildrenByNodeId.get(nodeId);
-        if (items == null) {
-            items = new MediaChildren(nodeId);
-            cache.mChildrenByNodeId.put(nodeId, items);
-        }
-
-        // Always refresh the subscription (to work around bugs in media apps).
-        mBrowsingState.mBrowser.unsubscribe(nodeId);
-        mBrowsingState.mBrowser.subscribe(nodeId, mBrowseCallback);
-
-        return items.mLiveData;
-    }
-
-    /** Sets the search query. Results will be given through {@link #getSearchMediaItems}. */
-    public void setSearchQuery(String query) {
-        mSearchQuery = query;
-        if (TextUtils.isEmpty(mSearchQuery)) {
-            clearSearchResults();
-        } else {
-            mSearchMediaItems.setLoading();
-            mBrowsingState.mBrowser.search(mSearchQuery, null, mSearchCallback);
-        }
-    }
-
-    private void clearSearchResults() {
-        mSearchMediaItems.clear();
-    }
-
-    private MediaSource getMediaSource() {
-        return (mBrowsingState != null) ? mBrowsingState.mMediaSource : null;
-    }
-
-    private void onMediaBrowsingStateChanged(BrowsingState newBrowsingState) {
-        mBrowsingState = newBrowsingState;
-        if (mBrowsingState == null) {
-            Log.e(TAG, "Null browsing state (no media source!)");
-            return;
-        }
-        mBrowsingStateLiveData.setValue(mBrowsingState);
-        switch (mBrowsingState.mConnectionStatus) {
-            case CONNECTING:
-                mRootMediaItems.setLoading();
-                break;
-            case CONNECTED:
-                String rootId = mBrowsingState.mBrowser.getRoot();
-                getCache().mRootId = rootId;
-                getMediaChildren(rootId);
-                break;
-            case DISCONNECTING:
-                unsubscribeNodes();
-                clearSearchResults();
-                clearNodes();
-                break;
-            case REJECTED:
-            case SUSPENDED:
-                onBrowseData(getCache().mRootId, null);
-                clearSearchResults();
-                clearNodes();
-        }
-    }
-
-    private PerMediaSourceCache getCache() {
-        PerMediaSourceCache cache = mCaches.get(getMediaSource());
-        if (cache == null) {
-            cache = new PerMediaSourceCache();
-            mCaches.put(getMediaSource(), cache);
-        }
-        return cache;
-    }
-
-    /** Does NOT clear the cache. */
-    private void unsubscribeNodes() {
-        PerMediaSourceCache cache = getCache();
-        for (String nodeId : cache.mChildrenByNodeId.keySet()) {
-            mBrowsingState.mBrowser.unsubscribe(nodeId);
-        }
-    }
-
-    /** Does NOT unsubscribe nodes. */
-    private void clearNodes() {
-        PerMediaSourceCache cache = getCache();
-        cache.mChildrenByNodeId.clear();
-    }
-
-    private void onBrowseData(@NonNull String parentId, @Nullable List<MediaItemMetadata> list) {
-        PerMediaSourceCache cache = getCache();
-        MediaChildren children = cache.mChildrenByNodeId.get(parentId);
-        if (children == null) {
-            if (Log.isLoggable(TAG, Log.WARN)) {
-                Log.w(TAG, "Browse parent not in the cache: " + parentId);
-            }
-            return;
-        }
-
-        List<MediaItemMetadata> old = children.mPreviousValue;
-        children.mPreviousValue = list;
-        children.mLiveData.onDataLoaded(old, list);
-
-        if (Objects.equals(parentId, cache.mRootId)) {
-            mRootMediaItems.onDataLoaded(old, list);
-        }
-    }
-
-    private void onSearchData(@Nullable List<MediaItemMetadata> list) {
-        mSearchMediaItems.onDataLoaded(null, list);
-    }
-
-    private final SubscriptionCallback mBrowseCallback = new SubscriptionCallback() {
-        @Override
-        public void onChildrenLoaded(@NonNull String parentId,
-                @NonNull List<MediaBrowserCompat.MediaItem> children) {
-
-            onBrowseData(parentId, children.stream()
-                    .filter(Objects::nonNull)
-                    .map(MediaItemMetadata::new)
-                    .collect(Collectors.toList()));
-        }
-
-        @Override
-        public void onChildrenLoaded(@NonNull String parentId,
-                @NonNull List<MediaBrowserCompat.MediaItem> children,
-                @NonNull Bundle options) {
-            onChildrenLoaded(parentId, children);
-        }
-
-        @Override
-        public void onError(@NonNull String parentId) {
-            onBrowseData(parentId, null);
-        }
-
-        @Override
-        public void onError(@NonNull String parentId, @NonNull Bundle options) {
-            onError(parentId);
-        }
-    };
-
-    private final SearchCallback mSearchCallback = new SearchCallback() {
-        @Override
-        public void onSearchResult(@NonNull String query, Bundle extras,
-                @NonNull List<MediaBrowserCompat.MediaItem> items) {
-            super.onSearchResult(query, extras, items);
-            if (Objects.equals(mSearchQuery, query)) {
-                onSearchData(items.stream()
-                        .filter(Objects::nonNull)
-                        .map(MediaItemMetadata::new)
-                        .collect(toList()));
-            }
-        }
-
-        @Override
-        public void onError(@NonNull String query, Bundle extras) {
-            super.onError(query, extras);
-            if (Objects.equals(mSearchQuery, query)) {
-                onSearchData(null);
-            }
-        }
-    };
-}
diff --git a/car-media-common/src/com/android/car/media/common/browse/MutableMediaBrowserViewModel.java b/car-media-common/src/com/android/car/media/common/browse/MutableMediaBrowserViewModel.java
new file mode 100644
index 0000000..1290b20
--- /dev/null
+++ b/car-media-common/src/com/android/car/media/common/browse/MutableMediaBrowserViewModel.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.media.common.browse;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.UiThread;
+
+/** This isn't a comment. */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public class MutableMediaBrowserViewModel extends MediaBrowserViewModelImpl implements
+        MediaBrowserViewModel.WithMutableBrowseId {
+    public MutableMediaBrowserViewModel(@NonNull Application application) {
+        super(application, /*isRoot*/ false);
+    }
+
+    @UiThread
+    @Override
+    public void setCurrentBrowseId(@NonNull String browseId) {
+        super.mCurrentBrowseId.setValue(browseId);
+    }
+
+    @UiThread
+    @Override
+    public void search(@Nullable String query) {
+        super.mCurrentSearchQuery.setValue(query);
+    }
+}
diff --git a/car-media-common/src/com/android/car/media/common/browse/RootMediaBrowserViewModel.java b/car-media-common/src/com/android/car/media/common/browse/RootMediaBrowserViewModel.java
new file mode 100644
index 0000000..f1ffc64
--- /dev/null
+++ b/car-media-common/src/com/android/car/media/common/browse/RootMediaBrowserViewModel.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.media.common.browse;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+/** This isn't a comment. */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public class RootMediaBrowserViewModel extends MediaBrowserViewModelImpl {
+    public RootMediaBrowserViewModel(@NonNull Application application) {
+        super(application, /*isRoot*/ true);
+    }
+}
diff --git a/car-media-common/src/com/android/car/media/common/browse/SearchedMediaItems.java b/car-media-common/src/com/android/car/media/common/browse/SearchedMediaItems.java
new file mode 100644
index 0000000..b8c7423
--- /dev/null
+++ b/car-media-common/src/com/android/car/media/common/browse/SearchedMediaItems.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 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.media.common.browse;
+
+import static java.util.stream.Collectors.toList;
+
+import android.os.Bundle;
+import android.support.v4.media.MediaBrowserCompat;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.LiveData;
+
+import com.android.car.media.common.MediaItemMetadata;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A LiveData that provides access to a MediaBrowser's search results for a given query
+ */
+public class SearchedMediaItems extends LiveData<List<MediaItemMetadata>> {
+
+    private final MediaBrowserCompat mBrowser;
+    private final String mQuery;
+
+    private final MediaBrowserCompat.SearchCallback mCallback =
+            new MediaBrowserCompat.SearchCallback() {
+        @Override
+        public void onSearchResult(@NonNull String query, Bundle extras,
+                                   @NonNull List<MediaBrowserCompat.MediaItem> items) {
+            super.onSearchResult(query, extras, items);
+            setValue(items.stream()
+                    .filter(Objects::nonNull)
+                    .map(MediaItemMetadata::new)
+                    .collect(toList()));
+        }
+
+        @Override
+        public void onError(@NonNull String query, Bundle extras) {
+            super.onError(query, extras);
+            setValue(null);
+        }
+    };
+
+    SearchedMediaItems(@NonNull MediaBrowserCompat mediaBrowser, @Nullable String query) {
+        mBrowser = mediaBrowser;
+        mQuery = query;
+    }
+
+    @Override
+    protected void onActive() {
+        super.onActive();
+        mBrowser.search(mQuery, null, mCallback);
+    }
+}
diff --git a/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java b/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java
index 713caa1..bcb9893 100644
--- a/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java
+++ b/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java
@@ -16,6 +16,8 @@
 
 package com.android.car.media.common.playback;
 
+import static android.car.media.CarMediaManager.MEDIA_SOURCE_MODE_PLAYBACK;
+
 import static androidx.lifecycle.Transformations.switchMap;
 
 import static com.android.car.arch.common.LiveDataFunctions.dataOf;
@@ -28,7 +30,6 @@
 import android.graphics.drawable.Drawable;
 import android.media.MediaMetadata;
 import android.os.Bundle;
-import android.support.v4.media.MediaBrowserCompat;
 import android.support.v4.media.MediaMetadataCompat;
 import android.support.v4.media.RatingCompat;
 import android.support.v4.media.session.MediaControllerCompat;
@@ -49,8 +50,6 @@
 import com.android.car.media.common.MediaConstants;
 import com.android.car.media.common.MediaItemMetadata;
 import com.android.car.media.common.R;
-import com.android.car.media.common.source.MediaBrowserConnector;
-import com.android.car.media.common.source.MediaBrowserConnector.ConnectionStatus;
 import com.android.car.media.common.source.MediaSourceColors;
 import com.android.car.media.common.source.MediaSourceViewModel;
 
@@ -68,7 +67,7 @@
  * Observes changes to the provided MediaController to expose playback state and metadata
  * observables.
  * <p>
- * PlaybackViewModel is a "singleton" tied to the application to provide a single source of truth.
+ * PlaybackViewModel is a singleton tied to the application to provide a single source of truth.
  */
 public class PlaybackViewModel extends AndroidViewModel {
     private static final String TAG = "PlaybackViewModel";
@@ -79,7 +78,15 @@
 
     private static PlaybackViewModel[] sInstances = new PlaybackViewModel[2];
 
-    /** Returns the PlaybackViewModel "singleton" tied to the application for the given mode. */
+    /**
+     * Returns the PlaybackViewModel singleton tied to the application.
+     * @deprecated should use get(Application application, int mode) instead
+     */
+    public static PlaybackViewModel get(@NonNull Application application) {
+        return get(application, MEDIA_SOURCE_MODE_PLAYBACK);
+    }
+
+    /** Returns the PlaybackViewModel singleton tied to the application. */
     public static PlaybackViewModel get(@NonNull Application application, int mode) {
         if (sInstances[mode] == null) {
             sInstances[mode] = new PlaybackViewModel(application, mode);
@@ -112,21 +119,12 @@
      */
     public static final int ACTION_PAUSE = 3;
 
-    /**
-     * Factory for creating dependencies. Can be swapped out for testing.
-     */
-    @VisibleForTesting
-    interface InputFactory {
-        MediaControllerCompat getControllerForBrowser(@NonNull MediaBrowserCompat browser);
-    }
-
-
     /** Needs to be a MediaMetadata because the compat class doesn't implement equals... */
     private static final MediaMetadata EMPTY_MEDIA_METADATA = new MediaMetadata.Builder().build();
 
     private final MediaControllerCallback mMediaControllerCallback = new MediaControllerCallback();
-    private final Observer<MediaBrowserConnector.BrowsingState> mMediaBrowsingObserver =
-            mMediaControllerCallback::onMediaBrowsingStateChanged;
+    private final Observer<MediaControllerCompat> mMediaControllerObserver =
+            mMediaControllerCallback::onMediaControllerChanged;
 
     private final MediaSourceColors.Factory mColorsFactory;
     private final MutableLiveData<MediaSourceColors> mColors = dataOf(null);
@@ -149,20 +147,15 @@
                     state -> state == null ? dataOf(new PlaybackProgress(0L, 0L))
                             : new ProgressLiveData(state.mState, state.getMaxProgress()));
 
-    private final InputFactory mInputFactory;
-
     private PlaybackViewModel(Application application, int mode) {
-        this(application, MediaSourceViewModel.get(application, mode).getBrowsingState(),
-                browser -> new MediaControllerCompat(application, browser.getSessionToken()));
+        this(application, MediaSourceViewModel.get(application, mode).getMediaController());
     }
 
     @VisibleForTesting
-    public PlaybackViewModel(Application application,
-            LiveData<MediaBrowserConnector.BrowsingState> browsingState, InputFactory factory) {
+    public PlaybackViewModel(Application application, LiveData<MediaControllerCompat> controller) {
         super(application);
-        mInputFactory =  factory;
         mColorsFactory = new MediaSourceColors.Factory(application);
-        browsingState.observeForever(mMediaBrowsingObserver);
+        controller.observeForever(mMediaControllerObserver);
     }
 
     /**
@@ -238,50 +231,29 @@
 
     private class MediaControllerCallback extends MediaControllerCompat.Callback {
 
-        private MediaBrowserConnector.BrowsingState mBrowsingState;
         private MediaControllerCompat mMediaController;
         private MediaMetadataCompat mMediaMetadata;
         private PlaybackStateCompat mPlaybackState;
 
-
-        void onMediaBrowsingStateChanged(MediaBrowserConnector.BrowsingState newBrowsingState) {
-            if (Objects.equals(mBrowsingState, newBrowsingState)) {
-                Log.w(TAG, "onMediaBrowsingStateChanged noop ");
+        void onMediaControllerChanged(MediaControllerCompat controller) {
+            if (mMediaController == controller) {
+                Log.w(TAG, "onMediaControllerChanged noop");
                 return;
             }
 
-            // Reset the old controller if any, unregistering the callback when browsing is
-            // not suspended (crashed).
             if (mMediaController != null) {
-                switch (newBrowsingState.mConnectionStatus) {
-                    case DISCONNECTING:
-                    case REJECTED:
-                    case CONNECTING:
-                    case CONNECTED:
-                        mMediaController.unregisterCallback(this);
-                        // Fall through
-                    case SUSPENDED:
-                        setMediaController(null);
-                }
+                mMediaController.unregisterCallback(this);
             }
 
-            mBrowsingState = newBrowsingState;
-
-            if (mBrowsingState.mConnectionStatus == ConnectionStatus.CONNECTED) {
-                setMediaController(mInputFactory.getControllerForBrowser(mBrowsingState.mBrowser));
-            }
-        }
-
-        private void setMediaController(MediaControllerCompat mediaController) {
             mMediaMetadata = null;
             mPlaybackState = null;
-            mMediaController = mediaController;
-            mPlaybackControls.setValue(new PlaybackController(mediaController));
+            mMediaController = controller;
+            mPlaybackControls.setValue(new PlaybackController(controller));
 
             if (mMediaController != null) {
                 mMediaController.registerCallback(this);
 
-                mColors.setValue(mColorsFactory.extractColors(mediaController.getPackageName()));
+                mColors.setValue(mColorsFactory.extractColors(controller.getPackageName()));
 
                 // The apps don't always send updates so make sure we fetch the most recent values.
                 onMetadataChanged(mMediaController.getMetadata());
@@ -302,9 +274,7 @@
         @Override
         public void onSessionDestroyed() {
             Log.w(TAG, "onSessionDestroyed");
-            // Bypass the unregisterCallback as the controller is dead.
-            // TODO: consider keeping track of orphaned callbacks in case they are resurrected...
-            setMediaController(null);
+            onMediaControllerChanged(null);
         }
 
         @Override
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java b/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java
index c1ef1d9..14271e4 100644
--- a/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java
+++ b/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java
@@ -26,106 +26,30 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.util.Preconditions;
 
 import com.android.car.media.common.MediaConstants;
 
-import java.util.Objects;
-
 /**
- * A helper class to connect to a single {@link MediaSource} to its {@link MediaBrowserCompat}.
- * Connecting to a new one automatically disconnects the previous browser. Changes in the
- * connection status are sent via {@link MediaBrowserConnector.Callback}.
+ * A helper class to connect to a single {@link MediaBrowserCompat}. Connecting to a new one
+ * automatically disconnects the previous browser. Changes of the currently connected browser are
+ * sent via {@link MediaBrowserConnector.Callback}.
  */
 
 public class MediaBrowserConnector {
 
     private static final String TAG = "MediaBrowserConnector";
 
-    /**
-     * Represents the state of the connection to the media browser service given to
-     * {@link #connectTo}.
-     */
-    public enum ConnectionStatus {
-        /**
-         * The connection request to the browser is being initiated.
-         * Sent from {@link #connectTo} just before calling {@link MediaBrowserCompat#connect}.
-         */
-        CONNECTING,
-        /**
-         * The connection to the browser has been established and it can be used.
-         * Sent from {@link MediaBrowserCompat.ConnectionCallback#onConnected} if
-         * {@link MediaBrowserCompat#isConnected} also returns true.
-         */
-        CONNECTED,
-        /**
-         * The connection to the browser was refused.
-         * Sent from {@link MediaBrowserCompat.ConnectionCallback#onConnectionFailed} or from
-         * {@link MediaBrowserCompat.ConnectionCallback#onConnected} if
-         * {@link MediaBrowserCompat#isConnected} returns false.
-         */
-        REJECTED,
-        /**
-         * The browser crashed and that calls should NOT be made to it anymore.
-         * Called from {@link MediaBrowserCompat.ConnectionCallback#onConnectionSuspended} and from
-         * {@link #connectTo} when {@link MediaBrowserCompat#connect} throws
-         * {@link IllegalStateException}.
-         */
-        SUSPENDED,
-        /**
-         * The connection to the browser is being closed.
-         * When connecting to a new browser and the old browser is connected, this is sent
-         * from {@link #connectTo} just before calling {@link MediaBrowserCompat#disconnect} on the
-         * old browser.
-         */
-        DISCONNECTING
-    }
-
-    /**
-     * Encapsulates a {@link ComponentName} with its {@link MediaBrowserCompat} and the
-     * {@link ConnectionStatus}.
-     */
-    public static class BrowsingState {
-        @NonNull public final MediaSource mMediaSource;
-        @NonNull public final MediaBrowserCompat mBrowser;
-        @NonNull public final ConnectionStatus mConnectionStatus;
-
-        @VisibleForTesting
-        public BrowsingState(@NonNull MediaSource mediaSource, @NonNull MediaBrowserCompat browser,
-                @NonNull ConnectionStatus status) {
-            mMediaSource = Preconditions.checkNotNull(mediaSource, "source can't be null");
-            mBrowser = Preconditions.checkNotNull(browser, "browser can't be null");
-            mConnectionStatus = Preconditions.checkNotNull(status, "status can't be null");
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            BrowsingState that = (BrowsingState) o;
-            return mMediaSource.equals(that.mMediaSource)
-                    && mBrowser.equals(that.mBrowser)
-                    && mConnectionStatus == that.mConnectionStatus;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mMediaSource, mBrowser, mConnectionStatus);
-        }
-    }
-
-    /** The callback to receive the current {@link MediaBrowserCompat} and its connection state. */
+    /** The callback to receive the currently connected {@link MediaBrowserCompat}. */
     public interface Callback {
-        /** Notifies the listener of connection status changes. */
-        void onBrowserConnectionChanged(@NonNull BrowsingState state);
+        /** When disconnecting, the given browser will be null. */
+        void onConnectedBrowserChanged(@Nullable MediaBrowserCompat browser);
     }
 
     private final Context mContext;
     private final Callback mCallback;
     private final int mMaxBitmapSizePx;
 
-    @Nullable private MediaSource mMediaSource;
+    @Nullable private ComponentName mBrowseService;
     @Nullable private MediaBrowserCompat mBrowser;
 
     /**
@@ -140,34 +64,22 @@
                 com.android.car.media.common.R.integer.media_items_bitmap_max_size_px);
     }
 
-    private String getSourcePackage() {
-        if (mMediaSource == null) return null;
-        return mMediaSource.getBrowseServiceComponentName().getPackageName();
-    }
-
     /** Counter so callbacks from obsolete connections can be ignored. */
     private int mBrowserConnectionCallbackCounter = 0;
 
     private class BrowserConnectionCallback extends MediaBrowserCompat.ConnectionCallback {
 
         private final int mSequenceNumber = ++mBrowserConnectionCallbackCounter;
-        private final String mCallbackPackage = getSourcePackage();
-
-        private BrowserConnectionCallback() {
-            if (Log.isLoggable(TAG, Log.INFO)) {
-                Log.i(TAG, "New Callback: " + idHash(this));
-            }
-        }
+        private final String mCallbackPackage = mBrowseService.getPackageName();
 
         private boolean isValidCall(String method) {
             if (mSequenceNumber != mBrowserConnectionCallbackCounter) {
-                Log.e(TAG, "Callback: " + idHash(this) + " ignoring " + method + " for "
-                        + mCallbackPackage + " seq: "
+                Log.e(TAG, "Ignoring callback " + method + " for " + mCallbackPackage + " seq: "
                         + mSequenceNumber + " current: " + mBrowserConnectionCallbackCounter
-                        + " package: " + getSourcePackage());
+                        + " current: " + mBrowseService.getPackageName());
                 return false;
             } else if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, method + " " + getSourcePackage() + " mBrowser: " + idHash(mBrowser));
+                Log.d(TAG, method + " " + mBrowseService.getPackageName() + idHash(mBrowser));
             }
             return true;
         }
@@ -175,67 +87,48 @@
         @Override
         public void onConnected() {
             if (isValidCall("onConnected")) {
-                if (mBrowser != null && mBrowser.isConnected()) {
-                    sendNewState(ConnectionStatus.CONNECTED);
-                } else {
-                    sendNewState(ConnectionStatus.REJECTED);
-                }
+                mCallback.onConnectedBrowserChanged(mBrowser);
             }
         }
 
         @Override
         public void onConnectionFailed() {
             if (isValidCall("onConnectionFailed")) {
-                sendNewState(ConnectionStatus.REJECTED);
+                mCallback.onConnectedBrowserChanged(null);
             }
         }
 
         @Override
         public void onConnectionSuspended() {
             if (isValidCall("onConnectionSuspended")) {
-                sendNewState(ConnectionStatus.SUSPENDED);
+                mCallback.onConnectedBrowserChanged(null);
             }
         }
     }
 
-    private void sendNewState(ConnectionStatus cnx) {
-        if (mMediaSource == null) {
-            Log.e(TAG, "sendNewState mMediaSource is null!");
-            return;
-        }
-        if (mBrowser == null) {
-            Log.e(TAG, "sendNewState mBrowser is null!");
-            return;
-        }
-        mCallback.onBrowserConnectionChanged(new BrowsingState(mMediaSource, mBrowser, cnx));
-    }
-
     /**
-     * Creates and connects a new {@link MediaBrowserCompat} if the given {@link MediaSource}
+     * Creates and connects a new {@link MediaBrowserCompat} if the given {@link ComponentName}
      * isn't null. If needed, the previous browser is disconnected.
-     * @param mediaSource the media source to connect to.
+     * @param browseService the ComponentName of the media browser service.
      * @see MediaBrowserCompat#MediaBrowserCompat(Context, ComponentName,
      * MediaBrowserCompat.ConnectionCallback, android.os.Bundle)
      */
-    public void connectTo(@Nullable MediaSource mediaSource) {
+    public void connectTo(@Nullable ComponentName browseService) {
         if (mBrowser != null && mBrowser.isConnected()) {
             if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Disconnecting: " + getSourcePackage()
-                        + " mBrowser: " + idHash(mBrowser));
+                Log.d(TAG, "Disconnecting: " + mBrowseService.getPackageName() + idHash(mBrowser));
             }
-            sendNewState(ConnectionStatus.DISCONNECTING);
+            mCallback.onConnectedBrowserChanged(null);
             mBrowser.disconnect();
         }
 
-        mMediaSource = mediaSource;
-        if (mMediaSource != null) {
-            mBrowser = createMediaBrowser(mMediaSource, new BrowserConnectionCallback());
+        mBrowseService = browseService;
+        if (mBrowseService != null) {
+            mBrowser = createMediaBrowser(mBrowseService, new BrowserConnectionCallback());
             if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Connecting to: " + getSourcePackage()
-                        + " mBrowser: " + idHash(mBrowser));
+                Log.d(TAG, "Connecting to: " + mBrowseService.getPackageName() + idHash(mBrowser));
             }
             try {
-                sendNewState(ConnectionStatus.CONNECTING);
                 mBrowser.connect();
             } catch (IllegalStateException ex) {
                 // Is this comment still valid ?
@@ -243,7 +136,6 @@
                 // disconnected either.). In this situation, trying to connect again can throw
                 // this exception, but there is no way to know without trying.
                 Log.e(TAG, "Connection exception: " + ex);
-                sendNewState(ConnectionStatus.SUSPENDED);
             }
         } else {
             mBrowser = null;
@@ -252,11 +144,10 @@
 
     // Override for testing.
     @NonNull
-    protected MediaBrowserCompat createMediaBrowser(@NonNull MediaSource mediaSource,
+    protected MediaBrowserCompat createMediaBrowser(@NonNull ComponentName browseService,
             @NonNull MediaBrowserCompat.ConnectionCallback callback) {
         Bundle rootHints = new Bundle();
         rootHints.putInt(MediaConstants.EXTRA_MEDIA_ART_SIZE_HINT_PIXELS, mMaxBitmapSizePx);
-        ComponentName browseService = mediaSource.getBrowseServiceComponentName();
         return new MediaBrowserCompat(mContext, browseService, callback, rootHints);
     }
 }
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaSource.java b/car-media-common/src/com/android/car/media/common/source/MediaSource.java
index 90a5b57..e09c248 100644
--- a/car-media-common/src/com/android/car/media/common/source/MediaSource.java
+++ b/car-media-common/src/com/android/car/media/common/source/MediaSource.java
@@ -31,7 +31,6 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
 
 import com.android.car.apps.common.BitmapUtils;
 import com.android.car.apps.common.IconCropper;
@@ -85,8 +84,7 @@
         }
     }
 
-    @VisibleForTesting
-    public MediaSource(@NonNull ComponentName browseService, @NonNull CharSequence displayName,
+    private MediaSource(@NonNull ComponentName browseService, @NonNull CharSequence displayName,
             @NonNull Drawable icon, @NonNull IconCropper iconCropper) {
         mBrowseService = browseService;
         mDisplayName = displayName;
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java b/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
index 8c93426..4fbb202 100644
--- a/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
+++ b/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
@@ -16,6 +16,9 @@
 
 package com.android.car.media.common.source;
 
+import static android.car.media.CarMediaManager.MEDIA_SOURCE_MODE_PLAYBACK;
+
+import static com.android.car.apps.common.util.CarAppsDebugUtils.idHash;
 import static com.android.car.arch.common.LiveDataFunctions.dataOf;
 
 import android.app.Application;
@@ -23,17 +26,20 @@
 import android.car.CarNotConnectedException;
 import android.car.media.CarMediaManager;
 import android.content.ComponentName;
+import android.media.session.MediaController;
 import android.os.Handler;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.lifecycle.AndroidViewModel;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
 
-import com.android.car.media.common.source.MediaBrowserConnector.BrowsingState;
-
 import java.util.Objects;
 
 /**
@@ -50,8 +56,10 @@
     // Primary media source.
     private final MutableLiveData<MediaSource> mPrimaryMediaSource = dataOf(null);
 
-    // Browser for the primary media source and its connection state.
-    private final MutableLiveData<BrowsingState> mBrowsingState = dataOf(null);
+    // Connected browser for the primary media source.
+    private final MutableLiveData<MediaBrowserCompat> mConnectedMediaBrowser = dataOf(null);
+    // Media controller for the connected browser.
+    private final MutableLiveData<MediaControllerCompat> mMediaController = dataOf(null);
 
     private final Handler mHandler;
     private final CarMediaManager.MediaSourceChangedListener mMediaSourceListener;
@@ -64,6 +72,8 @@
         MediaBrowserConnector createMediaBrowserConnector(@NonNull Application application,
                 @NonNull MediaBrowserConnector.Callback connectedBrowserCallback);
 
+        MediaControllerCompat getControllerForSession(@Nullable MediaSessionCompat.Token session);
+
         Car getCarApi();
 
         CarMediaManager getCarMediaManager(Car carApi) throws CarNotConnectedException;
@@ -71,6 +81,14 @@
         MediaSource getMediaSource(ComponentName componentName);
     }
 
+    /**
+     * Returns the MediaSourceViewModel singleton tied to the application.
+     * @deprecated should use get(Application application, int mode) instead
+     */
+    public static MediaSourceViewModel get(@NonNull Application application) {
+        return get(application, MEDIA_SOURCE_MODE_PLAYBACK);
+    }
+
     /** Returns the MediaSourceViewModel singleton tied to the application. */
     public static MediaSourceViewModel get(@NonNull Application application, int mode) {
         if (sInstances[mode] == null) {
@@ -94,6 +112,12 @@
             }
 
             @Override
+            public MediaControllerCompat getControllerForSession(
+                    @Nullable MediaSessionCompat.Token token) {
+                return token == null ? null : new MediaControllerCompat(application, token);
+            }
+
+            @Override
             public Car getCarApi() {
                 return Car.createCar(application);
             }
@@ -113,7 +137,7 @@
 
     private final InputFactory mInputFactory;
     private final MediaBrowserConnector mBrowserConnector;
-    private final MediaBrowserConnector.Callback mBrowserCallback = mBrowsingState::setValue;
+    private final MediaBrowserConnector.Callback mConnectedBrowserCallback;
 
     @VisibleForTesting
     MediaSourceViewModel(@NonNull Application application, int mode,
@@ -123,7 +147,23 @@
         mInputFactory = inputFactory;
         mCar = inputFactory.getCarApi();
 
-        mBrowserConnector = inputFactory.createMediaBrowserConnector(application, mBrowserCallback);
+        mConnectedBrowserCallback = browser -> {
+            mConnectedMediaBrowser.setValue(browser);
+            if (browser != null) {
+                if (!browser.isConnected()) {
+                    Log.e(TAG, "Browser is NOT connected !! "
+                            + mPrimaryMediaSource.getValue().toString() + idHash(browser));
+                    mMediaController.setValue(null);
+                } else {
+                    mMediaController.setValue(mInputFactory.getControllerForSession(
+                            browser.getSessionToken()));
+                }
+            } else {
+                mMediaController.setValue(null);
+            }
+        };
+        mBrowserConnector = inputFactory.createMediaBrowserConnector(application,
+                mConnectedBrowserCallback);
 
         mHandler = new Handler(application.getMainLooper());
         mMediaSourceListener = componentName -> mHandler.post(
@@ -145,8 +185,8 @@
     }
 
     @VisibleForTesting
-    MediaBrowserConnector.Callback getBrowserCallback() {
-        return mBrowserCallback;
+    MediaBrowserConnector.Callback getConnectedBrowserCallback() {
+        return mConnectedBrowserCallback;
     }
 
     /**
@@ -164,11 +204,21 @@
     }
 
     /**
-     * Returns a LiveData that emits a {@link BrowsingState}, or {@code null} if there is no media
-     * source.
+     * Returns a LiveData that emits the currently connected MediaBrowser. Emits {@code null} if no
+     * MediaSource is set, if the MediaSource does not support browsing, or if the MediaBrowser is
+     * not connected.
      */
-    public LiveData<BrowsingState> getBrowsingState() {
-        return mBrowsingState;
+    public LiveData<MediaBrowserCompat> getConnectedMediaBrowser() {
+        return mConnectedMediaBrowser;
+    }
+
+    /**
+     * Returns a LiveData that emits a {@link MediaController} that allows controlling this media
+     * source, or emits {@code null} if the media source doesn't support browsing or the browser is
+     * not connected.
+     */
+    public LiveData<MediaControllerCompat> getMediaController() {
+        return mMediaController;
     }
 
     private void updateModelState(MediaSource newMediaSource) {
@@ -183,7 +233,8 @@
 
         // Recompute dependent values
         if (newMediaSource != null) {
-            mBrowserConnector.connectTo(newMediaSource);
+            ComponentName browseService = newMediaSource.getBrowseServiceComponentName();
+            mBrowserConnector.connectTo(browseService);
         }
     }
 }
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaSourcesLiveData.java b/car-media-common/src/com/android/car/media/common/source/MediaSourcesLiveData.java
new file mode 100644
index 0000000..9f9cc26
--- /dev/null
+++ b/car-media-common/src/com/android/car/media/common/source/MediaSourcesLiveData.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2018 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.media.common.source;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.service.media.MediaBrowserService;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.car.media.common.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Singleton that provides access to the list of all possible media sources that can be selected
+ * to be played.
+ */
+// TODO(arnaudberry) rename to MediaSourcesProvider
+public class MediaSourcesLiveData {
+
+    private static final String TAG = "MediaSources";
+
+    private static MediaSourcesLiveData sInstance;
+    private final Context mAppContext;
+    @Nullable
+    private List<MediaSource> mMediaSources;
+
+    private final BroadcastReceiver mAppInstallUninstallReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            reset();
+        }
+    };
+
+    /** Returns the singleton instance. */
+    public static MediaSourcesLiveData getInstance(@NonNull Context context) {
+        if (sInstance == null) {
+            sInstance = new MediaSourcesLiveData(context);
+        }
+        return sInstance;
+    }
+
+    /** Returns a different instance every time (tests don't like statics) */
+    @VisibleForTesting
+    public static MediaSourcesLiveData createForTesting(@NonNull Context context) {
+        return new MediaSourcesLiveData(context);
+    }
+
+    @VisibleForTesting
+    void reset() {
+        mMediaSources = null;
+    }
+
+    private MediaSourcesLiveData(@NonNull Context context) {
+        mAppContext = context.getApplicationContext();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addDataScheme("package");
+        mAppContext.registerReceiver(mAppInstallUninstallReceiver, filter);
+    }
+
+    /**
+     * Returns the sorted list of available media sources. Sources listed in the array resource
+     * R.array.preferred_media_sources are included first. Other sources follow in alphabetical
+     * order.
+     */
+    public List<MediaSource> getList() {
+        if (mMediaSources == null) {
+            // Get the flattened components to display first.
+            String[] preferredFlats = mAppContext.getResources().getStringArray(
+                    R.array.preferred_media_sources);
+
+            // Make a map of components to display first (the value is the component's index).
+            HashMap<ComponentName, Integer> preferredComps = new HashMap<>(preferredFlats.length);
+            for (int i = 0; i < preferredFlats.length; i++) {
+                preferredComps.put(ComponentName.unflattenFromString(preferredFlats[i]), i);
+            }
+
+            // Prepare an array of the sources to display first (unavailable preferred components
+            // will be excluded).
+            MediaSource[] preferredSources = new MediaSource[preferredFlats.length];
+            List<MediaSource> sortedSources = getComponentNames().stream()
+                    .filter(Objects::nonNull)
+                    .map(componentName -> MediaSource.create(mAppContext, componentName))
+                    .filter(mediaSource -> {
+                        if (mediaSource == null) {
+                            Log.w(TAG, "Media source is null");
+                            return false;
+                        }
+                        ComponentName srcComp = mediaSource.getBrowseServiceComponentName();
+                        if (preferredComps.containsKey(srcComp)) {
+                            // Record the source in the preferred array...
+                            preferredSources[preferredComps.get(srcComp)] = mediaSource;
+                            // And exclude it from the alpha sort.
+                            return false;
+                        }
+                        return true;
+                    })
+                    .sorted(Comparator.comparing(
+                            mediaSource -> mediaSource.getDisplayName().toString()))
+                    .collect(Collectors.toList());
+
+            // Concatenate the non null preferred sources and the sorted ones into the result.
+            mMediaSources = new ArrayList<>(sortedSources.size() + preferredFlats.length);
+            Arrays.stream(preferredSources).filter(Objects::nonNull).forEach(mMediaSources::add);
+            mMediaSources.addAll(sortedSources);
+        }
+        return mMediaSources;
+    }
+
+    /**
+     * Generates a set of all possible media services to choose from.
+     */
+    private Set<ComponentName> getComponentNames() {
+        PackageManager packageManager = mAppContext.getPackageManager();
+        Intent mediaIntent = new Intent();
+        mediaIntent.setAction(MediaBrowserService.SERVICE_INTERFACE);
+        List<ResolveInfo> mediaServices = packageManager.queryIntentServices(mediaIntent,
+                PackageManager.GET_RESOLVED_FILTER);
+
+        Set<ComponentName> components = new HashSet<>();
+        for (ResolveInfo info : mediaServices) {
+            ComponentName componentName = new ComponentName(info.serviceInfo.packageName,
+                    info.serviceInfo.name);
+            components.add(componentName);
+        }
+        return components;
+    }
+
+}
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaSourcesProvider.java b/car-media-common/src/com/android/car/media/common/source/MediaSourcesProvider.java
deleted file mode 100644
index 7312589..0000000
--- a/car-media-common/src/com/android/car/media/common/source/MediaSourcesProvider.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2018 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.media.common.source;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.service.media.MediaBrowserService;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.media.common.R;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Singleton that provides access to the list of all possible media sources that can be selected
- * to be played.
- */
-public class MediaSourcesProvider {
-
-    private static final String TAG = "MediaSources";
-
-    private static MediaSourcesProvider sInstance;
-    private final Context mAppContext;
-    @Nullable
-    private List<MediaSource> mMediaSources;
-
-    private final BroadcastReceiver mAppInstallUninstallReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            reset();
-        }
-    };
-
-    /** Returns the singleton instance. */
-    public static MediaSourcesProvider getInstance(@NonNull Context context) {
-        if (sInstance == null) {
-            sInstance = new MediaSourcesProvider(context);
-        }
-        return sInstance;
-    }
-
-    /** Returns a different instance every time (tests don't like statics) */
-    @VisibleForTesting
-    public static MediaSourcesProvider createForTesting(@NonNull Context context) {
-        return new MediaSourcesProvider(context);
-    }
-
-    @VisibleForTesting
-    void reset() {
-        mMediaSources = null;
-    }
-
-    private MediaSourcesProvider(@NonNull Context context) {
-        mAppContext = context.getApplicationContext();
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        filter.addDataScheme("package");
-        mAppContext.registerReceiver(mAppInstallUninstallReceiver, filter);
-    }
-
-    /**
-     * Returns the sorted list of available media sources. Sources listed in the array resource
-     * R.array.preferred_media_sources are included first. Other sources follow in alphabetical
-     * order.
-     */
-    public List<MediaSource> getList() {
-        if (mMediaSources == null) {
-            // Get the flattened components to display first.
-            String[] preferredFlats = mAppContext.getResources().getStringArray(
-                    R.array.preferred_media_sources);
-
-            // Make a map of components to display first (the value is the component's index).
-            HashMap<ComponentName, Integer> preferredComps = new HashMap<>(preferredFlats.length);
-            for (int i = 0; i < preferredFlats.length; i++) {
-                preferredComps.put(ComponentName.unflattenFromString(preferredFlats[i]), i);
-            }
-
-            // Prepare an array of the sources to display first (unavailable preferred components
-            // will be excluded).
-            MediaSource[] preferredSources = new MediaSource[preferredFlats.length];
-            List<MediaSource> sortedSources = getComponentNames().stream()
-                    .filter(Objects::nonNull)
-                    .map(componentName -> MediaSource.create(mAppContext, componentName))
-                    .filter(mediaSource -> {
-                        if (mediaSource == null) {
-                            Log.w(TAG, "Media source is null");
-                            return false;
-                        }
-                        ComponentName srcComp = mediaSource.getBrowseServiceComponentName();
-                        if (preferredComps.containsKey(srcComp)) {
-                            // Record the source in the preferred array...
-                            preferredSources[preferredComps.get(srcComp)] = mediaSource;
-                            // And exclude it from the alpha sort.
-                            return false;
-                        }
-                        return true;
-                    })
-                    .sorted(Comparator.comparing(
-                            mediaSource -> mediaSource.getDisplayName().toString()))
-                    .collect(Collectors.toList());
-
-            // Concatenate the non null preferred sources and the sorted ones into the result.
-            mMediaSources = new ArrayList<>(sortedSources.size() + preferredFlats.length);
-            Arrays.stream(preferredSources).filter(Objects::nonNull).forEach(mMediaSources::add);
-            mMediaSources.addAll(sortedSources);
-        }
-        return mMediaSources;
-    }
-
-    /**
-     * Generates a set of all possible media services to choose from.
-     */
-    private Set<ComponentName> getComponentNames() {
-        PackageManager packageManager = mAppContext.getPackageManager();
-        Intent mediaIntent = new Intent();
-        mediaIntent.setAction(MediaBrowserService.SERVICE_INTERFACE);
-        List<ResolveInfo> mediaServices = packageManager.queryIntentServices(mediaIntent,
-                PackageManager.GET_RESOLVED_FILTER);
-
-        Set<ComponentName> components = new HashSet<>();
-        for (ResolveInfo info : mediaServices) {
-            ComponentName componentName = new ComponentName(info.serviceInfo.packageName,
-                    info.serviceInfo.name);
-            components.add(componentName);
-        }
-        return components;
-    }
-
-}
diff --git a/car-media-common/tests/robotests/Android.bp b/car-media-common/tests/robotests/Android.bp
index c20ef82..13e19f7 100644
--- a/car-media-common/tests/robotests/Android.bp
+++ b/car-media-common/tests/robotests/Android.bp
@@ -3,10 +3,6 @@
 //###########################################################
 // CarMediaCommon app just for Robolectric test target.     #
 //###########################################################
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_app {
     name: "CarMediaCommon",
 
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/MediaTestUtils.java b/car-media-common/tests/robotests/src/com/android/car/media/common/MediaTestUtils.java
deleted file mode 100644
index 84643c4..0000000
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/MediaTestUtils.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.media.common;
-
-import android.content.ComponentName;
-import android.graphics.Path;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.apps.common.IconCropper;
-import com.android.car.media.common.source.MediaSource;
-
-public class MediaTestUtils {
-
-    private MediaTestUtils() {
-    }
-
-    /** Creates a fake {@link MediaSource}. */
-    public static MediaSource newFakeMediaSource(@NonNull String pkg, @NonNull String cls) {
-        return newFakeMediaSource(new ComponentName(pkg, cls));
-    }
-
-    /** Creates a fake {@link MediaSource}. */
-    public static MediaSource newFakeMediaSource(@NonNull ComponentName browseService) {
-        String displayName = browseService.getClassName();
-        Drawable icon = new ColorDrawable();
-        IconCropper iconCropper = new IconCropper(new Path());
-        return new MediaSource(browseService, displayName, icon, iconCropper);
-    }
-}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java
index 33979e2..ad6cfe8 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java
@@ -17,7 +17,6 @@
 package com.android.car.media.common.playback;
 
 import static com.android.car.arch.common.LiveDataFunctions.dataOf;
-import static com.android.car.media.common.MediaTestUtils.newFakeMediaSource;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -26,7 +25,7 @@
 import static org.mockito.Mockito.when;
 import static org.robolectric.RuntimeEnvironment.application;
 
-import android.support.v4.media.MediaBrowserCompat;
+import android.media.MediaDescription;
 import android.support.v4.media.MediaDescriptionCompat;
 import android.support.v4.media.MediaMetadataCompat;
 import android.support.v4.media.session.MediaControllerCompat;
@@ -40,9 +39,6 @@
 import com.android.car.arch.common.testing.InstantTaskExecutorRule;
 import com.android.car.arch.common.testing.TestLifecycleOwner;
 import com.android.car.media.common.MediaItemMetadata;
-import com.android.car.media.common.source.MediaBrowserConnector.BrowsingState;
-import com.android.car.media.common.source.MediaBrowserConnector.ConnectionStatus;
-import com.android.car.media.common.source.MediaSource;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -55,11 +51,8 @@
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
 
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 @RunWith(RobolectricTestRunner.class)
 public class PlaybackViewModelTest {
@@ -71,15 +64,13 @@
     @Rule
     public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
 
-    private final MediaSource mMediaSource = newFakeMediaSource("test", "test");
-
-    @Mock
-    public MediaBrowserCompat mMediaBrowser;
     @Mock
     public MediaControllerCompat mMediaController;
     @Mock
     public MediaMetadataCompat mMediaMetadata;
     @Mock
+    public MediaDescription mMediaDescription;
+    @Mock
     public MediaDescriptionCompat mMediaDescriptionCompat;
     @Mock
     public PlaybackStateCompat mPlaybackState;
@@ -88,23 +79,19 @@
 
     private PlaybackViewModel mPlaybackViewModel;
 
-    private MutableLiveData<BrowsingState> mBrowsingStateLD;
-
-    private Map<MediaBrowserCompat, MediaControllerCompat> mBrowserToController = new HashMap<>();
+    private MutableLiveData<MediaControllerCompat> mMediaControllerLiveData;
 
     @Before
     public void setUp() {
-        mBrowserToController.put(mMediaBrowser, mMediaController);
         doNothing().when(mMediaController).registerCallback(mCapturedCallback.capture());
-        mBrowsingStateLD = dataOf(
-                new BrowsingState(mMediaSource, mMediaBrowser, ConnectionStatus.CONNECTED));
-        mPlaybackViewModel = new PlaybackViewModel(application, mBrowsingStateLD,
-                browser -> mBrowserToController.get(browser));
+        when(mMediaDescriptionCompat.getMediaDescription()).thenReturn(mMediaDescription);
+        when(mMediaMetadata.getDescription()).thenReturn(mMediaDescriptionCompat);
+        mMediaControllerLiveData = dataOf(mMediaController);
+        mPlaybackViewModel = new PlaybackViewModel(application, mMediaControllerLiveData);
     }
 
     @Test
     public void testGetMetadata() {
-        when(mMediaMetadata.getDescription()).thenReturn(mMediaDescriptionCompat);
         CaptureObserver<MediaItemMetadata> observer = new CaptureObserver<>();
         mPlaybackViewModel.getMetadata().observe(mLifecycleOwner, observer);
         observer.reset();
@@ -186,7 +173,7 @@
     @Test
     public void testGetHasQueue_true() {
         List<MediaSessionCompat.QueueItem> queue =
-                Arrays.asList(createQueueItem("title1", 1), createQueueItem("title2", 2));
+                Collections.singletonList(createQueueItem("title", 1));
         CaptureObserver<Boolean> observer = new CaptureObserver<>();
         mPlaybackViewModel.hasQueue().observe(mLifecycleOwner, observer);
         observer.reset();
@@ -199,13 +186,13 @@
 
     @Test
     public void testChangeMediaSource_consistentController() {
+        // Ensure getters are consistent with values delivered by callback
+        when(mMediaController.getMetadata()).thenReturn(mMediaMetadata);
+        when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
         deliverValuesToCallbacks(mCapturedCallback, mMediaMetadata, mPlaybackState);
 
-        // Create new MediaBrowser, new MediaController and associated callback captor
-        MediaBrowserCompat newMediaBrowser = mock(MediaBrowserCompat.class);
+        // Create new MediaController and associated callback captor
         MediaControllerCompat newController = mock(MediaControllerCompat.class);
-        mBrowserToController.put(newMediaBrowser, newController);
-
         ArgumentCaptor<MediaControllerCompat.Callback> newCallbackCaptor =
                 ArgumentCaptor.forClass(MediaControllerCompat.Callback.class);
         doNothing().when(newController).registerCallback(newCallbackCaptor.capture());
@@ -213,15 +200,16 @@
         // Wire up new data for new MediaController
         MediaMetadataCompat newMetadata = mock(MediaMetadataCompat.class);
         PlaybackStateCompat newPlaybackState = mock(PlaybackStateCompat.class);
+        when(newController.getMetadata()).thenReturn(newMetadata);
+        when(newController.getPlaybackState()).thenReturn(newPlaybackState);
 
         // Ensure that all values are coming from the correct MediaController.
         mPlaybackViewModel.getMetadata().observe(mLifecycleOwner, mediaItemMetadata -> {
             if (mPlaybackViewModel.getMediaMetadata() == newMetadata) {
-                assertThat(mPlaybackViewModel.getMediaController()).isSameInstanceAs(newController);
+                assertThat(mPlaybackViewModel.getMediaController()).isSameAs(newController);
             }
             if (mPlaybackViewModel.getMediaMetadata() == mMediaMetadata) {
-                assertThat(mPlaybackViewModel.getMediaController())
-                        .isSameInstanceAs(mMediaController);
+                assertThat(mPlaybackViewModel.getMediaController()).isSameAs(mMediaController);
             }
         });
 
@@ -229,16 +217,14 @@
             if (state == null) return;
 
             if (state.getStateCompat() == newPlaybackState) {
-                assertThat(mPlaybackViewModel.getMediaController()).isSameInstanceAs(newController);
+                assertThat(mPlaybackViewModel.getMediaController()).isSameAs(newController);
             }
             if (state.getStateCompat() == mPlaybackState) {
-                assertThat(mPlaybackViewModel.getMediaController())
-                        .isSameInstanceAs(mMediaController);
+                assertThat(mPlaybackViewModel.getMediaController()).isSameAs(mMediaController);
             }
         });
 
-        mBrowsingStateLD.setValue(
-                new BrowsingState(mMediaSource, newMediaBrowser, ConnectionStatus.CONNECTED));
+        mMediaControllerLiveData.setValue(newController);
         deliverValuesToCallbacks(newCallbackCaptor, newMetadata, newPlaybackState);
     }
 
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java
index fdf5a56..eeccb5e 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java
@@ -16,24 +16,21 @@
 
 package com.android.car.media.common.source;
 
-import static com.android.car.media.common.MediaTestUtils.newFakeMediaSource;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.robolectric.RuntimeEnvironment.application;
 
+import android.content.ComponentName;
 import android.support.v4.media.MediaBrowserCompat;
 
 import androidx.annotation.NonNull;
 
 import com.android.car.arch.common.testing.InstantTaskExecutorRule;
 import com.android.car.arch.common.testing.TestLifecycleOwner;
-import com.android.car.media.common.source.MediaBrowserConnector.BrowsingState;
-import com.android.car.media.common.source.MediaBrowserConnector.ConnectionStatus;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -65,10 +62,10 @@
     @Mock
     public MediaBrowserCompat mMediaBrowser2;
 
-    private final MediaSource mMediaSource1 = newFakeMediaSource("mediaService1", "className1");
-    private final MediaSource mMediaSource2 = newFakeMediaSource("mediaService2", "className2");
+    private final ComponentName mBrowseService1 = new ComponentName("mediaService1", "className1");
+    private final ComponentName mBrowseService2 = new ComponentName("mediaService2", "className2");
 
-    private final Map<MediaSource, MediaBrowserCompat> mBrowsers = new HashMap<>(2);
+    private final Map<ComponentName, MediaBrowserCompat> mBrowsers = new HashMap<>(2);
 
     private MediaBrowserConnector mBrowserConnector;
     private MediaBrowserCompat.ConnectionCallback mConnectionCallback;
@@ -76,22 +73,24 @@
     @Mock
     public MediaBrowserConnector.Callback mConnectedBrowserCallback;
     @Captor
-    private ArgumentCaptor<BrowsingState> mBrowsingStateCaptor;
+    private ArgumentCaptor<MediaBrowserCompat> mConnectedBrowserCaptor;
 
     @Before
     public void setUp() {
-        mBrowsers.put(mMediaSource1, mMediaBrowser1);
-        mBrowsers.put(mMediaSource2, mMediaBrowser2);
+        mBrowsers.put(mBrowseService1, mMediaBrowser1);
+        mBrowsers.put(mBrowseService2, mMediaBrowser2);
+        when(mMediaBrowser1.isConnected()).thenReturn(false);
+        when(mMediaBrowser2.isConnected()).thenReturn(false);
 
-        doNothing().when(mConnectedBrowserCallback).onBrowserConnectionChanged(
-                mBrowsingStateCaptor.capture());
+        doNothing().when(mConnectedBrowserCallback).onConnectedBrowserChanged(
+                mConnectedBrowserCaptor.capture());
 
         mBrowserConnector = new MediaBrowserConnector(application, mConnectedBrowserCallback) {
             @Override
-            protected MediaBrowserCompat createMediaBrowser(@NonNull MediaSource mediaSource,
+            protected MediaBrowserCompat createMediaBrowser(@NonNull ComponentName browseService,
                     @NonNull MediaBrowserCompat.ConnectionCallback callback) {
                 mConnectionCallback = callback;
-                return mBrowsers.get(mediaSource);
+                return mBrowsers.get(browseService);
             }
         };
     }
@@ -102,77 +101,54 @@
             throw new IllegalStateException("expected");
         });
 
-        mBrowserConnector.connectTo(mMediaSource1);
+        mBrowserConnector.connectTo(mBrowseService1);
         verify(mMediaBrowser1).connect();
     }
 
     @Test
     public void testConnectionCallback_onConnected() {
-        doReturn(true).when(mMediaBrowser1).isConnected();
         setConnectionAction(() -> mConnectionCallback.onConnected());
 
-        mBrowserConnector.connectTo(mMediaSource1);
+        mBrowserConnector.connectTo(mBrowseService1);
 
-        BrowsingState state = mBrowsingStateCaptor.getValue();
-        assertThat(state.mBrowser).isEqualTo(mMediaBrowser1);
-        assertThat(state.mConnectionStatus).isEqualTo(ConnectionStatus.CONNECTED);
-    }
-
-    @Test
-    public void testConnectionCallback_onConnected_inconsistentState() {
-        doReturn(false).when(mMediaBrowser1).isConnected();
-        setConnectionAction(() -> mConnectionCallback.onConnected());
-
-        mBrowserConnector.connectTo(mMediaSource1);
-
-        BrowsingState state = mBrowsingStateCaptor.getValue();
-        assertThat(state.mBrowser).isEqualTo(mMediaBrowser1);
-        assertThat(state.mConnectionStatus).isEqualTo(ConnectionStatus.REJECTED);
+        assertThat(mConnectedBrowserCaptor.getValue()).isEqualTo(mMediaBrowser1);
     }
 
     @Test
     public void testConnectionCallback_onConnectionFailed() {
         setConnectionAction(() -> mConnectionCallback.onConnectionFailed());
 
-        mBrowserConnector.connectTo(mMediaSource1);
+        mBrowserConnector.connectTo(mBrowseService1);
 
-        BrowsingState state = mBrowsingStateCaptor.getValue();
-        assertThat(state.mBrowser).isEqualTo(mMediaBrowser1);
-        assertThat(state.mConnectionStatus).isEqualTo(ConnectionStatus.REJECTED);
+        assertThat(mConnectedBrowserCaptor.getValue()).isNull();
     }
 
     @Test
     public void testConnectionCallback_onConnectionSuspended() {
-        doReturn(true).when(mMediaBrowser1).isConnected();
         setConnectionAction(() -> {
             mConnectionCallback.onConnected();
             mConnectionCallback.onConnectionSuspended();
         });
 
-        mBrowserConnector.connectTo(mMediaSource1);
+        mBrowserConnector.connectTo(mBrowseService1);
 
 
-        List<BrowsingState> browsingStates = mBrowsingStateCaptor.getAllValues();
-        assertThat(browsingStates.get(0).mBrowser).isEqualTo(mMediaBrowser1);
-        assertThat(browsingStates.get(1).mBrowser).isEqualTo(mMediaBrowser1);
-        assertThat(browsingStates.get(2).mBrowser).isEqualTo(mMediaBrowser1);
-
-        assertThat(browsingStates.get(0).mConnectionStatus).isEqualTo(ConnectionStatus.CONNECTING);
-        assertThat(browsingStates.get(1).mConnectionStatus).isEqualTo(ConnectionStatus.CONNECTED);
-        assertThat(browsingStates.get(2).mConnectionStatus).isEqualTo(ConnectionStatus.SUSPENDED);
+        List<MediaBrowserCompat> browsers = mConnectedBrowserCaptor.getAllValues();
+        assertThat(browsers.get(0)).isEqualTo(mMediaBrowser1);
+        assertThat(browsers.get(1)).isNull();
     }
 
     @Test
     public void testConnectionCallback_onConnectedIgnoredWhenLate() {
-        mBrowserConnector.connectTo(mMediaSource1);
+        mBrowserConnector.connectTo(mBrowseService1);
         MediaBrowserCompat.ConnectionCallback cb1 = mConnectionCallback;
 
-        mBrowserConnector.connectTo(mMediaSource2);
+        mBrowserConnector.connectTo(mBrowseService2);
         MediaBrowserCompat.ConnectionCallback cb2 = mConnectionCallback;
 
         cb2.onConnected();
         cb1.onConnected();
-        assertThat(mBrowsingStateCaptor.getValue().mBrowser).isEqualTo(mMediaBrowser2);
+        assertThat(mConnectedBrowserCaptor.getValue()).isEqualTo(mMediaBrowser2);
     }
 
     private void setConnectionAction(@NonNull Runnable action) {
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
index 638f8dc..b22bba2 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
@@ -18,11 +18,9 @@
 
 import static android.car.media.CarMediaManager.MEDIA_SOURCE_MODE_PLAYBACK;
 
-import static com.android.car.apps.common.util.CarAppsDebugUtils.idHash;
-import static com.android.car.media.common.MediaTestUtils.newFakeMediaSource;
-
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.robolectric.RuntimeEnvironment.application;
 
@@ -31,15 +29,15 @@
 import android.car.media.CarMediaManager;
 import android.content.ComponentName;
 import android.support.v4.media.MediaBrowserCompat;
-import android.util.Log;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.car.arch.common.testing.CaptureObserver;
 import com.android.car.arch.common.testing.InstantTaskExecutorRule;
 import com.android.car.arch.common.testing.TestLifecycleOwner;
-import com.android.car.media.common.source.MediaBrowserConnector.BrowsingState;
-import com.android.car.media.common.source.MediaBrowserConnector.ConnectionStatus;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -50,12 +48,11 @@
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
 
-
 @RunWith(RobolectricTestRunner.class)
 public class MediaSourceViewModelTest {
 
-    private static final String TAG = "MediaSourceVMTest";
-
+    private static final String BROWSER_CONTROLLER_PACKAGE_NAME = "browser";
+    private static final String SESSION_MANAGER_CONTROLLER_PACKAGE_NAME = "mediaSessionManager";
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
     @Rule
@@ -65,6 +62,10 @@
 
     @Mock
     public MediaBrowserCompat mMediaBrowser;
+    @Mock
+    public MediaControllerCompat mMediaControllerFromBrowser;
+    @Mock
+    public MediaControllerCompat mMediaControllerFromSessionManager;
 
     @Mock
     public Car mCar;
@@ -73,12 +74,17 @@
 
     private MediaSourceViewModel mViewModel;
 
-    private MediaSource mRequestedSource;
+    private ComponentName mRequestedBrowseService;
     private MediaSource mMediaSource;
 
     @Before
     public void setUp() {
-        mRequestedSource = null;
+        when(mMediaControllerFromBrowser.getPackageName())
+                .thenReturn(BROWSER_CONTROLLER_PACKAGE_NAME);
+        when(mMediaControllerFromSessionManager.getPackageName())
+                .thenReturn(SESSION_MANAGER_CONTROLLER_PACKAGE_NAME);
+
+        mRequestedBrowseService = null;
         mMediaSource = null;
     }
 
@@ -91,17 +97,21 @@
                     @NonNull MediaBrowserConnector.Callback connectedBrowserCallback) {
                 return new MediaBrowserConnector(application, connectedBrowserCallback) {
                     @Override
-                    protected MediaBrowserCompat createMediaBrowser(MediaSource mediaSource,
+                    protected MediaBrowserCompat createMediaBrowser(ComponentName browseService,
                             MediaBrowserCompat.ConnectionCallback callback) {
-                        mRequestedSource = mediaSource;
-                        MediaBrowserCompat bro = super.createMediaBrowser(mediaSource, callback);
-                        Log.i(TAG, "createMediaBrowser: " + idHash(bro) + " for: " + mediaSource);
-                        return bro;
+                        mRequestedBrowseService = browseService;
+                        return super.createMediaBrowser(browseService, callback);
                     }
                 };
             }
 
             @Override
+            public MediaControllerCompat getControllerForSession(
+                    @Nullable MediaSessionCompat.Token token) {
+                return mMediaControllerFromBrowser;
+            }
+
+            @Override
             public Car getCarApi() {
                 return mCar;
             }
@@ -130,35 +140,33 @@
 
     @Test
     public void testGetMediaController_connectedBrowser() {
-        CaptureObserver<BrowsingState> observer = new CaptureObserver<>();
-        mMediaSource = newFakeMediaSource("test", "test");
+        CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
+        ComponentName testComponent = new ComponentName("test", "test");
+        mMediaSource = mock(MediaSource.class);
+        when(mMediaSource.getBrowseServiceComponentName()).thenReturn(testComponent);
         when(mMediaBrowser.isConnected()).thenReturn(true);
         initializeViewModel();
 
-        mViewModel.getBrowserCallback().onBrowserConnectionChanged(
-                new BrowsingState(mMediaSource, mMediaBrowser, ConnectionStatus.CONNECTED));
-        mViewModel.getBrowsingState().observe(mLifecycleOwner, observer);
+        mViewModel.getConnectedBrowserCallback().onConnectedBrowserChanged(mMediaBrowser);
+        mViewModel.getMediaController().observe(mLifecycleOwner, observer);
 
-        BrowsingState browsingState = observer.getObservedValue();
-        assertThat(browsingState.mBrowser).isSameInstanceAs(mMediaBrowser);
-        assertThat(browsingState.mConnectionStatus).isEqualTo(ConnectionStatus.CONNECTED);
-        assertThat(mRequestedSource).isEqualTo(mMediaSource);
+        assertThat(observer.getObservedValue()).isSameAs(mMediaControllerFromBrowser);
+        assertThat(mRequestedBrowseService).isEqualTo(testComponent);
     }
 
     @Test
     public void testGetMediaController_noActiveSession_notConnected() {
-        CaptureObserver<BrowsingState> observer = new CaptureObserver<>();
-        mMediaSource = newFakeMediaSource("test", "test");
+        CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
+        ComponentName testComponent = new ComponentName("test", "test");
+        mMediaSource = mock(MediaSource.class);
+        when(mMediaSource.getBrowseServiceComponentName()).thenReturn(testComponent);
         when(mMediaBrowser.isConnected()).thenReturn(false);
         initializeViewModel();
 
-        mViewModel.getBrowserCallback().onBrowserConnectionChanged(
-                new BrowsingState(mMediaSource, mMediaBrowser, ConnectionStatus.REJECTED));
-        mViewModel.getBrowsingState().observe(mLifecycleOwner, observer);
+        mViewModel.getMediaController().observe(mLifecycleOwner, observer);
 
-        BrowsingState browsingState = observer.getObservedValue();
-        assertThat(browsingState.mBrowser).isSameInstanceAs(mMediaBrowser);
-        assertThat(browsingState.mConnectionStatus).isEqualTo(ConnectionStatus.REJECTED);
-        assertThat(mRequestedSource).isEqualTo(mMediaSource);
+        assertThat(observer.hasBeenNotified()).isTrue();
+        assertThat(observer.getObservedValue()).isNull();
+        assertThat(mRequestedBrowseService).isEqualTo(testComponent);
     }
 }
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourcesLiveDataTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourcesLiveDataTest.java
new file mode 100644
index 0000000..f97b278
--- /dev/null
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourcesLiveDataTest.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2018 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.media.common.source;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.RuntimeEnvironment.application;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Bundle;
+import android.service.media.MediaBrowserService;
+
+import androidx.annotation.NonNull;
+
+import com.android.car.arch.common.testing.InstantTaskExecutorRule;
+import com.android.car.arch.common.testing.TestLifecycleOwner;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowPackageManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RunWith(RobolectricTestRunner.class)
+public class MediaSourcesLiveDataTest {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
+    @Rule
+    public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
+
+    private static final String TEST_ACTIVITY_PACKAGE_1 = "activity_package1";
+    private static final String TEST_ACTIVITY_PACKAGE_2 = "activity_package2";
+    private static final String TEST_SERVICE_PACKAGE_1 = "service_package1";
+    private static final String TEST_SERVICE_PACKAGE_2 = "service_package2";
+    private static final String TEST_SERVICE_PACKAGE_WITH_METADATA = "service_package3";
+
+    private MediaSourcesLiveData mMediaSources;
+    private Intent mActivityIntent;
+    private Intent mServiceIntent;
+
+    @Before
+    public void setUp() {
+        mMediaSources = MediaSourcesLiveData.createForTesting(application);
+
+        mActivityIntent = new Intent(Intent.ACTION_MAIN, null);
+        mActivityIntent.addCategory(Intent.CATEGORY_APP_MUSIC);
+
+        mServiceIntent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
+        ShadowPackageManager packageManager = shadowOf(application.getPackageManager());
+
+        List<ResolveInfo> activityResolveInfo = buildActivityResolveInfo();
+        List<ResolveInfo> allActivityResolveInfo = new ArrayList<>(activityResolveInfo);
+        allActivityResolveInfo.add(newActivityResolveInfo(TEST_ACTIVITY_PACKAGE_2));
+        for (ResolveInfo info : allActivityResolveInfo) {
+            PackageInfo packageInfo = new PackageInfo();
+            packageInfo.activities = new ActivityInfo[]{info.activityInfo};
+            packageInfo.packageName = info.activityInfo.packageName;
+            packageInfo.applicationInfo = info.activityInfo.applicationInfo;
+            packageManager.addPackage(packageInfo);
+        }
+        List<ResolveInfo> serviceResolveInfo = buildServiceResolveInfo();
+        List<ResolveInfo> allServiceResolveInfo = new ArrayList<>(serviceResolveInfo);
+        allServiceResolveInfo.add(newServiceResolveInfo(TEST_SERVICE_PACKAGE_2));
+        for (ResolveInfo info : allServiceResolveInfo) {
+            PackageInfo packageInfo = new PackageInfo();
+            packageInfo.services = new ServiceInfo[]{info.serviceInfo};
+            packageInfo.packageName = info.serviceInfo.packageName;
+            packageInfo.applicationInfo = info.serviceInfo.applicationInfo;
+            packageManager.addPackage(packageInfo);
+        }
+        setPackageManagerResolveInfos(activityResolveInfo, serviceResolveInfo);
+    }
+
+    @Test
+    public void testGetAppsOnActive() {
+        List<MediaSource> observedValue = mMediaSources.getList();
+        assertThat(observedValue).isNotNull();
+        assertThat(
+                observedValue.stream().map(source -> source.getPackageName())
+                        .collect(Collectors.toList()))
+                .containsExactly(TEST_SERVICE_PACKAGE_1, TEST_SERVICE_PACKAGE_WITH_METADATA);
+    }
+
+    @Test
+    public void testGetAppsOnPackageAdded() {
+        List<ResolveInfo> activityResolveInfo = buildActivityResolveInfo();
+        activityResolveInfo.add(newActivityResolveInfo(TEST_ACTIVITY_PACKAGE_2));
+        List<ResolveInfo> serviceResolveInfo = buildServiceResolveInfo();
+        serviceResolveInfo.add(newServiceResolveInfo(TEST_SERVICE_PACKAGE_2));
+        setPackageManagerResolveInfos(activityResolveInfo, serviceResolveInfo);
+
+        Intent packageAdded = new Intent(Intent.ACTION_PACKAGE_ADDED);
+        ShadowApplication.getInstance().getRegisteredReceivers().stream()
+                .filter(wrapper -> wrapper.intentFilter.hasAction(Intent.ACTION_PACKAGE_ADDED))
+                .map(wrapper -> wrapper.broadcastReceiver)
+                .forEach(broadcastReceiver -> broadcastReceiver.onReceive(application,
+                        packageAdded));
+
+        List<MediaSource> observedValue = mMediaSources.getList();
+        assertThat(observedValue).isNotNull();
+        assertThat(
+                observedValue.stream().map(source -> source.getPackageName())
+                        .collect(Collectors.toList()))
+                .containsExactly(TEST_SERVICE_PACKAGE_1, TEST_SERVICE_PACKAGE_2,
+                        TEST_SERVICE_PACKAGE_WITH_METADATA);
+    }
+
+    @Test
+    public void testGetAppsOnPackageRemoved() {
+        List<ResolveInfo> activityResolveInfo = buildActivityResolveInfo();
+        List<ResolveInfo> serviceResolveInfo = buildServiceResolveInfo();
+        serviceResolveInfo.remove(0);
+        setPackageManagerResolveInfos(activityResolveInfo, serviceResolveInfo);
+
+        Intent packageRemoved = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+        ShadowApplication.getInstance().getRegisteredReceivers().stream()
+                .filter(wrapper -> wrapper.intentFilter.hasAction(Intent.ACTION_PACKAGE_REMOVED))
+                .map(wrapper -> wrapper.broadcastReceiver)
+                .forEach(broadcastReceiver ->
+                        broadcastReceiver.onReceive(application, packageRemoved));
+
+        List<MediaSource> observedValue = mMediaSources.getList();
+        assertThat(observedValue).isNotNull();
+        assertThat(
+                observedValue.stream().map(source -> source.getPackageName())
+                        .collect(Collectors.toList()))
+                .containsExactly(TEST_SERVICE_PACKAGE_WITH_METADATA);
+    }
+
+    @NonNull
+    private List<ResolveInfo> buildActivityResolveInfo() {
+        List<ResolveInfo> activityResolveInfo = new ArrayList<>();
+        activityResolveInfo.add(newActivityResolveInfo(TEST_ACTIVITY_PACKAGE_1));
+        return activityResolveInfo;
+    }
+
+    @NonNull
+    private List<ResolveInfo> buildServiceResolveInfo() {
+        List<ResolveInfo> serviceResolveInfo = new ArrayList<>();
+        serviceResolveInfo.add(newServiceResolveInfo(TEST_SERVICE_PACKAGE_1));
+        ResolveInfo withMetadata = newServiceResolveInfo(TEST_SERVICE_PACKAGE_WITH_METADATA);
+        withMetadata.serviceInfo.applicationInfo.metaData = new Bundle();
+        serviceResolveInfo.add(withMetadata);
+        return serviceResolveInfo;
+    }
+
+    private void setPackageManagerResolveInfos(List<ResolveInfo> activityResolveInfo,
+            List<ResolveInfo> serviceResolveInfo) {
+        ShadowPackageManager packageManager = shadowOf(application.getPackageManager());
+        packageManager.removeResolveInfosForIntent(mActivityIntent, TEST_ACTIVITY_PACKAGE_1);
+        packageManager.removeResolveInfosForIntent(mActivityIntent, TEST_ACTIVITY_PACKAGE_2);
+        packageManager.removeResolveInfosForIntent(mServiceIntent, TEST_SERVICE_PACKAGE_1);
+        packageManager.removeResolveInfosForIntent(mServiceIntent, TEST_SERVICE_PACKAGE_2);
+        packageManager.removeResolveInfosForIntent(mServiceIntent,
+                TEST_SERVICE_PACKAGE_WITH_METADATA);
+
+        packageManager.addResolveInfoForIntent(mActivityIntent, activityResolveInfo);
+
+        packageManager.addResolveInfoForIntent(mServiceIntent, serviceResolveInfo);
+        for (ResolveInfo info : serviceResolveInfo) {
+            Intent intent = new Intent(mServiceIntent);
+            intent.setPackage(info.serviceInfo.packageName);
+            packageManager.addResolveInfoForIntent(intent, info);
+        }
+        mMediaSources.reset();
+    }
+
+
+    private ResolveInfo newActivityResolveInfo(String packageName) {
+        ResolveInfo resolveInfo = new ResolveInfo();
+        ActivityInfo activityInfo = new ActivityInfo();
+        activityInfo.packageName = packageName;
+        activityInfo.name = "activity";
+        activityInfo.nonLocalizedLabel = "Activity Label " + packageName;
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.packageName = packageName;
+        applicationInfo.nonLocalizedLabel = "Activity Label " + packageName;
+        activityInfo.applicationInfo = applicationInfo;
+        resolveInfo.activityInfo = activityInfo;
+        return resolveInfo;
+    }
+
+    private ResolveInfo newServiceResolveInfo(String packageName) {
+        ResolveInfo resolveInfo = new ResolveInfo();
+        ServiceInfo serviceInfo = new ServiceInfo();
+        serviceInfo.packageName = packageName;
+        serviceInfo.name = "service";
+        serviceInfo.nonLocalizedLabel = "Service Label " + packageName;
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.packageName = packageName;
+        applicationInfo.nonLocalizedLabel = "Service Label " + packageName;
+        serviceInfo.applicationInfo = applicationInfo;
+        resolveInfo.serviceInfo = serviceInfo;
+        // ShadowPackageManager#removeResolveInfosForIntent requires activityInfo to be set...
+        resolveInfo.activityInfo = newActivityResolveInfo(packageName).activityInfo;
+        return resolveInfo;
+    }
+}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourcesProviderTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourcesProviderTest.java
deleted file mode 100644
index 79dc196..0000000
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourcesProviderTest.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright 2018 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.media.common.source;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.robolectric.RuntimeEnvironment.application;
-import static org.robolectric.Shadows.shadowOf;
-
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.os.Bundle;
-import android.service.media.MediaBrowserService;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.arch.common.testing.InstantTaskExecutorRule;
-import com.android.car.arch.common.testing.TestLifecycleOwner;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.shadows.ShadowApplication;
-import org.robolectric.shadows.ShadowPackageManager;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RunWith(RobolectricTestRunner.class)
-public class MediaSourcesProviderTest {
-
-    @Rule
-    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-    @Rule
-    public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
-    @Rule
-    public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
-
-    private static final String TEST_ACTIVITY_PACKAGE_1 = "activity_package1";
-    private static final String TEST_ACTIVITY_PACKAGE_2 = "activity_package2";
-    private static final String TEST_SERVICE_PACKAGE_1 = "service_package1";
-    private static final String TEST_SERVICE_PACKAGE_2 = "service_package2";
-    private static final String TEST_SERVICE_PACKAGE_WITH_METADATA = "service_package3";
-
-    private MediaSourcesProvider mMediaSources;
-    private Intent mActivityIntent;
-    private Intent mServiceIntent;
-
-    @Before
-    public void setUp() {
-        mMediaSources = MediaSourcesProvider.createForTesting(application);
-
-        mActivityIntent = new Intent(Intent.ACTION_MAIN, null);
-        mActivityIntent.addCategory(Intent.CATEGORY_APP_MUSIC);
-
-        mServiceIntent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
-        ShadowPackageManager packageManager = shadowOf(application.getPackageManager());
-
-        List<ResolveInfo> activityResolveInfo = buildActivityResolveInfo();
-        List<ResolveInfo> allActivityResolveInfo = new ArrayList<>(activityResolveInfo);
-        allActivityResolveInfo.add(newActivityResolveInfo(TEST_ACTIVITY_PACKAGE_2));
-        for (ResolveInfo info : allActivityResolveInfo) {
-            PackageInfo packageInfo = new PackageInfo();
-            packageInfo.activities = new ActivityInfo[]{info.activityInfo};
-            packageInfo.packageName = info.activityInfo.packageName;
-            packageInfo.applicationInfo = info.activityInfo.applicationInfo;
-            packageManager.addPackage(packageInfo);
-        }
-        List<ResolveInfo> serviceResolveInfo = buildServiceResolveInfo();
-        List<ResolveInfo> allServiceResolveInfo = new ArrayList<>(serviceResolveInfo);
-        allServiceResolveInfo.add(newServiceResolveInfo(TEST_SERVICE_PACKAGE_2));
-        for (ResolveInfo info : allServiceResolveInfo) {
-            PackageInfo packageInfo = new PackageInfo();
-            packageInfo.services = new ServiceInfo[]{info.serviceInfo};
-            packageInfo.packageName = info.serviceInfo.packageName;
-            packageInfo.applicationInfo = info.serviceInfo.applicationInfo;
-            packageManager.addPackage(packageInfo);
-        }
-        setPackageManagerResolveInfos(activityResolveInfo, serviceResolveInfo);
-    }
-
-    @Test
-    public void testGetAppsOnActive() {
-        List<MediaSource> observedValue = mMediaSources.getList();
-        assertThat(observedValue).isNotNull();
-        assertThat(
-                observedValue.stream().map(source -> source.getPackageName())
-                        .collect(Collectors.toList()))
-                .containsExactly(TEST_SERVICE_PACKAGE_1, TEST_SERVICE_PACKAGE_WITH_METADATA);
-    }
-
-    @Test
-    public void testGetAppsOnPackageAdded() {
-        List<ResolveInfo> activityResolveInfo = buildActivityResolveInfo();
-        activityResolveInfo.add(newActivityResolveInfo(TEST_ACTIVITY_PACKAGE_2));
-        List<ResolveInfo> serviceResolveInfo = buildServiceResolveInfo();
-        serviceResolveInfo.add(newServiceResolveInfo(TEST_SERVICE_PACKAGE_2));
-        setPackageManagerResolveInfos(activityResolveInfo, serviceResolveInfo);
-
-        Intent packageAdded = new Intent(Intent.ACTION_PACKAGE_ADDED);
-        ShadowApplication.getInstance().getRegisteredReceivers().stream()
-                .filter(wrapper -> wrapper.intentFilter.hasAction(Intent.ACTION_PACKAGE_ADDED))
-                .map(wrapper -> wrapper.broadcastReceiver)
-                .forEach(broadcastReceiver -> broadcastReceiver.onReceive(application,
-                        packageAdded));
-
-        List<MediaSource> observedValue = mMediaSources.getList();
-        assertThat(observedValue).isNotNull();
-        assertThat(
-                observedValue.stream().map(source -> source.getPackageName())
-                        .collect(Collectors.toList()))
-                .containsExactly(TEST_SERVICE_PACKAGE_1, TEST_SERVICE_PACKAGE_2,
-                        TEST_SERVICE_PACKAGE_WITH_METADATA);
-    }
-
-    @Test
-    public void testGetAppsOnPackageRemoved() {
-        List<ResolveInfo> activityResolveInfo = buildActivityResolveInfo();
-        List<ResolveInfo> serviceResolveInfo = buildServiceResolveInfo();
-        serviceResolveInfo.remove(0);
-        setPackageManagerResolveInfos(activityResolveInfo, serviceResolveInfo);
-
-        Intent packageRemoved = new Intent(Intent.ACTION_PACKAGE_REMOVED);
-        ShadowApplication.getInstance().getRegisteredReceivers().stream()
-                .filter(wrapper -> wrapper.intentFilter.hasAction(Intent.ACTION_PACKAGE_REMOVED))
-                .map(wrapper -> wrapper.broadcastReceiver)
-                .forEach(broadcastReceiver ->
-                        broadcastReceiver.onReceive(application, packageRemoved));
-
-        List<MediaSource> observedValue = mMediaSources.getList();
-        assertThat(observedValue).isNotNull();
-        assertThat(
-                observedValue.stream().map(source -> source.getPackageName())
-                        .collect(Collectors.toList()))
-                .containsExactly(TEST_SERVICE_PACKAGE_WITH_METADATA);
-    }
-
-    @NonNull
-    private List<ResolveInfo> buildActivityResolveInfo() {
-        List<ResolveInfo> activityResolveInfo = new ArrayList<>();
-        activityResolveInfo.add(newActivityResolveInfo(TEST_ACTIVITY_PACKAGE_1));
-        return activityResolveInfo;
-    }
-
-    @NonNull
-    private List<ResolveInfo> buildServiceResolveInfo() {
-        List<ResolveInfo> serviceResolveInfo = new ArrayList<>();
-        serviceResolveInfo.add(newServiceResolveInfo(TEST_SERVICE_PACKAGE_1));
-        ResolveInfo withMetadata = newServiceResolveInfo(TEST_SERVICE_PACKAGE_WITH_METADATA);
-        withMetadata.serviceInfo.applicationInfo.metaData = new Bundle();
-        serviceResolveInfo.add(withMetadata);
-        return serviceResolveInfo;
-    }
-
-    private void setPackageManagerResolveInfos(List<ResolveInfo> activityResolveInfo,
-            List<ResolveInfo> serviceResolveInfo) {
-        ShadowPackageManager packageManager = shadowOf(application.getPackageManager());
-        packageManager.removeResolveInfosForIntent(mActivityIntent, TEST_ACTIVITY_PACKAGE_1);
-        packageManager.removeResolveInfosForIntent(mActivityIntent, TEST_ACTIVITY_PACKAGE_2);
-        packageManager.removeResolveInfosForIntent(mServiceIntent, TEST_SERVICE_PACKAGE_1);
-        packageManager.removeResolveInfosForIntent(mServiceIntent, TEST_SERVICE_PACKAGE_2);
-        packageManager.removeResolveInfosForIntent(mServiceIntent,
-                TEST_SERVICE_PACKAGE_WITH_METADATA);
-
-        packageManager.addResolveInfoForIntent(mActivityIntent, activityResolveInfo);
-
-        packageManager.addResolveInfoForIntent(mServiceIntent, serviceResolveInfo);
-        for (ResolveInfo info : serviceResolveInfo) {
-            Intent intent = new Intent(mServiceIntent);
-            intent.setPackage(info.serviceInfo.packageName);
-            packageManager.addResolveInfoForIntent(intent, info);
-        }
-        mMediaSources.reset();
-    }
-
-
-    private ResolveInfo newActivityResolveInfo(String packageName) {
-        ResolveInfo resolveInfo = new ResolveInfo();
-        ActivityInfo activityInfo = new ActivityInfo();
-        activityInfo.packageName = packageName;
-        activityInfo.name = "activity";
-        activityInfo.nonLocalizedLabel = "Activity Label " + packageName;
-        ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.packageName = packageName;
-        applicationInfo.nonLocalizedLabel = "Activity Label " + packageName;
-        activityInfo.applicationInfo = applicationInfo;
-        resolveInfo.activityInfo = activityInfo;
-        return resolveInfo;
-    }
-
-    private ResolveInfo newServiceResolveInfo(String packageName) {
-        ResolveInfo resolveInfo = new ResolveInfo();
-        ServiceInfo serviceInfo = new ServiceInfo();
-        serviceInfo.packageName = packageName;
-        serviceInfo.name = "service";
-        serviceInfo.nonLocalizedLabel = "Service Label " + packageName;
-        ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.packageName = packageName;
-        applicationInfo.nonLocalizedLabel = "Service Label " + packageName;
-        serviceInfo.applicationInfo = applicationInfo;
-        resolveInfo.serviceInfo = serviceInfo;
-        // ShadowPackageManager#removeResolveInfosForIntent requires activityInfo to be set...
-        resolveInfo.activityInfo = newActivityResolveInfo(packageName).activityInfo;
-        return resolveInfo;
-    }
-}
diff --git a/car-messenger-common/Android.bp b/car-messenger-common/Android.bp
index 96fbf15..f826816 100644
--- a/car-messenger-common/Android.bp
+++ b/car-messenger-common/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-messenger-common",
 
@@ -27,36 +23,17 @@
         enabled: false,
     },
 
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-
-    libs: ["android.car-system-stubs",],
+    libs: ["android.car"],
 
     resource_dirs: ["res"],
 
     static_libs: [
+        "android.car.userlib",
+        "androidx.legacy_legacy-support-v4",
         "car-apps-common",
         "car-messenger-protos",
         "car-telephony-common",
+        "connected-device-protos",
         "libphonenumber",
     ],
 }
-// Car Messaging Models, Unbundled
-android_library {
-    name: "car-messaging-models",
-
-    srcs: [
-      "src/com/android/car/messenger/common/Conversation.java",
-    ],
-
-    optimize: {
-        enabled: false,
-    },
-
-    sdk_version: "current",
-
-    static_libs: [
-        "androidx.legacy_legacy-support-v4",
-        "androidx.annotation_annotation",
-    ],
-}
diff --git a/car-messenger-common/lint-baseline.xml b/car-messenger-common/lint-baseline.xml
deleted file mode 100644
index 0139e70..0000000
--- a/car-messenger-common/lint-baseline.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.content.res.Resources#getFloat`"
-        errorLine1="                .getFloat(R.dimen.contact_avatar_corner_radius_percent);"
-        errorLine2="                 ~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-messenger-common/src/com/android/car/messenger/common/BaseNotificationDelegate.java"
-            line="123"
-            column="18"/>
-    </issue>
-
-</issues>
diff --git a/car-messenger-common/proto/Android.bp b/car-messenger-common/proto/Android.bp
index dde012f..c08e72b 100644
--- a/car-messenger-common/proto/Android.bp
+++ b/car-messenger-common/proto/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 java_library_static {
     name: "car-messenger-protos",
     host_supported: true,
diff --git a/car-messenger-common/res/values/strings.xml b/car-messenger-common/res/values/strings.xml
index b19ffdb..ff604e2 100644
--- a/car-messenger-common/res/values/strings.xml
+++ b/car-messenger-common/res/values/strings.xml
@@ -41,6 +41,6 @@
     <string name="name_not_available">Name not available</string>
 
     <!-- Formats a group conversation's title for a message notification. The format is: <Sender of last message> mdot <Name of the conversation>.-->
-    <string name="group_conversation_title_separator" translatable="false">&#160;&#8226;&#160;</string>
+    <string name="group_conversation_title_separator" translatable="false">%1$s&#160;&#8226;&#160;%2$s</string>
 
 </resources>
diff --git a/car-messenger-common/src/com/android/car/messenger/common/BaseNotificationDelegate.java b/car-messenger-common/src/com/android/car/messenger/common/BaseNotificationDelegate.java
index 89bf029..da48646 100644
--- a/car-messenger-common/src/com/android/car/messenger/common/BaseNotificationDelegate.java
+++ b/car-messenger-common/src/com/android/car/messenger/common/BaseNotificationDelegate.java
@@ -16,6 +16,7 @@
 
 package com.android.car.messenger.common;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -23,10 +24,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
 import android.os.Bundle;
 
-import androidx.annotation.Nullable;
 import androidx.core.app.NotificationCompat;
 import androidx.core.app.NotificationCompat.Action;
 import androidx.core.app.Person;
@@ -203,11 +202,9 @@
         if (avatarIcon != null) {
             builder.setLargeIcon(avatarIcon);
         } else if (mUseLetterTile) {
-            BitmapDrawable drawable = (BitmapDrawable) TelecomUtils.createLetterTile(mContext,
+            builder.setLargeIcon(TelecomUtils.createLetterTile(mContext,
                     Utils.getInitials(lastMessage.getSenderName(), ""),
-                    lastMessage.getSenderName(), mBitmapSize, mCornerRadiusPercent)
-                    .loadDrawable(mContext);
-            builder.setLargeIcon(drawable.getBitmap());
+                    lastMessage.getSenderName(), mBitmapSize, mCornerRadiusPercent).getBitmap());
         }
         // Else, no avatar icon will be shown.
 
@@ -238,10 +235,9 @@
             }
         });
         if (notificationInfo.isGroupConvo()) {
-            messagingStyle.setConversationTitle(Utils.constructGroupConversationHeader(
-                    lastMessage.getSenderName(), notificationInfo.getConvoTitle(),
-                    mContext.getString(R.string.group_conversation_title_separator)
-            ));
+            messagingStyle.setConversationTitle(
+                    mContext.getString(R.string.group_conversation_title_separator,
+                            lastMessage.getSenderName(), notificationInfo.getConvoTitle()));
         }
 
         // We are creating this notification for the first time.
@@ -265,7 +261,7 @@
 
             PendingIntent deleteIntent = createServiceIntent(conversationKey,
                     notificationInfo.getNotificationId(),
-                    ACTION_DISMISS_NOTIFICATION, /* isMutable= */ false);
+                    ACTION_DISMISS_NOTIFICATION);
             builder.setDeleteIntent(deleteIntent);
 
             List<Action> actions = buildNotificationActions(conversationKey,
@@ -295,7 +291,7 @@
         if (shouldAddReplyAction(conversationKey.getDeviceId())) {
             final String replyString = mContext.getString(R.string.action_reply);
             PendingIntent replyIntent = createServiceIntent(conversationKey, notificationId,
-                    ACTION_REPLY, /* isMutable= */ true);
+                    ACTION_REPLY);
             actionList.add(
                     new NotificationCompat.Action.Builder(icon, replyString, replyIntent)
                             .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
@@ -312,7 +308,7 @@
         // Mark-as-read Action. This will be the callback of Notification Center's "Read" action.
         final String markAsRead = mContext.getString(R.string.action_mark_as_read);
         PendingIntent markAsReadIntent = createServiceIntent(conversationKey, notificationId,
-                ACTION_MARK_AS_READ, /* isMutable= */ false);
+                ACTION_MARK_AS_READ);
         actionList.add(
                 new NotificationCompat.Action.Builder(icon, markAsRead, markAsReadIntent)
                         .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ)
@@ -324,16 +320,14 @@
     }
 
     private PendingIntent createServiceIntent(ConversationKey conversationKey, int notificationId,
-            String action, boolean isMutable) {
+            String action) {
         Intent intent = new Intent(mContext, mContext.getClass())
                 .setAction(action)
                 .setClassName(mContext, mContext.getClass().getName())
                 .putExtra(EXTRA_CONVERSATION_KEY, conversationKey);
 
-        int flags = PendingIntent.FLAG_UPDATE_CURRENT;
-        flags |= isMutable ? PendingIntent.FLAG_MUTABLE : PendingIntent.FLAG_IMMUTABLE;
-
-        return PendingIntent.getForegroundService(mContext, notificationId, intent, flags);
+        return PendingIntent.getForegroundService(mContext, notificationId, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
 }
diff --git a/car-messenger-common/src/com/android/car/messenger/common/Conversation.java b/car-messenger-common/src/com/android/car/messenger/common/Conversation.java
deleted file mode 100644
index cbe26c2..0000000
--- a/car-messenger-common/src/com/android/car/messenger/common/Conversation.java
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.messenger.common;
-
-import static java.util.Arrays.stream;
-
-import android.app.PendingIntent;
-import android.app.RemoteAction;
-import android.app.RemoteInput;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.util.Log;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.app.Person;
-import androidx.core.graphics.drawable.IconCompat;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * A generic conversation model that holds messaging conversation metadata.
- */
-public final class Conversation {
-    private static final String KEY_ID = "id";
-    private static final String KEY_USER = "user";
-    private static final String KEY_TITLE = "title";
-    private static final String KEY_MESSAGES = "messages";
-    private static final String KEY_PARTICIPANTS = "participants";
-    private static final String KEY_ICON = "icon";
-    private static final String KEY_ACTIONS = "actions";
-    private static final String KEY_UNREAD_COUNT = "unread_count";
-    private static final String KEY_IS_MUTED = "is_muted";
-    private static final String KEY_EXTRAS = "extras";
-
-    private static final String TAG = "CMC.Conversation";
-
-    @NonNull
-    private final String mId;
-    @NonNull
-    private final Person mUser;
-    @Nullable
-    private final String mConversationTitle;
-    @Nullable
-    private final IconCompat mConversationIcon;
-    @NonNull
-    private final List<Message> mMessages;
-    @NonNull
-    private final List<Person> mParticipants;
-    @Nullable
-    private final List<ConversationAction> mActions;
-
-    private final int mUnreadCount;
-    private final boolean mIsMuted;
-    @NonNull
-    private final Bundle mExtras;
-
-    public Conversation(
-            @NonNull String id,
-            @NonNull Person user,
-            @Nullable String conversationTitle,
-            @Nullable IconCompat conversationIcon,
-            @NonNull List<Message> messages,
-            @NonNull List<Person> participants,
-            @Nullable List<ConversationAction> actions,
-            int unreadCount,
-            boolean isMuted,
-            @Nullable Bundle extras
-    ) {
-        mId = id;
-        mUser = user;
-        mConversationTitle = conversationTitle;
-        mConversationIcon = conversationIcon;
-        mMessages = messages;
-        mParticipants = participants;
-        mActions = actions;
-        mUnreadCount = unreadCount;
-        mIsMuted = isMuted;
-        mExtras = (extras == null) ? new Bundle() : extras;
-    }
-
-    /**
-     * Useful method for saving as a parcelable and transferring across processes
-     */
-    @NonNull
-    public Bundle toBundle() {
-        Bundle bundle = new Bundle();
-        bundle.putString(KEY_ID, mId);
-        bundle.putBundle(KEY_USER, mUser.toBundle());
-        if (mConversationTitle != null) {
-            bundle.putString(KEY_TITLE, mConversationTitle);
-        }
-        if (mConversationIcon != null) {
-            bundle.putBundle(KEY_ICON, mConversationIcon.toBundle());
-        }
-        bundle.putParcelableArray(KEY_MESSAGES, Message.getBundleArrayForMessages(mMessages));
-        Bundle[] participantBundle =
-                mParticipants.stream().map(Person::toBundle).toArray(Bundle[]::new);
-        bundle.putParcelableArray(KEY_PARTICIPANTS, participantBundle);
-        if (mActions != null) {
-            bundle.putParcelableArray(
-                    KEY_ACTIONS,
-                    ConversationAction.getBundleArrayForAction(mActions));
-        }
-        bundle.putInt(KEY_UNREAD_COUNT, mUnreadCount);
-        bundle.putBoolean(KEY_IS_MUTED, mIsMuted);
-        bundle.putBundle(KEY_EXTRAS, mExtras);
-        return bundle;
-    }
-
-    /**
-     * Creates a {@link Conversation} from the given Bundle.
-     */
-    @Nullable
-    public static Conversation fromBundle(@Nullable Bundle bundle) {
-        if (bundle == null) {
-            return null;
-        }
-        if (bundle.getString(KEY_ID) == null
-                || bundle.getBundle(KEY_USER) == null
-                || bundle.getParcelableArray(KEY_MESSAGES) == null
-                || bundle.getParcelableArray(KEY_PARTICIPANTS) == null
-        ) {
-            return null;
-        }
-        List<Person> participants =
-                stream(bundle.getParcelableArray(KEY_PARTICIPANTS))
-                        .map(
-                                personBundle ->
-                                        personBundle instanceof Bundle
-                                                ? Person.fromBundle((Bundle) personBundle)
-                                                : null)
-                        .filter(Objects::nonNull)
-                        .collect(Collectors.toList());
-
-        Bundle iconBundle = bundle.getBundle(KEY_ICON);
-        IconCompat icon = iconBundle == null
-                ? null : IconCompat.createFromBundle(iconBundle);
-        return new Conversation(
-                Objects.requireNonNull(bundle.getString(KEY_ID)),
-                Person.fromBundle(Objects.requireNonNull(bundle.getBundle(KEY_USER))),
-                bundle.getString(KEY_TITLE),
-                icon,
-                Message.getMessagesFromBundleArray(
-                        Objects.requireNonNull(bundle.getParcelableArray(KEY_MESSAGES))),
-                participants,
-                ConversationAction.getActionsFromBundleArray(
-                        bundle.getParcelableArray(KEY_ACTIONS)
-                ),
-                bundle.getInt(KEY_UNREAD_COUNT),
-                bundle.getBoolean(KEY_IS_MUTED),
-                bundle.getBundle(KEY_EXTRAS)
-        );
-
-    }
-
-    /**
-     * Gets the unique identifier for this conversation
-     */
-    @NonNull
-    public String getId() {
-        return mId;
-    }
-
-    /**
-     * Gets the current user for this conversation.
-     * <p>
-     * The user receives inbound messages and sends outbound messages from the messaging
-     * app/device.
-     */
-    @NonNull
-    public Person getUser() {
-        return mUser;
-    }
-
-    /**
-     * Gets conversation title.
-     *
-     * @return null if conversation title is not set, or {@link String} if set
-     */
-    @Nullable
-    public String getConversationTitle() {
-        return mConversationTitle;
-    }
-
-    /**
-     * Gets conversation icon.
-     *
-     * @return null if conversation icon is not set, or {@link IconCompat} if set
-     */
-    @Nullable
-    public IconCompat getConversationIcon() {
-        return mConversationIcon;
-    }
-
-    /**
-     * Gets the list of messages conveyed by this conversation.
-     */
-    @NonNull
-    public List<Message> getMessages() {
-        return mMessages;
-    }
-
-    /**
-     * Gets the participants in the conversation, excluding the user
-     *
-     * @return list of participants or empty if not set
-     */
-    @NonNull
-    public List<Person> getParticipants() {
-        return mParticipants;
-    }
-
-    /**
-     * Gets the actions in the conversation.
-     */
-    @Nullable
-    public List<ConversationAction> getActions() {
-        return mActions;
-    }
-
-    /**
-     * Get the number of unread messages
-     *
-     * @return 0 if no unread messages, or a positive number when there are unread messages.
-     */
-    public int getUnreadCount() {
-        return mUnreadCount;
-    }
-
-    /**
-     * Gets if the conversation should be muted based on the user's preference. This is useful when
-     * posting a notification.
-     */
-    public boolean isMuted() {
-        return mIsMuted;
-    }
-
-    /**
-     * Gets the extras for the conversation. This can be used to hold additional data on the
-     * conversation.
-     */
-    @NonNull
-    public Bundle getExtras() {
-        return mExtras;
-    }
-
-    /**
-     * Creates and returns a new {@link Conversation.Builder} initialized with this Conversation's
-     * data
-     */
-    @NonNull
-    public Conversation.Builder toBuilder() {
-        return new Conversation.Builder(this);
-    }
-
-    /**
-     * Builder class for {@link Conversation} objects.
-     */
-    public static class Builder {
-        @NonNull
-        private final String mId;
-        @NonNull
-        private final Person mUser;
-        @Nullable
-        private String mConversationTitle;
-        @Nullable
-        private IconCompat mConversationIcon;
-        @NonNull
-        private List<Message> mMessages;
-        @NonNull
-        private List<Person> mParticipants;
-        @Nullable
-        private List<ConversationAction> mActions;
-        private int mUnreadCount;
-        private boolean mIsMuted;
-        @NonNull
-        private Bundle mExtras;
-
-        /**
-         * Constructs a new builder from a {@link Conversation}?
-         *
-         * @param conversation the conversation containing the data to initialize builder with
-         */
-        private Builder(@NonNull Conversation conversation) {
-            mUser = conversation.mUser;
-            mId = conversation.mId;
-            mMessages = conversation.mMessages;
-            mConversationTitle = conversation.getConversationTitle();
-            mConversationIcon = conversation.getConversationIcon();
-            mParticipants = conversation.getParticipants();
-            mActions = conversation.getActions();
-            mUnreadCount = conversation.getUnreadCount();
-            mIsMuted = conversation.isMuted();
-            mExtras = conversation.getExtras();
-        }
-
-        /**
-         * Constructs a new builder for {@link Conversation}.
-         *
-         * @param conversationId the unique identifier of this conversation.
-         * @param user           The name of the other participant in the conversation.
-         */
-        public Builder(
-                @NonNull Person user,
-                @NonNull String conversationId
-        ) {
-            mUser = user;
-            mId = conversationId;
-            mMessages = new ArrayList<>();
-            mParticipants = new ArrayList<>();
-            mExtras = new Bundle();
-        }
-
-        /**
-         * Sets list of messages for this conversation.
-         *
-         * @param messages List of messages
-         * @return This object for method chaining.
-         */
-        @NonNull
-        public Builder setMessages(@NonNull List<Message> messages) {
-            mMessages = messages;
-            return this;
-        }
-
-        /**
-         * Sets list of participants for this conversation
-         *
-         * @return This object for method chaining.
-         */
-        @NonNull
-        public Builder setParticipants(@NonNull List<Person> participants) {
-            mParticipants = participants;
-            return this;
-        }
-
-        /**
-         * Sets list of messages for this conversation.
-         *
-         * @param actions list of actions
-         * @return This object for method chaining.
-         */
-        @NonNull
-        public Builder setActions(@NonNull List<ConversationAction> actions) {
-            mActions = actions;
-            return this;
-        }
-
-        /**
-         * Sets conversation title which would be used when displaying the name of the
-         * conversation.
-         * <p>
-         * This could be the sender name for a 1-1 message, or an appended string of participants
-         * name for a group message, or a nickname for the group.
-         *
-         * @param conversationTitle the title to refer to the conversation
-         * @return This object for method chaining
-         */
-        @NonNull
-        public Builder setConversationTitle(@Nullable String conversationTitle) {
-            mConversationTitle = conversationTitle;
-            return this;
-        }
-
-        /**
-         * Sets conversation icon for display purposes
-         *
-         * @param conversationIcon This could be the sender icon for a 1-1 message or a collage of
-         *                         participants' icons for a group message, or an icon the user
-         *                         uploaded as the conversation icon.
-         * @return This object for method chaining.
-         */
-        @NonNull
-        public Builder setConversationIcon(@Nullable IconCompat conversationIcon) {
-            mConversationIcon = conversationIcon;
-            return this;
-        }
-
-        /**
-         * Sets the number of unread message, default is 0
-         *
-         * @return This object for method chaining.
-         */
-        @NonNull
-        public Builder setUnreadCount(int unreadCount) {
-            mUnreadCount = unreadCount;
-            return this;
-        }
-
-        /**
-         * Sets if this conversation should be muted per user's request A muted conversation may not
-         * post notifications for instance.
-         *
-         * @return This object for method chaining.
-         */
-        @NonNull
-        public Builder setMuted(boolean muted) {
-            mIsMuted = muted;
-            return this;
-        }
-
-        /**
-         * Sets bundle extra for the conversation
-         *
-         * @param extras this could contain additional data on the conversation
-         * @return This object for method chaining.
-         */
-        @NonNull
-        public Builder setExtras(@NonNull Bundle extras) {
-            mExtras = extras;
-            return this;
-        }
-
-        /**
-         * Builds a new unread conversation object.
-         *
-         * @return The new unread conversation object.
-         */
-        @NonNull
-        public Conversation build() {
-            return new Conversation(
-                    mId,
-                    mUser,
-                    mConversationTitle,
-                    mConversationIcon,
-                    mMessages,
-                    mParticipants,
-                    mActions,
-                    mUnreadCount,
-                    mIsMuted,
-                    mExtras
-            );
-        }
-    }
-
-    /**
-     * A class representing the metadata for a conversation message.
-     */
-    public static final class Message {
-        private static final String KEY_TEXT = "text";
-        private static final String KEY_TIMESTAMP = "time";
-        private static final String KEY_SENDER = "sender";
-        private static final String KEY_DATA_MIME_TYPE = "type";
-        private static final String KEY_DATA_URI = "uri";
-
-        @NonNull
-        private final String mText;
-        private final long mTimestamp;
-        @Nullable
-        private final Person mPerson;
-        @MessageStatus
-        private int mMessageStatus;
-        @MessageType
-        private int mMessageType;
-
-        @NonNull
-        private final Bundle mExtras = new Bundle();
-        @Nullable
-        private String mDataMimeType;
-        @Nullable
-        private Uri mDataUri;
-
-        /**
-         * Creates a new {@link Message} with the given text, timestamp, and sender.
-         *
-         * @param text      A {@link String} to be displayed as the message content
-         * @param timestamp Time at which the message arrived in ms since Unix epoch
-         * @param person    A {@link Person} whose {@link Person#getName()} value is used as the
-         *                  display name for the sender. For messages by the current user, this
-         *                  should be identical to {@link Conversation#getUser()}
-         */
-        public Message(@NonNull String text, long timestamp, @Nullable Person person) {
-            mText = text;
-            mTimestamp = timestamp;
-            mPerson = person;
-        }
-
-        private Bundle toBundle() {
-            Bundle bundle = new Bundle();
-            bundle.putString(KEY_TEXT, mText);
-            bundle.putLong(KEY_TIMESTAMP, mTimestamp);
-            if (mPerson != null) {
-                bundle.putBundle(KEY_SENDER, mPerson.toBundle());
-            }
-            if (mDataMimeType != null) {
-                bundle.putString(KEY_DATA_MIME_TYPE, mDataMimeType);
-            }
-            if (mDataUri != null) {
-                bundle.putParcelable(KEY_DATA_URI, mDataUri);
-            }
-            return bundle;
-        }
-
-        private static Bundle[] getBundleArrayForMessages(List<Message> messages) {
-            int size = messages.size();
-            Bundle[] bundles = new Bundle[size];
-            for (int i = 0; i < size; i++) {
-                bundles[i] = messages.get(i).toBundle();
-            }
-            return bundles;
-        }
-
-        private static List<Message> getMessagesFromBundleArray(Parcelable[] bundles) {
-            List<Message> messages = new ArrayList<>(bundles.length);
-            for (Parcelable element : bundles) {
-                if (element instanceof Bundle) {
-                    Message message = getMessageFromBundle((Bundle) element);
-                    if (message != null) {
-                        messages.add(message);
-                    }
-                }
-            }
-            return messages;
-        }
-
-        @Nullable
-        private static Message getMessageFromBundle(Bundle bundle) {
-            if (!bundle.containsKey(KEY_TEXT)
-                    || !bundle.containsKey(KEY_TIMESTAMP)
-                    || !bundle.containsKey(KEY_SENDER)
-            ) {
-                return null;
-            }
-            Message message = new Message(
-                    Objects.requireNonNull(bundle.getString(KEY_TEXT)),
-                    bundle.getLong(KEY_TIMESTAMP),
-                    Person.fromBundle(Objects.requireNonNull(bundle.getBundle(KEY_SENDER))
-                    )
-            );
-            if (bundle.containsKey(KEY_DATA_MIME_TYPE)
-                    && bundle.containsKey(KEY_DATA_URI)) {
-                try {
-                    message.setData(
-                            Objects.requireNonNull(bundle.getString(KEY_DATA_MIME_TYPE)),
-                            Objects.requireNonNull(bundle.getParcelable(KEY_DATA_URI))
-                    );
-                } catch (ClassCastException e) {
-                    Log.w(TAG, "Failed to set Data Type/Uri");
-                }
-            }
-            return message;
-        }
-
-        /**
-         * Sets a binary blob of data and an associated MIME type for a message. In the case where
-         * the platform doesn't support the MIME type, the original text provided in the constructor
-         * will be used.
-         *
-         * @param dataMimeType The MIME type of the content.
-         * @param dataUri      The uri containing the content whose type is given by the MIME type.
-         * @return this object for method chaining
-         */
-        @NonNull
-        public Message setData(@NonNull String dataMimeType, @NonNull Uri dataUri) {
-            mDataMimeType = dataMimeType;
-            mDataUri = dataUri;
-            return this;
-        }
-
-        /**
-         * Sets the message status for a message.
-         */
-        @NonNull
-        public Message setMessageStatus(@MessageStatus int messageStatus) {
-            mMessageStatus = messageStatus;
-            return this;
-        }
-
-        /**
-         * Sets the message type for a message.
-         *
-         * @return this object for method chaining
-         */
-        @NonNull
-        public Message setMessageType(@MessageType int messageType) {
-            mMessageType = messageType;
-            return this;
-        }
-
-        /**
-         * Get the text to be used for this message, or the fallback text if a type and content Uri
-         * have been set
-         */
-        @NonNull
-        public String getText() {
-            return mText;
-        }
-
-        /**
-         * Get the time at which this message arrived in ms since Unix epoch.
-         */
-        public long getTimestamp() {
-            return mTimestamp;
-        }
-
-        /**
-         * Gets the message status for this message
-         */
-        @MessageStatus
-        public int getMessageStatus() {
-            return mMessageStatus;
-        }
-
-        /**
-         * Get the message type for this message
-         */
-        @MessageType
-        public int getMessageType() {
-            return mMessageType;
-        }
-
-        /**
-         * Get the extras Bundle for this message.
-         */
-        @NonNull
-        public Bundle getExtras() {
-            return mExtras;
-        }
-
-        /**
-         * Returns the {@link Person} sender of this message.
-         */
-        @Nullable
-        public Person getPerson() {
-            return mPerson;
-        }
-
-        /**
-         * Get the MIME type of the data pointed to by the URI.
-         */
-        @Nullable
-        public String getDataMimeType() {
-            return mDataMimeType;
-        }
-
-        /**
-         * Get the Uri pointing to the content of the message. Can be null, in which case {@see
-         * #getText()} is used.
-         */
-        @Nullable
-        public Uri getDataUri() {
-            return mDataUri;
-        }
-
-        /**
-         * Indicates the message status of the message.
-         */
-        @IntDef(value = {
-                MessageStatus.MESSAGE_STATUS_NONE,
-                MessageStatus.MESSAGE_STATUS_UNREAD,
-                MessageStatus.MESSAGE_STATUS_SEEN,
-                MessageStatus.MESSAGE_STATUS_READ,
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface MessageStatus {
-            /**
-             * {@code MessageStatus}: No message status defined.
-             */
-            int MESSAGE_STATUS_NONE = 0;
-
-            /**
-             * {@code MessageStatus}: Message is unread
-             */
-            int MESSAGE_STATUS_UNREAD = 1;
-
-            /**
-             * {@code MessageStatus}: Message is seen; The "seen" flag determines whether we need to
-             * show a notification.
-             */
-            int MESSAGE_STATUS_SEEN = 2;
-
-            /**
-             * {@code MessageStatus}: Message is read
-             */
-            int MESSAGE_STATUS_READ = 3;
-
-        }
-
-        /**
-         * Indicates the message status of the message.
-         */
-        @IntDef(value = {
-                MessageType.MESSAGE_TYPE_ALL,
-                MessageType.MESSAGE_TYPE_INBOX,
-                MessageType.MESSAGE_TYPE_SENT,
-                MessageType.MESSAGE_TYPE_DRAFT,
-                MessageType.MESSAGE_TYPE_FAILED,
-                MessageType.MESSAGE_TYPE_OUTBOX,
-                MessageType.MESSAGE_TYPE_QUEUED
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface MessageType {
-
-            /**
-             * Message type: all messages.
-             */
-            int MESSAGE_TYPE_ALL = 0;
-
-            /**
-             * Message type: inbox.
-             */
-            int MESSAGE_TYPE_INBOX = 1;
-
-            /**
-             * Message type: sent messages.
-             */
-            int MESSAGE_TYPE_SENT = 2;
-
-            /**
-             * Message type: drafts.
-             */
-            int MESSAGE_TYPE_DRAFT = 3;
-
-            /**
-             * Message type: outbox.
-             */
-            int MESSAGE_TYPE_OUTBOX = 4;
-
-            /**
-             * Message type: failed outgoing message.
-             */
-            int MESSAGE_TYPE_FAILED = 5;
-
-            /**
-             * Message type: queued to send later.
-             */
-            int MESSAGE_TYPE_QUEUED = 6;
-        }
-    }
-
-    /**
-     * {@link ConversationAction} provides the actions for this conversation. The semantic action
-     * indicates the type of action represented. The remote action holds the pending intent to be
-     * fired The remote input holds a key by which responses can be filled into.
-     */
-    public static class ConversationAction {
-        private static final String KEY_TYPE = "type";
-        private static final String KEY_REMOTE_ACTION = "remote_action";
-        private static final String KEY_REMOTE_INPUT = "remote_input";
-        private static final String KEY_EXTRAS = "extras";
-
-        @ActionType
-        private final int mActionType;
-        @NonNull
-        private final RemoteAction mRemoteAction;
-        @Nullable
-        private final RemoteInput mRemoteInput;
-        @NonNull
-        private final Bundle mExtras = new Bundle();
-
-        public ConversationAction(
-                @ActionType int actionType,
-                @NonNull RemoteAction remoteAction,
-                @Nullable RemoteInput remoteInput) {
-            mActionType = actionType;
-            mRemoteAction = remoteAction;
-            mRemoteInput = remoteInput;
-        }
-
-        private static Bundle[] getBundleArrayForAction(List<ConversationAction> actions) {
-            int size = actions.size();
-            Bundle[] bundles = new Bundle[size];
-            for (int i = 0; i < size; i++) {
-                bundles[i] = actions.get(i).toBundle();
-            }
-            return bundles;
-        }
-
-        @Nullable
-        private static List<ConversationAction> getActionsFromBundleArray(
-                @Nullable Parcelable[] bundles
-        ) {
-            if (bundles == null) {
-                return null;
-            }
-            List<ConversationAction> actions = new ArrayList<>(bundles.length);
-            for (Parcelable element : bundles) {
-                if (element instanceof Bundle) {
-                    ConversationAction action = fromBundle((Bundle) element);
-                    if (action != null) {
-                        actions.add(action);
-                    }
-                }
-            }
-            return actions;
-        }
-
-        private Bundle toBundle() {
-            Bundle bundle = new Bundle();
-            bundle.putInt(KEY_TYPE, mActionType);
-            bundle.putParcelable(KEY_REMOTE_ACTION, mRemoteAction);
-            bundle.putParcelable(KEY_REMOTE_INPUT, mRemoteInput);
-            bundle.putBundle(KEY_EXTRAS, mExtras);
-            return bundle;
-        }
-
-        @Nullable
-        private static ConversationAction fromBundle(@Nullable Bundle bundle) {
-            if (bundle == null
-                    || !bundle.containsKey(KEY_REMOTE_ACTION)
-            ) {
-                return null;
-            }
-            ConversationAction action = new ConversationAction(
-                    bundle.getInt(KEY_TYPE),
-                    bundle.getParcelable(KEY_REMOTE_ACTION),
-                    bundle.getParcelable(KEY_REMOTE_INPUT)
-            );
-            action.getExtras().putAll(bundle.getBundle(KEY_EXTRAS));
-            return action;
-        }
-
-        @ActionType
-        public int getActionType() {
-            return mActionType;
-        }
-
-        @NonNull
-        public RemoteAction getRemoteAction() {
-            return mRemoteAction;
-        }
-
-        @Nullable
-        public RemoteInput getRemoteInput() {
-            return mRemoteInput;
-        }
-
-        @NonNull
-        public Bundle getExtras() {
-            return mExtras;
-        }
-
-        /**
-         * Provides meaning to an {@link ConversationAction} that hints at what the associated
-         * {@link PendingIntent} will do. For example, an {@link ConversationAction} with a {@link
-         * PendingIntent} that replies to a text message may have the {@link #ACTION_TYPE_REPLY}
-         * {@code ActionType} set within it.
-         */
-        @IntDef(value = {
-                ActionType.ACTION_TYPE_NONE,
-                ActionType.ACTION_TYPE_REPLY,
-                ActionType.ACTION_TYPE_MARK_AS_READ,
-                ActionType.ACTION_TYPE_MARK_AS_UNREAD,
-                ActionType.ACTION_TYPE_DELETE,
-                ActionType.ACTION_TYPE_ARCHIVE,
-                ActionType.ACTION_TYPE_MUTE,
-                ActionType.ACTION_TYPE_UNMUTE
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface ActionType {
-
-            /**
-             * {@code ActionType}: No semantic action defined.
-             */
-            int ACTION_TYPE_NONE = 0;
-
-            /**
-             * {@code ActionType}: Reply to a conversation, chat, group, or wherever replies may be
-             * appropriate.
-             */
-            int ACTION_TYPE_REPLY = 1;
-
-            /**
-             * {@code ActionType}: Mark content as read.
-             */
-            int ACTION_TYPE_MARK_AS_READ = 2;
-
-            /**
-             * {@code ActionType}: Mark content as unread.
-             */
-            int ACTION_TYPE_MARK_AS_UNREAD = 3;
-
-            /**
-             * {@code ActionType}: Delete the content associated with the conversation.
-             */
-            int ACTION_TYPE_DELETE = 4;
-
-            /**
-             * {@code ActionType}: Archive the content associated with the conversation. This could
-             * mean hiding a conversation, or placing it in an archived list.
-             */
-            int ACTION_TYPE_ARCHIVE = 5;
-
-            /**
-             * {@code ActionType}: Mute the content associated with the conversation. This could
-             * mean silencing a conversation or currently playing media.
-             */
-            int ACTION_TYPE_MUTE = 6;
-
-            /**
-             * {@code ActionType}: Unmute the content associated with the conversation. This could
-             * mean un-silencing a conversation or currently playing media.
-             */
-            int ACTION_TYPE_UNMUTE = 7;
-        }
-    }
-}
diff --git a/car-messenger-common/src/com/android/car/messenger/common/ConversationKey.java b/car-messenger-common/src/com/android/car/messenger/common/ConversationKey.java
index cf7a737..93a774a 100644
--- a/car-messenger-common/src/com/android/car/messenger/common/ConversationKey.java
+++ b/car-messenger-common/src/com/android/car/messenger/common/ConversationKey.java
@@ -21,9 +21,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.util.Collections;
-import java.util.List;
-
 /**
  * {@link CompositeKey} subclass used to give each conversation on all the connected devices a
  * unique Key.
@@ -41,9 +38,7 @@
         String senderName = Utils.getSenderName(intent);
         String subKey = senderName + "/" + senderUri;
         if (Utils.isGroupConversation(intent)) {
-            List<String> names = Utils.getInclusiveRecipientsUrisList(intent);
-            Collections.sort(names);
-            subKey = names.toString();
+            subKey = Utils.getInclusiveRecipientsUrisList(intent).toString();
         }
         return new ConversationKey(device.getAddress(), subKey);
     }
diff --git a/car-messenger-common/src/com/android/car/messenger/common/ConversationNotificationInfo.java b/car-messenger-common/src/com/android/car/messenger/common/ConversationNotificationInfo.java
index d563d12..3baf3fd 100644
--- a/car-messenger-common/src/com/android/car/messenger/common/ConversationNotificationInfo.java
+++ b/car-messenger-common/src/com/android/car/messenger/common/ConversationNotificationInfo.java
@@ -18,14 +18,14 @@
 
 import static com.android.car.apps.common.util.SafeLog.logw;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.bluetooth.BluetoothDevice;
 import android.content.Intent;
 import android.graphics.drawable.Icon;
+import android.os.Build;
 import android.util.Log;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
 import com.android.car.messenger.NotificationMsgProto.NotificationMsg;
 import com.android.car.messenger.NotificationMsgProto.NotificationMsg.ConversationNotification;
 import com.android.car.messenger.NotificationMsgProto.NotificationMsg.MessagingStyle;
@@ -77,7 +77,7 @@
         MessagingStyle messagingStyle = conversation.getMessagingStyle();
 
         if (!Utils.isValidConversationNotification(conversation, /* isShallowCheck= */ true)) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Log.isLoggable(TAG, Log.DEBUG) || Build.IS_DEBUGGABLE) {
                 throw new IllegalArgumentException(
                         "ConversationNotificationInfo is missing required fields");
             } else {
diff --git a/car-messenger-common/src/com/android/car/messenger/common/Message.java b/car-messenger-common/src/com/android/car/messenger/common/Message.java
index 8e016dd..a2c1d60 100644
--- a/car-messenger-common/src/com/android/car/messenger/common/Message.java
+++ b/car-messenger-common/src/com/android/car/messenger/common/Message.java
@@ -21,12 +21,12 @@
 import static com.android.car.messenger.common.Utils.BMC_EXTRA_MESSAGE_READ_STATUS;
 import static com.android.car.messenger.common.Utils.BMC_EXTRA_MESSAGE_TIMESTAMP;
 
+import android.annotation.Nullable;
 import android.bluetooth.BluetoothDevice;
 import android.content.Intent;
+import android.os.Build;
 import android.util.Log;
 
-import androidx.annotation.Nullable;
-
 import com.android.car.messenger.NotificationMsgProto.NotificationMsg;
 import com.android.car.messenger.NotificationMsgProto.NotificationMsg.MessagingStyleMessage;
 
@@ -77,7 +77,7 @@
             MessagingStyleMessage updatedMessage, SenderKey senderKey) {
 
         if (!Utils.isValidMessagingStyleMessage(updatedMessage)) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Log.isLoggable(TAG, Log.DEBUG) || Build.IS_DEBUGGABLE) {
                 throw new IllegalArgumentException(
                         "MessagingStyleMessage is missing required fields");
             } else {
@@ -103,7 +103,7 @@
      **/
     public static Message parseFromIntent(Intent intent) {
         if (!Utils.isValidMapClientIntent(intent)) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Log.isLoggable(TAG, Log.DEBUG) || Build.IS_DEBUGGABLE) {
                 throw new IllegalArgumentException(
                         "BluetoothMapClient intent is missing required fields");
             } else {
diff --git a/car-messenger-common/src/com/android/car/messenger/common/Utils.java b/car-messenger-common/src/com/android/car/messenger/common/Utils.java
index ccea454..282c1f5 100644
--- a/car-messenger-common/src/com/android/car/messenger/common/Utils.java
+++ b/car-messenger-common/src/com/android/car/messenger/common/Utils.java
@@ -23,8 +23,6 @@
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.text.BidiFormatter;
-import android.text.TextDirectionHeuristics;
 import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
@@ -48,7 +46,6 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /** Utils methods for the car-messenger-common lib. **/
 public class Utils {
@@ -285,7 +282,7 @@
     /** Returns whether the BluetoothMapClient intent represents a group conversation. **/
     public static boolean isGroupConversation(Intent intent) {
         return (intent.getStringArrayExtra(Intent.EXTRA_CC) != null
-                && intent.getStringArrayExtra(Intent.EXTRA_CC).length > 1);
+                && intent.getStringArrayExtra(Intent.EXTRA_CC).length > 0);
     }
 
     /**
@@ -321,14 +318,11 @@
     /** Returns the list of recipient uris for a BluetoothMapClient intent. **/
     public static List<String> getInclusiveRecipientsUrisList(Intent intent) {
         List<String> ccUris = new ArrayList<>();
-        String uri = getSenderUri(intent);
+        ccUris.add(getSenderUri(intent));
         if (isGroupConversation(intent)) {
             ccUris.addAll(Arrays.asList(intent.getStringArrayExtra(Intent.EXTRA_CC)));
+            Collections.sort(ccUris);
         }
-        if (!ccUris.contains(uri)) {
-            ccUris.add(uri);
-        }
-
         return ccUris;
     }
 
@@ -338,96 +332,12 @@
     @Nullable
     public static String getPhoneNumberFromMapClient(@Nullable String senderContactUri) {
         if (senderContactUri == null || !senderContactUri.matches(MAP_CLIENT_URI_REGEX)) {
-            logw(TAG, " contactUri is malformed! " + senderContactUri);
             return null;
         }
 
         return senderContactUri.substring(MAP_CLIENT_URI_PHONE_NUMBER_SUBSTRING_INDEX);
     }
 
-    /**
-     * Creates a Header for a group conversation, where the senderName and groupName are both shown,
-     * separated by a delimiter.
-     *
-     * @param senderName Sender's name.
-     * @param groupName  Group conversation's name.
-     * @param delimiter  delimiter that separates each element.
-     */
-    public static String constructGroupConversationHeader(String senderName, String groupName,
-            String delimiter) {
-        return constructGroupConversationHeader(senderName, groupName, delimiter,
-                BidiFormatter.getInstance());
-    }
-
-    /**
-     * Creates a Header for a group conversation, where the senderName and groupName are both shown,
-     * separated by a delimiter.
-     *
-     * @param senderName Sender's name.
-     * @param groupName  Group conversation's name.
-     * @param delimiter  delimiter that separates each element.
-     * @param bidiFormatter  formatter for the context's locale.
-     */
-    public static String constructGroupConversationHeader(String senderName, String groupName,
-            String delimiter, BidiFormatter bidiFormatter) {
-        String formattedSenderName = bidiFormatter.unicodeWrap(senderName,
-                TextDirectionHeuristics.FIRSTSTRONG_LTR, /* isolate= */ true);
-        String formattedGroupName = bidiFormatter.unicodeWrap(groupName,
-                TextDirectionHeuristics.FIRSTSTRONG_LTR, /* isolate= */ true);
-        String title = String.join(delimiter, formattedSenderName, formattedGroupName);
-        return bidiFormatter.unicodeWrap(title, TextDirectionHeuristics.LOCALE);
-    }
-
-    /**
-     * Given a name of all the participants in a group conversation (some names might be phone
-     * numbers), this function creates the conversation title by putting the names in alphabetical
-     * order first, then adding any phone numbers. This title should not exceed the
-     * conversationTitleLength, so not all participants' names are guaranteed to be
-     * in the conversation title.
-     */
-    public static String constructGroupConversationTitle(List<String> names, String delimiter,
-            int conversationTitleLength) {
-        return constructGroupConversationTitle(names, delimiter, conversationTitleLength,
-                BidiFormatter.getInstance());
-    }
-
-    /**
-     * Given a name of all the participants in a group conversation (some names might be phone
-     * numbers), this function creates the conversation title by putting the names in alphabetical
-     * order first, then adding any phone numbers. This title should not exceed the
-     * conversationTitleLength, so not all participants' names are guaranteed to be
-     * in the conversation title.
-     */
-    public static String constructGroupConversationTitle(List<String> names, String delimiter,
-            int conversationTitleLength, BidiFormatter bidiFormatter) {
-        List<String> sortedNames = getSortedSubsetNames(names, conversationTitleLength,
-                delimiter.length());
-        String formattedDelimiter = bidiFormatter.unicodeWrap(delimiter,
-                TextDirectionHeuristics.LOCALE);
-
-        String conversationName = sortedNames.stream().map(name -> bidiFormatter.unicodeWrap(name,
-                TextDirectionHeuristics.FIRSTSTRONG_LTR))
-                .collect(Collectors.joining(formattedDelimiter));
-        return bidiFormatter.unicodeWrap(conversationName, TextDirectionHeuristics.LOCALE);
-    }
-
-    /**
-     * Sorts the list, and returns the first elements whose total length is less than the given
-     * conversationTitleLength.
-     */
-    private static List<String> getSortedSubsetNames(List<String> names,
-            int conversationTitleLength,
-            int delimiterLength) {
-        Collections.sort(names, Utils.ALPHA_THEN_NUMERIC_COMPARATOR);
-        int namesCounter = 0;
-        int indexCounter = 0;
-        while (namesCounter < conversationTitleLength && indexCounter < names.size()) {
-            namesCounter = namesCounter + names.get(indexCounter).length() + delimiterLength;
-            indexCounter = indexCounter + 1;
-        }
-        return names.subList(0, indexCounter);
-    }
-
     /** Comparator that sorts names alphabetically first, then phone numbers numerically. **/
     public static final Comparator<String> ALPHA_THEN_NUMERIC_COMPARATOR =
             new Comparator<String>() {
@@ -438,10 +348,7 @@
                                 null);
                         return util.isValidNumber(phoneNumber);
                     } catch (NumberParseException e) {
-                        // Phone numbers without country codes should still be classified as
-                        // phone numbers.
-                        return e.getErrorType().equals(
-                                NumberParseException.ErrorType.INVALID_COUNTRY_CODE);
+                        return false;
                     }
                 }
 
@@ -463,5 +370,4 @@
                     }
                 }
             };
-
 }
diff --git a/car-messenger-common/tests/unit/Android.bp b/car-messenger-common/tests/unit/Android.bp
deleted file mode 100644
index eb31d43..0000000
--- a/car-messenger-common/tests/unit/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test {
-    name: "car-messenger-common-lib-unit-tests",
-
-    srcs: ["src/**/*.java"],
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.test.mock",
-    ],
-
-    static_libs: [
-        "android.car",
-        "androidx.test.core",
-        "androidx.test.ext.junit",
-        "androidx.test.rules",
-        "car-messenger-common",
-        "mockito-target-extended-minus-junit4",
-        "truth-prebuilt",
-    ],
-
-    platform_apis: true,
-}
diff --git a/car-messenger-common/tests/unit/AndroidManifest.xml b/car-messenger-common/tests/unit/AndroidManifest.xml
deleted file mode 100644
index eefce32..0000000
--- a/car-messenger-common/tests/unit/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.car.messenger.common.tests.unit">
-    <uses-permission android:name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"/>
-    <application android:testOnly="true"
-                 android:debuggable="true"
-                 xmlns:tools="http://schemas.android.com/tools">
-        <uses-library android:name="android.test.runner" />
-        <!-- Workaround for b/113294940 -->
-        <provider
-            android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
-            tools:replace="android:authorities"
-            android:authorities="${applicationId}.lifecycle"
-            android:exported="false"
-            android:multiprocess="true" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.car.messenger.common.tests.unit"
-                     android:label="Car Messenger Lib Test Cases" />
-</manifest>
\ No newline at end of file
diff --git a/car-messenger-common/tests/unit/README.md b/car-messenger-common/tests/unit/README.md
deleted file mode 100644
index 12bb628..0000000
--- a/car-messenger-common/tests/unit/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Instructions for running unit tests
-
-### Build unit test module
-
-`m car-messenger-common-lib-unit-tests`
-
-### Install resulting apk on device
-
-`adb install -r -t $OUT/testcases/car-messenger-common-lib-unit-tests/arm64/car-messenger-common-lib-unit-tests.apk`
-
-### Run all tests
-
-`adb shell am instrument -w com.android.car.messenger.common.tests.unit`
-
-### Run tests in a class
-
-`adb shell am instrument -w -e class com.android.car.messenger.common.<classPath> com.android.car.messenger.common.tests.unit`
-
-### Run a specific test
-
-`adb shell am instrument -w -e class com.android.car.messenger.common.<classPath>#<testMethod> com.android.car.messenger.common.tests.unit`
-
-More general information can be found at
-http://developer.android.com/reference/android/support/test/runner/AndroidJUnitRunner.html
\ No newline at end of file
diff --git a/car-messenger-common/tests/unit/src/com.android.car.messenger.common/UtilsTest.java b/car-messenger-common/tests/unit/src/com.android.car.messenger.common/UtilsTest.java
deleted file mode 100644
index c64703a..0000000
--- a/car-messenger-common/tests/unit/src/com.android.car.messenger.common/UtilsTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.messenger.common;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.text.BidiFormatter;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class UtilsTest {
-
-    private static final String ARABIC_NAME = "جﺗﺧ";
-    private static final List<String> NAMES = Arrays.asList("+1-650-900-1234", "Logan.", "Emily",
-            "Christopher", "!Sam", ARABIC_NAME);
-    private static final String NAME_DELIMITER = "، ";
-    private static final String TITLE_DELIMITER = " : ";
-    private static final int TITLE_LENGTH = 30;
-    private static final BidiFormatter RTL_FORMATTER = BidiFormatter.getInstance(/* rtlContext= */
-            true);
-
-    @Test
-    public void testNameWithMultipleNumbers() {
-        // Ensure that a group name with many phone numbers sorts the phone numbers correctly.
-        List<String> senderNames = Arrays.asList("+1-650-900-1234", "+1-650-900-1111",
-                "+1-100-200-1234");
-        String actual = Utils.constructGroupConversationTitle(senderNames, NAME_DELIMITER,
-                TITLE_LENGTH + 20);
-        String expected = "+1-100-200-1234، +1-650-900-1111، +1-650-900-1234";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testNameWithInternationalNumbers() {
-        // Ensure that a group name with many phone numbers sorts the phone numbers correctly.
-        List<String> senderNames = Arrays.asList("+44-20-7183-8750", "+1-650-900-1111",
-                "+1-100-200-1234");
-        String actual = Utils.constructGroupConversationTitle(senderNames, NAME_DELIMITER,
-                TITLE_LENGTH + 20);
-        String expected = "+1-100-200-1234، +1-650-900-1111، +44-20-7183-8750";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testNameConstructorLtr() {
-        String actual = Utils.constructGroupConversationTitle(NAMES, NAME_DELIMITER, TITLE_LENGTH);
-        assertThat(actual).isEqualTo("!Sam، Christopher، Emily، Logan.");
-    }
-
-    @Test
-    public void testNameConstructorLtr_longerTitle() {
-        String actual = Utils.constructGroupConversationTitle(NAMES, NAME_DELIMITER,
-                TITLE_LENGTH + 5);
-        assertThat(actual).isEqualTo(
-                "!Sam، Christopher، Emily، Logan.، \u200E\u202Bجﺗﺧ\u202C\u200E");
-
-    }
-
-    @Test
-    public void testTitleConstructorLtr() {
-        String actual = Utils.constructGroupConversationHeader("Christopher",
-                "!Sam، Emily، Logan.، +1-650-900-1234", TITLE_DELIMITER);
-        String expected = "Christopher : !Sam، Emily، Logan.، +1-650-900-1234";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testTitleConstructorLtr_with_rtlName() {
-        String actual = Utils.constructGroupConversationHeader(ARABIC_NAME, "!Sam، Logan.، جﺗﺧ",
-                TITLE_DELIMITER);
-        // Note: the Group name doesn't have the RTL tag because in the function we format the
-        // entire group name string, not each name in the string.
-        String expected = "\u200E\u202Bجﺗﺧ\u202C\u200E : !Sam، Logan.، جﺗﺧ\u200E";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testTitleConstructorLtr_with_phoneNumber() {
-        String actual = Utils.constructGroupConversationHeader("+1-650-900-1234",
-                "!Sam، Logan.، جﺗﺧ",
-                TITLE_DELIMITER);
-        // Note: the Group name doesn't have the RTL tag because in the function we format the
-        // entire group name string, not each name in the string.
-        String expected = "+1-650-900-1234 : !Sam، Logan.، جﺗﺧ\u200E";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    /**
-     * NOTE for all the RTL tests done below: When BidiFormatter is unicode-wrapping strings, they
-     * are actually adding invisible Unicode characters to denote whether a section is RTL, LTR,
-     * etc. These invisible characters are NOT visible on the terminal output, or if you copy
-     * paste the string to most HTML pages. They ARE visible when you paste them in certain
-     * text editors like IntelliJ, or there are some online tools that provide this as well.
-     *
-     * Therefore, in most of these RTL tests (and some of the LTR tests) you will see the
-     * invisible characters in the expected strings. Here's a couple of the characters, and what
-     * they're used for:
-     * \u200F is the RTL mark
-     * \u200E is the LTR mark
-     * \u202A marks the start of LTR embedding
-     * \u202B marks the start of RTL embedding
-     * \u202C pops the directional formatting - Must be used to end an embedding
-     */
-    @Test
-    public void testNameWithInternationalNumbers_rtl() {
-        // Ensure that a group name with many phone numbers sorts the phone numbers correctly.
-        List<String> senderNames = Arrays.asList("+44-20-7183-8750", "+1-650-900-1111",
-                "+1-100-200-1234");
-        String actual = Utils.constructGroupConversationTitle(senderNames, NAME_DELIMITER,
-                TITLE_LENGTH + 20, RTL_FORMATTER);
-        String expected = "\u200F\u202A\u200F\u202A+1-100-200-1234\u202C\u200F\u200F\u202A، "
-                + "\u202C\u200F\u200F\u202A+1-650-900-1111\u202C\u200F\u200F\u202A، "
-                + "\u202C\u200F\u200F\u202A+44-20-7183-8750\u202C\u200F\u202C\u200F";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testNameConstructorRtl() {
-        String actual = Utils.constructGroupConversationTitle(NAMES, NAME_DELIMITER, TITLE_LENGTH,
-                /* isRtl */ RTL_FORMATTER);
-
-        String expected =
-                "\u200F\u202A\u200F\u202A!Sam\u202C\u200F\u200F\u202A، \u202C\u200F"
-                        + "\u200F\u202AChristopher\u202C\u200F\u200F\u202A، \u202C\u200F"
-                        + "\u200F\u202AEmily\u202C\u200F\u200F\u202A، "
-                        + "\u202C\u200F\u200F\u202ALogan.\u202C\u200F\u202C\u200F";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testNameConstructorRtl_longerTitle() {
-        String actual = Utils.constructGroupConversationTitle(NAMES, NAME_DELIMITER,
-                TITLE_LENGTH + 5, /* isRtl */ RTL_FORMATTER);
-
-        String expected =
-                "\u200F\u202A\u200F\u202A!Sam\u202C\u200F\u200F\u202A، "
-                        + "\u202C\u200F\u200F\u202AChristopher\u202C\u200F\u200F"
-                        + "\u202A، \u202C\u200F\u200F\u202AEmily\u202C\u200F\u200F\u202A، "
-                        + "\u202C\u200F\u200F\u202ALogan.\u202C\u200F\u200F\u202A، "
-                        + "\u202C\u200Fجﺗﺧ\u202C\u200F";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testTitleConstructorRtl_with_rtlName() {
-        String actual = Utils.constructGroupConversationHeader(ARABIC_NAME, "!Sam، Logan.، جﺗﺧ",
-                TITLE_DELIMITER, RTL_FORMATTER);
-        // Note: the Group name doesn't have the RTL tag because in the function we format the
-        // entire group name string, not each name in the string.
-        // Also, note that the sender's name, which is RTL still has LTR embedded because we wrap
-        // it with FIRSTSTRONG_LTR.
-        String expected = "\u200F\u202Aجﺗﺧ : \u200F\u202A!Sam، Logan.، جﺗﺧ\u202C\u200F\u202C"
-                + "\u200F";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-
-    @Test
-    public void testTitleConstructorRtl_with_phoneNumber() {
-        String actual = Utils.constructGroupConversationHeader("+1-650-900-1234",
-                "!Sam، Logan.، جﺗﺧ",
-                TITLE_DELIMITER, RTL_FORMATTER);
-        // Note: the Group name doesn't have the RTL tag because in the function we format the
-        // entire group name string, not each name in the string.
-        String expected = "\u200F\u202A\u200F\u202A+1-650-900-1234\u202C\u200F : "
-                + "\u200F\u202A!Sam، Logan.، جﺗﺧ\u202C\u200F\u202C\u200F";
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testTitleConstructorRtl() {
-        String actual = Utils.constructGroupConversationHeader("Christopher",
-                "+1-650-900-1234، Logan.، Emily، Christopher، !Sam", TITLE_DELIMITER, /* isRtl */
-                RTL_FORMATTER).trim();
-
-        String expected =
-                "\u200F\u202A\u200F\u202AChristopher\u202C\u200F : \u200F\u202A+1-650-900-1234، "
-                        + "Logan.، Emily، Christopher، !Sam\u202C\u200F\u202C\u200F";
-
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void testTitleConstructorRtl_withTrailingPunctuation() {
-        String actual = Utils.constructGroupConversationHeader("Christopher",
-                "Abcd!!!", TITLE_DELIMITER, /* isRtl */
-                RTL_FORMATTER).trim();
-
-        String expected =
-                "\u200F\u202A\u200F\u202AChristopher\u202C\u200F : \u200F\u202AAbcd!!!"
-                        + "\u202C\u200F\u202C\u200F";
-
-        assertThat(actual).isEqualTo(expected);
-    }
-}
diff --git a/car-telephony-common/Android.bp b/car-telephony-common/Android.bp
index 843abc5..8f9318e 100644
--- a/car-telephony-common/Android.bp
+++ b/car-telephony-common/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-telephony-common",
 
@@ -29,9 +25,6 @@
         enabled: false,
     },
 
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-
     static_libs: [
         "androidx.legacy_legacy-support-v4",
         "car-apps-common",
@@ -39,27 +32,6 @@
         "libphonenumber",
     ],
 
-    libs: ["android.car-system-stubs"],
-}
+    libs: ["android.car"],
 
-// Used by instrumented test
-android_app {
-    name: "CarTelephonyLibTestsApp",
-
-    resource_dirs: ["res"],
-
-    srcs: ["src/**/*.java"],
-
-    static_libs: [
-        "androidx.legacy_legacy-support-v4",
-        "car-apps-common",
-        "glide-prebuilt",
-        "libphonenumber",
-    ],
-
-    optimize: {
-        enabled: false,
-    },
-
-    sdk_version: "system_current",
 }
diff --git a/car-telephony-common/OWNERS b/car-telephony-common/OWNERS
index 99c12c9..e1353ab 100644
--- a/car-telephony-common/OWNERS
+++ b/car-telephony-common/OWNERS
@@ -1,3 +1,4 @@
 # People who can approve changes for submission.
-igorr@google.com
-yiqunw@google.com
+deanh@google.com
+jiayuzhou@google.com
+
diff --git a/car-telephony-common/lint-baseline.xml b/car-telephony-common/lint-baseline.xml
deleted file mode 100644
index 1c72bb0..0000000
--- a/car-telephony-common/lint-baseline.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#writeBoolean`"
-        errorLine1="        dest.writeBoolean(mIsStarred);"
-        errorLine2="             ~~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/Contact.java"
-            line="577"
-            column="14"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#writeBoolean`"
-        errorLine1="        dest.writeBoolean(mIsVoiceMail);"
-        errorLine2="             ~~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/Contact.java"
-            line="580"
-            column="14"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#readBoolean`"
-        errorLine1="        contact.mIsStarred = source.readBoolean();"
-        errorLine2="                                    ~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/Contact.java"
-            line="622"
-            column="37"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#readBoolean`"
-        errorLine1="        contact.mIsVoiceMail = source.readBoolean();"
-        errorLine2="                                      ~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/Contact.java"
-            line="625"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#writeBoolean`"
-        errorLine1="        dest.writeBoolean(mIsPrimary);"
-        errorLine2="             ~~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java"
-            line="241"
-            column="14"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#writeBoolean`"
-        errorLine1="        dest.writeBoolean(mIsFavorite);"
-        errorLine2="             ~~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java"
-            line="246"
-            column="14"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#readBoolean`"
-        errorLine1="            boolean isPrimary = source.readBoolean();"
-        errorLine2="                                       ~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java"
-            line="256"
-            column="40"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 29 (current min is 28): `android.os.Parcel#readBoolean`"
-        errorLine1="            phoneNumber.setIsFavorite(source.readBoolean());"
-        errorLine2="                                             ~~~~~~~~~~~">
-        <location
-            file="packages/apps/Car/libs/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java"
-            line="263"
-            column="46"/>
-    </issue>
-
-</issues>
diff --git a/car-telephony-common/src/com/android/car/telephony/common/AsyncQueryLiveData.java b/car-telephony-common/src/com/android/car/telephony/common/AsyncQueryLiveData.java
index c4f6170..ecacb51 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/AsyncQueryLiveData.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/AsyncQueryLiveData.java
@@ -51,7 +51,8 @@
 
     public AsyncQueryLiveData(Context context, QueryParam.Provider provider,
             ExecutorService executorService) {
-        mObservableAsyncQuery = new ObservableAsyncQuery(context, provider, this::onCursorLoaded);
+        mObservableAsyncQuery = new ObservableAsyncQuery(provider, context.getContentResolver(),
+                this::onCursorLoaded);
         mExecutorService = executorService;
     }
 
diff --git a/car-telephony-common/src/com/android/car/telephony/common/CallDetail.java b/car-telephony-common/src/com/android/car/telephony/common/CallDetail.java
index 79a1bff..828b7f7 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/CallDetail.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/CallDetail.java
@@ -17,11 +17,9 @@
 package com.android.car.telephony.common;
 
 import android.net.Uri;
-import android.os.Bundle;
 import android.telecom.Call;
 import android.telecom.DisconnectCause;
 import android.telecom.GatewayInfo;
-import android.telecom.PhoneAccountHandle;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -30,31 +28,20 @@
  * Represents details of {@link Call.Details}.
  */
 public class CallDetail {
-    private static final String EXTRA_SCO_STATE = "com.android.bluetooth.hfpclient.SCO_STATE";
-
-    public static final int STATE_AUDIO_ERROR = -1;
-    public static final int STATE_AUDIO_DISCONNECTED = 0;
-    public static final int STATE_AUDIO_CONNECTING = 1;
-    public static final int STATE_AUDIO_CONNECTED = 2;
-
     private final String mNumber;
     private final CharSequence mDisconnectCause;
     private final Uri mGatewayInfoOriginalAddress;
     private final long mConnectTimeMillis;
     private final boolean mIsConference;
-    private final PhoneAccountHandle mPhoneAccountHandle;
-    private final int mScoState;
 
     private CallDetail(String number, CharSequence disconnectCause,
-            Uri gatewayInfoOriginalAddress, long connectTimeMillis,
-            boolean isConference, PhoneAccountHandle phoneAccountHandle, int scoState) {
+                       Uri gatewayInfoOriginalAddress, long connectTimeMillis,
+                       boolean isConference) {
         mNumber = number;
         mDisconnectCause = disconnectCause;
         mGatewayInfoOriginalAddress = gatewayInfoOriginalAddress;
-        mConnectTimeMillis = connectTimeMillis;
+        this.mConnectTimeMillis = connectTimeMillis;
         mIsConference = isConference;
-        mPhoneAccountHandle = phoneAccountHandle;
-        mScoState = scoState;
     }
 
     /**
@@ -63,8 +50,7 @@
     public static CallDetail fromTelecomCallDetail(@Nullable Call.Details callDetail) {
         return new CallDetail(getNumber(callDetail), getDisconnectCause(callDetail),
                 getGatewayInfoOriginalAddress(callDetail), getConnectTimeMillis(callDetail),
-                isConferenceCall(callDetail), getPhoneAccountHandle(callDetail),
-                getScoState(callDetail));
+                callDetail.hasProperty(Call.Details.PROPERTY_CONFERENCE));
     }
 
     /**
@@ -105,19 +91,6 @@
         return mIsConference;
     }
 
-    /**
-     * Returns the SCO state of the call.
-     */
-    public int getScoState() {
-        return mScoState;
-    }
-
-    /** Returns the {@link PhoneAccountHandle} for this call. */
-    @Nullable
-    public PhoneAccountHandle getPhoneAccountHandle() {
-        return mPhoneAccountHandle;
-    }
-
     private static String getNumber(Call.Details callDetail) {
         String number = "";
         if (callDetail == null) {
@@ -147,26 +120,10 @@
     }
 
     private static long getConnectTimeMillis(Call.Details callDetail) {
-        return callDetail == null ? 0 : callDetail.getConnectTimeMillis();
-    }
-
-    private static boolean isConferenceCall(Call.Details callDetail) {
-        return callDetail != null && callDetail.hasProperty(Call.Details.PROPERTY_CONFERENCE);
-    }
-
-    @Nullable
-    private static PhoneAccountHandle getPhoneAccountHandle(Call.Details callDetail) {
-        return callDetail == null ? null : callDetail.getAccountHandle();
-    }
-
-    private static int getScoState(Call.Details callDetail) {
-        int state = STATE_AUDIO_ERROR;
         if (callDetail != null) {
-            Bundle extras = callDetail.getExtras();
-            if (extras != null && extras.containsKey(EXTRA_SCO_STATE)) {
-                state = extras.getInt(EXTRA_SCO_STATE);
-            }
+            return callDetail.getConnectTimeMillis();
+        } else {
+            return 0;
         }
-        return state;
     }
 }
diff --git a/car-telephony-common/src/com/android/car/telephony/common/Contact.java b/car-telephony-common/src/com/android/car/telephony/common/Contact.java
index f40a566..e700632 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/Contact.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/Contact.java
@@ -32,7 +32,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 
 /**
  * Encapsulates data about a phone Contact entry. Typically loaded from the local Contact store.
@@ -201,21 +200,11 @@
 
     /**
      * All postal addresses of this contact mapping to the unique primary key for the raw data
-     * entry.
+     * entry
      */
     private final List<PostalAddress> mPostalAddresses = new ArrayList<>();
 
     /**
-     * Collator instance for proper comparison based on localized names.
-     */
-    private Collator mCollator;
-
-    /**
-     * Locale used for mCollator creation.
-     */
-    private Locale mLocale;
-
-    /**
      * Parses a contact entry for a Cursor loaded from the Contact Database. A new contact will be
      * created and returned.
      */
@@ -375,7 +364,7 @@
     @Override
     public boolean equals(Object obj) {
         return obj instanceof Contact && mLookupKey.equals(((Contact) obj).mLookupKey)
-                && TextUtils.equals(((Contact) obj).mAccountName, mAccountName);
+                && mAccountName.equals(((Contact) obj).mAccountName);
     }
 
     @Override
@@ -461,17 +450,6 @@
     }
 
     /**
-     * Returns the initials of the contact's name based on display order.
-     */
-    public String getInitialsBasedOnDisplayOrder(boolean startWithFirstName) {
-        if (startWithFirstName) {
-            return TelecomUtils.getInitials(mDisplayName, mDisplayNameAlt);
-        } else {
-            return TelecomUtils.getInitials(mDisplayNameAlt, mDisplayName);
-        }
-    }
-
-    /**
      * Returns {@link #mPhoneBookLabel}
      */
     public String getPhonebookLabel() {
@@ -639,7 +617,7 @@
         for (int i = 0; i < phoneNumberListLength; i++) {
             PhoneNumber phoneNumber = source.readParcelable(PhoneNumber.class.getClassLoader());
             contact.mPhoneNumbers.add(phoneNumber);
-            if (phoneNumber != null && phoneNumber.isPrimary()) {
+            if (phoneNumber.isPrimary()) {
                 contact.mPrimaryPhoneNumber = phoneNumber;
             }
         }
@@ -687,12 +665,8 @@
         if (type != otherType) {
             return Integer.compare(type, otherType);
         }
-        Locale currentLocale = Locale.getDefault();
-        if (mCollator == null || mLocale == null || !mLocale.equals(currentLocale)) {
-            mCollator = Collator.getInstance(currentLocale);
-            mLocale = currentLocale;
-        }
-        return mCollator.compare(name == null ? "" : name, otherName == null ? "" : otherName);
+        Collator collator = Collator.getInstance();
+        return collator.compare(name == null ? "" : name, otherName == null ? "" : otherName);
     }
 
     /**
diff --git a/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java b/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java
index 25b40be..5d8e3eb 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java
@@ -16,23 +16,17 @@
 
 package com.android.car.telephony.common;
 
-import android.Manifest;
 import android.content.Context;
 import android.database.Cursor;
 import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds;
-import android.provider.ContactsContract.Data;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.Observer;
-import androidx.lifecycle.Transformations;
 
 import com.android.car.apps.common.log.L;
-import com.android.car.telephony.common.QueryParam.QueryBuilder.Condition;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -61,11 +55,6 @@
      * key to contacts for one account.
      */
     private final Map<String, Map<String, Contact>> mLookupKeyContactMap = new HashMap<>();
-
-    /**
-     * A map which divides contacts by account.
-     */
-    private final Map<String, List<Contact>> mAccountContactsMap = new ArrayMap<>();
     private boolean mIsLoaded = false;
 
     /**
@@ -112,16 +101,18 @@
 
     private InMemoryPhoneBook(Context context) {
         mContext = context;
-        QueryParam contactListQueryParam = new QueryParam.QueryBuilder(Data.CONTENT_URI)
-                .projectAll()
-                .where(Condition
-                        .is(Data.MIMETYPE, "=", CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
-                        .or(Data.MIMETYPE, "=", CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
-                        .or(Data.MIMETYPE, "=", CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE))
-                .orderAscBy(ContactsContract.Contacts.DISPLAY_NAME)
-                .checkPermission(Manifest.permission.READ_CONTACTS)
-                .toQueryParam();
 
+        QueryParam contactListQueryParam = new QueryParam(
+                ContactsContract.Data.CONTENT_URI,
+                null,
+                ContactsContract.Data.MIMETYPE + " = ? OR "
+                        + ContactsContract.Data.MIMETYPE + " = ? OR "
+                        + ContactsContract.Data.MIMETYPE + " = ?",
+                new String[]{
+                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
+                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
+                        ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE},
+                ContactsContract.Contacts.DISPLAY_NAME + " ASC ");
         mContactListAsyncQueryLiveData = new AsyncQueryLiveData<List<Contact>>(mContext,
                 QueryParam.of(contactListQueryParam), Executors.newSingleThreadExecutor()) {
             @Override
@@ -145,27 +136,12 @@
 
     /**
      * Returns a {@link LiveData} which monitors the contact list changes.
-     *
-     * @deprecated Use {@link #getContactsLiveDataByAccount(String)} instead.
      */
-    @Deprecated
     public LiveData<List<Contact>> getContactsLiveData() {
         return mContactListAsyncQueryLiveData;
     }
 
     /**
-     * Returns a LiveData that represents all contacts within an account.
-     *
-     * @param accountName the name of an account that contains all the contacts. For the contacts
-     *                    from a Bluetooth connected phone, the account name is equal to the
-     *                    Bluetooth address.
-     */
-    public LiveData<List<Contact>> getContactsLiveDataByAccount(String accountName) {
-        return Transformations.map(mContactListAsyncQueryLiveData,
-                contacts -> contacts == null ? null : mAccountContactsMap.get(accountName));
-    }
-
-    /**
      * Looks up a {@link Contact} by the given phone number. Returns null if can't find a Contact or
      * the {@link InMemoryPhoneBook} is still loading.
      */
@@ -239,7 +215,7 @@
         while (cursor.moveToNext()) {
             int accountNameColumn = cursor.getColumnIndex(
                     ContactsContract.RawContacts.ACCOUNT_NAME);
-            int lookupKeyColumn = cursor.getColumnIndex(Data.LOOKUP_KEY);
+            int lookupKeyColumn = cursor.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
             String accountName = cursor.getString(accountNameColumn);
             String lookupKey = cursor.getString(lookupKeyColumn);
 
@@ -251,13 +227,8 @@
             subMap.put(lookupKey, Contact.fromCursor(mContext, cursor, subMap.get(lookupKey)));
         }
 
-        mAccountContactsMap.clear();
-        for (String accountName : contactMap.keySet()) {
-            Map<String, Contact> subMap = contactMap.get(accountName);
+        for (Map<String, Contact> subMap : contactMap.values()) {
             contactList.addAll(subMap.values());
-            List<Contact> accountContacts = new ArrayList<>();
-            accountContacts.addAll(subMap.values());
-            mAccountContactsMap.put(accountName, accountContacts);
         }
 
         mLookupKeyContactMap.clear();
diff --git a/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java b/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java
index 9f2f0cb..b3c1fb1 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java
@@ -18,15 +18,12 @@
 
 import android.content.AsyncQueryHandler;
 import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.database.Cursor;
 
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
 
 import com.android.car.apps.common.log.L;
 
@@ -51,12 +48,11 @@
         void onQueryFinished(@Nullable Cursor cursor);
     }
 
-    private Context mContext;
     private AsyncQueryHandler mAsyncQueryHandler;
     private QueryParam.Provider mQueryParamProvider;
+    private Cursor mCurrentCursor;
     private OnQueryFinishedListener mOnQueryFinishedListener;
     private ContentObserver mContentObserver;
-    private ContentResolver mContentResolver;
     private boolean mIsActive = false;
     private int mToken;
 
@@ -65,12 +61,10 @@
      * @param listener           Listener which will be called when data is available.
      */
     public ObservableAsyncQuery(
-            @NonNull Context context,
             @NonNull QueryParam.Provider queryParamProvider,
+            @NonNull ContentResolver cr,
             @NonNull OnQueryFinishedListener listener) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mAsyncQueryHandler = new AsyncQueryHandlerImpl(this, mContentResolver);
+        mAsyncQueryHandler = new AsyncQueryHandlerImpl(this, cr);
         mContentObserver = new ContentObserver(mAsyncQueryHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -89,12 +83,10 @@
     public void startQuery() {
         L.d(TAG, "startQuery");
         mAsyncQueryHandler.cancelOperation(mToken); // Cancel the query task.
-        mContentResolver.unregisterContentObserver(mContentObserver);
 
         mToken++;
         QueryParam queryParam = mQueryParamProvider.getQueryParam();
-        if (queryParam != null && ContextCompat.checkSelfPermission(mContext,
-                queryParam.mPermission) == PackageManager.PERMISSION_GRANTED) {
+        if (queryParam != null) {
             mAsyncQueryHandler.startQuery(
                     mToken,
                     null,
@@ -103,7 +95,6 @@
                     queryParam.mSelection,
                     queryParam.mSelectionArgs,
                     queryParam.mOrderBy);
-            mContentResolver.registerContentObserver(queryParam.mUri, false, mContentObserver);
         } else {
             mOnQueryFinishedListener.onQueryFinished(null);
         }
@@ -118,7 +109,7 @@
     public void stopQuery() {
         L.d(TAG, "stopQuery");
         mIsActive = false;
-        mContentResolver.unregisterContentObserver(mContentObserver);
+        cleanupCursorIfNecessary();
         mAsyncQueryHandler.cancelOperation(mToken); // Cancel the query task.
     }
 
@@ -127,11 +118,23 @@
             return;
         }
         L.d(TAG, "onQueryComplete");
+        cleanupCursorIfNecessary();
+        if (cursor != null) {
+            cursor.registerContentObserver(mContentObserver);
+            mCurrentCursor = cursor;
+        }
         if (mOnQueryFinishedListener != null) {
             mOnQueryFinishedListener.onQueryFinished(cursor);
         }
     }
 
+    protected void cleanupCursorIfNecessary() {
+        if (mCurrentCursor != null) {
+            mCurrentCursor.unregisterContentObserver(mContentObserver);
+        }
+        mCurrentCursor = null;
+    }
+
     private static class AsyncQueryHandlerImpl extends AsyncQueryHandler {
         private ObservableAsyncQuery mQuery;
 
diff --git a/car-telephony-common/src/com/android/car/telephony/common/PhoneCallLog.java b/car-telephony-common/src/com/android/car/telephony/common/PhoneCallLog.java
index a1e25f2..815e3d5 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/PhoneCallLog.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/PhoneCallLog.java
@@ -70,7 +70,6 @@
     private long mId;
     private String mPhoneNumberString;
     private I18nPhoneNumberWrapper mI18nPhoneNumberWrapper;
-    private String mAccountName;
     private List<Record> mCallRecords = new ArrayList<>();
 
     /**
@@ -81,7 +80,6 @@
         int numberColumn = cursor.getColumnIndex(CallLog.Calls.NUMBER);
         int dateColumn = cursor.getColumnIndex(CallLog.Calls.DATE);
         int callTypeColumn = cursor.getColumnIndex(CallLog.Calls.TYPE);
-        int accountNameColumn = cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID);
 
         PhoneCallLog phoneCallLog = new PhoneCallLog();
         phoneCallLog.mId = cursor.getLong(idColumn);
@@ -90,7 +88,6 @@
                 phoneCallLog.mPhoneNumberString);
         Record record = new Record(cursor.getLong(dateColumn), cursor.getInt(callTypeColumn));
         phoneCallLog.mCallRecords.add(record);
-        phoneCallLog.mAccountName = cursor.getString(accountNameColumn);
         return phoneCallLog;
     }
 
@@ -99,14 +96,6 @@
         return mPhoneNumberString;
     }
 
-    /**
-     * Returns the account name that this call log belongs to. For call logs from Bluetooth device,
-     * account name is the same as Bluetooth address.
-     */
-    public String getAccountName() {
-        return mAccountName;
-    }
-
     /** Returns the id of this log. */
     public long getPhoneLogId() {
         return mId;
@@ -174,8 +163,6 @@
         sb.append(TelecomUtils.piiLog(mPhoneNumberString));
         sb.append(" CallLog: ");
         sb.append(mCallRecords.size());
-        sb.append(" Account: ");
-        sb.append(mAccountName);
         return sb.toString();
     }
 }
diff --git a/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java b/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java
index 255def0..4e3eff6 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/PhoneNumber.java
@@ -23,6 +23,7 @@
 import android.os.Parcelable;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -106,8 +107,8 @@
         mLabel = label;
         mIsPrimary = isPrimary;
         mId = id;
-        mAccountName = accountName == null ? "" : accountName;
-        mAccountType = accountType == null ? "" : accountType;
+        mAccountName = TextUtils.emptyIfNull(accountName);
+        mAccountType = TextUtils.emptyIfNull(accountType);
         mDataVersion = dataVersion;
     }
 
diff --git a/car-telephony-common/src/com/android/car/telephony/common/QueryParam.java b/car-telephony-common/src/com/android/car/telephony/common/QueryParam.java
index 2df3a26..9628124 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/QueryParam.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/QueryParam.java
@@ -21,12 +21,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
 /** Represents query parameters. */
 public class QueryParam {
 
@@ -41,10 +35,7 @@
      * <ul>
      * <li>Return the same instance every time calling the getter.
      * <li>Return an updated instance or create a new instance every time calling the getter.
-     *
-     * @deprecated use {@link QueryBuilder}.
      */
-    @Deprecated
     public interface Provider {
 
         /** Returns an instance of query params. */
@@ -62,196 +53,17 @@
     final String[] mSelectionArgs;
     /** Used by {@link ObservableAsyncQuery#startQuery()} as query param. */
     final String mOrderBy;
-    /** Used by {@link ObservableAsyncQuery#startQuery()} to check query permission. */
-    final String mPermission;
 
     public QueryParam(
             @NonNull Uri uri,
             @Nullable String[] projection,
             @Nullable String selection,
             @Nullable String[] selectionArgs,
-            @Nullable String orderBy,
-            @NonNull String permission) {
+            @Nullable String orderBy) {
         mUri = uri;
         mProjection = projection;
         mSelection = selection;
         mSelectionArgs = selectionArgs;
         mOrderBy = orderBy;
-        mPermission = permission;
-    }
-
-    /**
-     * Builds the {@link QueryParam}.
-     */
-    public static class QueryBuilder {
-        public static final String AND = "AND";
-        public static final String OR = "OR";
-
-        static final String ORDER_ASC = "ASC";
-        static final String ORDER_DESC = "DESC";
-
-        private final Uri mUri;
-
-        private String mPermission;
-
-        private Condition mWhere = Condition.emptyCondition();
-        private final List<String> mOrderBy = new ArrayList<>();
-        private final Set<String> mProjectionColumns = new HashSet<>();
-
-        /**
-         *
-         * @param contentUri the content uri for querying.
-         */
-        public QueryBuilder(Uri contentUri) {
-            mUri = contentUri;
-        }
-
-        /**
-         * Specify the projection column. Calling this function multiple times to add more columns
-         * to the projection. When the same column is added multiple times, only one column will
-         * be remembered.
-         */
-        public QueryBuilder project(String columnName) {
-            mProjectionColumns.add(columnName);
-            return this;
-        }
-
-        /**
-         * Selects all columns for projection. This function call will override all previous
-         * {@link #project(String)} call. Calling this function is optional. By default, all
-         * columns will be selected.
-         */
-        public QueryBuilder projectAll() {
-            mProjectionColumns.clear();
-            return this;
-        }
-
-        /**
-         * Specify the select condition.
-         *
-         * @see Condition
-         */
-        public QueryBuilder where(@NonNull Condition condition) {
-            mWhere = condition;
-            return this;
-        }
-
-        private QueryBuilder orderBy(String column, String order) {
-            mOrderBy.add(column + " " + order);
-            return this;
-        }
-
-        /**
-         * Sorts the query result in an ascending order based on the given column.
-         * Calling this function multiple times will add additional orders.
-         * The order of calling this method matters.
-         * @param column The column to be order by.
-         */
-        public QueryBuilder orderAscBy(String column) {
-            return orderBy(column, ORDER_ASC);
-        }
-
-        /**
-         * Sorts the query result in an descending order based on the given column.
-         * Calling this function multiple times will add additional orders.
-         * The order of calling this method matters.
-         * @param column The column to be order by.
-         */
-        public QueryBuilder orderDescBy(String column) {
-            return orderBy(column, ORDER_DESC);
-        }
-
-        /**
-         * Specify the column and order all together.
-         * @param orderBy Should follow "{column} {order}" pattern.
-         */
-        public QueryBuilder orderBy(String orderBy) {
-            mOrderBy.add(orderBy);
-            return this;
-        }
-
-        /**Specifies the permission needed for this query.*/
-        public QueryBuilder checkPermission(@NonNull String permission) {
-            mPermission = permission;
-            return this;
-        }
-        /**
-         * Builds the selection condition. Use {@link #is(String, String, Object)} to create an
-         * initial condition.
-         */
-        public static class Condition {
-            private String mSelection = "";
-            private List<String> mArgs = new ArrayList<>();
-
-            private Condition() {}
-
-            private static Condition emptyCondition() {
-                Condition condition = new Condition();
-                condition.mSelection = null;
-                return condition;
-            }
-
-            /**
-             * Creates the inital condition.
-             */
-            public static Condition is(String columnName, String operator, @NonNull Object value) {
-                Condition condition = new Condition();
-                condition.mSelection = condition.toSelectionString(columnName, operator);
-                condition.mArgs.add(value.toString());
-                return condition;
-            }
-
-            /**
-             * Appends an "AND" condition to the existing conditions.
-             */
-            public Condition and(String columnName, String operator, @NonNull Object value) {
-                mSelection += wrapWithSpaces(AND) + toSelectionString(columnName, operator);
-                mArgs.add(value.toString());
-                return this;
-            }
-
-            /**
-             * Appends an "OR" condition to the existing conditions.
-             */
-            public Condition or(String columnName, String operator, @NonNull Object value) {
-                mSelection += wrapWithSpaces(OR) + toSelectionString(columnName, operator);
-                mArgs.add(value.toString());
-                return this;
-            }
-
-            public String getSelection() {
-                return mSelection;
-            }
-
-            public String[] getWhereArgs() {
-                return mArgs.stream().toArray(String[]::new);
-            }
-
-            static String toSelectionString(String columnName, String op) {
-                return columnName + " " + op + " ?";
-            }
-
-            static String wrapWithSpaces(String s) {
-                return " " + s + " ";
-            }
-        }
-
-        /**
-         * Builds the QueryParam.
-         */
-        public QueryParam toQueryParam() {
-            String[] projection = mProjectionColumns.isEmpty()
-                    ? null
-                    : mProjectionColumns.stream().toArray(String[]::new);
-            String orderBy = mOrderBy.stream().collect(Collectors.joining(","));
-
-            return new QueryParam(
-                    mUri,
-                    projection,
-                    mWhere.getSelection(),
-                    mWhere.getWhereArgs(),
-                    orderBy,
-                    mPermission);
-        }
     }
 }
diff --git a/car-telephony-common/src/com/android/car/telephony/common/TelecomUtils.java b/car-telephony-common/src/com/android/car/telephony/common/TelecomUtils.java
index 7f2be0a..0ad3d57 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/TelecomUtils.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/TelecomUtils.java
@@ -27,6 +27,8 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.Icon;
+import android.location.Country;
+import android.location.CountryDetector;
 import android.net.Uri;
 import android.provider.CallLog;
 import android.provider.ContactsContract;
@@ -42,7 +44,6 @@
 import android.widget.ImageView;
 
 import androidx.annotation.Nullable;
-import androidx.annotation.WorkerThread;
 import androidx.core.content.ContextCompat;
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
 import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
@@ -68,14 +69,6 @@
     private static final String TAG = "CD.TelecomUtils";
     private static final int PII_STRING_LENGTH = 4;
     private static final String COUNTRY_US = "US";
-    /**
-     * A reference to keep track of the soring method of sorting by the contact's first name.
-     */
-    public static final Integer SORT_BY_FIRST_NAME = 1;
-    /**
-     * A reference to keep track of the soring method of sorting by the contact's last name.
-     */
-    public static final Integer SORT_BY_LAST_NAME = 2;
 
     private static String sVoicemailNumber;
     private static TelephonyManager sTelephonyManager;
@@ -130,10 +123,11 @@
         }
 
         String countryIso = getCurrentCountryIsoFromLocale(context);
-        L.d(TAG, "PhoneNumberUtils.formatNumber, number: " + piiLog(number)
-                + ", country: " + countryIso);
+        L.d(TAG, "PhoneNumberUtils.formatNumberToE16, number: "
+                    + piiLog(number) + ", country: " + countryIso);
 
-        String formattedNumber = PhoneNumberUtils.formatNumber(number, countryIso);
+        String e164 = PhoneNumberUtils.formatNumberToE164(number, countryIso);
+        String formattedNumber = PhoneNumberUtils.formatNumber(number, e164, countryIso);
         formattedNumber = TextUtils.isEmpty(formattedNumber) ? number : formattedNumber;
         L.d(TAG, "getFormattedNumber, result: " + piiLog(formattedNumber));
 
@@ -144,7 +138,22 @@
      * @return The ISO 3166-1 two letters country code of the country the user is in.
      */
     private static String getCurrentCountryIso(Context context, Locale locale) {
-        String countryIso = locale.getCountry();
+        String countryIso = null;
+        CountryDetector detector = (CountryDetector) context.getSystemService(
+                Context.COUNTRY_DETECTOR);
+        if (detector != null) {
+            Country country = detector.detectCountry();
+            if (country != null) {
+                countryIso = country.getCountryIso();
+            } else {
+                L.e(TAG, "CountryDetector.detectCountry() returned null.");
+            }
+        }
+        if (countryIso == null) {
+            countryIso = locale.getCountry();
+            L.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
+                    + countryIso);
+        }
         if (countryIso == null || countryIso.length() != 2) {
             L.w(TAG, "Invalid locale, falling back to US");
             countryIso = COUNTRY_US;
@@ -188,21 +197,17 @@
     public static final class PhoneNumberInfo {
         private final String mPhoneNumber;
         private final String mDisplayName;
-        private final String mDisplayNameAlt;
         private final String mInitials;
         private final Uri mAvatarUri;
         private final String mTypeLabel;
-        private final String mLookupKey;
 
-        public PhoneNumberInfo(String phoneNumber, String displayName, String displayNameAlt,
-                String initials, Uri avatarUri, String typeLabel, String lookupKey) {
+        public PhoneNumberInfo(String phoneNumber, String displayName,
+                String initials, Uri avatarUri, String typeLabel) {
             mPhoneNumber = phoneNumber;
             mDisplayName = displayName;
-            mDisplayNameAlt = displayNameAlt;
             mInitials = initials;
             mAvatarUri = avatarUri;
             mTypeLabel = typeLabel;
-            mLookupKey = lookupKey;
         }
 
         public String getPhoneNumber() {
@@ -213,10 +218,6 @@
             return mDisplayName;
         }
 
-        public String getDisplayNameAlt() {
-            return mDisplayNameAlt;
-        }
-
         /**
          * Returns the initials of the contact related to the phone number. Returns null if there is
          * no related contact.
@@ -235,12 +236,6 @@
             return mTypeLabel;
         }
 
-        /** Returns the lookup key of the contact if any is found. */
-        @Nullable
-        public String getLookupKey() {
-            return mLookupKey;
-        }
-
     }
 
     /**
@@ -250,135 +245,102 @@
      */
     public static CompletableFuture<PhoneNumberInfo> getPhoneNumberInfo(
             Context context, String number) {
-        return CompletableFuture.supplyAsync(() -> lookupNumberInBackground(context, number));
-    }
-
-    /** Lookup phone number info in background. */
-    @WorkerThread
-    public static PhoneNumberInfo lookupNumberInBackground(Context context, String number) {
-        if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
-                != PackageManager.PERMISSION_GRANTED) {
-            String readableNumber = getReadableNumber(context, number);
-            return new PhoneNumberInfo(number, readableNumber, readableNumber, null, null, null,
-                    null);
-        }
 
         if (TextUtils.isEmpty(number)) {
-            return new PhoneNumberInfo(
+            return CompletableFuture.completedFuture(new PhoneNumberInfo(
                     number,
                     context.getString(R.string.unknown),
-                    context.getString(R.string.unknown),
                     null,
                     null,
-                    "",
-                    null);
+                    ""));
         }
 
         if (isVoicemailNumber(context, number)) {
-            return new PhoneNumberInfo(
+            return CompletableFuture.completedFuture(new PhoneNumberInfo(
                     number,
                     context.getString(R.string.voicemail),
-                    context.getString(R.string.voicemail),
                     null,
                     makeResourceUri(context, R.drawable.ic_voicemail),
-                    "",
-                    null);
+                    ""));
         }
 
         if (InMemoryPhoneBook.isInitialized()) {
             Contact contact = InMemoryPhoneBook.get().lookupContactEntry(number);
             if (contact != null) {
                 String name = contact.getDisplayName();
-                String nameAlt = contact.getDisplayNameAlt();
-                if (TextUtils.isEmpty(name)) {
-                    name = getReadableNumber(context, number);
+                if (name == null) {
+                    name = getFormattedNumber(context, number);
                 }
-                if (TextUtils.isEmpty(nameAlt)) {
-                    nameAlt = name;
+
+                if (name == null) {
+                    name = context.getString(R.string.unknown);
                 }
 
                 PhoneNumber phoneNumber = contact.getPhoneNumber(context, number);
-                CharSequence typeLabel = phoneNumber == null ? "" : phoneNumber.getReadableLabel(
-                        context.getResources());
+                CharSequence typeLabel = "";
+                if (phoneNumber != null) {
+                    typeLabel = Phone.getTypeLabel(context.getResources(),
+                            phoneNumber.getType(),
+                            phoneNumber.getLabel());
+                }
 
-                return new PhoneNumberInfo(
+                return CompletableFuture.completedFuture(new PhoneNumberInfo(
                         number,
                         name,
-                        nameAlt,
                         contact.getInitials(),
                         contact.getAvatarUri(),
-                        typeLabel.toString(),
-                        contact.getLookupKey());
-            }
-        } else {
-          L.d(TAG, "InMemoryPhoneBook not initialized.");
-        }
-
-        String name = null;
-        String nameAlt = null;
-        String initials = null;
-        String photoUriString = null;
-        CharSequence typeLabel = "";
-        String lookupKey = null;
-
-        ContentResolver cr = context.getContentResolver();
-        try (Cursor cursor = cr.query(
-                Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
-                new String[]{
-                        PhoneLookup.DISPLAY_NAME,
-                        PhoneLookup.DISPLAY_NAME_ALTERNATIVE,
-                        PhoneLookup.PHOTO_URI,
-                        PhoneLookup.TYPE,
-                        PhoneLookup.LABEL,
-                        PhoneLookup.LOOKUP_KEY,
-                },
-                null, null, null)) {
-
-            if (cursor != null && cursor.moveToFirst()) {
-                int nameColumn = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME);
-                int altNameColumn = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME_ALTERNATIVE);
-                int photoUriColumn = cursor.getColumnIndex(PhoneLookup.PHOTO_URI);
-                int typeColumn = cursor.getColumnIndex(PhoneLookup.TYPE);
-                int labelColumn = cursor.getColumnIndex(PhoneLookup.LABEL);
-                int lookupKeyColumn = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY);
-
-                name = cursor.getString(nameColumn);
-                nameAlt = cursor.getString(altNameColumn);
-                photoUriString = cursor.getString(photoUriColumn);
-                initials = getInitials(name, nameAlt);
-
-                int type = cursor.getInt(typeColumn);
-                String label = cursor.getString(labelColumn);
-                typeLabel = Phone.getTypeLabel(context.getResources(), type, label);
-
-                lookupKey = cursor.getString(lookupKeyColumn);
+                        typeLabel.toString()));
             }
         }
 
-        if (TextUtils.isEmpty(name)) {
-            name = getReadableNumber(context, number);
-        }
-        if (TextUtils.isEmpty(nameAlt)) {
-            nameAlt = name;
-        }
+        return CompletableFuture.supplyAsync(() -> {
+            String name = null;
+            String nameAlt = null;
+            String photoUriString = null;
+            CharSequence typeLabel = "";
+            ContentResolver cr = context.getContentResolver();
+            String initials;
+            try (Cursor cursor = cr.query(
+                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
+                    new String[]{
+                            PhoneLookup.DISPLAY_NAME,
+                            PhoneLookup.DISPLAY_NAME_ALTERNATIVE,
+                            PhoneLookup.PHOTO_URI,
+                            PhoneLookup.TYPE,
+                            PhoneLookup.LABEL,
+                    },
+                    null, null, null)) {
 
-        return new PhoneNumberInfo(
-                number,
-                name,
-                nameAlt,
-                initials,
-                TextUtils.isEmpty(photoUriString) ? null : Uri.parse(photoUriString),
-                typeLabel.toString(),
-                lookupKey);
-    }
+                if (cursor != null && cursor.moveToFirst()) {
+                    int nameColumn = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME);
+                    int altNameColumn = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME_ALTERNATIVE);
+                    int photoUriColumn = cursor.getColumnIndex(PhoneLookup.PHOTO_URI);
+                    int typeColumn = cursor.getColumnIndex(PhoneLookup.TYPE);
+                    int labelColumn = cursor.getColumnIndex(PhoneLookup.LABEL);
 
-    private static String getReadableNumber(Context context, String number) {
-        String readableNumber = getFormattedNumber(context, number);
+                    name = cursor.getString(nameColumn);
+                    nameAlt = cursor.getString(altNameColumn);
+                    photoUriString = cursor.getString(photoUriColumn);
+                    int type = cursor.getInt(typeColumn);
+                    String label = cursor.getString(labelColumn);
+                    typeLabel = Phone.getTypeLabel(context.getResources(), type, label);
+                }
+            }
 
-        if (readableNumber == null) {
-            readableNumber = context.getString(R.string.unknown);
-        }
-        return readableNumber;
+            initials = getInitials(name, nameAlt);
+
+            if (name == null) {
+                name = getFormattedNumber(context, number);
+            }
+
+            if (name == null) {
+                name = context.getString(R.string.unknown);
+            }
+
+            return new PhoneNumberInfo(number, name, initials,
+                    TextUtils.isEmpty(photoUriString) ? null : Uri.parse(photoUriString),
+                    typeLabel.toString());
+        });
     }
 
     /**
@@ -429,48 +391,26 @@
     /**
      * Sets a Contact avatar onto the provided {@code icon}. The first letter or both letters of the
      * contact's initials.
-     *
-     * @param sortMethod can be either {@link #SORT_BY_FIRST_NAME} or {@link #SORT_BY_LAST_NAME}.
      */
     public static void setContactBitmapAsync(
             Context context,
             @Nullable final ImageView icon,
-            @Nullable final Contact contact,
-            Integer sortMethod) {
-        setContactBitmapAsync(context, icon, contact, null, sortMethod);
-    }
-
-    /**
-     * Sets a Contact avatar onto the provided {@code icon}. The first letter or both letters of the
-     * contact's initials. Will start with first name by default.
-     */
-    public static void setContactBitmapAsync(
-            Context context,
-            @Nullable final ImageView icon,
-            @Nullable final Contact contact,
-            @Nullable final String fallbackDisplayName) {
-        setContactBitmapAsync(context, icon, contact, fallbackDisplayName, SORT_BY_FIRST_NAME);
+            @Nullable final Contact contact) {
+        setContactBitmapAsync(context, icon, contact, null);
     }
 
     /**
      * Sets a Contact avatar onto the provided {@code icon}. The first letter or both letters of the
      * contact's initials or {@code fallbackDisplayName} will be used as a fallback resource if
      * avatar loading fails.
-     *
-     * @param sortMethod can be either {@link #SORT_BY_FIRST_NAME} or {@link #SORT_BY_LAST_NAME}. If
-     *                   the value is {@link #SORT_BY_FIRST_NAME}, the name and initials order will
-     *                   be first name first. Otherwise, the order will be last name first.
      */
     public static void setContactBitmapAsync(
             Context context,
             @Nullable final ImageView icon,
             @Nullable final Contact contact,
-            @Nullable final String fallbackDisplayName,
-            Integer sortMethod) {
+            @Nullable final String fallbackDisplayName) {
         Uri avatarUri = contact != null ? contact.getAvatarUri() : null;
-        boolean startWithFirstName = isSortByFirstName(sortMethod);
-        String initials = contact != null
-                ? contact.getInitialsBasedOnDisplayOrder(startWithFirstName)
+        String initials = contact != null ? contact.getInitials()
                 : (fallbackDisplayName == null ? null : getInitials(fallbackDisplayName, null));
         String identifier = contact == null ? fallbackDisplayName : contact.getDisplayName();
 
@@ -524,11 +464,6 @@
      * Set the given phone number as the primary phone number for its associated contact.
      */
     public static void setAsPrimaryPhoneNumber(Context context, PhoneNumber phoneNumber) {
-        if (context.checkSelfPermission(Manifest.permission.WRITE_CONTACTS)
-                != PackageManager.PERMISSION_GRANTED) {
-            L.w(TAG, "Missing WRITE_CONTACTS permission, not setting primary number.");
-            return;
-        }
         // Update the primary values in the data record.
         ContentValues values = new ContentValues(1);
         values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
@@ -540,28 +475,27 @@
     }
 
     /**
+     * Add a contact to favorite or remove it from favorite.
+     */
+    public static int setAsFavoriteContact(Context context, Contact contact, boolean isFavorite) {
+        if (contact.isStarred() == isFavorite) {
+            return 0;
+        }
+
+        ContentValues values = new ContentValues(1);
+        values.put(ContactsContract.Contacts.STARRED, isFavorite ? 1 : 0);
+
+        String where = ContactsContract.Contacts._ID + " = ?";
+        String[] selectionArgs = new String[]{Long.toString(contact.getId())};
+        return context.getContentResolver().update(ContactsContract.Contacts.CONTENT_URI, values,
+                where, selectionArgs);
+    }
+
+    /**
      * Mark missed call log matching given phone number as read. If phone number string is not
      * valid, it will mark all new missed call log as read.
      */
     public static void markCallLogAsRead(Context context, String phoneNumberString) {
-        markCallLogAsRead(context, CallLog.Calls.NUMBER, phoneNumberString);
-    }
-
-    /**
-     * Mark missed call log matching given call log id as read. If phone number string is not
-     * valid, it will mark all new missed call log as read.
-     */
-    public static void markCallLogAsRead(Context context, long callLogId) {
-        markCallLogAsRead(context, CallLog.Calls._ID,
-                callLogId < 0 ? null : String.valueOf(callLogId));
-    }
-
-    /**
-     * Mark missed call log matching given column name and selection argument as read. If the column
-     * name or the selection argument is not valid, mark all new missed call log as read.
-     */
-    private static void markCallLogAsRead(Context context, String columnName,
-            String selectionArg) {
         if (context.checkSelfPermission(Manifest.permission.WRITE_CALL_LOG)
                 != PackageManager.PERMISSION_GRANTED) {
             L.w(TAG, "Missing WRITE_CALL_LOG permission; not marking missed calls as read.");
@@ -578,22 +512,21 @@
         where.append(CallLog.Calls.TYPE);
         where.append(" = ?");
         selectionArgs.add(Integer.toString(CallLog.Calls.MISSED_TYPE));
-        if (!TextUtils.isEmpty(columnName) && !TextUtils.isEmpty(selectionArg)) {
+        if (!TextUtils.isEmpty(phoneNumberString)) {
             where.append(" AND ");
-            where.append(columnName);
+            where.append(CallLog.Calls.NUMBER);
             where.append(" = ?");
-            selectionArgs.add(selectionArg);
+            selectionArgs.add(phoneNumberString);
         }
         String[] selectionArgsArray = new String[0];
         try {
-            ContentResolver contentResolver = context.getContentResolver();
-            contentResolver.update(
-                    CallLog.Calls.CONTENT_URI,
-                    contentValues,
-                    where.toString(),
-                    selectionArgs.toArray(selectionArgsArray));
-            // #update doesn't notify change any more. Notify change to rerun query from database.
-            contentResolver.notifyChange(CallLog.Calls.CONTENT_URI, null);
+            context
+                    .getContentResolver()
+                    .update(
+                            CallLog.Calls.CONTENT_URI,
+                            contentValues,
+                            where.toString(),
+                            selectionArgs.toArray(selectionArgsArray));
         } catch (IllegalArgumentException e) {
             L.e(TAG, "markCallLogAsRead failed", e);
         }
@@ -656,7 +589,7 @@
     private static Uri makeResourceUri(Context context, int resourceId) {
         return new Uri.Builder()
                 .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
-                .encodedAuthority(context.getPackageName())
+                .encodedAuthority(context.getBasePackageName())
                 .appendEncodedPath(String.valueOf(resourceId))
                 .build();
     }
@@ -670,12 +603,4 @@
         return piiString.length() >= PII_STRING_LENGTH ? "*" + piiString.substring(
                 piiString.length() - PII_STRING_LENGTH) : piiString;
     }
-
-    /**
-     * Returns true if contacts are sorted by their first names. Returns false if they are sorted by
-     * last names.
-     */
-    public static boolean isSortByFirstName(Integer sortMethod) {
-        return SORT_BY_FIRST_NAME.equals(sortMethod);
-    }
 }
diff --git a/car-telephony-common/tests/robotests/Android.bp b/car-telephony-common/tests/robotests/Android.bp
index 7f91c67..57bf759 100644
--- a/car-telephony-common/tests/robotests/Android.bp
+++ b/car-telephony-common/tests/robotests/Android.bp
@@ -1,10 +1,6 @@
 //###########################################################
 // car-telephony-common just for Robolectric test target.   #
 //###########################################################
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_app {
     name: "CarTelephonyCommonForTesting",
 
diff --git a/car-telephony-common/tests/robotests/src/com/android/car/telephony/common/ContactTest.java b/car-telephony-common/tests/robotests/src/com/android/car/telephony/common/ContactTest.java
index 4825895..572dc8a 100644
--- a/car-telephony-common/tests/robotests/src/com/android/car/telephony/common/ContactTest.java
+++ b/car-telephony-common/tests/robotests/src/com/android/car/telephony/common/ContactTest.java
@@ -38,18 +38,12 @@
 import java.util.Collections;
 import java.util.List;
 
+
 @RunWith(RobolectricTestRunner.class)
 public class ContactTest {
 
     private static final int DISPLAY_NAME_COLUMN = 1;
-    private static final int MIMETYPE_COLUMN = 2;
-    private static final int LOOK_UP_KEY_COLUMN = 3;
-    private static final int PRIMARY_KEY_COLUMN = 4;
-    private static final String PHONEBOOK_LABEL = "phonebook_label";
-    private static final int PHONEBOOK_LABEL_COLUMN = 5;
 
-    private static final String EMPTY_MIME = "";
-    private static final String DEFAULT_LOOK_UP_KEY = "PRIMARY";
     private static final String NULL_NAME = null;
     private static final String EMPTY_NAME = "";
     private static final String LETTER_NAME_1 = "test";
@@ -85,124 +79,94 @@
 
         when(mMockCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)).thenReturn(
                 DISPLAY_NAME_COLUMN);
-        when(mMockCursor.getColumnIndex(ContactsContract.RawContacts.SORT_KEY_PRIMARY)).thenReturn(
-                PRIMARY_KEY_COLUMN);
-        when(mMockCursor.getColumnIndex(ContactsContract.Data.MIMETYPE)).thenReturn(
-                MIMETYPE_COLUMN);
-        when(mMockCursor.getString(MIMETYPE_COLUMN)).thenReturn(EMPTY_MIME);
-        when(mMockCursor.getColumnIndex(ContactsContract.Data.LOOKUP_KEY)).thenReturn(
-                LOOK_UP_KEY_COLUMN);
-        when(mMockCursor.getString(LOOK_UP_KEY_COLUMN)).thenReturn(DEFAULT_LOOK_UP_KEY);
-        when(mMockCursor.getColumnIndex(PHONEBOOK_LABEL)).thenReturn(
-                PHONEBOOK_LABEL_COLUMN);
-
         when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(
                 mMockTelephonyManager);
         when(mMockTelephonyManager.getSimCountryIso()).thenReturn("");
 
-        when(mMockCursor.getString(PHONEBOOK_LABEL_COLUMN)).thenReturn("");
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn(NULL_NAME);
+        when(mMockCursor.getString(DISPLAY_NAME_COLUMN)).thenReturn(NULL_NAME);
         mNullName = Contact.fromCursor(mMockContext, mMockCursor);
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn(EMPTY_NAME);
+        when(mMockCursor.getString(DISPLAY_NAME_COLUMN)).thenReturn(EMPTY_NAME);
         mEmptyName = Contact.fromCursor(mMockContext, mMockCursor);
-
-        when(mMockCursor.getString(PHONEBOOK_LABEL_COLUMN)).thenReturn("T");
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn(LETTER_NAME_1);
+        when(mMockCursor.getString(DISPLAY_NAME_COLUMN)).thenReturn(LETTER_NAME_1);
         mLetterName1 = Contact.fromCursor(mMockContext, mMockCursor);
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn(LETTER_NAME_2);
+        when(mMockCursor.getString(DISPLAY_NAME_COLUMN)).thenReturn(LETTER_NAME_2);
         mLetterName2 = Contact.fromCursor(mMockContext, mMockCursor);
-
-        when(mMockCursor.getString(PHONEBOOK_LABEL_COLUMN)).thenReturn("#");
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn(DIGIT_NAME_1);
+        when(mMockCursor.getString(DISPLAY_NAME_COLUMN)).thenReturn(DIGIT_NAME_1);
         mDigitName1 = Contact.fromCursor(mMockContext, mMockCursor);
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn(DIGIT_NAME_2);
+        when(mMockCursor.getString(DISPLAY_NAME_COLUMN)).thenReturn(DIGIT_NAME_2);
         mDigitName2 = Contact.fromCursor(mMockContext, mMockCursor);
-
-        when(mMockCursor.getString(PHONEBOOK_LABEL_COLUMN)).thenReturn("");
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn(SPEC_CHAR_NAME);
+        when(mMockCursor.getString(DISPLAY_NAME_COLUMN)).thenReturn(SPEC_CHAR_NAME);
         mSpecCharName = Contact.fromCursor(mMockContext, mMockCursor);
     }
 
     @Test
     public void compareTo_TwoNullStrings_Equal() {
-        // NULL == NULL
         int compareResult = mNullName.compareTo(mNullName);
         assertEquals(COMPARE_RESULT_EQUAL, compareResult);
     }
 
     @Test
     public void compareTo_TwoEmptyStrings_Equal() {
-        // "" == NULL
         int compareResult = mEmptyName.compareTo(mEmptyName);
         assertEquals(COMPARE_RESULT_EQUAL, compareResult);
     }
 
     @Test
     public void compareTo_TwoLetterStrings_Larger() {
-        // "test" > "ta"
         int compareResult = mLetterName1.compareTo(mLetterName2);
         assertEquals(COMPARE_RESULT_LARGER, compareResult);
     }
 
     @Test
     public void compareTo_TwoDigitStrings_Smaller() {
-        // "123" < "321"
         int compareResult = mDigitName1.compareTo(mDigitName2);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_LetterAndDigitStrings_Smaller() {
-        // "test" < "123", because of Phonebook_label
         int compareResult = mLetterName1.compareTo(mDigitName1);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_LetterAndSpecialCharStrings_Smaller() {
-        // "test" <"-", because of Phonebook_label
         int compareResult = mLetterName1.compareTo(mSpecCharName);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_LetterAndEmptyStrings_Smaller() {
-        // "test" < "", because of Phonebook_label
         int compareResult = mLetterName1.compareTo(mEmptyName);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_LetterAndNullStrings_Smaller() {
-        // "test < NULL, because of Phonebook_label
         int compareResult = mLetterName1.compareTo(mNullName);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_DigitAndSpecialCharStrings_Smaller() {
-        // "123" < "-", because of Phonebook_label
         int compareResult = mDigitName1.compareTo(mSpecCharName);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_DigitAndEmptyStrings_Smaller() {
-        // "123" > "", because of Phonebook_label
         int compareResult = mDigitName1.compareTo(mEmptyName);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_DigitAndNullStrings_Smaller() {
-        // "123" < NULL, because of Phonebook_label
         int compareResult = mDigitName1.compareTo(mNullName);
         assertEquals(COMPARE_RESULT_SMALLER, compareResult);
     }
 
     @Test
     public void compareTo_SpecialCharAndEmptyStrings_Any() {
-        // "-" > ""
         int compareResult = mSpecCharName.compareTo(mEmptyName);
         assertThat(compareResult).isAnyOf(COMPARE_RESULT_SMALLER, COMPARE_RESULT_EQUAL,
                 COMPARE_RESULT_LARGER);
@@ -210,7 +174,6 @@
 
     @Test
     public void compareTo_SpecialCharAndNullStrings_Any() {
-        // "-" > NULL
         int compareResult = mSpecCharName.compareTo(mNullName);
         assertThat(compareResult).isAnyOf(COMPARE_RESULT_SMALLER, COMPARE_RESULT_EQUAL,
                 COMPARE_RESULT_LARGER);
@@ -218,97 +181,24 @@
 
     @Test
     public void compareTo_EmptyAndNullStrings_Equal() {
-        // "" == NULL
         int compareResult = mEmptyName.compareTo(mNullName);
         assertEquals(COMPARE_RESULT_EQUAL, compareResult);
     }
 
     @Test
     public void sortContactTest() {
-        List<Contact> expectedList = new ArrayList<>();
-        expectedList.add(mLetterName2);
-        expectedList.add(mLetterName1);
-        expectedList.add(mDigitName1);
-        expectedList.add(mDigitName2);
-        expectedList.add(mEmptyName);
-        expectedList.add(mSpecCharName);
-
+        List<Contact> sortResultList = new ArrayList<>();
+        sortResultList.add(mLetterName2);
+        sortResultList.add(mLetterName1);
+        sortResultList.add(mDigitName1);
+        sortResultList.add(mDigitName2);
+        sortResultList.add(mEmptyName);
+        sortResultList.add(mSpecCharName);
         List<Contact> contactList = new ArrayList<>();
-        contactList.add(mDigitName1);
-        contactList.add(mSpecCharName);
-        contactList.add(mLetterName1);
-        contactList.add(mEmptyName);
-        contactList.add(mLetterName2);
-        contactList.add(mDigitName2);
+        contactList.addAll(sortResultList);
 
+        Collections.shuffle(contactList);
         Collections.sort(contactList);
-        assertArrayEquals(expectedList.toArray(), contactList.toArray());
-    }
-
-    @Test
-    public void sortContactPrimaryTest() {
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn("tä");
-        Contact letterName3 = Contact.fromCursor(mMockContext, mMockCursor);
-
-        when(mMockCursor.getString(PRIMARY_KEY_COLUMN)).thenReturn("tb");
-        Contact letterName4 = Contact.fromCursor(mMockContext, mMockCursor);
-
-        List<Contact> expectedList = new ArrayList<>();
-        expectedList.add(mLetterName2);
-        expectedList.add(letterName3);
-        expectedList.add(letterName4);
-        expectedList.add(mLetterName1);
-        expectedList.add(mDigitName1);
-        expectedList.add(mDigitName2);
-        expectedList.add(mEmptyName);
-        expectedList.add(mSpecCharName);
-
-        List<Contact> contactList = new ArrayList<>();
-        contactList.add(mDigitName1);
-        contactList.add(letterName4);
-        contactList.add(mSpecCharName);
-        contactList.add(mLetterName1);
-        contactList.add(mEmptyName);
-        contactList.add(mLetterName2);
-        contactList.add(letterName3);
-        contactList.add(mDigitName2);
-
-        Collections.sort(contactList, (o1, o2) -> o1.compareBySortKeyPrimary(o2));
-        assertArrayEquals(expectedList.toArray(), contactList.toArray());
-    }
-
-    @Test
-    public void sortContactAlternativeTest() {
-        int alternativeColumnIndex = 20;
-        when(mMockCursor.getColumnIndex(ContactsContract.RawContacts.SORT_KEY_ALTERNATIVE))
-                .thenReturn(alternativeColumnIndex);
-        when(mMockCursor.getString(alternativeColumnIndex)).thenReturn("tä");
-        Contact letterName3 = Contact.fromCursor(mMockContext, mMockCursor);
-
-        when(mMockCursor.getString(alternativeColumnIndex)).thenReturn("tb");
-        Contact letterName4 = Contact.fromCursor(mMockContext, mMockCursor);
-
-        List<Contact> expectedList = new ArrayList<>();
-        expectedList.add(mLetterName2);
-        expectedList.add(letterName3);
-        expectedList.add(letterName4);
-        expectedList.add(mLetterName1);
-        expectedList.add(mDigitName1);
-        expectedList.add(mDigitName2);
-        expectedList.add(mEmptyName);
-        expectedList.add(mSpecCharName);
-
-        List<Contact> contactList = new ArrayList<>();
-        contactList.add(mDigitName1);
-        contactList.add(letterName4);
-        contactList.add(mSpecCharName);
-        contactList.add(mLetterName1);
-        contactList.add(mEmptyName);
-        contactList.add(mLetterName2);
-        contactList.add(letterName3);
-        contactList.add(mDigitName2);
-
-        Collections.sort(contactList, (o1, o2) -> o1.compareBySortKeyAlt(o2));
-        assertArrayEquals(expectedList.toArray(), contactList.toArray());
+        assertArrayEquals(sortResultList.toArray(), contactList.toArray());
     }
 }
diff --git a/car-telephony-common/tests/unittests/Android.bp b/car-telephony-common/tests/unittests/Android.bp
deleted file mode 100644
index 466cd41..0000000
--- a/car-telephony-common/tests/unittests/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-//############################################################
-// Car car-telephony-common test target.                              #
-//############################################################
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test {
-    name: "CarTelephonyLibTests",
-
-    srcs: ["src/**/*.java"],
-
-    static_libs: [
-        "androidx.test.core",
-        "androidx.test.rules",
-        "androidx.test.runner",
-        "androidx.test.ext.junit",
-        "truth-prebuilt",
-        "mockito-target-minus-junit4",
-    ],
-
-    instrumentation_for: "CarTelephonyLibTestsApp",
-}
diff --git a/car-telephony-common/tests/unittests/AndroidManifest.xml b/car-telephony-common/tests/unittests/AndroidManifest.xml
deleted file mode 100644
index 0cf6187..0000000
--- a/car-telephony-common/tests/unittests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<manifest
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.car.telephony.common.unittests">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="29" />
-
-    <application android:testOnly="false"
-                 android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.car.telephony.common"
-                     android:label="Car telephony common lib Unit Tests" />
-</manifest>
diff --git a/car-telephony-common/tests/unittests/readme.md b/car-telephony-common/tests/unittests/readme.md
deleted file mode 100644
index 258c653..0000000
--- a/car-telephony-common/tests/unittests/readme.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Unit test suite for car-telephony-common.
-
-```
-$ m CarTelephonyLibTestsApp
-$ adb install out/target/product/{product}/system/app/CarTelephonyLibTestsApp/CarTelephonyLibTestsApp.apk
-$ atest CarTelephonyLibTests
-```
\ No newline at end of file
diff --git a/car-telephony-common/tests/unittests/src/com/android/car/telephony/common/QueryParamTest.java b/car-telephony-common/tests/unittests/src/com/android/car/telephony/common/QueryParamTest.java
deleted file mode 100644
index 8189781..0000000
--- a/car-telephony-common/tests/unittests/src/com/android/car/telephony/common/QueryParamTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.telephony.common;
-
-import static com.android.car.telephony.common.QueryParam.QueryBuilder.AND;
-import static com.android.car.telephony.common.QueryParam.QueryBuilder.OR;
-import static com.android.car.telephony.common.QueryParam.QueryBuilder.ORDER_ASC;
-import static com.android.car.telephony.common.QueryParam.QueryBuilder.ORDER_DESC;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.Manifest;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.Data;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.car.telephony.common.QueryParam.QueryBuilder.Condition;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-public class QueryParamTest {
-    private static final Uri CONTENT_URI = Data.CONTENT_URI;
-    private static final String COLUMN_A = "COLUMN_A";
-    private static final String COLUMN_B = "COLUMN_B";
-
-    private static final String OP_EQUAL = "=";
-
-    private static final String STRING_VALUE = "STRING_VALUE";
-    private static final int INTEGER_VALUE = 100;
-
-    @Test
-    public void testContentUri() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        assertThat(queryParam.mUri).isEqualTo(CONTENT_URI);
-        assertThat(queryParam.mProjection).isNull();
-        assertThat(queryParam.mSelection).isNull();
-        assertThat(queryParam.mSelectionArgs).isEmpty();
-        assertThat(queryParam.mOrderBy).isEmpty();
-    }
-
-    @Test
-    public void testEmptyQueryParam() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-        builder.project(COLUMN_A);
-        builder.project(COLUMN_B);
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        assertThat(queryParam.mProjection).hasLength(2);
-        assertThat(Arrays.stream(queryParam.mProjection).anyMatch(COLUMN_A::equals)).isTrue();
-        assertThat(Arrays.stream(queryParam.mProjection).anyMatch(COLUMN_B::equals)).isTrue();
-    }
-
-    @Test
-    public void testBuildQueryParam() {
-        QueryParam expectedParams = new QueryParam(
-                Data.CONTENT_URI,
-                null,
-                Data.MIMETYPE + " = ? OR "
-                        + Data.MIMETYPE + " = ? OR "
-                        + Data.MIMETYPE + " = ?",
-                new String[]{
-                        Phone.CONTENT_ITEM_TYPE,
-                        StructuredName.CONTENT_ITEM_TYPE,
-                        StructuredPostal.CONTENT_ITEM_TYPE},
-                ContactsContract.Contacts.DISPLAY_NAME + " ASC",
-                Manifest.permission.READ_CONTACTS);
-
-        QueryParam builtQueryParam = new QueryParam.QueryBuilder(Data.CONTENT_URI)
-                .projectAll()
-                .where(Condition
-                        .is(Data.MIMETYPE, "=", Phone.CONTENT_ITEM_TYPE)
-                        .or(Data.MIMETYPE, "=", StructuredName.CONTENT_ITEM_TYPE)
-                        .or(Data.MIMETYPE, "=", StructuredPostal.CONTENT_ITEM_TYPE))
-                .orderAscBy(ContactsContract.Contacts.DISPLAY_NAME)
-                .checkPermission(Manifest.permission.READ_CONTACTS)
-                .toQueryParam();
-
-        assertThat(builtQueryParam.mUri).isEqualTo(expectedParams.mUri);
-        assertThat(builtQueryParam.mSelection).isEqualTo(expectedParams.mSelection);
-        assertThat(builtQueryParam.mProjection).isEqualTo(expectedParams.mProjection);
-        assertThat(Arrays.equals(builtQueryParam.mSelectionArgs, expectedParams.mSelectionArgs))
-                .isTrue();
-        assertThat(builtQueryParam.mOrderBy).isEqualTo(expectedParams.mOrderBy);
-        assertThat(builtQueryParam.mPermission).isEqualTo(expectedParams.mPermission);
-    }
-
-    @Test
-    public void testBuildProjection_selectAll() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-        builder.projectAll();
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        assertThat(queryParam.mProjection).isNull();
-    }
-
-    @Test
-    public void testBuildSelection() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-        builder.where(Condition.is(COLUMN_A, OP_EQUAL, STRING_VALUE));
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        assertThat(queryParam.mSelection)
-                .isEqualTo(Condition.toSelectionString(COLUMN_A, OP_EQUAL));
-        assertThat(queryParam.mSelectionArgs[0]).isEqualTo(STRING_VALUE);
-    }
-
-    @Test
-    public void testBuildSelection_andCondition() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-        builder.where(Condition
-                .is(COLUMN_A, OP_EQUAL, STRING_VALUE)
-                .and(COLUMN_B, OP_EQUAL, INTEGER_VALUE));
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        String expectedSelection = Condition.toSelectionString(COLUMN_A, OP_EQUAL);
-        expectedSelection += Condition.wrapWithSpaces(AND)
-                + Condition.toSelectionString(COLUMN_B, OP_EQUAL);
-        assertThat(queryParam.mSelection).isEqualTo(expectedSelection);
-        assertThat(queryParam.mSelectionArgs).hasLength(2);
-        assertThat(queryParam.mSelectionArgs[0]).isEqualTo(STRING_VALUE);
-        assertThat(queryParam.mSelectionArgs[1]).isEqualTo(Integer.toString(INTEGER_VALUE));
-    }
-
-    @Test
-    public void testBuildSelection_orCondition() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-        builder.where(Condition
-                .is(COLUMN_A, OP_EQUAL, STRING_VALUE)
-                .or(COLUMN_B, OP_EQUAL, INTEGER_VALUE));
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        String expectedSelection = Condition.toSelectionString(COLUMN_A, OP_EQUAL);
-        expectedSelection += Condition.wrapWithSpaces(OR)
-                + Condition.toSelectionString(COLUMN_B, OP_EQUAL);
-        assertThat(queryParam.mSelection).isEqualTo(expectedSelection);
-        assertThat(queryParam.mSelectionArgs).hasLength(2);
-        assertThat(queryParam.mSelectionArgs[0]).isEqualTo(STRING_VALUE);
-        assertThat(queryParam.mSelectionArgs[1]).isEqualTo(Integer.toString(INTEGER_VALUE));
-    }
-
-    @Test
-    public void testOrderAscBy() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-        builder.orderAscBy(COLUMN_A);
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        String expectedOrder = COLUMN_A + " " + ORDER_ASC;
-        assertThat(queryParam.mOrderBy).isEqualTo(expectedOrder);
-    }
-
-    @Test
-    public void testOrderBy_twoOrder() {
-        QueryParam.QueryBuilder builder = new QueryParam.QueryBuilder(CONTENT_URI);
-        builder.orderAscBy(COLUMN_A);
-        builder.orderDescBy(COLUMN_B);
-
-        QueryParam queryParam = builder.toQueryParam();
-
-        String expectedOrder = COLUMN_A + " " + ORDER_ASC;
-        expectedOrder += "," + COLUMN_B + " " + ORDER_DESC;
-        assertThat(queryParam.mOrderBy).isEqualTo(expectedOrder);
-    }
-}
-
diff --git a/car-theme-lib/Android.bp b/car-theme-lib/Android.bp
index d2b8772..30c780c 100644
--- a/car-theme-lib/Android.bp
+++ b/car-theme-lib/Android.bp
@@ -14,10 +14,6 @@
 // limitations under the License.
 //
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-theme-lib",
 
@@ -25,6 +21,8 @@
 
     resource_dirs: ["res"],
 
+    static_libs: ["androidx.car_car"],
+
     optimize: {
         enabled: false,
     },
diff --git a/car-ui-lib/.gitignore b/car-ui-lib/.gitignore
index 57df0a4..cedb234 100644
--- a/car-ui-lib/.gitignore
+++ b/car-ui-lib/.gitignore
@@ -13,9 +13,3 @@
 
 # Python
 *.pyc
-
-# Android studio's layout inspector captures
-captures/
-
-# A file created when launching android emulators
-read-snapshot.txt
diff --git a/car-ui-lib/Android.bp b/car-ui-lib/Android.bp
index 28ef55b..3506a3e 100644
--- a/car-ui-lib/Android.bp
+++ b/car-ui-lib/Android.bp
@@ -1,3 +1,5 @@
+
+//
 // Copyright (C) 2019 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,34 +14,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "car-ui-lib",
-
-    sdk_version: "current",
+    sdk_version: "system_current",
     min_sdk_version: "28",
-    target_sdk_version: "30",
-
-    manifest: "car-ui-lib/src/main/AndroidManifest.xml",
-    srcs: ["car-ui-lib/src/main/java/**/*.java"],
-    resource_dirs: [
-        "car-ui-lib/src/main/res",
-        "car-ui-lib/src/main/res-overlayable",
-        "car-ui-lib/src/main/res-private"
-    ],
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
     optimize: {
-        proguard_flags_files: [
-            "car-ui-lib/proguard-rules.pro",
-            "car-ui-lib/proguard-rules-platform.pro",
-        ],
+        enabled: false,
     },
-    libs: [
-        "android.car-stubs",
-        "car-ui-lib-oem-apis",
-    ],
+    libs: ["android.car-stubs"],
     static_libs: [
         "androidx.annotation_annotation",
         "androidx.appcompat_appcompat",
@@ -48,18 +32,13 @@
         "androidx.recyclerview_recyclerview",
         "androidx-constraintlayout_constraintlayout-solver",
         "androidx.asynclayoutinflater_asynclayoutinflater",
-        "car-rotary-lib",
     ],
 }
 
 android_library {
     name: "car-ui-lib-testing-support",
-
-    sdk_version: "current",
+    sdk_version: "system_current",
     min_sdk_version: "28",
-    target_sdk_version: "30",
-
-    manifest: "car-ui-lib/src/main/AndroidManifest.xml",
     srcs: [
         "tests/baselayouttests/src/**/*.java",
     ],
@@ -71,67 +50,4 @@
         "car-ui-lib",
         "Robolectric_all-target",
     ],
-}
-
-android_test {
-    name: "CarUILibUnitTests",
-    certificate: "platform",
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.car-stubs",
-        "android.test.mock.stubs"
-    ],
-    manifest: "car-ui-lib/src/androidTest/AndroidManifest.xml",
-    resource_dirs: ["car-ui-lib/src/androidTest/res"],
-    // Include all test java files.
-    srcs: ["car-ui-lib/src/androidTest/java/**/*.java"],
-    static_libs: [
-        "androidx.test.rules",
-        "androidx.test.espresso.core",
-        "androidx.test.espresso.contrib",
-        "androidx.test.ext.junit",
-        "car-ui-lib",
-        "platform-test-annotations",
-        "mockito-target-inline-minus-junit4",
-        "truth-prebuilt",
-    ],
-    jni_libs: [
-        // For mockito extended
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-    ],
-
-    platform_apis: true,
-    test_suites: ["device-tests"],
-}
-
-android_app {
-    name: "PaintBooth",
-
-    manifest: "paintbooth/src/main/AndroidManifest.xml",
-    srcs: [
-        "paintbooth/src/**/*.java",
-        "paintbooth/src/**/*.kt",
-    ],
-    resource_dirs: [
-        "paintbooth/src/main/res",
-        "paintbooth/src/main/res-overlayable",
-        "paintbooth/src/main/res-public",
-    ],
-
-    required: ["allowed_privapp_com.android.car.ui.paintbooth"],
-
-    libs: ["android.car-stubs"],
-    static_libs: [
-        "car-ui-lib",
-        "guava",
-        "gson-prebuilt-jar",
-    ],
-
-    platform_apis: true,
-    certificate: "platform",
-    privileged: true,
-
-    export_package_resources: true,
-}
+}
\ No newline at end of file
diff --git a/car-ui-lib/AndroidManifest-gradle.xml b/car-ui-lib/AndroidManifest-gradle.xml
new file mode 100644
index 0000000..36ffbb8
--- /dev/null
+++ b/car-ui-lib/AndroidManifest-gradle.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.car.ui">
+    <application>
+        <provider
+            android:name="com.android.car.ui.core.CarUiInstaller"
+            android:authorities="${applicationId}.CarUiInstaller"
+            android:exported="false"/>
+    </application>
+</manifest>
diff --git a/car-ui-lib/AndroidManifest.xml b/car-ui-lib/AndroidManifest.xml
new file mode 100644
index 0000000..5136dc2
--- /dev/null
+++ b/car-ui-lib/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.car.ui">
+    <uses-sdk
+        android:minSdkVersion="14"
+        android:targetSdkVersion="28" />
+
+    <application>
+        <provider
+            android:name="com.android.car.ui.core.CarUiInstaller"
+            android:authorities="${applicationId}.CarUiInstaller"
+            android:directBootAware="true"
+            android:exported="false"
+            android:process="@string/car_ui_installer_process_name"/>
+    </application>
+</manifest>
diff --git a/car-ui-lib/AndroidTest.xml b/car-ui-lib/AndroidTest.xml
deleted file mode 100644
index cc3c463..0000000
--- a/car-ui-lib/AndroidTest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<!-- This AndroidTest.xml is mostly autogenerated, except for the
-     line adding -no-window-animation. If you remove this file, you
-     can find the autogenerated version in
-     $OUT/testcases/CarUILibUnitTests/CarUILibUnitTests.config.
-     Although not explicitly referenced from our Android.bp, it is
-     picked up and used instead of the autogenerated version as long
-     as it has the name "AndroidTest.xml".
-
-     -no-window-animation is needed because of the new sparkle
-     animation on ripples. It causes espresso's
-     onView(...).perform(click()) to fail, because normally it
-     sends a touch down event, waits for idle, then sends a touch
-     up event. The sparkle animation causes the system to never be
-     idle, and thus the button will just be held down forever. -->
-<configuration description="Runs Chassis Test Cases.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-instrumentation" />
-
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CarUILibUnitTests.apk" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.car.ui.test" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="instrumentation-arg" key="thisisignored" value="thisisignored --no-window-animation" />
-    </test>
-</configuration>
diff --git a/car-ui-lib/OWNERS b/car-ui-lib/OWNERS
index 9656c1f..aef5c65 100644
--- a/car-ui-lib/OWNERS
+++ b/car-ui-lib/OWNERS
@@ -1,11 +1,9 @@
 # People who can approve changes for submission.
-set noparent
-
-# TLs
-stenning@google.com
 
 # Engs
 colefaust@google.com
-farivar@google.com
 priyanksingh@google.com
 rampara@google.com
+ckoessler@google.com
+
+
diff --git a/car-ui-lib/README.md b/car-ui-lib/README.md
index 8cb8c39..282f8e1 100644
--- a/car-ui-lib/README.md
+++ b/car-ui-lib/README.md
@@ -2,60 +2,14 @@
 Components and resources designed to increase Automotive UI consistency between
 GAS (Google Automotive Services) apps, system-apps and OEM developed apps.
 
-See: go/aae-chassis-site
+See: go/aae-carui
 
 ## Content
 
 Components and resources designed to be configured by means of RRO (Runtime
 Resource Overlays) by OEMs.
 
-## Developing
-
-Project layout:
-* __car-ui-lib__: The main library that is statically linked into applications
-* __paintbooth__: A test application that contains demos of all the car-ui components
-* __referencedesign__: An RRO applied to internal google targets that does some minor car-ui customizations. It's used to make changes to car-ui that would cause backwards compatability issues if we were to create them directly in the library. It can also serve as an example RRO for OEMs, and should be kept reasonably functional and up-to-date because we use it actively.
-
-### Building and running PaintBooth
-
-While car-ui-lib can be developed by using aidegen, it's probably easier to use Android Studio with the gradle build files. To do this, select "Open an existing Android Studio project", then navigating to the (outer) car-ui-lib folder:
-
-![Open an existing Android Studio project](documentation/images/open_existing_android_studio_project.png)
-![Navigating to car-ui-lib](documentation/images/navigating_to_car_ui_lib.png)
-
-If this is your first time using Android Studio, it may ask you to install an SDK. Go ahead and do that.
-
-It may ask if you want to generate the gradle wrapper files, select "Yes". Wait for it to finish indexing, and then you should see car-ui-lib and PaintBooth projects in the project pane on the left. Make sure your project view is set to "Android" mode, as opposed to the regular "Project" mode:
-
-![Android project view](documentation/images/android_project_view.png)
-
-To launch paintbooth, start a car emulator or connect a device, make sure the PaintBooth module and "Virtual Device" is selected in your Android Studio toolbar, then click the green arrow:
-
-![Launching Paintbooth](documentation/images/launch_paintbooth.png)
-
-If it launches a LeakCanary activity instead of PaintBooth, either exit LeakCanary and launch PaintBooth as normal through the car's launcher, or click on the PaintBooth module > Edit configurations > Change "Launch: Default Activity" to "Specified Activity", and enter `com.android.car.ui.paintbooth.MainActivity`.
-
-### Building and running the shared library
-
-Setting up the shared library is mostly the same as setting up paintbooth. However, when you attempt to install the shared library, Android Studio will complain it can't launch any activity (despite the installation succeeding), and your changes won't properly show up. To fix these issues, edit the shared library configuration, change the "Launch:" option to launch nothing, and check the "Always install with package manager (disables deployment optimizations on Android 11 and higher)" button. This checkbox shouldn't be required after b/188220380 is fixed.
-
-![Shared library setup](documentation/images/shared_library_setup.png)
-
-### Running tests
-
-Once you've set up paintbooth as described above, just open one of the test classes in car-ui-lib > java > com.android.car.ui (androidTest) and click the green arrow next to one of the tests to run it:
-
-![Running tests](documentation/images/running_tests.png)
-
-The tests can also be run from the command line via `atest CarUILibUnitTests`, but that's much slower than running them through Android Studio.
-
-### Getting coverage reports
-
-Coverage reports must be generated from the command line as opposed to Android Studio. Run `./gradlew createDebugCoverageReport` to generate a coverate report under `packages/apps/Car/libs/car-ui-lib/car-ui-lib/build/reports/coverage/debug/index.html`. Currently, you must first run `adb shell am switch-user 0` due to b/183903243
-
-To only run certain tests, run `./gradlew clean createDebugCoverageReport -Pandroid.testInstrumentationRunnerArguments.tests_regex=CarUiIme*`, changing the regex as necessary.
-
-## Updating Google3
+## Updating
 
 This library is developed in Gerrit and copied as source to Google3 using
 Copybara (go/copybara).
@@ -66,13 +20,9 @@
 Here is the process for updating this library:
 
 1. Develop, test and upload changes to Gerrit
-2. On Google3, run `./update.sh review <cl>` (with <cl> being your Gerrit CL #) and test your changes
+2. On Google3, run './update.sh review <cl>' (with <cl> being your Gerrit CL #) and test your changes
 3. Repeat #1 and #2 until your changes look okay on both places.
 4. Back on Gerrit, submit your CL.
-5. Back on Google3, run `./update.sh manual` submit
+5. Back on Google3, run './update.sh manual' submit
 
 TODO: Automate this process using CaaS (in progress)
-
-If you're just updating the current state of car-ui-lib, and not testing a review that has yet to be submitted, the process can be simplified to:
-
-`/google/data/ro/teams/copybara/copybara /google/src/head/depot/google3/third_party/java_src/android_libs/car_chassis_lib/copy.bara.sky default`
diff --git a/car-ui-lib/TEST_MAPPING b/car-ui-lib/TEST_MAPPING
index 568ac71..dd3e2be 100644
--- a/car-ui-lib/TEST_MAPPING
+++ b/car-ui-lib/TEST_MAPPING
@@ -1,7 +1,7 @@
 {
-  "carui-presubmit": [
+  "presubmit": [
     {
-      "name": "CarUILibUnitTests"
+      "name": "generate-resources"
     }
   ]
 }
diff --git a/car-ui-lib/build.gradle b/car-ui-lib/build.gradle
index da2a961..c230345 100644
--- a/car-ui-lib/build.gradle
+++ b/car-ui-lib/build.gradle
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -23,12 +23,7 @@
 
     }
     dependencies {
-        // Before upgrading this version, make sure you can close android
-        // studio, run git clean -fxd, and then reopen this folder in android
-        // studio and have it work. Sometimes android studio's built in gradle
-        // wrapper seems to lag behind the version required by the android
-        // plugin.
-        classpath 'com.android.tools.build:gradle:4.1.3'
+        classpath 'com.android.tools.build:gradle:3.6.1'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -40,8 +35,49 @@
         google()
         jcenter()
     }
+    buildDir = "/tmp/car-ui-build/${rootProject.name}/${project.name}"
     tasks.withType(JavaCompile) {
         options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
     }
 }
 
+// Library-level build file
+
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 29
+
+    defaultConfig {
+        minSdkVersion 28
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest-gradle.xml'
+            java.srcDirs = ['src']
+            res.srcDirs = ['res']
+        }
+    }
+}
+
+dependencies {
+    api 'androidx.annotation:annotation:1.1.0'
+    api 'androidx.appcompat:appcompat:1.1.0'
+    api 'androidx.constraintlayout:constraintlayout:1.1.3'
+    api 'androidx.preference:preference:1.1.0'
+    api 'androidx.recyclerview:recyclerview:1.0.0'
+    api 'androidx.core:core:1.2.0'
+    implementation 'com.android.support:support-annotations:28.0.0'
+
+    // This is the gradle equivalent of the libs: ["android.car"] in our Android.bp
+    implementation files('../../../../../out/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/classes.jar')
+}
diff --git a/car-ui-lib/car-rotary-lib/.gitignore b/car-ui-lib/car-rotary-lib/.gitignore
deleted file mode 100644
index 42afabf..0000000
--- a/car-ui-lib/car-rotary-lib/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
\ No newline at end of file
diff --git a/car-ui-lib/car-rotary-lib/Android.bp b/car-ui-lib/car-rotary-lib/Android.bp
deleted file mode 100644
index f701cf5..0000000
--- a/car-ui-lib/car-rotary-lib/Android.bp
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_library {
-    name: "car-rotary-lib",
-
-    sdk_version: "current",
-    min_sdk_version: "28",
-    target_sdk_version: "30",
-
-    manifest: "src/main/AndroidManifest.xml",
-    srcs: ["src/main/java/**/*.java"],
-    resource_dirs: [
-        "src/main/res",
-        "src/main/res-overlayable",
-    ],
-    optimize: {
-        enabled: false,
-    },
-    static_libs: [
-        "androidx.annotation_annotation",
-        "androidx.recyclerview_recyclerview",
-    ],
-    apex_available: [
-        "com.android.permission",
-        "//apex_available:platform",
-    ],
-}
-
-android_test {
-    name: "CarRotaryLibUnitTests",
-    certificate: "platform",
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.car-stubs",
-        "android.test.mock.stubs"
-    ],
-    manifest: "src/androidTest/AndroidManifest.xml",
-    resource_dirs: ["src/androidTest/res"],
-    // Include all test java files.
-    srcs: ["src/androidTest/java/**/*.java"],
-    static_libs: [
-        "androidx.test.rules",
-        "androidx.test.espresso.core",
-        "androidx.test.espresso.contrib",
-        "androidx.test.ext.junit",
-        "car-rotary-lib",
-        "car-ui-lib",
-        "platform-test-annotations",
-        "mockito-target-inline-minus-junit4",
-        "truth-prebuilt",
-    ],
-    jni_libs: [
-        // For mockito extended
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-    ],
-
-    platform_apis: true,
-    test_suites: ["device-tests"],
-}
diff --git a/car-ui-lib/car-rotary-lib/OWNERS b/car-ui-lib/car-rotary-lib/OWNERS
deleted file mode 100644
index 0439586..0000000
--- a/car-ui-lib/car-rotary-lib/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/packages/apps/Car/RotaryController:/OWNERS
\ No newline at end of file
diff --git a/car-ui-lib/car-rotary-lib/TEST_MAPPING b/car-ui-lib/car-rotary-lib/TEST_MAPPING
deleted file mode 100644
index b3f8ecbc..0000000
--- a/car-ui-lib/car-rotary-lib/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "carrotarylib-presubmit": [
-    {
-      "name": "CarRotaryLibUnitTests"
-    }
-  ]
-}
diff --git a/car-ui-lib/car-rotary-lib/build.gradle b/car-ui-lib/car-rotary-lib/build.gradle
deleted file mode 100644
index 0784ed6..0000000
--- a/car-ui-lib/car-rotary-lib/build.gradle
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Library-level build file
-
-apply plugin: 'com.android.library'
-apply plugin: 'jacoco'
-
-android {
-    compileSdkVersion 30
-
-    defaultConfig {
-        minSdkVersion 28
-        targetSdkVersion 30
-        versionCode 1
-        versionName "1.0"
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-        testApplicationId "com.android.car.rotary.test"
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
-    }
-
-    testOptions {
-        unitTests {
-            includeAndroidResources = true
-        }
-        animationsDisabled = true
-    }
-
-    buildTypes {
-        debug {
-            testCoverageEnabled = true
-        }
-    }
-
-    project.gradle.taskGraph.whenReady {
-        connectedDebugAndroidTest {
-            ignoreFailures = true
-        }
-    }
-
-    // This is the gradle equivalent of the libs: ["android.car"] in the Android.bp
-    useLibrary 'android.car'
-
-    useLibrary 'android.test.runner'
-    useLibrary 'android.test.base'
-    useLibrary 'android.test.mock'
-}
-
-dependencies {
-    api 'androidx.annotation:annotation:1.2.0'
-    api 'androidx.recyclerview:recyclerview:1.2.0'
-
-    // The tests use a CarUiRecyclerView
-    androidTestImplementation project(':car-ui-lib')
-    androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
-    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.3.0'
-    androidTestImplementation "com.google.truth:truth:1.1.2"
-    androidTestImplementation "androidx.test.ext:junit:1.1.2"
-    androidTestImplementation "org.mockito:mockito-core:2.19.0"
-    androidTestImplementation 'androidx.test:runner:1.3.0'
-    androidTestImplementation 'androidx.test:rules:1.3.0'
-    // This is needed to be able to spy certain classes with Mockito
-    // It's major/minor version must match Mockito's.
-    androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito-inline:2.19.0'
-    // Required for instrumented tests
-    androidTestImplementation 'com.android.support:support-annotations:28.0.0'
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/AndroidManifest.xml b/car-ui-lib/car-rotary-lib/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 977e4be..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2021 Google Inc.
-
-    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.
--->
-<!-- The package name shouldn't be "com.android.car.ui.test" because it's already defined in
-     car-ui-lib. -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.car.rotary.test">
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-        <activity android:name="com.android.car.ui.FocusAreaTestActivity" />
-        <activity android:name="com.android.car.ui.FocusParkingViewTestActivity" />
-        <activity android:name="com.android.car.ui.utils.ViewUtilsTestActivity" />
-    </application>
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.car.rotary.test"
-        android:label="Car Rotary Lib Test Cases">
-    </instrumentation>
-</manifest>
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
deleted file mode 100644
index 400c946..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import static android.view.View.FOCUS_DOWN;
-import static android.view.View.FOCUS_LEFT;
-import static android.view.View.FOCUS_RIGHT;
-import static android.view.View.FOCUS_UP;
-import static android.view.View.LAYOUT_DIRECTION_LTR;
-import static android.view.View.LAYOUT_DIRECTION_RTL;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
-
-import static com.android.car.ui.RotaryCache.CACHE_TYPE_DISABLED;
-import static com.android.car.ui.RotaryCache.CACHE_TYPE_NEVER_EXPIRE;
-import static com.android.car.ui.utils.RotaryConstants.ACTION_NUDGE_SHORTCUT;
-import static com.android.car.ui.utils.RotaryConstants.ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_BOTTOM_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_LEFT_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_RIGHT_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_TOP_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.NUDGE_DIRECTION;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.Bundle;
-import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.Button;
-
-import androidx.annotation.NonNull;
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.rotary.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/** Unit tests for {@link FocusArea} not in touch mode. */
-// TODO(b/187553946): Improve this test.
-public class FocusAreaTest {
-    private static final long WAIT_TIME_MS = 3000;
-
-    @Rule
-    public ActivityTestRule<FocusAreaTestActivity> mActivityRule =
-            new ActivityTestRule<>(FocusAreaTestActivity.class);
-
-    private FocusAreaTestActivity mActivity;
-    private TestFocusArea mFocusArea1;
-    private TestFocusArea mFocusArea2;
-    private TestFocusArea mFocusArea3;
-    private TestFocusArea mFocusArea4;
-    private TestFocusArea mFocusArea5;
-    private TestFocusArea mFocusArea6;
-    private FocusParkingView mFpv;
-    private View mView1;
-    private Button mButton1;
-    private View mView2;
-    private View mDefaultFocus2;
-    private View mView3;
-    private View mNudgeShortcut3;
-    private View mView4;
-    private View mView5;
-    private Button mButton5;
-    private View mView6;
-    private View mNudgeShortcut6;
-
-    @Before
-    public void setUp() {
-        mActivity = mActivityRule.getActivity();
-        mFocusArea1 = mActivity.findViewById(R.id.focus_area1);
-        mFocusArea2 = mActivity.findViewById(R.id.focus_area2);
-        mFocusArea3 = mActivity.findViewById(R.id.focus_area3);
-        mFocusArea4 = mActivity.findViewById(R.id.focus_area4);
-        mFocusArea5 = mActivity.findViewById(R.id.focus_area5);
-        mFocusArea6 = mActivity.findViewById(R.id.focus_area6);
-        mFpv = mActivity.findViewById(R.id.fpv);
-        mView1 = mActivity.findViewById(R.id.view1);
-        mButton1 = mActivity.findViewById(R.id.button1);
-        mView2 = mActivity.findViewById(R.id.view2);
-        mDefaultFocus2 = mActivity.findViewById(R.id.default_focus2);
-        mView3 = mActivity.findViewById(R.id.view3);
-        mNudgeShortcut3 = mActivity.findViewById(R.id.nudge_shortcut3);
-        mView4 = mActivity.findViewById(R.id.view4);
-        mView5 = mActivity.findViewById(R.id.view5);
-        mButton5 = mActivity.findViewById(R.id.button5);
-        mView6 = mActivity.findViewById(R.id.view6);
-        mNudgeShortcut6 = mActivity.findViewById(R.id.nudge_shortcut6);
-    }
-
-    @Test
-    public void testDrawMethodsCalled() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mFocusArea1.enableForegroundHighlight();
-            mFocusArea2.enableForegroundHighlight();
-            mFocusArea1.setOnDrawCalled(false);
-            mFocusArea1.setDrawCalled(false);
-            mFocusArea2.setOnDrawCalled(false);
-            mFocusArea2.setDrawCalled(false);
-
-            mView2.requestFocus();
-            mView2.post(() -> latch.countDown());
-        });
-
-        // The methods should be called when a FocusArea gains or loses focus.
-        assertDrawMethodsCalled(mFocusArea1, latch);
-        assertDrawMethodsCalled(mFocusArea2, latch);
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionNudgeShortcut_legacy() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView3.post(() -> {
-            mView3.requestFocus();
-            mView3.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView3.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea3.post(() -> {
-            // Nudge to the nudgeShortcut view.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
-            mFocusArea3.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea3.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mNudgeShortcut3.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mView3.post(() -> {
-            mView3.requestFocus();
-            mView3.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView3.isFocused()).isTrue();
-
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea3.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea3.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea3.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // nudgeShortcutDirection doesn't match. The focus should stay the same.
-        assertThat(mView3.isFocused()).isTrue();
-
-        CountDownLatch latch5 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch5.countDown());
-        });
-        latch5.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch6 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
-            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea1.post(() -> latch6.countDown());
-        });
-        latch6.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // No nudgeShortcut view in the current FocusArea. The focus should stay the same.
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionNudgeShortcut_new()throws Exception  {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView6.post(() -> {
-            mView6.requestFocus();
-            mView6.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView6.isFocused()).isTrue();
-
-        Bundle arguments = new Bundle();
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFocusArea6.post(() -> {
-            // Nudge to the nudgeShortcut view.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
-            mFocusArea6.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea6.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mNudgeShortcut6.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mView6.post(() -> {
-            mView6.requestFocus();
-            mView6.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView6.isFocused()).isTrue();
-
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea6.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea6.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea6.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // No shortcut specified for given direction. The focus should stay the same.
-        assertThat(mView6.isFocused()).isTrue();
-
-        CountDownLatch latch5 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch5.countDown());
-        });
-        latch5.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch6 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
-            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea1.post(() -> latch6.countDown());
-        });
-        latch6.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // No shortcut specified for any direction. The focus should stay the same.
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionNudgeShortcut_programmatic()throws Exception  {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView6.post(() -> {
-            // Programmatically change the nudge shortcut from right to left.
-            mFocusArea6.setNudgeShortcut(FOCUS_RIGHT, null);
-            mFocusArea6.setNudgeShortcut(FOCUS_LEFT, mNudgeShortcut3);
-
-            mView6.requestFocus();
-            mView6.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView6.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea6.post(() -> {
-            // Nudge to the nudgeShortcut view.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_LEFT);
-            mFocusArea6.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea6.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mNudgeShortcut3.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mView6.post(() -> {
-            mView6.requestFocus();
-            mView6.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView6.isFocused()).isTrue();
-
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea6.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
-            mFocusArea6.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea6.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // No shortcut specified for given direction. The focus should stay the same.
-        assertThat(mView6.isFocused()).isTrue();
-
-        CountDownLatch latch5 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch5.countDown());
-        });
-        latch5.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch6 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
-            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
-            mFocusArea1.post(() -> latch6.countDown());
-        });
-        latch6.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // No shortcut specified for any direction. The focus should stay the same.
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionFocus() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            mFocusArea1.performAccessibilityAction(ACTION_FOCUS, null);
-            mFocusArea1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
-            mFocusArea2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // It should focus on the default or the first view in the FocusArea.
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionFocus_enabledFocusCache() throws Exception {
-        RotaryCache cache =
-                new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mButton1.post(() -> {
-            mFocusArea1.setRotaryCache(cache);
-            mButton1.requestFocus();
-            mButton1.post(() -> latch1.countDown());
-
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView2.post(() -> {
-            mView2.requestFocus();
-            mView2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView2.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            mFocusArea1.performAccessibilityAction(ACTION_FOCUS, null);
-            mFocusArea1.post(() -> latch3.countDown());
-
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // With cache, it should focus on the lastly focused view in the FocusArea.
-        assertThat(mButton1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionFocus_disabledFocusCache() throws Exception {
-        RotaryCache cache = new RotaryCache(CACHE_TYPE_DISABLED, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mButton1.post(() -> {
-            mFocusArea1.setRotaryCache(cache);
-            mButton1.requestFocus();
-            mButton1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView2.post(() -> {
-            mView2.requestFocus();
-            mView2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView2.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            mFocusArea1.performAccessibilityAction(ACTION_FOCUS, null);
-            mFocusArea1.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // Without cache, it should focus on the default or the first view in the FocusArea.
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionFocus_lastFocusedViewRemoved()
-            throws Exception {
-        // Focus on mDefaultFocus2 in mFocusArea2, then mView1 in mFocusArea1.
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mDefaultFocus2.post(() -> {
-            mDefaultFocus2.requestFocus();
-            mDefaultFocus2.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            // Remove mDefaultFocus2, then Perform ACTION_FOCUS on mFocusArea2.
-            mFocusArea2.removeView(mDefaultFocus2);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
-            mFocusArea2.post(() -> latch3.countDown());
-        });
-        // mView2 in mFocusArea2 should get focused.
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView2.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_enabledCache()
-            throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mButton1.post(() -> {
-            RotaryCache cache1 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea1.setRotaryCache(cache1);
-            RotaryCache cache2 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea2.setRotaryCache(cache2);
-
-            // Focus on the second view in mFocusArea1.
-            mButton1.requestFocus();
-            mButton1.post(() -> latch1.countDown());
-
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea2.post(() -> {
-            // Nudge to mFocusArea2.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            // Nudge back. It should focus on the cached view (mButton1) in the cached
-            // FocusArea (mFocusArea1).
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea2.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            // Nudge back. It should fail and the focus should stay the same because of one-way
-            // nudge history.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea1.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_mixedCache()
-            throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mButton1.post(() -> {
-            // Disabled FocusCache but enabled FocusAreaCache.
-            RotaryCache cache1 =
-                    new RotaryCache(CACHE_TYPE_DISABLED, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea1.setRotaryCache(cache1);
-            RotaryCache cache2 =
-                    new RotaryCache(CACHE_TYPE_DISABLED, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea2.setRotaryCache(cache2);
-
-            // Focus on the second view in mFocusArea1.
-            mButton1.requestFocus();
-            mButton1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea2.post(() -> {
-            // Nudge to mFocusArea2.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            // Nudge back. Since FocusCache is disabled, it should focus on the default or the first
-            // view (mView1) in the cached FocusArea (mFocusArea1).
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea2.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_mixedCache2()
-            throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mButton1.post(() -> {
-            // Enabled FocusCache but disabled FocusAreaCache.
-            RotaryCache cache1 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_DISABLED, 0);
-            mFocusArea1.setRotaryCache(cache1);
-            RotaryCache cache2 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_DISABLED, 0);
-            mFocusArea2.setRotaryCache(cache2);
-
-            // Focus on the second view in mFocusArea1, then nudge to mFocusArea2.
-            mButton1.requestFocus();
-            mButton1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea2.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            // Nudge back. Since FocusAreaCache is disabled, nudge should fail and the focus should
-            // stay the same.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea2.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_specifiedTarget()
-            throws Exception {
-        // Nudge to specified FocusArea.
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView4.post(() -> {
-            mView4.requestFocus();
-            mView4.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView4.isFocused()).isTrue();
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea4.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_LEFT);
-            mFocusArea4.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea4.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        // Direction doesn't match specified FocusArea. The focus should stay the same.
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mView4.post(() -> {
-            mView4.requestFocus();
-            mView4.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView4.isFocused()).isTrue();
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea4.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea4.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea4.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView4.isFocused()).isTrue();
-
-        // The FocusArea doesn't specify a target FocusArea. The focus should stay the same.
-        CountDownLatch latch5 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch5.countDown());
-        });
-        latch5.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-        CountDownLatch latch6 = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_LEFT);
-            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea1.post(() -> latch6.countDown());
-        });
-        latch6.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testDefaultFocusOverridesHistory_override() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView2.post(() -> {
-            RotaryCache cache =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea2.setRotaryCache(cache);
-            mFocusArea2.setDefaultFocusOverridesHistory(true);
-            mView2.requestFocus();
-            mView2.post(() -> latch1.countDown());
-
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView2.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
-            mFocusArea2.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // The focused view should be the default focus view rather than the cached view.
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testDefaultFocusOverridesHistory_notOverride() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView2.post(() -> {
-            RotaryCache cache =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea2.setRotaryCache(cache);
-            mView2.requestFocus();
-            mView2.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView2.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
-            mFocusArea2.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // The focused view should be the cached view rather than the default focus view.
-        assertThat(mView2.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testClearFocusAreaHistoryWhenRotating_clear() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            RotaryCache cache1 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea1.setRotaryCache(cache1);
-            mFocusArea1.setClearFocusAreaHistoryWhenRotating(true);
-            RotaryCache cache2 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea2.setRotaryCache(cache2);
-            mFocusArea2.setClearFocusAreaHistoryWhenRotating(true);
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea2.post(() -> {
-            // Nudging down from mFocusArea1 to mFocusArea2.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mView2.post(() -> {
-            // Rotate.
-            mView2.requestFocus();
-            mView2.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView2.isFocused()).isTrue();
-
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea2.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        // Since nudge history is cleared, nudging up should fail and the focus should stay
-        // the same.
-        assertThat(mView2.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testClearFocusAreaHistoryWhenRotating_notClear() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            RotaryCache cache1 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea1.setRotaryCache(cache1);
-            mFocusArea1.setClearFocusAreaHistoryWhenRotating(false);
-            RotaryCache cache2 =
-                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
-            mFocusArea2.setRotaryCache(cache2);
-            mFocusArea2.setClearFocusAreaHistoryWhenRotating(false);
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        Bundle arguments = new Bundle();
-        mFocusArea2.post(() -> {
-            // Nudging down from mFocusArea1 to mFocusArea2.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea2.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mView2.post(() -> {
-            // Rotate.
-            mView2.requestFocus();
-            mView2.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView2.isFocused()).isTrue();
-
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            // Nudging up should move focus to mFocusArea1 according to nudge history.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea2.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testBoundsOffset() {
-        assertThat(mFocusArea1.getLayoutDirection()).isEqualTo(LAYOUT_DIRECTION_LTR);
-
-        // FocusArea's bounds offset specified in layout file:
-        // 10dp(start), 20dp(end), 30dp(top), 40dp(bottom).
-        int left = dp2Px(10);
-        int right = dp2Px(20);
-        int top = dp2Px(30);
-        int bottom = dp2Px(40);
-        AccessibilityNodeInfo node = mFocusArea1.createAccessibilityNodeInfo();
-        assertBoundsOffset(node, left, top, right, bottom);
-        node.recycle();
-    }
-
-    @Test
-    public void testBoundsOffsetWithRtl() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
-        mFocusArea1.post(() -> {
-            mFocusArea1.setLayoutDirection(LAYOUT_DIRECTION_RTL);
-            mFocusArea1.post(() -> latch.countDown());
-        });
-        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusArea1.getLayoutDirection()).isEqualTo(LAYOUT_DIRECTION_RTL);
-
-        // FocusArea highlight padding specified in layout file:
-        // 10dp(start), 20dp(end), 30dp(top), 40dp(bottom).
-        int left = dp2Px(20);
-        int right = dp2Px(10);
-        int top = dp2Px(30);
-        int bottom = dp2Px(40);
-        AccessibilityNodeInfo node = mFocusArea1.createAccessibilityNodeInfo();
-        assertBoundsOffset(node, left, top, right, bottom);
-        node.recycle();
-    }
-
-    @Test
-    public void testSetBoundsOffset() {
-        mFocusArea1.setBoundsOffset(50, 60, 70, 80);
-        AccessibilityNodeInfo node = mFocusArea1.createAccessibilityNodeInfo();
-        assertBoundsOffset(node, 50, 60, 70, 80);
-        node.recycle();
-    }
-
-    @Test
-    public void testHighlightPadding() {
-        assertThat(mFocusArea2.getLayoutDirection()).isEqualTo(LAYOUT_DIRECTION_LTR);
-
-        int left = dp2Px(50);
-        int right = dp2Px(10);
-        int top = dp2Px(40);
-        int bottom = dp2Px(20);
-        AccessibilityNodeInfo node = mFocusArea2.createAccessibilityNodeInfo();
-        assertBoundsOffset(node, left, top, right, bottom);
-        node.recycle();
-    }
-
-    @Test
-    public void testBug170423337() throws Exception {
-        Bundle arguments = new Bundle();
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            // Focus on app bar (assume mFocusArea1 is app bar).
-            mView1.requestFocus();
-
-            // Nudge down to browse list (assume mFocusArea2 is browse list).
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea2.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFocusArea3.post(() -> {
-            // Nudge down to playback control bar (assume mFocusArea3 is playback control bar).
-            mFocusArea3.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea3.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView3.isFocused()).isTrue();
-
-        CountDownLatch latch3 = new CountDownLatch(1);
-        mFocusArea3.post(() -> {
-            // Nudge down to navigation bar (navigation bar is in system window without FocusAreas).
-            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
-
-            // Nudge up to playback control bar.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea3.performAccessibilityAction(ACTION_FOCUS, arguments);
-            mFocusArea3.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView3.isFocused()).isTrue();
-
-        CountDownLatch latch4 = new CountDownLatch(1);
-        mFocusArea3.post(() -> {
-            // Nudge up to browse list.
-            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
-            mFocusArea3.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea3.post(() -> latch4.countDown());
-        });
-        latch4.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus2.isFocused()).isTrue();
-
-        CountDownLatch latch5 = new CountDownLatch(1);
-        mFocusArea2.post(() -> {
-            // Nudge up, and it should focus on app bar.
-            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
-            mFocusArea2.post(() -> latch5.countDown());
-        });
-        latch5.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testWrapAround() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView5.post(() -> {
-            mView5.requestFocus();
-            mView5.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView5.isFocused()).isTrue();
-
-        View focusSearch = mView5.focusSearch(View.FOCUS_FORWARD);
-        assertWithMessage("Forward wrap-around").that(focusSearch).isEqualTo(mButton5);
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mButton5.post(() -> {
-            mButton5.requestFocus();
-            mButton5.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton5.isFocused()).isTrue();
-
-        focusSearch = mButton5.focusSearch(View.FOCUS_BACKWARD);
-        assertWithMessage("Backward wrap-around").that(focusSearch).isEqualTo(mView5);
-    }
-
-    @Test
-    public void testNoWrapAround() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mButton1.post(() -> {
-            mButton1.requestFocus();
-            mButton1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mButton1.isFocused()).isTrue();
-
-        View focusSearch = mButton1.focusSearch(View.FOCUS_FORWARD);
-        assertWithMessage("Forward wrap-around").that(focusSearch).isNotEqualTo(mView1);
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        focusSearch = mView1.focusSearch(View.FOCUS_BACKWARD);
-        assertWithMessage("Backward wrap-around").that(focusSearch).isNotEqualTo(mButton1);
-    }
-
-    private void assertBoundsOffset(
-            @NonNull AccessibilityNodeInfo node, int leftPx, int topPx, int rightPx, int bottomPx) {
-        Bundle extras = node.getExtras();
-        assertThat(extras.getInt(FOCUS_AREA_LEFT_BOUND_OFFSET)).isEqualTo(leftPx);
-        assertThat(extras.getInt(FOCUS_AREA_RIGHT_BOUND_OFFSET)).isEqualTo(rightPx);
-        assertThat(extras.getInt(FOCUS_AREA_TOP_BOUND_OFFSET)).isEqualTo(topPx);
-        assertThat(extras.getInt(FOCUS_AREA_BOTTOM_BOUND_OFFSET)).isEqualTo(bottomPx);
-    }
-
-    /** Converts dp unit to equivalent pixels. */
-    private int dp2Px(int dp) {
-        return (int) (dp * mActivity.getResources().getDisplayMetrics().density + 0.5f);
-    }
-
-    private void assertDrawMethodsCalled(@NonNull TestFocusArea focusArea, CountDownLatch latch)
-            throws Exception {
-        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(focusArea.onDrawCalled()).isTrue();
-        assertThat(focusArea.drawCalled()).isTrue();
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTestActivity.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTestActivity.java
deleted file mode 100644
index af4a754..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTestActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.car.rotary.test.R;
-
-/** An activity used for testing {@link FocusArea}. */
-public class FocusAreaTestActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.focus_area_test_activity);
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTouchModeTest.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTouchModeTest.java
deleted file mode 100644
index 4064b3c..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusAreaTouchModeTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import static android.view.View.FOCUS_RIGHT;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.graphics.Rect;
-import android.view.View;
-
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.rotary.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-/** Unit tests for {@link FocusArea} in touch mode. */
-public class FocusAreaTouchModeTest {
-    @Rule
-    public ActivityTestRule<FocusAreaTestActivity> mActivityRule =
-            new ActivityTestRule<>(FocusAreaTestActivity.class, /* initialTouchMode= */ true);
-
-    private FocusAreaTestActivity mActivity;
-    private TestFocusArea mFocusArea2;
-    private View mView1;
-
-    @Before
-    public void setUp() {
-        mActivity = mActivityRule.getActivity();
-        mFocusArea2 = mActivity.findViewById(R.id.focus_area2);
-        mView1 = mActivity.findViewById(R.id.view1);
-    }
-
-    @Test
-    public void testOnRequestFocusInDescendants_doesNothing() {
-        mFocusArea2.post(() -> {
-            Rect previouslyFocusedRect = new Rect();
-            previouslyFocusedRect.left = mView1.getLeft();
-            previouslyFocusedRect.top = mView1.getTop();
-            previouslyFocusedRect.right = previouslyFocusedRect.left + mView1.getWidth();
-            previouslyFocusedRect.bottom = previouslyFocusedRect.top + mView1.getHeight();
-            boolean focusTaken =
-                    mFocusArea2.onRequestFocusInDescendants(FOCUS_RIGHT, previouslyFocusedRect);
-
-            assertWithMessage("onRequestFocusInDescendants returned").that(focusTaken).isFalse();
-            assertWithMessage("No view should be focused")
-                    .that(mFocusArea2.getRootView().findFocus()).isNull();
-        });
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTest.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTest.java
deleted file mode 100644
index 8076481..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTest.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
-
-import static com.android.car.ui.utils.RotaryConstants.ACTION_RESTORE_DEFAULT_FOCUS;
-import static com.android.car.ui.utils.ViewUtils.setRotaryScrollEnabled;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.rotary.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/** Unit test for {@link FocusParkingView} not in touch mode. */
-// TODO(b/187553946): Improve this test.
-public class FocusParkingViewTest {
-
-    private static final long WAIT_TIME_MS = 3000;
-    private static final int NUM_ITEMS = 40;
-
-    @Rule
-    public ActivityTestRule<FocusParkingViewTestActivity> mActivityRule =
-            new ActivityTestRule<>(FocusParkingViewTestActivity.class);
-
-    private FocusParkingViewTestActivity mActivity;
-    private FocusParkingView mFpv;
-    private ViewGroup mParent1;
-    private View mView1;
-    private View mFocusedByDefault;
-    private RecyclerView mList;
-
-    @Before
-    public void setUp() {
-        mActivity = mActivityRule.getActivity();
-        mFpv = mActivity.findViewById(R.id.fpv);
-        mParent1 = mActivity.findViewById(R.id.parent1);
-        mView1 = mActivity.findViewById(R.id.view1);
-        mFocusedByDefault = mActivity.findViewById(R.id.focused_by_default);
-        mList = mActivity.findViewById(R.id.list);
-
-        mList.post(() -> {
-            mList.setLayoutManager(new LinearLayoutManager(mActivity));
-            mList.setAdapter(new TestAdapter(NUM_ITEMS));
-            setRotaryScrollEnabled(mList, /* isVertical= */ true);
-        });
-    }
-
-    @Test
-    public void testGetWidthAndHeight() {
-        assertThat(mFpv.getWidth()).isEqualTo(1);
-        assertThat(mFpv.getHeight()).isEqualTo(1);
-    }
-
-    @Test
-    public void testRequestFocus_focusOnDefaultFocus() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
-            mFpv.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.requestFocus();
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRequestFocus_doNothing() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.requestFocus();
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRestoreDefaultFocus_focusOnDefaultFocus() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
-            mFpv.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.restoreDefaultFocus();
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRestoreDefaultFocus_doNothing() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.restoreDefaultFocus();
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testOnWindowFocusChanged_loseFocus() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.onWindowFocusChanged(false);
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testOnWindowFocusChanged_focusOnDefaultFocus() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
-            mFpv.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.onWindowFocusChanged(true);
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionRestoreDefaultFocus() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
-            mFpv.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.performAccessibilityAction(ACTION_RESTORE_DEFAULT_FOCUS, null);
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_doNothing() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.performAccessibilityAction(ACTION_RESTORE_DEFAULT_FOCUS, null);
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testPerformAccessibilityAction_actionFocus() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRestoreFocusInRoot_recyclerViewItemRemoved() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mList.post(() -> mList.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        mList.post(() -> latch1.countDown());
-                    }
-                })
-        );
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-
-        View firstItem = mList.getLayoutManager().findViewByPosition(0);
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mList.post(() -> {
-            firstItem.requestFocus();
-            mList.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(firstItem.isFocused()).isTrue();
-
-        ViewGroup parent = (ViewGroup) firstItem.getParent();
-        CountDownLatch latch3 = new CountDownLatch(1);
-        parent.post(() -> {
-            parent.removeView(firstItem);
-            parent.post(() -> latch3.countDown());
-        });
-        latch3.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    // TODO(b/179734335) Reenable this test, and remove the asserts inside of layout listeners.
-    // When an assert fails inside of a layout listener, it causes a whole bunch of tests in the
-    // test suite to fail with "test did not run due to instrumentation issue.
-    // See run level error for reason.", making it hard to debug.
-//    @Test
-//    public void testRestoreFocusInRoot_recyclerViewItemScrolledOffScreen() {
-//        mList.post(() -> mList.getViewTreeObserver().addOnGlobalLayoutListener(
-//                new ViewTreeObserver.OnGlobalLayoutListener() {
-//                    @Override
-//                    public void onGlobalLayout() {
-//                        mList.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-//                        View firstItem = mList.getLayoutManager().findViewByPosition(0);
-//                        firstItem.requestFocus();
-//                        assertThat(firstItem.isFocused()).isTrue();
-//
-//                        mList.scrollToPosition(NUM_ITEMS - 1);
-//                        mList.getViewTreeObserver().addOnGlobalLayoutListener(
-//                                new ViewTreeObserver.OnGlobalLayoutListener() {
-//                                    @Override
-//                                    public void onGlobalLayout() {
-//                                        mList.getViewTreeObserver()
-//                                                .removeOnGlobalLayoutListener(this);
-//                                        assertThat(mList.isFocused()).isTrue();
-//                                    }
-//                                });
-//                    }
-//                }));
-//    }
-
-    @Test
-    public void testRestoreFocusInRoot_focusedViewRemoved() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView1.post(() -> {
-            ViewGroup parent = (ViewGroup) mView1.getParent();
-            parent.removeView(mView1);
-            mView1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRestoreFocusInRoot_focusedViewDisabled() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.setEnabled(false);
-            mView1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRestoreFocusInRoot_focusedViewBecomesInvisible() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.setVisibility(View.INVISIBLE);
-            mView1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRestoreFocusInRoot_focusedViewParentBecomesInvisible() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mParent1.post(() -> {
-            mParent1.setVisibility(View.INVISIBLE);
-            mParent1.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusedByDefault.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRequestFocus_focusesFpvWhenShouldRestoreFocusIsFalse() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.setShouldRestoreFocus(false);
-            mFpv.requestFocus();
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-    }
-
-    @Test
-    public void testRestoreDefaultFocus_focusesFpvWhenShouldRestoreFocusIsFalse() throws Exception {
-        CountDownLatch latch1 = new CountDownLatch(1);
-        mView1.post(() -> {
-            mView1.requestFocus();
-            mView1.post(() -> latch1.countDown());
-        });
-        latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mView1.isFocused()).isTrue();
-
-        CountDownLatch latch2 = new CountDownLatch(1);
-        mFpv.post(() -> {
-            mFpv.setShouldRestoreFocus(false);
-            mFpv.restoreDefaultFocus();
-            mFpv.post(() -> latch2.countDown());
-        });
-        latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFpv.isFocused()).isTrue();
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTestActivity.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTestActivity.java
deleted file mode 100644
index d88d759..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTestActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.car.rotary.test.R;
-
-/** An Activity used for testing {@link FocusParkingView}. */
-public class FocusParkingViewTestActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.focus_parking_view_test_activity);
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java
deleted file mode 100644
index efa2e90..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import static com.android.car.ui.utils.RotaryConstants.ACTION_RESTORE_DEFAULT_FOCUS;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.view.View;
-
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.rotary.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-/** Unit test for {@link FocusParkingView} in touch mode. */
-public class FocusParkingViewTouchModeTest {
-
-    @Rule
-    public ActivityTestRule<FocusParkingViewTestActivity> mActivityRule =
-            new ActivityTestRule<>(FocusParkingViewTestActivity.class,
-                    /* initialTouchMode= */ true);
-
-    private FocusParkingView mFpv;
-
-    @Before
-    public void setUp() {
-        FocusParkingViewTestActivity activity = mActivityRule.getActivity();
-        mFpv = activity.findViewById(R.id.fpv);
-    }
-
-    @Test
-    public void testRestoreDefaultFocus_doesNothing() {
-        mFpv.post(() -> {
-            assertThat(mFpv.getRootView().findFocus()).isNull();
-
-            boolean result = mFpv.restoreDefaultFocus();
-
-            assertWithMessage("restoreDefaultFocus returned").that(result).isFalse();
-            assertWithMessage("No view should be focused")
-                    .that(mFpv.getRootView().findFocus()).isNull();
-        });
-    }
-
-    @Test
-    public void testRequestFocus_doesNothing() {
-        mFpv.post(() -> {
-            assertThat(mFpv.getRootView().findFocus()).isNull();
-
-            boolean result = mFpv.requestFocus(View.FOCUS_DOWN, /* previouslyFocusedRect= */ null);
-
-            assertWithMessage("requestFocus returned").that(result).isFalse();
-            assertWithMessage("No view should be focused")
-                    .that(mFpv.getRootView().findFocus()).isNull();
-        });
-    }
-
-    @Test
-    public void testPerformActionRestoreDefaultFocus_exitsTouchMode() {
-        mFpv.post(() -> {
-            assertThat(mFpv.getRootView().findFocus()).isNull();
-
-            boolean result = mFpv.performAccessibilityAction(
-                    ACTION_RESTORE_DEFAULT_FOCUS, /* arguments= */ null);
-
-            assertWithMessage("performAccessibilityAction returned").that(result).isTrue();
-            assertWithMessage("A view should be focused")
-                    .that(mFpv.getRootView().findFocus()).isNotNull();
-        });
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/RotaryCacheTest.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/RotaryCacheTest.java
deleted file mode 100644
index b1b9b59..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/RotaryCacheTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import static com.android.car.ui.RotaryCache.CACHE_TYPE_EXPIRED_AFTER_SOME_TIME;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** Unit tests for {@link RotaryCache}. */
-@RunWith(AndroidJUnit4.class)
-public class RotaryCacheTest {
-    private static final int CACHE_TIME_OUT_MS = 10000;
-
-    private RotaryCache mRotaryCache;
-    private long mValidTime;
-    private long mExpiredTime;
-    private Context mContext;
-    private FocusArea mFocusArea;
-    private View mFocusedView;
-
-    @Before
-    public void setUp() {
-        mRotaryCache = new RotaryCache(CACHE_TYPE_EXPIRED_AFTER_SOME_TIME, CACHE_TIME_OUT_MS,
-                CACHE_TYPE_EXPIRED_AFTER_SOME_TIME, CACHE_TIME_OUT_MS);
-        mValidTime = CACHE_TIME_OUT_MS - 1;
-        mExpiredTime = CACHE_TIME_OUT_MS + 1;
-        mContext = ApplicationProvider.getApplicationContext();
-        mFocusArea = new FocusArea(mContext);
-        mFocusedView = new View(mContext);
-    }
-
-    @Test
-    public void testGetFocusedView_inTheCache() {
-        mRotaryCache.saveFocusedView(mFocusedView, 0);
-        View view = mRotaryCache.getFocusedView(mValidTime);
-        assertThat(view).isEqualTo(mFocusedView);
-    }
-
-    @Test
-    public void testGetFocusedView_notInTheCache() {
-        View view = mRotaryCache.getFocusedView(mValidTime);
-        assertThat(view).isNull();
-    }
-
-    @Test
-    public void testGetFocusedView_expiredCache() {
-        mRotaryCache.saveFocusedView(mFocusedView, 0);
-        View view = mRotaryCache.getFocusedView(mExpiredTime);
-        assertThat(view).isNull();
-    }
-
-    @Test
-    public void testGetCachedFocusArea_inTheCache() {
-        int direction = View.FOCUS_LEFT;
-        mRotaryCache.saveFocusArea(direction, mFocusArea, 0);
-        FocusArea focusArea = mRotaryCache.getCachedFocusArea(direction, mValidTime);
-        assertThat(focusArea).isEqualTo(mFocusArea);
-    }
-
-    @Test
-    public void testGetCachedFocusArea_notInTheCache() {
-        int direction = View.FOCUS_LEFT;
-        mRotaryCache.saveFocusArea(direction, mFocusArea, 0);
-
-        FocusArea focusArea = mRotaryCache.getCachedFocusArea(View.FOCUS_RIGHT, mValidTime);
-        assertThat(focusArea).isNull();
-        focusArea = mRotaryCache.getCachedFocusArea(View.FOCUS_UP, mValidTime);
-        assertThat(focusArea).isNull();
-    }
-
-    @Test
-    public void testGetCachedFocusArea_expiredCache() {
-        int direction = View.FOCUS_LEFT;
-        mRotaryCache.saveFocusArea(direction, mFocusArea, 0);
-        FocusArea focusArea = mRotaryCache.getCachedFocusArea(direction, mExpiredTime);
-        assertThat(focusArea).isNull();
-    }
-
-    @Test
-    public void testClearFocusAreaHistory() {
-        mRotaryCache.saveFocusArea(View.FOCUS_UP, mFocusArea, 0);
-        assertThat(mRotaryCache.getCachedFocusArea(View.FOCUS_UP, mValidTime)).isEqualTo(
-                mFocusArea);
-
-        mRotaryCache.clearFocusAreaHistory();
-        assertThat(mRotaryCache.getCachedFocusArea(View.FOCUS_UP, mValidTime)).isNull();
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/TestAdapter.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/TestAdapter.java
deleted file mode 100644
index c71b0d8..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/TestAdapter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.Adapter;
-
-import com.android.car.rotary.test.R;
-import com.android.car.ui.TestAdapter.TestViewHolder;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public final class TestAdapter extends Adapter<TestViewHolder> {
-
-    private final List<String> mItems;
-
-    public TestAdapter(int numItems) {
-        mItems = new ArrayList<>();
-        for (int i = 0; i < numItems; i++) {
-            mItems.add("Item " + i);
-        }
-    }
-
-    @Override
-    public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
-            int viewType) {
-        View layout = LayoutInflater.from(parent.getContext())
-                .inflate(R.layout.test_car_ui_recycler_view_list_item, parent, false);
-        return new TestViewHolder(layout);
-    }
-
-    @Override
-    public void onBindViewHolder(TestViewHolder holder, int position) {
-        holder.bind(mItems.get(position));
-    }
-
-    @Override
-    public int getItemCount() {
-        return mItems.size();
-    }
-
-    static class TestViewHolder extends RecyclerView.ViewHolder {
-
-        TestViewHolder(@NonNull View itemView) {
-            super(itemView);
-        }
-
-        void bind(CharSequence text) {
-            TextView textView = itemView.requireViewById(R.id.textTitle);
-            textView.setText(text);
-        }
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/TestFocusArea.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/TestFocusArea.java
deleted file mode 100644
index 444cbc5..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/TestFocusArea.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-
-import androidx.annotation.Nullable;
-
-/** A {@link FocusArea} used for testing. */
-public class TestFocusArea extends FocusArea {
-
-    /** Whether {@link #onDraw(Canvas)} was called. */
-    private boolean mOnDrawCalled;
-
-    /** Whether {@link #draw(Canvas)} was called. */
-    private boolean mDrawCalled;
-
-    private int mLayoutDirection = LAYOUT_DIRECTION_LTR;
-
-    public TestFocusArea(Context context) {
-        super(context);
-    }
-
-    public TestFocusArea(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public TestFocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public TestFocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        mOnDrawCalled = true;
-        super.onDraw(canvas);
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        mDrawCalled = true;
-        super.draw(canvas);
-    }
-
-    public boolean onDrawCalled() {
-        return mOnDrawCalled;
-    }
-
-    public void setOnDrawCalled(boolean onDrawCalled) {
-        mOnDrawCalled = onDrawCalled;
-    }
-
-    public boolean drawCalled() {
-        return mDrawCalled;
-    }
-
-    public void setDrawCalled(boolean drawCalled) {
-        mDrawCalled = drawCalled;
-    }
-
-    @Override
-    public void setLayoutDirection(int layoutDirection) {
-        // The real setLayoutDirection doesn't work in the test, so let's mock it.
-        if (mLayoutDirection != layoutDirection) {
-            mLayoutDirection = layoutDirection;
-            // To trigger the highlight padding update, we need to call onLayout. Note: the
-            // parameters don't matter.
-            onLayout(false, 0, 0, 0, 0);
-        }
-    }
-
-    @Override
-    public int getLayoutDirection() {
-        return mLayoutDirection;
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/actions/WaitForViewAction.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/actions/WaitForViewAction.java
deleted file mode 100644
index 7ce2bf6..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/actions/WaitForViewAction.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.actions;
-
-import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
-
-import android.view.View;
-
-import androidx.test.espresso.PerformException;
-import androidx.test.espresso.UiController;
-import androidx.test.espresso.ViewAction;
-import androidx.test.espresso.util.HumanReadables;
-import androidx.test.espresso.util.TreeIterables;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.StringDescription;
-
-import java.util.concurrent.TimeoutException;
-
-public class WaitForViewAction implements ViewAction {
-
-    private Matcher<View> mMatcher;
-    private long mWaitTimeMillis;
-
-    public WaitForViewAction(Matcher<View> matcher, long waitTimeMillis) {
-        mMatcher = matcher;
-        mWaitTimeMillis = waitTimeMillis;
-    }
-
-    @Override
-    public Matcher<View> getConstraints() {
-        return isRoot();
-    }
-
-    @Override
-    public String getDescription() {
-        Description description = new StringDescription();
-        mMatcher.describeTo(description);
-        return "wait at most " + mWaitTimeMillis + " milliseconds for view "
-                + description.toString();
-    }
-
-    @Override
-    public void perform(UiController uiController, View view) {
-        uiController.loopMainThreadUntilIdle();
-        final long startTime = System.currentTimeMillis();
-        final long endTime = startTime + mWaitTimeMillis;
-
-        do {
-            for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
-                if (mMatcher.matches(child)) {
-                    return;
-                }
-            }
-
-            uiController.loopMainThreadForAtLeast(50);
-        }
-        while (System.currentTimeMillis() < endTime);
-
-        throw new PerformException.Builder()
-                .withActionDescription(this.getDescription())
-                .withViewDescription(HumanReadables.describe(view))
-                .withCause(new TimeoutException())
-                .build();
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTest.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTest.java
deleted file mode 100644
index d29772c..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTest.java
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.utils;
-
-import static android.view.View.GONE;
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.actions.ViewActions.waitForView;
-import static com.android.car.ui.utils.ViewUtils.DEFAULT_FOCUS;
-import static com.android.car.ui.utils.ViewUtils.FOCUSED_BY_DEFAULT;
-import static com.android.car.ui.utils.ViewUtils.IMPLICIT_DEFAULT_FOCUS;
-import static com.android.car.ui.utils.ViewUtils.NO_FOCUS;
-import static com.android.car.ui.utils.ViewUtils.REGULAR_FOCUS;
-import static com.android.car.ui.utils.ViewUtils.SCROLLABLE_CONTAINER_FOCUS;
-import static com.android.car.ui.utils.ViewUtils.setRotaryScrollEnabled;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.View;
-import android.view.ViewTreeObserver;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.rotary.test.R;
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.FocusParkingView;
-import com.android.car.ui.TestAdapter;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-/** Unit tests for {@link ViewUtils}. */
-public class ViewUtilsTest {
-
-    @Rule
-    public ActivityTestRule<ViewUtilsTestActivity> mActivityRule =
-            new ActivityTestRule<>(ViewUtilsTestActivity.class);
-
-    private ViewUtilsTestActivity mActivity;
-    private FocusArea mFocusArea1;
-    private FocusArea mFocusArea2;
-    private FocusArea mFocusArea3;
-    private FocusArea mFocusArea4;
-    private FocusArea mFocusArea5;
-    private FocusParkingView mFpv;
-    private View mView2;
-    private View mFocusedByDefault3;
-    private View mView4;
-    private View mDefaultFocus4;
-    private RecyclerView mList5;
-    private View mRoot;
-
-    @Before
-    public void setUp() {
-        mActivity = mActivityRule.getActivity();
-        mFocusArea1 = mActivity.findViewById(R.id.focus_area1);
-        mFocusArea2 = mActivity.findViewById(R.id.focus_area2);
-        mFocusArea3 = mActivity.findViewById(R.id.focus_area3);
-        mFocusArea4 = mActivity.findViewById(R.id.focus_area4);
-        mFocusArea5 = mActivity.findViewById(R.id.focus_area5);
-        mFpv = mActivity.findViewById(R.id.fpv);
-        mView2 = mActivity.findViewById(R.id.view2);
-        mFocusedByDefault3 = mActivity.findViewById(R.id.focused_by_default3);
-        mView4 = mActivity.findViewById(R.id.view4);
-        mDefaultFocus4 = mActivity.findViewById(R.id.default_focus4);
-        mList5 = mActivity.findViewById(R.id.list5);
-        mRoot = mFocusArea1.getRootView();
-
-        mRoot.post(() -> {
-            mList5.setLayoutManager(new LinearLayoutManager(mActivity));
-            mList5.setAdapter(new TestAdapter(/* numItems= */ 2));
-            setRotaryScrollEnabled(mList5, /* isVertical= */ true);
-        });
-        // If we don't wait for the recyclerview items to show up, some of the tests flake
-        onView(isRoot()).perform(waitForView(withText("Item 0"), 500));
-    }
-
-    @Test
-    public void testRootVisible() {
-        mRoot.post(() -> assertThat(mRoot.getVisibility()).isEqualTo(VISIBLE));
-    }
-
-    @Test
-    public void testGetAncestorFocusArea() {
-        mRoot.post(() -> assertThat(ViewUtils.getAncestorFocusArea(mView2)).isEqualTo(mFocusArea2));
-    }
-
-    @Test
-    public void testGetAncestorFocusArea_doesNotReturnItself() {
-        mRoot.post(() -> assertThat(ViewUtils.getAncestorFocusArea(mFocusArea2)).isNull());
-    }
-
-    @Test
-    public void testGetAncestorFocusArea_outsideFocusArea() {
-        mRoot.post(() -> assertThat(ViewUtils.getAncestorFocusArea(mFpv)).isNull());
-    }
-
-    @Test
-    public void testGetAncestorScrollableContainer() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        View firstItem = mList5.getLayoutManager().findViewByPosition(0);
-                        assertThat(ViewUtils.getAncestorScrollableContainer(firstItem))
-                                .isEqualTo(mList5);
-                    }
-                }));
-    }
-
-    @Test
-    public void testGetAncestorScrollableContainer_returnNull() {
-        mRoot.post(() -> assertThat(ViewUtils.getAncestorScrollableContainer(mView2)).isNull());
-    }
-
-    @Test
-    public void testFindFocusedByDefaultView() {
-        mRoot.post(() -> {
-            View focusedByDefault = ViewUtils.findFocusedByDefaultView(mRoot);
-            assertThat(focusedByDefault).isEqualTo(mFocusedByDefault3);
-        });
-    }
-
-    @Test
-    public void testFindFocusedByDefaultView_skipNotFocusable() {
-        mRoot.post(() -> {
-            mFocusedByDefault3.setFocusable(false);
-            View focusedByDefault = ViewUtils.findFocusedByDefaultView(mRoot);
-            assertThat(focusedByDefault).isNull();
-        });
-    }
-
-    @Test
-    public void testFindFocusedByDefaultView_skipInvisibleView() {
-        mRoot.post(() -> {
-            mFocusArea3.setVisibility(INVISIBLE);
-            assertThat(mFocusArea3.getVisibility()).isEqualTo(INVISIBLE);
-            View focusedByDefault = ViewUtils.findFocusedByDefaultView(mRoot);
-            assertThat(focusedByDefault).isNull();
-        });
-    }
-
-    @Test
-    public void testFindFocusedByDefaultView_skipInvisibleAncestor() {
-        mRoot.post(() -> {
-            mRoot.setVisibility(INVISIBLE);
-            View focusedByDefault = ViewUtils.findFocusedByDefaultView(mFocusArea3);
-            assertThat(focusedByDefault).isNull();
-        });
-    }
-
-    @Test
-    public void testFindImplicitDefaultFocusView_inRoot() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        View firstItem = mList5.getLayoutManager().findViewByPosition(0);
-                        View implicitDefaultFocus = ViewUtils.findImplicitDefaultFocusView(mRoot);
-                        assertThat(implicitDefaultFocus).isEqualTo(firstItem);
-                    }
-                }));
-    }
-
-    @Test
-    public void testFindImplicitDefaultFocusView_inFocusArea() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        View firstItem = mList5.getLayoutManager().findViewByPosition(0);
-                        View implicitDefaultFocus =
-                                ViewUtils.findImplicitDefaultFocusView(mFocusArea5);
-                        assertThat(implicitDefaultFocus).isEqualTo(firstItem);
-                    }
-                }));
-    }
-
-    @Test
-    public void testFindImplicitDefaultFocusView_skipInvisibleAncestor() {
-        mRoot.post(() -> {
-            mRoot.setVisibility(INVISIBLE);
-            View implicitDefaultFocus = ViewUtils.findImplicitDefaultFocusView(mFocusArea5);
-            assertThat(implicitDefaultFocus).isNull();
-        });
-    }
-
-    @Test
-    public void testFindImplicitDefaultFocusView_selectedItem_inFocusArea() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        View selectedItem = mList5.getLayoutManager().findViewByPosition(1);
-                        selectedItem.setSelected(true);
-                        View implicitDefaultFocus =
-                                ViewUtils.findImplicitDefaultFocusView(mFocusArea5);
-                        assertThat(implicitDefaultFocus).isEqualTo(selectedItem);
-                    }
-                }));
-    }
-
-    @Test
-    public void testFindFirstFocusableDescendant() {
-        mRoot.post(() -> {
-            mFocusArea2.setFocusable(true);
-            View firstFocusable = ViewUtils.findFirstFocusableDescendant(mRoot);
-            assertThat(firstFocusable).isEqualTo(mFocusArea2);
-        });
-    }
-
-    @Test
-    public void testFindFirstFocusableDescendant_skipItself() {
-        mRoot.post(() -> {
-            mFocusArea2.setFocusable(true);
-            View firstFocusable = ViewUtils.findFirstFocusableDescendant(mFocusArea2);
-            assertThat(firstFocusable).isEqualTo(mView2);
-        });
-    }
-
-    @Test
-    public void testFindFirstFocusableDescendant_skipInvisibleAndGoneView() {
-        mRoot.post(() -> {
-            mFocusArea2.setVisibility(INVISIBLE);
-            mFocusArea3.setVisibility(GONE);
-            View firstFocusable = ViewUtils.findFirstFocusableDescendant(mRoot);
-            assertThat(firstFocusable).isEqualTo(mView4);
-        });
-    }
-
-    @Test
-    public void testFindFirstFocusableDescendant_skipInvisibleAncestor() {
-        mRoot.post(() -> {
-            mRoot.setVisibility(INVISIBLE);
-            View firstFocusable = ViewUtils.findFirstFocusableDescendant(mFocusArea2);
-            assertThat(firstFocusable).isNull();
-        });
-    }
-
-    @Test
-    public void testIsImplicitDefaultFocusView_firstItem() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        View firstItem = mList5.getLayoutManager().findViewByPosition(0);
-                        assertThat(ViewUtils.isImplicitDefaultFocusView(firstItem)).isTrue();
-                    }
-                }));
-    }
-
-    @Test
-    public void testIsImplicitDefaultFocusView_secondItem() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        View secondItem = mList5.getLayoutManager().findViewByPosition(1);
-                        assertThat(ViewUtils.isImplicitDefaultFocusView(secondItem)).isFalse();
-                    }
-                }));
-    }
-
-    @Test
-    public void testIsImplicitDefaultFocusView_normalView() {
-        mRoot.post(() -> assertThat(ViewUtils.isImplicitDefaultFocusView(mView2)).isFalse());
-    }
-
-    @Test
-    public void testIsImplicitDefaultFocusView_skipInvisibleAncestor() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        mFocusArea5.setVisibility(INVISIBLE);
-                        View firstItem = mList5.getLayoutManager().findViewByPosition(0);
-                        assertThat(ViewUtils.isImplicitDefaultFocusView(firstItem)).isFalse();
-                    }
-                }));
-    }
-
-    @Test
-    public void testIsImplicitDefaultFocusView_selectedItem() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        View selectedItem = mList5.getLayoutManager().findViewByPosition(1);
-                        selectedItem.setSelected(true);
-                        assertThat(ViewUtils.isImplicitDefaultFocusView(selectedItem)).isTrue();
-                    }
-                }));
-    }
-
-    @Test
-    public void testRequestFocus() {
-        mRoot.post(() -> assertRequestFocus(mView2, true));
-    }
-
-    @Test
-    public void testRequestFocus_nullView() {
-        mRoot.post(() -> assertRequestFocus(null, false));
-    }
-
-    @Test
-    public void testRequestFocus_alreadyFocused() {
-        mRoot.post(() -> {
-            assertRequestFocus(mView2, true);
-            // mView2 is already focused before requesting focus.
-            assertRequestFocus(mView2, true);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_notFocusable() {
-        mRoot.post(() -> {
-            mView2.setFocusable(false);
-            assertRequestFocus(mView2, false);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_disabled() {
-        mRoot.post(() -> {
-            mView2.setEnabled(false);
-            assertRequestFocus(mView2, false);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_notVisible() {
-        mRoot.post(() -> {
-            mView2.setVisibility(View.INVISIBLE);
-            assertRequestFocus(mView2, false);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_skipInvisibleAncestor() {
-        mRoot.post(() -> {
-            mFocusArea2.setVisibility(View.INVISIBLE);
-            assertRequestFocus(mView2, false);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_zeroWidth() {
-        mRoot.post(() -> {
-            mView2.setRight(mView2.getLeft());
-            assertThat(mView2.getWidth()).isEqualTo(0);
-            assertRequestFocus(mView2, false);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_detachedFromWindow() {
-        mRoot.post(() -> {
-            mFocusArea2.removeView(mView2);
-            assertRequestFocus(mView2, false);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_FocusParkingView() {
-        mRoot.post(() -> {
-            assertRequestFocus(mView2, true);
-            assertRequestFocus(mFpv, false);
-        });
-    }
-
-    @Test
-    public void testRequestFocus_rotaryContainer() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        assertRequestFocus(mList5, false);
-                    }
-                }));
-    }
-
-    @Test
-    public void testRequestFocus_scrollableContainer() {
-        mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        assertRequestFocus(mList5, false);
-                    }
-                }));
-    }
-
-    @Test
-    public void testAdjustFocus_inRoot() {
-        mRoot.post(() -> {
-            assertRequestFocus(mView2, true);
-            ViewUtils.adjustFocus(mRoot, null);
-            assertThat(mFocusedByDefault3.isFocused()).isTrue();
-        });
-    }
-
-    @Test
-    public void testAdjustFocus_inFocusAreaWithDefaultFocus() {
-        mRoot.post(() -> {
-            assertRequestFocus(mView2, true);
-            ViewUtils.adjustFocus(mFocusArea3, null);
-            assertThat(mFocusedByDefault3.isFocused()).isTrue();
-        });
-    }
-
-    @Test
-    public void testAdjustFocus_inFocusAreaWithoutDefaultFocus() {
-        mRoot.post(() -> {
-            assertRequestFocus(mView4, true);
-            ViewUtils.adjustFocus(mFocusArea2, null);
-            assertThat(mView2.isFocused()).isTrue();
-        });
-    }
-
-    @Test
-    public void testAdjustFocus_inFocusAreaWithoutFocusableDescendant() {
-        mRoot.post(() -> {
-            assertRequestFocus(mView2, true);
-            boolean success = ViewUtils.adjustFocus(mFocusArea1, null);
-            assertThat(mFocusArea1.hasFocus()).isFalse();
-            assertThat(success).isFalse();
-        });
-    }
-
-    @Test
-    public void testAdjustFocus_differentFocusLevels() {
-        mRoot.post(() -> {
-            assertThat(ViewUtils.adjustFocus(mFocusArea2, SCROLLABLE_CONTAINER_FOCUS)).isTrue();
-            assertThat(ViewUtils.adjustFocus(mFocusArea2, REGULAR_FOCUS)).isFalse();
-
-            assertThat(ViewUtils.adjustFocus(mFocusArea5, REGULAR_FOCUS)).isTrue();
-            assertThat(ViewUtils.adjustFocus(mFocusArea5, IMPLICIT_DEFAULT_FOCUS)).isFalse();
-
-            assertThat(ViewUtils.adjustFocus(mFocusArea4, IMPLICIT_DEFAULT_FOCUS)).isTrue();
-            assertThat(ViewUtils.adjustFocus(mFocusArea4, DEFAULT_FOCUS)).isFalse();
-
-            assertThat(ViewUtils.adjustFocus(mFocusArea3, DEFAULT_FOCUS)).isTrue();
-            assertThat(ViewUtils.adjustFocus(mFocusArea3, FOCUSED_BY_DEFAULT)).isFalse();
-
-            View firstItem = mList5.getLayoutManager().findViewByPosition(0);
-            firstItem.setFocusable(false);
-            View secondItem = mList5.getLayoutManager().findViewByPosition(1);
-            secondItem.setFocusable(false);
-            assertThat(ViewUtils.adjustFocus(mFocusArea5, NO_FOCUS)).isTrue();
-            assertThat(ViewUtils.adjustFocus(mFocusArea5, SCROLLABLE_CONTAINER_FOCUS)).isFalse();
-        });
-    }
-
-    @Test
-    public void testGetFocusLevel() {
-        mRoot.post(() -> {
-            assertThat(ViewUtils.getFocusLevel(null)).isEqualTo(NO_FOCUS);
-            assertThat(ViewUtils.getFocusLevel(mFpv)).isEqualTo(NO_FOCUS);
-            mFocusArea2.setVisibility(INVISIBLE);
-            assertThat(ViewUtils.getFocusLevel(mView2)).isEqualTo(NO_FOCUS);
-
-            assertThat(ViewUtils.getFocusLevel(mList5)).isEqualTo(SCROLLABLE_CONTAINER_FOCUS);
-
-            assertThat(ViewUtils.getFocusLevel(mView4)).isEqualTo(REGULAR_FOCUS);
-
-            mRoot.post(() -> mList5.getViewTreeObserver().addOnGlobalLayoutListener(
-                    new ViewTreeObserver.OnGlobalLayoutListener() {
-                        @Override
-                        public void onGlobalLayout() {
-                            mList5.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                            View firstItem = mList5.getLayoutManager().findViewByPosition(0);
-                            assertThat(ViewUtils.getFocusLevel(firstItem))
-                                    .isEqualTo(IMPLICIT_DEFAULT_FOCUS);
-                        }
-                    }));
-
-            assertThat(ViewUtils.getFocusLevel(mDefaultFocus4)).isEqualTo(DEFAULT_FOCUS);
-
-            assertThat(ViewUtils.getFocusLevel(mFocusedByDefault3)).isEqualTo(FOCUSED_BY_DEFAULT);
-        });
-    }
-
-    private static void assertRequestFocus(@Nullable View view, boolean focused) {
-        boolean result = ViewUtils.requestFocus(view);
-        assertThat(result).isEqualTo(focused);
-        if (view != null) {
-            assertThat(view.isFocused()).isEqualTo(focused);
-        }
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTestActivity.java b/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTestActivity.java
deleted file mode 100644
index 7b51737..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTestActivity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.utils;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.car.rotary.test.R;
-
-/** An activity used for testing {@link ViewUtils}. */
-public class ViewUtilsTestActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.view_utils_test_activity);
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/focus_area_test_activity.xml b/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/focus_area_test_activity.xml
deleted file mode 100644
index 0d1c3cd..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/focus_area_test_activity.xml
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-    <com.android.car.ui.FocusParkingView
-        android:id="@+id/fpv"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-    <com.android.car.ui.TestFocusArea
-        android:id="@+id/focus_area1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:startBoundOffset="10dp"
-        app:endBoundOffset="20dp"
-        app:topBoundOffset="30dp"
-        app:bottomBoundOffset="40dp">
-        <View
-            android:id="@+id/view1"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <Button
-            android:id="@+id/button1"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-    </com.android.car.ui.TestFocusArea>
-    <com.android.car.ui.TestFocusArea
-        android:id="@+id/focus_area2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:defaultFocus="@+id/default_focus2"
-        app:highlightPaddingHorizontal="10dp"
-        app:highlightPaddingVertical="20dp"
-        app:highlightPaddingStart="30dp"
-        app:highlightPaddingTop="40dp"
-        app:startBoundOffset="50dp">
-        <View
-            android:id="@+id/view2"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <View
-            android:id="@+id/default_focus2"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-    </com.android.car.ui.TestFocusArea>
-    <com.android.car.ui.TestFocusArea
-        android:id="@+id/focus_area3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:nudgeShortcut="@+id/nudge_shortcut3"
-        app:nudgeShortcutDirection="right">
-        <View
-            android:id="@+id/view3"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <View
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <View
-            android:id="@+id/nudge_shortcut3"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-    </com.android.car.ui.TestFocusArea>
-    <com.android.car.ui.TestFocusArea
-        android:id="@+id/focus_area4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:nudgeLeft="@+id/focus_area2">
-        <View
-            android:id="@+id/view4"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-    </com.android.car.ui.TestFocusArea>
-    <com.android.car.ui.TestFocusArea
-        android:id="@+id/focus_area5"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:wrapAround="true">
-        <View
-            android:id="@+id/view5"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <Button
-            android:id="@+id/button5"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-    </com.android.car.ui.TestFocusArea>
-    <com.android.car.ui.TestFocusArea
-        android:id="@+id/focus_area6"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:nudgeRightShortcut="@+id/nudge_shortcut6">
-        <View
-            android:id="@+id/view6"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <View
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <View
-            android:id="@+id/nudge_shortcut6"
-            android:focusable="true"
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-    </com.android.car.ui.TestFocusArea>
-</LinearLayout>
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/focus_parking_view_test_activity.xml b/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/focus_parking_view_test_activity.xml
deleted file mode 100644
index 02d7326..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/focus_parking_view_test_activity.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <com.android.car.ui.FocusParkingView
-        android:id="@+id/fpv"
-        android:layout_width="10dp"
-        android:layout_height="10dp"/>
-    <LinearLayout
-        android:id="@+id/parent1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content">
-        <View
-            android:id="@+id/view1"
-            android:layout_width="100dp"
-            android:layout_height="40dp"
-            android:focusable="true"/>
-    </LinearLayout>
-    <View
-        android:id="@+id/focused_by_default"
-        android:layout_width="100dp"
-        android:layout_height="40dp"
-        android:focusable="true"
-        android:focusedByDefault="true"/>
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/list"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-</LinearLayout>
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/test_car_ui_recycler_view_list_item.xml b/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/test_car_ui_recycler_view_list_item.xml
deleted file mode 100644
index 8297f6b..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/test_car_ui_recycler_view_list_item.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="horizontal"
-    android:focusable="true">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="10dp"
-        android:layout_marginBottom="10dp"
-        android:id="@+id/textTitle"
-        android:text="TESTING"/>
-
-</LinearLayout>
-
-
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/view_utils_test_activity.xml b/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/view_utils_test_activity.xml
deleted file mode 100644
index c6470ba..0000000
--- a/car-ui-lib/car-rotary-lib/src/androidTest/res/layout/view_utils_test_activity.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <com.android.car.ui.FocusParkingView
-        android:id="@+id/fpv"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-    <com.android.car.ui.FocusArea
-        android:id="@+id/focus_area1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-        <View
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-    </com.android.car.ui.FocusArea>
-    <com.android.car.ui.FocusArea
-        android:id="@+id/focus_area2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-        <View
-            android:layout_width="100dp"
-            android:layout_height="100dp"/>
-        <View
-            android:id="@+id/view2"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
-            android:focusable="true"/>
-    </com.android.car.ui.FocusArea>
-    <com.android.car.ui.FocusArea
-        android:id="@+id/focus_area3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-        <View
-            android:layout_width="100dp"
-            android:layout_height="100dp"
-            android:focusable="true"/>
-        <View
-            android:id="@+id/focused_by_default3"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
-            android:focusable="true"
-            android:focusedByDefault="true"/>
-    </com.android.car.ui.FocusArea>
-    <com.android.car.ui.FocusArea
-        android:id="@+id/focus_area4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:defaultFocus="@+id/default_focus4">
-        <View
-            android:id="@+id/view4"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
-            android:focusable="true"/>
-        <View
-            android:id="@+id/default_focus4"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
-            android:focusable="true"/>
-    </com.android.car.ui.FocusArea>
-    <com.android.car.ui.FocusArea
-        android:id="@+id/focus_area5"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/list5"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-    </com.android.car.ui.FocusArea>
-</LinearLayout>
diff --git a/car-ui-lib/car-rotary-lib/src/main/AndroidManifest.xml b/car-ui-lib/car-rotary-lib/src/main/AndroidManifest.xml
deleted file mode 100644
index 161f898..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.car.ui">
-
-</manifest>
diff --git a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/FocusArea.java b/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/FocusArea.java
deleted file mode 100644
index bc9ff3a..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/FocusArea.java
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
-
-import static com.android.car.ui.utils.RotaryConstants.ACTION_NUDGE_SHORTCUT;
-import static com.android.car.ui.utils.RotaryConstants.ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_BOTTOM_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_LEFT_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_RIGHT_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.FOCUS_AREA_TOP_BOUND_OFFSET;
-import static com.android.car.ui.utils.RotaryConstants.NUDGE_DIRECTION;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-import android.view.FocusFinder;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.LinearLayout;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.ui.utils.ViewUtils;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A {@link LinearLayout} used as a navigation block for the rotary controller.
- * <p>
- * The {@link com.android.car.rotary.RotaryService} looks for instances of {@link FocusArea} in the
- * view hierarchy when handling rotate and nudge actions. When receiving a rotation event ({@link
- * android.car.input.RotaryEvent}), RotaryService will move the focus to another {@link View} that
- * can take focus within the same FocusArea. When receiving a nudge event ({@link
- * KeyEvent#KEYCODE_SYSTEM_NAVIGATION_UP}, {@link KeyEvent#KEYCODE_SYSTEM_NAVIGATION_DOWN}, {@link
- * KeyEvent#KEYCODE_SYSTEM_NAVIGATION_LEFT}, or {@link KeyEvent#KEYCODE_SYSTEM_NAVIGATION_RIGHT}),
- * RotaryService will move the focus to another view that can take focus in another (typically
- * adjacent) FocusArea.
- * <p>
- * If enabled, FocusArea can draw highlights when one of its descendants has focus and it's not in
- * touch mode.
- * <p>
- * When creating a navigation block in the layout file, if you intend to use a LinearLayout as a
- * container for that block, just use a FocusArea instead; otherwise wrap the block in a FocusArea.
- * <p>
- * DO NOT nest a FocusArea inside another FocusArea because it will result in undefined navigation
- * behavior.
- */
-public class FocusArea extends LinearLayout {
-
-    private static final String TAG = "FocusArea";
-
-    private static final int INVALID_DIMEN = -1;
-
-    private static final int INVALID_DIRECTION = -1;
-
-    private static final List<Integer> NUDGE_DIRECTIONS =
-            Collections.unmodifiableList(Arrays.asList(
-                    FOCUS_LEFT, FOCUS_RIGHT, FOCUS_UP, FOCUS_DOWN));
-
-    /** Whether the FocusArea's descendant has focus (the FocusArea itself is not focusable). */
-    private boolean mHasFocus;
-
-    /**
-     * Whether to draw {@link #mForegroundHighlight} when one of the FocusArea's descendants has
-     * focus and it's not in touch mode.
-     */
-    private boolean mEnableForegroundHighlight;
-
-    /**
-     * Whether to draw {@link #mBackgroundHighlight} when one of the FocusArea's descendants has
-     * focus and it's not in touch mode.
-     */
-    private boolean mEnableBackgroundHighlight;
-
-    /**
-     * Highlight (typically outline of the FocusArea) drawn on top of the FocusArea and its
-     * descendants.
-     */
-    private Drawable mForegroundHighlight;
-
-    /**
-     * Highlight (typically a solid or gradient shape) drawn on top of the FocusArea but behind its
-     * descendants.
-     */
-    private Drawable mBackgroundHighlight;
-
-    /** The padding (in pixels) of the FocusArea highlight. */
-    private int mPaddingLeft;
-    private int mPaddingRight;
-    private int mPaddingTop;
-    private int mPaddingBottom;
-
-    /** The offset (in pixels) of the FocusArea's bounds. */
-    private int mLeftOffset;
-    private int mRightOffset;
-    private int mTopOffset;
-    private int mBottomOffset;
-
-    /** Whether the layout direction is {@link View#LAYOUT_DIRECTION_RTL}. */
-    private boolean mRtl;
-
-    /** The ID of the view specified in {@code app:defaultFocus}. */
-    private int mDefaultFocusId;
-    /** The view specified in {@code app:defaultFocus}. */
-    @Nullable
-    private View mDefaultFocusView;
-
-    /**
-     * Whether to focus on the default focus view when nudging to the FocusArea, even if there was
-     * another view in the FocusArea focused before.
-     */
-    private boolean mDefaultFocusOverridesHistory;
-
-    /**
-     * Map from direction to nudge shortcut IDs specified in {@code app:nudgeLeftShortcut},
-     * {@code app:nudgRightShortcut}, {@code app:nudgeUpShortcut}, and {@code app
-     * :nudgeDownShortcut}.
-     */
-    private final SparseIntArray mSpecifiedNudgeShortcutIdMap = new SparseIntArray();
-
-    /** Map from direction to specified nudge shortcut views. */
-    private SparseArray<View> mSpecifiedNudgeShortcutMap;
-
-    /**
-     * Map from direction to nudge target FocusArea IDs specified in {@code app:nudgeLeft},
-     * {@code app:nudgRight}, {@code app:nudgeUp}, or {@code app:nudgeDown}.
-     */
-    private final SparseIntArray mSpecifiedNudgeIdMap = new SparseIntArray();
-
-    /** Map from direction to specified nudge target FocusAreas. */
-    private SparseArray<FocusArea> mSpecifiedNudgeFocusAreaMap;
-
-    /** Whether wrap-around is enabled. */
-    private boolean mWrapAround;
-
-    /**
-     * Cache of focus history and nudge history of the rotary controller.
-     * <p>
-     * For focus history, the previously focused view and a timestamp will be saved when the
-     * focused view has changed.
-     * <p>
-     * For nudge history, the target FocusArea, direction, and a timestamp will be saved when the
-     * focus has moved from another FocusArea to this FocusArea. There are 2 cases:
-     * <ul>
-     *     <li>The focus is moved to another FocusArea because this FocusArea has called {@link
-     *         #nudgeToAnotherFocusArea}. In this case, the target FocusArea and direction are
-     *         trivial to this FocusArea.
-     *     <li>The focus is moved to this FocusArea because RotaryService has performed {@link
-     *         AccessibilityNodeInfo#ACTION_FOCUS} on this FocusArea. In this case, this FocusArea
-     *         can get the source FocusArea through the {@link
-     *         android.view.ViewTreeObserver.OnGlobalFocusChangeListener} registered, and can get
-     *         the direction when handling the action. Since the listener is triggered before
-     *         {@link #requestFocus} returns (which is called when handling the action), the
-     *         source FocusArea is revealed earlier than the direction, so the nudge history should
-     *         be saved when the direction is revealed.
-     * </ul>
-     */
-    private RotaryCache mRotaryCache;
-
-    /** Whether to clear focus area history when the user rotates the rotary controller. */
-    private boolean mClearFocusAreaHistoryWhenRotating;
-
-    /** The FocusArea that had focus before this FocusArea, if any. */
-    private FocusArea mPreviousFocusArea;
-
-    /** The focused view in this FocusArea, if any. */
-    private View mFocusedView;
-
-    private final OnGlobalFocusChangeListener mFocusChangeListener =
-            (oldFocus, newFocus) -> {
-                boolean hasFocus = hasFocus();
-                saveFocusHistory(hasFocus);
-                maybeUpdatePreviousFocusArea(hasFocus, oldFocus);
-                maybeClearFocusAreaHistory(hasFocus, oldFocus);
-                maybeUpdateFocusAreaHighlight(hasFocus);
-                mHasFocus = hasFocus;
-            };
-
-    public FocusArea(Context context) {
-        super(context);
-        init(context, null);
-    }
-
-    public FocusArea(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        init(context, attrs);
-    }
-
-    public FocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(context, attrs);
-    }
-
-    public FocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(context, attrs);
-    }
-
-    private void init(Context context, @Nullable AttributeSet attrs) {
-        Resources resources = getContext().getResources();
-        mEnableForegroundHighlight = resources.getBoolean(
-                R.bool.car_ui_enable_focus_area_foreground_highlight);
-        mEnableBackgroundHighlight = resources.getBoolean(
-                R.bool.car_ui_enable_focus_area_background_highlight);
-        mForegroundHighlight = resources.getDrawable(
-                R.drawable.car_ui_focus_area_foreground_highlight, getContext().getTheme());
-        mBackgroundHighlight = resources.getDrawable(
-                R.drawable.car_ui_focus_area_background_highlight, getContext().getTheme());
-
-        mClearFocusAreaHistoryWhenRotating = resources.getBoolean(
-                R.bool.car_ui_clear_focus_area_history_when_rotating);
-
-        @RotaryCache.CacheType
-        int focusHistoryCacheType = resources.getInteger(R.integer.car_ui_focus_history_cache_type);
-        int focusHistoryExpirationPeriodMs =
-                resources.getInteger(R.integer.car_ui_focus_history_expiration_period_ms);
-        @RotaryCache.CacheType
-        int focusAreaHistoryCacheType = resources.getInteger(
-                R.integer.car_ui_focus_area_history_cache_type);
-        int focusAreaHistoryExpirationPeriodMs =
-                resources.getInteger(R.integer.car_ui_focus_area_history_expiration_period_ms);
-        mRotaryCache = new RotaryCache(focusHistoryCacheType, focusHistoryExpirationPeriodMs,
-                focusAreaHistoryCacheType, focusAreaHistoryExpirationPeriodMs);
-
-        // Ensure that an AccessibilityNodeInfo is created for this view.
-        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-
-        // By default all ViewGroup subclasses do not call their draw() and onDraw() methods. We
-        // should enable it since we override these methods.
-        setWillNotDraw(false);
-
-        initAttrs(context, attrs);
-    }
-
-    private void saveFocusHistory(boolean hasFocus) {
-        // Save focus history and clear mFocusedView if focus is leaving this FocusArea.
-        if (!hasFocus) {
-            if (mHasFocus) {
-                mRotaryCache.saveFocusedView(mFocusedView, SystemClock.uptimeMillis());
-                mFocusedView = null;
-            }
-            return;
-        }
-
-        // Update mFocusedView if a view inside this FocusArea is focused.
-        View v = getFocusedChild();
-        while (v != null) {
-            if (v.isFocused()) {
-                break;
-            }
-            v = v instanceof ViewGroup ? ((ViewGroup) v).getFocusedChild() : null;
-        }
-        mFocusedView = v;
-    }
-
-    /**
-     * Updates {@link #mPreviousFocusArea} when the focus has moved from another FocusArea to this
-     * FocusArea, and sets it to {@code null} in any other cases.
-     */
-    private void maybeUpdatePreviousFocusArea(boolean hasFocus, View oldFocus) {
-        if (mHasFocus || !hasFocus || oldFocus == null || oldFocus instanceof FocusParkingView) {
-            mPreviousFocusArea = null;
-            return;
-        }
-        mPreviousFocusArea = ViewUtils.getAncestorFocusArea(oldFocus);
-        if (mPreviousFocusArea == null) {
-            Log.w(TAG, "No parent FocusArea for " + oldFocus);
-        }
-    }
-
-    /**
-     * Clears FocusArea nudge history when the user rotates the controller to move focus within this
-     * FocusArea.
-     */
-    private void maybeClearFocusAreaHistory(boolean hasFocus, View oldFocus) {
-        if (!mClearFocusAreaHistoryWhenRotating) {
-            return;
-        }
-        if (!hasFocus || oldFocus == null) {
-            return;
-        }
-        FocusArea oldFocusArea = ViewUtils.getAncestorFocusArea(oldFocus);
-        if (oldFocusArea != this) {
-            return;
-        }
-        mRotaryCache.clearFocusAreaHistory();
-    }
-
-    /** Updates highlight of the FocusArea if this FocusArea has gained or lost focus. */
-    private void maybeUpdateFocusAreaHighlight(boolean hasFocus) {
-        if (!mEnableBackgroundHighlight && !mEnableForegroundHighlight) {
-            return;
-        }
-        if (mHasFocus != hasFocus) {
-            invalidate();
-        }
-    }
-
-    private void initAttrs(Context context, @Nullable AttributeSet attrs) {
-        if (attrs == null) {
-            return;
-        }
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FocusArea);
-        try {
-            mDefaultFocusId = a.getResourceId(R.styleable.FocusArea_defaultFocus, View.NO_ID);
-
-            // Initialize the highlight padding. The padding, for example, left padding, is set in
-            // the following order:
-            // 1. if highlightPaddingStart (or highlightPaddingEnd in RTL layout) specified, use it
-            // 2. otherwise, if highlightPaddingHorizontal is specified, use it
-            // 3. otherwise use 0
-
-            int paddingStart = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_highlightPaddingStart, INVALID_DIMEN);
-            if (paddingStart == INVALID_DIMEN) {
-                paddingStart = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_highlightPaddingHorizontal, 0);
-            }
-
-            int paddingEnd = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_highlightPaddingEnd, INVALID_DIMEN);
-            if (paddingEnd == INVALID_DIMEN) {
-                paddingEnd = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_highlightPaddingHorizontal, 0);
-            }
-
-            mRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-            mPaddingLeft = mRtl ? paddingEnd : paddingStart;
-            mPaddingRight = mRtl ? paddingStart : paddingEnd;
-
-            mPaddingTop = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_highlightPaddingTop, INVALID_DIMEN);
-            if (mPaddingTop == INVALID_DIMEN) {
-                mPaddingTop = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_highlightPaddingVertical, 0);
-            }
-
-            mPaddingBottom = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_highlightPaddingBottom, INVALID_DIMEN);
-            if (mPaddingBottom == INVALID_DIMEN) {
-                mPaddingBottom = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_highlightPaddingVertical, 0);
-            }
-
-            // Initialize the offset of the FocusArea's bounds. The offset, for example, left
-            // offset, is set in the following order:
-            // 1. if startBoundOffset (or endBoundOffset in RTL layout) specified, use it
-            // 2. otherwise, if horizontalBoundOffset is specified, use it
-            // 3. otherwise use mPaddingLeft
-
-            int startOffset = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_startBoundOffset, INVALID_DIMEN);
-            if (startOffset == INVALID_DIMEN) {
-                startOffset = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_horizontalBoundOffset, paddingStart);
-            }
-
-            int endOffset = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_endBoundOffset, INVALID_DIMEN);
-            if (endOffset == INVALID_DIMEN) {
-                endOffset = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_horizontalBoundOffset, paddingEnd);
-            }
-
-            mLeftOffset = mRtl ? endOffset : startOffset;
-            mRightOffset = mRtl ? startOffset : endOffset;
-
-            mTopOffset = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_topBoundOffset, INVALID_DIMEN);
-            if (mTopOffset == INVALID_DIMEN) {
-                mTopOffset = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_verticalBoundOffset, mPaddingTop);
-            }
-
-            mBottomOffset = a.getDimensionPixelSize(
-                    R.styleable.FocusArea_bottomBoundOffset, INVALID_DIMEN);
-            if (mBottomOffset == INVALID_DIMEN) {
-                mBottomOffset = a.getDimensionPixelSize(
-                        R.styleable.FocusArea_verticalBoundOffset, mPaddingBottom);
-            }
-
-            // Handle new nudge shortcut attributes.
-            if (a.hasValue(R.styleable.FocusArea_nudgeLeftShortcut)) {
-                mSpecifiedNudgeShortcutIdMap.put(FOCUS_LEFT,
-                        a.getResourceId(R.styleable.FocusArea_nudgeLeftShortcut, View.NO_ID));
-            }
-            if (a.hasValue(R.styleable.FocusArea_nudgeRightShortcut)) {
-                mSpecifiedNudgeShortcutIdMap.put(FOCUS_RIGHT,
-                        a.getResourceId(R.styleable.FocusArea_nudgeRightShortcut, View.NO_ID));
-            }
-            if (a.hasValue(R.styleable.FocusArea_nudgeUpShortcut)) {
-                mSpecifiedNudgeShortcutIdMap.put(FOCUS_UP,
-                        a.getResourceId(R.styleable.FocusArea_nudgeUpShortcut, View.NO_ID));
-            }
-            if (a.hasValue(R.styleable.FocusArea_nudgeDownShortcut)) {
-                mSpecifiedNudgeShortcutIdMap.put(FOCUS_DOWN,
-                        a.getResourceId(R.styleable.FocusArea_nudgeDownShortcut, View.NO_ID));
-            }
-
-            // Handle legacy nudge shortcut attributes.
-            int nudgeShortcutId = a.getResourceId(R.styleable.FocusArea_nudgeShortcut, View.NO_ID);
-            int nudgeShortcutDirection = a.getInt(
-                    R.styleable.FocusArea_nudgeShortcutDirection, INVALID_DIRECTION);
-            if ((nudgeShortcutId == View.NO_ID) ^ (nudgeShortcutDirection == INVALID_DIRECTION)) {
-                throw new IllegalStateException("nudgeShortcut and nudgeShortcutDirection must "
-                        + "be specified together");
-            }
-            if (nudgeShortcutId != View.NO_ID) {
-                if (mSpecifiedNudgeShortcutIdMap.size() > 0) {
-                    throw new IllegalStateException(
-                            "Don't use nudgeShortcut/nudgeShortcutDirection and nudge*Shortcut in "
-                                    + "the same FocusArea. Use nudge*Shortcut only.");
-                }
-                mSpecifiedNudgeShortcutIdMap.put(nudgeShortcutDirection, nudgeShortcutId);
-            }
-
-            // Handle nudge targets.
-            if (a.hasValue(R.styleable.FocusArea_nudgeLeft)) {
-                mSpecifiedNudgeIdMap.put(FOCUS_LEFT,
-                        a.getResourceId(R.styleable.FocusArea_nudgeLeft, View.NO_ID));
-            }
-            if (a.hasValue(R.styleable.FocusArea_nudgeRight)) {
-                mSpecifiedNudgeIdMap.put(FOCUS_RIGHT,
-                        a.getResourceId(R.styleable.FocusArea_nudgeRight, View.NO_ID));
-            }
-            if (a.hasValue(R.styleable.FocusArea_nudgeUp)) {
-                mSpecifiedNudgeIdMap.put(FOCUS_UP,
-                        a.getResourceId(R.styleable.FocusArea_nudgeUp, View.NO_ID));
-            }
-            if (a.hasValue(R.styleable.FocusArea_nudgeDown)) {
-                mSpecifiedNudgeIdMap.put(FOCUS_DOWN,
-                        a.getResourceId(R.styleable.FocusArea_nudgeDown, View.NO_ID));
-            }
-
-            mDefaultFocusOverridesHistory = a.getBoolean(
-                    R.styleable.FocusArea_defaultFocusOverridesHistory, false);
-
-            mWrapAround = a.getBoolean(R.styleable.FocusArea_wrapAround, false);
-        } finally {
-            a.recycle();
-        }
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        if (mDefaultFocusId != View.NO_ID) {
-            mDefaultFocusView = requireViewById(mDefaultFocusId);
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        if (mRtl != rtl) {
-            mRtl = rtl;
-
-            int temp = mPaddingLeft;
-            mPaddingLeft = mPaddingRight;
-            mPaddingRight = temp;
-
-            temp = mLeftOffset;
-            mLeftOffset = mRightOffset;
-            mRightOffset = temp;
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        getViewTreeObserver().addOnGlobalFocusChangeListener(mFocusChangeListener);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        getViewTreeObserver().removeOnGlobalFocusChangeListener(mFocusChangeListener);
-        super.onDetachedFromWindow();
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasWindowFocus) {
-        // To ensure the focus is initialized properly in rotary mode when there is a window focus
-        // change, this FocusArea will grab the focus if nothing is focused or the currently
-        // focused view's FocusLevel is lower than REGULAR_FOCUS.
-        if (hasWindowFocus && !isInTouchMode()) {
-            maybeInitFocus();
-        }
-        super.onWindowFocusChanged(hasWindowFocus);
-    }
-
-    /**
-     * Focuses on another view in this FocusArea if nothing is focused or the currently focused
-     * view's FocusLevel is lower than REGULAR_FOCUS.
-     */
-    private boolean maybeInitFocus() {
-        View root = getRootView();
-        View focus = root.findFocus();
-        return ViewUtils.initFocus(root, focus);
-    }
-
-    /**
-     * Focuses on a view in this FocusArea if the view is a better focus candidate than the
-     * currently focused view.
-     */
-    private boolean maybeAdjustFocus() {
-        View root = getRootView();
-        View focus = root.findFocus();
-        return ViewUtils.adjustFocus(root, focus);
-    }
-
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        switch (action) {
-            case ACTION_FOCUS:
-                // Repurpose ACTION_FOCUS to focus on its descendant. We can do this because
-                // FocusArea is not focusable and it didn't consume ACTION_FOCUS previously.
-                boolean success = focusOnDescendant();
-                if (success && mPreviousFocusArea != null) {
-                    int direction = getNudgeDirection(arguments);
-                    if (direction != INVALID_DIRECTION) {
-                        saveFocusAreaHistory(direction, mPreviousFocusArea, this,
-                                SystemClock.uptimeMillis());
-                    }
-                }
-                return success;
-            case ACTION_NUDGE_SHORTCUT:
-                return nudgeToShortcutView(arguments);
-            case ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA:
-                return nudgeToAnotherFocusArea(arguments);
-            default:
-                return super.performAccessibilityAction(action, arguments);
-        }
-    }
-
-    private boolean focusOnDescendant() {
-        View lastFocusedView = mRotaryCache.getFocusedView(SystemClock.uptimeMillis());
-        return ViewUtils.adjustFocus(this, lastFocusedView, mDefaultFocusOverridesHistory);
-    }
-
-    /**
-     * Gets the {@code app:defaultFocus} view.
-     *
-     * @hidden
-     */
-    @Nullable
-    public View getDefaultFocusView() {
-        return mDefaultFocusView;
-    }
-
-    private boolean nudgeToShortcutView(Bundle arguments) {
-        int direction = getNudgeDirection(arguments);
-        View targetView = getSpecifiedShortcut(direction);
-        if (targetView == null) {
-            // No nudge shortcut configured for the given direction.
-            return false;
-        }
-        if (targetView.isFocused()) {
-            // The nudge shortcut view is already focused; return false so that the user can
-            // nudge to another FocusArea.
-            return false;
-        }
-        return ViewUtils.requestFocus(targetView);
-    }
-
-    private boolean nudgeToAnotherFocusArea(Bundle arguments) {
-        int direction = getNudgeDirection(arguments);
-        long elapsedRealtime = SystemClock.uptimeMillis();
-
-        // Try to nudge to specified FocusArea, if any.
-        FocusArea targetFocusArea = getSpecifiedFocusArea(direction);
-        boolean success = targetFocusArea != null && targetFocusArea.focusOnDescendant();
-
-        // If failed, try to nudge to cached FocusArea, if any.
-        if (!success) {
-            targetFocusArea = mRotaryCache.getCachedFocusArea(direction, elapsedRealtime);
-            success = targetFocusArea != null && targetFocusArea.focusOnDescendant();
-        }
-
-        return success;
-    }
-
-    private static int getNudgeDirection(Bundle arguments) {
-        return arguments == null
-                ? INVALID_DIRECTION
-                : arguments.getInt(NUDGE_DIRECTION, INVALID_DIRECTION);
-    }
-
-    private void saveFocusAreaHistory(int direction, @NonNull FocusArea sourceFocusArea,
-            @NonNull FocusArea targetFocusArea, long elapsedRealtime) {
-        // Save one-way rather than two-way nudge history to avoid infinite nudge loop.
-        if (sourceFocusArea.mRotaryCache.getCachedFocusArea(direction, elapsedRealtime) == null) {
-            // Save reversed nudge history so that the users can nudge back to where they were.
-            int oppositeDirection = getOppositeDirection(direction);
-            targetFocusArea.mRotaryCache.saveFocusArea(oppositeDirection, sourceFocusArea,
-                    elapsedRealtime);
-        }
-    }
-
-    /** Returns the direction opposite the given {@code direction} */
-    private static int getOppositeDirection(int direction) {
-        switch (direction) {
-            case View.FOCUS_LEFT:
-                return View.FOCUS_RIGHT;
-            case View.FOCUS_RIGHT:
-                return View.FOCUS_LEFT;
-            case View.FOCUS_UP:
-                return View.FOCUS_DOWN;
-            case View.FOCUS_DOWN:
-                return View.FOCUS_UP;
-            default: // fall out
-        }
-        throw new IllegalArgumentException("direction must be "
-                + "FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, or FOCUS_RIGHT.");
-    }
-
-    @Nullable
-    private FocusArea getSpecifiedFocusArea(int direction) {
-        maybeInitializeSpecifiedFocusAreas();
-        return mSpecifiedNudgeFocusAreaMap.get(direction);
-    }
-
-    @Nullable
-    private View getSpecifiedShortcut(int direction) {
-        maybeInitializeSpecifiedShortcuts();
-        return mSpecifiedNudgeShortcutMap.get(direction);
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        // Draw highlight on top of this FocusArea (including its background and content) but
-        // behind its children.
-        if (mEnableBackgroundHighlight && mHasFocus && !isInTouchMode()) {
-            mBackgroundHighlight.setBounds(
-                    mPaddingLeft + getScrollX(),
-                    mPaddingTop + getScrollY(),
-                    getScrollX() + getWidth() - mPaddingRight,
-                    getScrollY() + getHeight() - mPaddingBottom);
-            mBackgroundHighlight.draw(canvas);
-        }
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        super.draw(canvas);
-
-        // Draw highlight on top of this FocusArea (including its background and content) and its
-        // children (including background, content, focus highlight, etc).
-        if (mEnableForegroundHighlight && mHasFocus && !isInTouchMode()) {
-            mForegroundHighlight.setBounds(
-                    mPaddingLeft + getScrollX(),
-                    mPaddingTop + getScrollY(),
-                    getScrollX() + getWidth() - mPaddingRight,
-                    getScrollY() + getHeight() - mPaddingBottom);
-            mForegroundHighlight.draw(canvas);
-        }
-    }
-
-    @Override
-    public CharSequence getAccessibilityClassName() {
-        return FocusArea.class.getName();
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        Bundle bundle = info.getExtras();
-        bundle.putInt(FOCUS_AREA_LEFT_BOUND_OFFSET, mLeftOffset);
-        bundle.putInt(FOCUS_AREA_RIGHT_BOUND_OFFSET, mRightOffset);
-        bundle.putInt(FOCUS_AREA_TOP_BOUND_OFFSET, mTopOffset);
-        bundle.putInt(FOCUS_AREA_BOTTOM_BOUND_OFFSET, mBottomOffset);
-    }
-
-    @Override
-    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
-        if (isInTouchMode()) {
-            return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
-        }
-        return maybeAdjustFocus();
-    }
-
-    @Override
-    public boolean restoreDefaultFocus() {
-        return maybeAdjustFocus();
-    }
-
-    private void maybeInitializeSpecifiedFocusAreas() {
-        if (mSpecifiedNudgeFocusAreaMap != null) {
-            return;
-        }
-        View root = getRootView();
-        mSpecifiedNudgeFocusAreaMap = new SparseArray<>();
-        for (int direction : NUDGE_DIRECTIONS) {
-            int id = mSpecifiedNudgeIdMap.get(direction, View.NO_ID);
-            mSpecifiedNudgeFocusAreaMap.put(direction, root.findViewById(id));
-        }
-    }
-
-    private void maybeInitializeSpecifiedShortcuts() {
-        if (mSpecifiedNudgeShortcutMap != null) {
-            return;
-        }
-        View root = getRootView();
-        mSpecifiedNudgeShortcutMap = new SparseArray<>();
-        for (int direction : NUDGE_DIRECTIONS) {
-            int id = mSpecifiedNudgeShortcutIdMap.get(direction, View.NO_ID);
-            mSpecifiedNudgeShortcutMap.put(direction, root.findViewById(id));
-        }
-    }
-
-    /**
-     * Sets the padding (in pixels) of the FocusArea highlight.
-     * <p>
-     * It doesn't affect other values, such as the paddings on its child views.
-     */
-    public void setHighlightPadding(int left, int top, int right, int bottom) {
-        if (mPaddingLeft == left && mPaddingTop == top && mPaddingRight == right
-                && mPaddingBottom == bottom) {
-            return;
-        }
-        mPaddingLeft = left;
-        mPaddingTop = top;
-        mPaddingRight = right;
-        mPaddingBottom = bottom;
-        invalidate();
-    }
-
-    /**
-     * Sets the offset (in pixels) of the FocusArea's bounds.
-     * <p>
-     * It only affects the perceived bounds for the purposes of finding the nudge target. It doesn't
-     * affect the FocusArea's view bounds or highlight bounds. The offset should only be used when
-     * FocusAreas are overlapping and nudge interaction is ambiguous.
-     */
-    public void setBoundsOffset(int left, int top, int right, int bottom) {
-        mLeftOffset = left;
-        mTopOffset = top;
-        mRightOffset = right;
-        mBottomOffset = bottom;
-    }
-
-    /** Sets whether wrap-around is enabled for this FocusArea. */
-    public void setWrapAround(boolean wrapAround) {
-        mWrapAround = wrapAround;
-    }
-
-    /** Sets the default focus view in this FocusArea. */
-    public void setDefaultFocus(@NonNull View defaultFocus) {
-        mDefaultFocusView = defaultFocus;
-    }
-
-    /**
-     * Sets the nudge shortcut for the given {@code direction}. Removes the nudge shortcut if {@code
-     * view} is {@code null}.
-     */
-    public void setNudgeShortcut(int direction, @Nullable View view) {
-        if (!NUDGE_DIRECTIONS.contains(direction)) {
-            throw new IllegalArgumentException("direction must be "
-                    + "FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, or FOCUS_RIGHT.");
-        }
-        maybeInitializeSpecifiedShortcuts();
-        if (view == null) {
-            mSpecifiedNudgeShortcutMap.remove(direction);
-        } else {
-            mSpecifiedNudgeShortcutMap.put(direction, view);
-        }
-    }
-
-    /**
-     * @inheritDoc
-     * <p>
-     * When {@link #mWrapAround} is true, the search is restricted to descendants of this
-     * {@link FocusArea}.
-     */
-    @Override
-    public View focusSearch(View focused, int direction) {
-        if (mWrapAround) {
-            return FocusFinder.getInstance().findNextFocus(/* root= */ this, focused, direction);
-        }
-        return super.focusSearch(focused, direction);
-    }
-
-    @VisibleForTesting
-    void enableForegroundHighlight() {
-        mEnableForegroundHighlight = true;
-    }
-
-    @VisibleForTesting
-    void setDefaultFocusOverridesHistory(boolean override) {
-        mDefaultFocusOverridesHistory = override;
-    }
-
-    @VisibleForTesting
-    void setRotaryCache(@NonNull RotaryCache rotaryCache) {
-        mRotaryCache = rotaryCache;
-    }
-
-    @VisibleForTesting
-    void setClearFocusAreaHistoryWhenRotating(boolean clear) {
-        mClearFocusAreaHistoryWhenRotating = clear;
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/FocusParkingView.java b/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/FocusParkingView.java
deleted file mode 100644
index ab42857..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/FocusParkingView.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
-
-import static com.android.car.ui.utils.RotaryConstants.ACTION_HIDE_IME;
-import static com.android.car.ui.utils.RotaryConstants.ACTION_RESTORE_DEFAULT_FOCUS;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-import android.view.inputmethod.InputMethodManager;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.utils.ViewUtils;
-
-/**
- * A transparent {@link View} that can take focus. It's used by {@link
- * com.android.car.rotary.RotaryService} to support rotary controller navigation. It's also used to
- * initialize the focus when in rotary mode.
- * <p>
- * To support the rotary controller, each {@link android.view.Window} must have a FocusParkingView
- * as the first focusable view in the view tree, and outside of all {@link FocusArea}s.
- * <p>
- * Android doesn't clear focus automatically when focus is set in another window. If we try to clear
- * focus in the previous window, Android will re-focus a view in that window, resulting in two
- * windows being focused simultaneously. Adding this view to each window can fix this issue. This
- * view is transparent and its default focus highlight is disabled, so it's invisible to the user no
- * matter whether it's focused or not. It can take focus so that RotaryService can "park" the focus
- * on it to remove the focus highlight.
- * <p>
- * If there is only one focus area in the current window, rotating the controller within the focus
- * area will cause RotaryService to move the focus around from the view on the right to the view on
- * the left or vice versa. Adding this view to each window can fix this issue. When RotaryService
- * finds out the focus target is a FocusParkingView, it will know a wrap-around is going to happen.
- * Then it will avoid the wrap-around by not moving focus.
- * <p>
- * To ensure the focus is initialized properly when there is a window change, the FocusParkingView
- * will not get focused when the framework wants to focus on it. Instead, it will try to find a
- * better focus target in the window and focus on the target. That said, the FocusParkingView can
- * still be focused in order to clear focus highlight in the window, such as when RotaryService
- * performs {@link android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS} on the
- * FocusParkingView, or the window has lost focus.
- */
-public class FocusParkingView extends View {
-
-    /**
-     * The focused view in the window containing this FocusParkingView. It's null if no view is
-     * focused, or the focused view is a FocusParkingView.
-     */
-    @Nullable
-    private View mFocusedView;
-
-    /** The cache to save the previously focused view. */
-    private RotaryCache.FocusCache mFocusCache;
-
-    /** The scrollable container that contains the {@link #mFocusedView}, if any. */
-    @Nullable
-    ViewGroup mScrollableContainer;
-
-    /**
-     * Whether to restore focus when the frameworks wants to focus this view. When false, this view
-     * allows itself to be focused instead. This should be false for the {@code FocusParkingView} in
-     * a {@code TaskView}. The default value is true.
-     */
-    private boolean mShouldRestoreFocus = true;
-
-    /**
-     * Whether to focus on the default focus view when nudging to the explicit focus area containing
-     * this FocusParkingView, even if there was another view in the explicit focus area focused
-     * before.
-     */
-    private boolean mDefaultFocusOverridesHistory;
-
-    private final OnGlobalFocusChangeListener mFocusChangeListener =
-            (oldFocus, newFocus) -> {
-                // Keep track of the focused view so that we can recover focus when it's removed.
-                View focusedView = newFocus instanceof FocusParkingView ? null : newFocus;
-                updateFocusedView(focusedView);
-            };
-
-    public FocusParkingView(Context context) {
-        super(context);
-        init(context, /* attrs= */ null);
-    }
-
-    public FocusParkingView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        init(context, attrs);
-    }
-
-    public FocusParkingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(context, attrs);
-    }
-
-    public FocusParkingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(context, attrs);
-    }
-
-    private void init(Context context, @Nullable AttributeSet attrs) {
-        if (attrs != null) {
-            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FocusParkingView);
-            mShouldRestoreFocus = a.getBoolean(R.styleable.FocusParkingView_shouldRestoreFocus,
-                    /* defValue= */ true);
-        }
-
-        // This view is focusable, visible and enabled so it can take focus.
-        setFocusable(View.FOCUSABLE);
-        setVisibility(VISIBLE);
-        setEnabled(true);
-
-        // This view is not clickable so it won't affect the app's behavior when the user clicks on
-        // it by accident.
-        setClickable(false);
-
-        // This view is always transparent.
-        setAlpha(0f);
-
-        // Prevent Android from drawing the default focus highlight for this view when it's focused.
-        setDefaultFocusHighlightEnabled(false);
-
-        Resources resources = getResources();
-        @RotaryCache.CacheType
-        int focusHistoryCacheType = resources.getInteger(R.integer.car_ui_focus_history_cache_type);
-        int focusHistoryExpirationPeriodMs =
-                resources.getInteger(R.integer.car_ui_focus_history_expiration_period_ms);
-        mFocusCache =
-                new RotaryCache.FocusCache(focusHistoryCacheType, focusHistoryExpirationPeriodMs);
-
-        mDefaultFocusOverridesHistory = resources.getBoolean(
-                R.bool.car_ui_focus_area_default_focus_overrides_history);
-    }
-
-    private void updateFocusedView(@Nullable View focusedView) {
-        if (mFocusedView != null) {
-            mFocusCache.setFocusedView(mFocusedView, SystemClock.uptimeMillis());
-        }
-        mFocusedView = focusedView;
-        mScrollableContainer = ViewUtils.getAncestorScrollableContainer(focusedView);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // This size of the view is always 1 x 1 pixel, no matter what value is set in the layout
-        // file (match_parent, wrap_content, 100dp, 0dp, etc). Small size is to ensure it has little
-        // impact on the layout, non-zero size is to ensure it can take focus.
-        setMeasuredDimension(1, 1);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        getViewTreeObserver().addOnGlobalFocusChangeListener(mFocusChangeListener);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        getViewTreeObserver().removeOnGlobalFocusChangeListener(mFocusChangeListener);
-        super.onDetachedFromWindow();
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasWindowFocus) {
-        if (!hasWindowFocus) {
-            // We need to clear the focus highlight(by parking the focus on the FocusParkingView)
-            // once the current window goes to background. This can't be done by RotaryService
-            // because RotaryService sees the window as removed, thus can't perform any action
-            // (such as focus, clear focus) on the nodes in the window. So FocusParkingView has to
-            // grab the focus proactively.
-            super.requestFocus(FOCUS_DOWN, null);
-
-            // OnGlobalFocusChangeListener won't be triggered when the window lost focus, so reset
-            // the focused view here.
-            updateFocusedView(null);
-        } else if (isFocused()) {
-            // When FocusParkingView is focused and the window just gets focused, transfer the view
-            // focus to a non-FocusParkingView in the window.
-            restoreFocusInRoot(/* checkForTouchMode= */ true);
-        }
-        super.onWindowFocusChanged(hasWindowFocus);
-    }
-
-    @Override
-    public CharSequence getAccessibilityClassName() {
-        return FocusParkingView.class.getName();
-    }
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        switch (action) {
-            case ACTION_RESTORE_DEFAULT_FOCUS:
-                return restoreFocusInRoot(/* checkForTouchMode= */ false);
-            case ACTION_HIDE_IME:
-                InputMethodManager inputMethodManager =
-                        getContext().getSystemService(InputMethodManager.class);
-                return inputMethodManager.hideSoftInputFromWindow(getWindowToken(),
-                        /* flags= */ 0);
-            case ACTION_FOCUS:
-                // Don't leave this to View to handle as it will exit touch mode.
-                if (!hasFocus()) {
-                    return super.requestFocus(FOCUS_DOWN, null);
-                }
-                return false;
-        }
-        return super.performAccessibilityAction(action, arguments);
-    }
-
-    @Override
-    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
-        if (!mShouldRestoreFocus) {
-            return super.requestFocus(direction, previouslyFocusedRect);
-        }
-        // Find a better target to focus instead of focusing this FocusParkingView when the
-        // framework wants to focus it.
-        return restoreFocusInRoot(/* checkForTouchMode= */ true);
-    }
-
-    @Override
-    public boolean restoreDefaultFocus() {
-        if (!mShouldRestoreFocus) {
-            return super.restoreDefaultFocus();
-        }
-        // Find a better target to focus instead of focusing this FocusParkingView when the
-        // framework wants to focus it.
-        return restoreFocusInRoot(/* checkForTouchMode= */ true);
-    }
-
-    /**
-     * Sets whether this view should restore focus when the framework wants to focus this view. When
-     * set to false, this view allows itself to be focused instead. This should be set to false for
-     * the {@code FocusParkingView} in a {@code TaskView}.  The default value is true.
-     */
-    public void setShouldRestoreFocus(boolean shouldRestoreFocus) {
-        mShouldRestoreFocus = shouldRestoreFocus;
-    }
-
-    private boolean restoreFocusInRoot(boolean checkForTouchMode) {
-        // Don't do anything in touch mode if checkForTouchMode is true.
-        if (checkForTouchMode && isInTouchMode()) {
-            return false;
-        }
-
-        // When initializing the focus, if there is a focused view already, do nothing rather than
-        // moving focus to the view with highest priority. For example, when an item in
-        // RecyclerView is focused, and the RecyclerView does a full layout. See b/175630971.
-        if (mFocusedView != null && mFocusedView.isFocused() && mFocusedView.isAttachedToWindow()) {
-            return true;
-        }
-
-        // The focused view was in a scrollable container and the Framework unfocused it because it
-        // was scrolled off the screen. In this case focus on the scrollable container so that the
-        // rotary controller can scroll the scrollable container.
-        if (maybeFocusOnScrollableContainer()) {
-            return true;
-        }
-
-        // Otherwise try to find the best target view to focus.
-        View cachedFocusedView = mFocusCache.getFocusedView(SystemClock.uptimeMillis());
-        if (ViewUtils.adjustFocus(
-                getRootView(), cachedFocusedView, mDefaultFocusOverridesHistory)) {
-            return true;
-        }
-
-        // It failed to find a target view (e.g., all the views are not shown), so focus on this
-        // FocusParkingView as fallback.
-        return super.requestFocus(FOCUS_DOWN, /* previouslyFocusedRect= */ null);
-    }
-
-    private boolean maybeFocusOnScrollableContainer() {
-        // If the focused view was in a scrollable container and it was scrolled off the screen,
-        // focus on the scrollable container. When a view is scrolled off the screen, it is no
-        // longer attached to window and its parent is not null. When a view is removed, its parent
-        // is null. There is no need to focus on the scrollable container when its focused element
-        // is removed.
-        if (mFocusedView != null && !mFocusedView.isAttachedToWindow()
-                && mFocusedView.getParent() != null && mScrollableContainer != null
-                && mScrollableContainer.isAttachedToWindow() && mScrollableContainer.isShown()) {
-            RecyclerView recyclerView = mScrollableContainer instanceof RecyclerView
-                    ? (RecyclerView) mScrollableContainer
-                    : null;
-            if (mScrollableContainer.requestFocus()) {
-                if (recyclerView != null && recyclerView.isComputingLayout()) {
-                    // When a RecyclerView gains focus, it won't dispatch AccessibilityEvent if its
-                    // layout is not ready. So wait until its layout is ready then dispatch the
-                    // event.
-                    getViewTreeObserver().addOnGlobalLayoutListener(
-                            new OnGlobalLayoutListener() {
-                                @Override
-                                public void onGlobalLayout() {
-                                    // At this point the layout is complete and the dimensions of
-                                    // recyclerView and any child views are known.
-                                    recyclerView.sendAccessibilityEvent(TYPE_VIEW_FOCUSED);
-                                    getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                                }
-                            });
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/RotaryCache.java b/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/RotaryCache.java
deleted file mode 100644
index 97de7c3..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/RotaryCache.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import android.os.SystemClock;
-import android.view.View;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-
-/**
- * Cache used by {@link FocusArea} to save focus history and nudge history of the rotary controller.
- */
-class RotaryCache {
-    /** The cache is disabled. */
-    @VisibleForTesting
-    static final int CACHE_TYPE_DISABLED = 1;
-    /** Entries in the cache will expire after a period of time. */
-    @VisibleForTesting
-    static final int CACHE_TYPE_EXPIRED_AFTER_SOME_TIME = 2;
-    /** Entries in the cache will never expire. */
-    @VisibleForTesting
-    static final int CACHE_TYPE_NEVER_EXPIRE = 3;
-
-    @IntDef(flag = true, value = {
-            CACHE_TYPE_DISABLED, CACHE_TYPE_EXPIRED_AFTER_SOME_TIME, CACHE_TYPE_NEVER_EXPIRE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CacheType {
-    }
-
-    /** Cache of focused view. */
-    @NonNull
-    private final FocusCache mFocusCache;
-
-    /** Cache of FocusAreas that were nudged to. */
-    @NonNull
-    private final FocusAreaCache mFocusAreaCache;
-
-    /** A record of when a View was focused. */
-    private static class FocusHistory {
-        /** The focused view. */
-        @NonNull
-        final View mFocusedView;
-        /** The {@link SystemClock#uptimeMillis} when this history was recorded. */
-        final long mTimestamp;
-
-        FocusHistory(@NonNull View focusedView, long timestamp) {
-            mFocusedView = focusedView;
-            mTimestamp = timestamp;
-        }
-    }
-
-    /** Cache of focused view. */
-    static class FocusCache {
-        /** The cache type. */
-        @CacheType
-        final int mCacheType;
-        /** How many milliseconds before the entry in the cache expires. */
-        long mExpirationPeriodMs;
-        /** The record of focused view. */
-        @Nullable
-        FocusHistory mFocusHistory;
-
-        FocusCache(@CacheType int cacheType, final long expirationPeriodMs) {
-            mCacheType = cacheType;
-            mExpirationPeriodMs = expirationPeriodMs;
-            if (mCacheType == CACHE_TYPE_EXPIRED_AFTER_SOME_TIME && mExpirationPeriodMs <= 0) {
-                throw new IllegalArgumentException(
-                        "Expiration time must be positive if CacheType is "
-                                + "CACHE_TYPE_EXPIRED_AFTER_SOME_TIME");
-            }
-        }
-
-        View getFocusedView(long elapsedRealtime) {
-            return isValidHistory(elapsedRealtime) ? mFocusHistory.mFocusedView : null;
-        }
-
-        void setFocusedView(@Nullable View focusedView, long elapsedRealtime) {
-            if (mCacheType == CACHE_TYPE_DISABLED) {
-                return;
-            }
-            mFocusHistory = focusedView != null
-                    ? new FocusHistory(focusedView, elapsedRealtime)
-                    : null;
-        }
-
-        boolean isValidHistory(long elapsedRealtime) {
-            if (mFocusHistory == null) {
-                return false;
-            }
-            switch (mCacheType) {
-                case CACHE_TYPE_NEVER_EXPIRE:
-                    return true;
-                case CACHE_TYPE_EXPIRED_AFTER_SOME_TIME:
-                    return elapsedRealtime < mFocusHistory.mTimestamp + mExpirationPeriodMs;
-                default:
-                    return false;
-            }
-        }
-    }
-
-    /** A record of a FocusArea that was nudged to. */
-    private static class FocusAreaHistory {
-        /** The FocusArea that was nudged to. */
-        @NonNull
-        final FocusArea mFocusArea;
-        /** The {@link SystemClock#uptimeMillis} when this history was recorded. */
-        final long mTimestamp;
-
-        FocusAreaHistory(@NonNull FocusArea focusArea, long timestamp) {
-            mFocusArea = focusArea;
-            mTimestamp = timestamp;
-        }
-    }
-
-    /** Cache of FocusAreas that were nudged to. */
-    private static class FocusAreaCache extends HashMap<Integer, FocusAreaHistory> {
-        /** Type of the cache. */
-        @CacheType
-        private final int mCacheType;
-        /** How many milliseconds before an entry in the cache expires. */
-        private final int mExpirationPeriodMs;
-
-        FocusAreaCache(@CacheType int cacheType, int expirationPeriodMs) {
-            mCacheType = cacheType;
-            mExpirationPeriodMs = expirationPeriodMs;
-            if (mCacheType == CACHE_TYPE_EXPIRED_AFTER_SOME_TIME && mExpirationPeriodMs <= 0) {
-                throw new IllegalArgumentException(
-                        "Expiration time must be positive if CacheType is "
-                                + "CACHE_TYPE_EXPIRED_AFTER_SOME_TIME");
-            }
-        }
-
-        void put(int direction, @NonNull FocusArea targetFocusArea, long elapsedRealtime) {
-            if (mCacheType == CACHE_TYPE_DISABLED) {
-                return;
-            }
-            put(direction, new FocusAreaHistory(targetFocusArea, elapsedRealtime));
-        }
-
-        FocusArea get(int direction, long elapsedRealtime) {
-            FocusAreaHistory history = get(direction);
-            return isValidHistory(history, elapsedRealtime) ? history.mFocusArea : null;
-        }
-
-        boolean isValidHistory(@Nullable FocusAreaHistory history, long elapsedRealtime) {
-            if (history == null) {
-                return false;
-            }
-            switch (mCacheType) {
-                case CACHE_TYPE_NEVER_EXPIRE:
-                    return true;
-                case CACHE_TYPE_EXPIRED_AFTER_SOME_TIME:
-                    return elapsedRealtime - history.mTimestamp < mExpirationPeriodMs;
-                default:
-                    return false;
-            }
-        }
-    }
-
-    RotaryCache(@CacheType int focusHistoryCacheType,
-            int focusHistoryExpirationPeriodMs,
-            @CacheType int focusAreaHistoryCacheType,
-            int focusAreaHistoryExpirationPeriodMs) {
-        mFocusCache = new FocusCache(focusHistoryCacheType, focusHistoryExpirationPeriodMs);
-        mFocusAreaCache = new FocusAreaCache(
-                focusAreaHistoryCacheType, focusAreaHistoryExpirationPeriodMs);
-    }
-
-    /**
-     * Searches the cache to find the last focused view of the FocusArea. Returns the view, or null
-     * if there is nothing in the cache, the cache is stale.
-     */
-    @Nullable
-    View getFocusedView(long elapsedRealtime) {
-        return mFocusCache.getFocusedView(elapsedRealtime);
-    }
-
-    /** Saves the focused view. */
-    void saveFocusedView(@NonNull View view, long elapsedRealtime) {
-        mFocusCache.setFocusedView(view, elapsedRealtime);
-    }
-
-    /**
-     * Searches the cache to find the target FocusArea for a nudge in a given {@code direction}.
-     * Returns the target FocusArea, or null if there is nothing in the cache, the cache is stale.
-     */
-    @Nullable
-    FocusArea getCachedFocusArea(int direction, long elapsedRealtime) {
-        return mFocusAreaCache.get(direction, elapsedRealtime);
-    }
-
-    /** Saves the FocusArea nudge history. */
-    void saveFocusArea(int direction, @NonNull FocusArea targetFocusArea, long elapsedRealtime) {
-        mFocusAreaCache.put(direction, targetFocusArea, elapsedRealtime);
-    }
-
-    /** Clears the FocusArea nudge history cache. */
-    void clearFocusAreaHistory() {
-        mFocusAreaCache.clear();
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java b/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
deleted file mode 100644
index e6c62c9..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.utils;
-
-/**
- * Constants for the rotary controller.
- *
- * @hide
- */
-public final class RotaryConstants {
-    /**
-     * Content description indicating that the view is a rotary container.
-     * <p>
-     * A rotary container contains focusable elements. When initializing focus, the first element
-     * in the rotary container is prioritized to take focus. When searching for nudge target, the
-     * bounds of the rotary container is the minimum bounds containing its descendants.
-     * <p>
-     * A rotary container shouldn't be focusable unless it's a scrollable container. Though it
-     * can't be focused, it can be scrolled as a side-effect of moving the focus within it.
-     */
-    public static final String ROTARY_CONTAINER =
-            "com.android.car.ui.utils.ROTARY_CONTAINER";
-
-    /**
-     * Content description indicating that the view is a scrollable container and can be scrolled
-     * horizontally by the rotary controller.
-     * <p>
-     * A scrollable container is a focusable rotary container. When it's focused, it can be scrolled
-     * when the rotary controller rotates. A scrollable container is often used to show long text.
-     */
-    public static final String ROTARY_HORIZONTALLY_SCROLLABLE =
-            "com.android.car.ui.utils.HORIZONTALLY_SCROLLABLE";
-
-    /**
-     * Content description indicating that the view is a scrollable container and can be scrolled
-     * vertically by the rotary controller.
-     * <p>
-     * A scrollable container is a focusable rotary container. When it's focused, it can be scrolled
-     * when the rotary controller rotates. A scrollable container is often used to show long text.
-     */
-    public static final String ROTARY_VERTICALLY_SCROLLABLE =
-            "com.android.car.ui.utils.VERTICALLY_SCROLLABLE";
-
-    /**
-     * Content description indicating that the view is a focus delegating container. When
-     * restoring focus, FocusParkingView and FocusArea will skip non-focusable views unless it's
-     * a focus delegating container. The focus delegating container can delegate focus to one of
-     * its descendants.
-     */
-    public static final String ROTARY_FOCUS_DELEGATING_CONTAINER =
-            "com.android.car.ui.utils.FOCUS_DELEGATING_CONTAINER";
-
-    /** The key to store the offset of the FocusArea's left bound in the node's extras. */
-    public static final String FOCUS_AREA_LEFT_BOUND_OFFSET =
-            "com.android.car.ui.utils.FOCUS_AREA_LEFT_BOUND_OFFSET";
-
-    /** The key to store the offset of the FocusArea's right bound in the node's extras. */
-    public static final String FOCUS_AREA_RIGHT_BOUND_OFFSET =
-            "com.android.car.ui.utils.FOCUS_AREA_RIGHT_BOUND_OFFSET";
-
-    /** The key to store the offset of the FocusArea's top bound in the node's extras. */
-    public static final String FOCUS_AREA_TOP_BOUND_OFFSET =
-            "com.android.car.ui.utils.FOCUS_AREA_TOP_BOUND_OFFSET";
-
-    /** The key to store the offset of the FocusArea's bottom bound in the node's extras. */
-    public static final String FOCUS_AREA_BOTTOM_BOUND_OFFSET =
-            "com.android.car.ui.utils.FOCUS_AREA_BOTTOM_BOUND_OFFSET";
-
-    /** The key to store nudge direction in the Bundle. */
-    public static final String NUDGE_DIRECTION =
-            "com.android.car.ui.utils.NUDGE_DIRECTION";
-
-    /**
-     * Action performed on a FocusArea to move focus to the nudge shortcut within the same
-     * FocusArea.
-     * <p>
-     * This action and the actions below only use the most significant 8 bits to avoid
-     * conflicting with legacy standard actions (which don't use the most significant 8 bits),
-     * e.g. ACTION_FOCUS. The actions only use one bit to avoid conflicting with IDs defined in
-     * framework (which start with 0x0102), e.g. R.id.accessibilityActionScrollUp.
-     */
-    public static final int ACTION_NUDGE_SHORTCUT = 0x01000000;
-
-    /** Action performed on a FocusArea to move focus to another FocusArea. */
-    public static final int ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA = 0x02000000;
-
-    /** Action performed on a FocusParkingView to restore the focus in the window. */
-    public static final int ACTION_RESTORE_DEFAULT_FOCUS = 0x04000000;
-
-    /** Action performed on a FocusParkingView to hide the IME. */
-    public static final int ACTION_HIDE_IME = 0x08000000;
-
-    /** Prevent instantiation. */
-    private RotaryConstants() {
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java b/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
deleted file mode 100644
index fb8b4ab..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.utils;
-
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
-
-import static com.android.car.ui.utils.RotaryConstants.ROTARY_CONTAINER;
-import static com.android.car.ui.utils.RotaryConstants.ROTARY_FOCUS_DELEGATING_CONTAINER;
-import static com.android.car.ui.utils.RotaryConstants.ROTARY_HORIZONTALLY_SCROLLABLE;
-import static com.android.car.ui.utils.RotaryConstants.ROTARY_VERTICALLY_SCROLLABLE;
-
-import android.text.TextUtils;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.FocusParkingView;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Utility class used by {@link com.android.car.ui.FocusArea} and {@link
- * com.android.car.ui.FocusParkingView}.
- *
- * @hide
- */
-public final class ViewUtils {
-
-    /**
-     * How many milliseconds to wait before trying to restore the focus inside the LazyLayoutView
-     * the second time.
-     */
-    private static final int RESTORE_FOCUS_RETRY_DELAY_MS = 3000;
-
-    /**
-     * No view is focused, the focused view is not shown, or the focused view is a FocusParkingView.
-     */
-    @VisibleForTesting
-    static final int NO_FOCUS = 1;
-
-    /** A scrollable container is focused. */
-    @VisibleForTesting
-    static final int SCROLLABLE_CONTAINER_FOCUS = 2;
-
-    /**
-     * A regular view is focused. A regular View is a View that is neither a FocusParkingView nor a
-     * scrollable container.
-     */
-    @VisibleForTesting
-    static final int REGULAR_FOCUS = 3;
-
-    /**
-     * An implicit default focus view (i.e., the selected item or the first focusable item in a
-     * scrollable container) is focused.
-     */
-    @VisibleForTesting
-    static final int IMPLICIT_DEFAULT_FOCUS = 4;
-
-    /** The {@code app:defaultFocus} view is focused. */
-    @VisibleForTesting
-    static final int DEFAULT_FOCUS = 5;
-
-    /** The {@code android:focusedByDefault} view is focused. */
-    @VisibleForTesting
-    static final int FOCUSED_BY_DEFAULT = 6;
-
-    /**
-     * Focus level of a view. When adjusting the focus, the view with the highest focus level will
-     * be focused.
-     */
-    @IntDef(flag = true, value = {NO_FOCUS, SCROLLABLE_CONTAINER_FOCUS, REGULAR_FOCUS,
-            IMPLICIT_DEFAULT_FOCUS, DEFAULT_FOCUS, FOCUSED_BY_DEFAULT})
-    @Retention(RetentionPolicy.SOURCE)
-    private @interface FocusLevel {
-    }
-
-    /** This is a utility class. */
-    private ViewUtils() {
-    }
-
-    /**
-     * This is a functional interface and can therefore be used as the assignment target for a
-     * lambda expression or method reference.
-     *
-     * @param <T> the type of the input to the predicate
-     */
-    private interface Predicate<T> {
-        /** Evaluates this predicate on the given argument. */
-        boolean test(@NonNull T t);
-    }
-
-    /**
-     * An interface used to restore focus inside a view when its layout is completed.
-     * <p>
-     * The view that needs to restore focus lazily should implement this interface.
-     */
-    public interface LazyLayoutView {
-
-        /**
-         * Returnes whether the view's layout is completed and ready to restore focus inside it.
-         */
-        boolean isLayoutCompleted();
-
-        /**
-         * Adds a listener to be called when the view's layout is completed.
-         */
-        void addOnLayoutCompleteListener(@Nullable Runnable runnable);
-
-        /**
-         * Removes a listener to be called when the view's layout is completed.
-         */
-        void removeOnLayoutCompleteListener(@Nullable Runnable runnable);
-    }
-
-    /**
-     * Hides the focus by searching the view tree for the {@link FocusParkingView}
-     * and focusing on it.
-     *
-     * @param root the root view to search from
-     * @return true if the FocusParkingView was successfully found and focused
-     *         or if it was already focused
-     */
-    public static boolean hideFocus(@NonNull View root) {
-        FocusParkingView fpv = (FocusParkingView) depthFirstSearch(root,
-                /* targetPredicate= */ v -> v instanceof FocusParkingView,
-                /* skipPredicate= */ null);
-        if (fpv == null) {
-            return false;
-        }
-        if (fpv.isFocused()) {
-            return true;
-        }
-        return fpv.performAccessibilityAction(ACTION_FOCUS, /* arguments= */ null);
-    }
-
-    /** Gets the ancestor FocusArea of the {@code view}, if any. Returns null if not found. */
-    @Nullable
-    public static FocusArea getAncestorFocusArea(@NonNull View view) {
-        ViewParent parent = view.getParent();
-        while (parent != null) {
-            if (parent instanceof FocusArea) {
-                return (FocusArea) parent;
-            }
-            parent = parent.getParent();
-        }
-        return null;
-    }
-
-    /**
-     * Gets the ancestor scrollable container of the {@code view}, if any. Returns null if not
-     * found.
-     */
-    @Nullable
-    public static ViewGroup getAncestorScrollableContainer(@Nullable View view) {
-        if (view == null) {
-            return null;
-        }
-        ViewParent parent = view.getParent();
-        // A scrollable container can't contain a FocusArea, so let's return earlier if we found
-        // a FocusArea.
-        while (parent != null && parent instanceof ViewGroup && !(parent instanceof FocusArea)) {
-            ViewGroup viewGroup = (ViewGroup) parent;
-            if (isScrollableContainer(viewGroup)) {
-                return viewGroup;
-            }
-            parent = parent.getParent();
-        }
-        return null;
-    }
-
-    /**
-     * Focuses on the {@code view} if it can be focused.
-     *
-     * @return whether it was successfully focused or already focused
-     */
-    public static boolean requestFocus(@Nullable View view) {
-        if (view == null || !canTakeFocus(view)) {
-            return false;
-        }
-        if (view.isFocused()) {
-            return true;
-        }
-        // Exit touch mode and focus the view. The view may not be focusable in touch mode, so we
-        // need to exit touch mode before focusing it.
-        return view.performAccessibilityAction(ACTION_FOCUS, /* arguments= */ null);
-    }
-
-    /**
-     * Searches the {@code root}'s descendants for a view with the highest {@link FocusLevel}. If
-     * the view's FocusLevel is higher than the {@code currentFocus}'s FocusLevel, focuses on the
-     * view. If it tried to focus on a LazyLayoutView but failed, requests to adjust the focus
-     * inside the LazyLayoutView later.
-     *
-     * @return whether the view is focused
-     */
-    public static boolean adjustFocus(@NonNull View root, @Nullable View currentFocus) {
-        @FocusLevel int currentLevel = getFocusLevel(currentFocus);
-        return adjustFocus(root, currentLevel, /* cachedFocusedView= */ null,
-                /* defaultFocusOverridesHistory= */ false);
-    }
-
-    /**
-     * Similar to {@link #adjustFocus(View, View)} but without requesting to adjust the focus
-     * inside the LazyLayoutView later.
-     */
-    public static boolean adjustFocusImmediately(@NonNull View root, @Nullable View currentFocus) {
-        @FocusLevel int currentLevel = getFocusLevel(currentFocus);
-        return adjustFocus(root, currentLevel, /* cachedFocusedView= */ null,
-                /* defaultFocusOverridesHistory= */ false, /* delayed= */ false);
-    }
-
-    /**
-     * If the {@code currentFocus}'s FocusLevel is lower than REGULAR_FOCUS, adjusts focus within
-     * {@code root}. See {@link #adjustFocus(View, int)}. Otherwise no-op.
-     *
-     * @return whether the focus has changed
-     */
-    public static boolean initFocus(@NonNull View root, @Nullable View currentFocus) {
-        @FocusLevel int currentLevel = getFocusLevel(currentFocus);
-        if (currentLevel >= REGULAR_FOCUS) {
-            return false;
-        }
-        return adjustFocus(root, currentLevel, /* cachedFocusedView= */ null,
-                /* defaultFocusOverridesHistory= */ false);
-    }
-
-    /**
-     * Searches the {@code root}'s descendants for a view with the highest {@link FocusLevel}. If
-     * the view's FocusLevel is higher than {@code currentLevel}, focuses on the view.
-     *
-     * @return whether the view is focused
-     */
-    @VisibleForTesting
-    static boolean adjustFocus(@NonNull View root, @FocusLevel int currentLevel) {
-        return adjustFocus(root, currentLevel, /* cachedFocusedView= */ null,
-                /* defaultFocusOverridesHistory= */ false);
-    }
-
-    /**
-     * Searches the {@code root}'s descendants for a view with the highest {@link FocusLevel} and
-     * focuses on it or the {@code cachedFocusedView}.
-     *
-     * @return whether the view is focused
-     */
-    public static boolean adjustFocus(@NonNull View root,
-            @Nullable View cachedFocusedView,
-            boolean defaultFocusOverridesHistory) {
-        return adjustFocus(root, NO_FOCUS, cachedFocusedView, defaultFocusOverridesHistory);
-    }
-
-    private static boolean adjustFocus(@NonNull View root,
-            @FocusLevel int currentLevel,
-            @Nullable View cachedFocusedView,
-            boolean defaultFocusOverridesHistory) {
-        return adjustFocus(root, currentLevel, cachedFocusedView, defaultFocusOverridesHistory,
-                /* delayed= */true);
-    }
-
-    /**
-     * Searches the {@code root}'s descendants for a view with the highest {@link FocusLevel}. If
-     * the view's FocusLevel is higher than {@code currentLevel}, focuses on the view or {@code
-     * cachedFocusedView}.
-     *
-     * @return whether the view is focused
-     */
-    private static boolean adjustFocus(@NonNull View root,
-            @FocusLevel int currentLevel,
-            @Nullable View cachedFocusedView,
-            boolean defaultFocusOverridesHistory,
-            boolean delayed) {
-        // If the previously focused view has higher priority than the default focus, try to focus
-        // on the previously focused view.
-        if (!defaultFocusOverridesHistory && requestFocus(cachedFocusedView)) {
-            return true;
-        }
-
-        // Try to focus on the default focus view.
-        if (currentLevel < FOCUSED_BY_DEFAULT && focusOnFocusedByDefaultView(root)) {
-            return true;
-        }
-        if (currentLevel < DEFAULT_FOCUS && focusOnDefaultFocusView(root)) {
-            return true;
-        }
-        if (currentLevel < IMPLICIT_DEFAULT_FOCUS && focusOnImplicitDefaultFocusView(root)) {
-            return true;
-        }
-
-        // When delayed is true, if there is a LazyLayoutView but it failed to adjust focus
-        // inside it because it is not loaded yet or it's loaded but has no descendnats, request to
-        // restore focus inside it later, and return false for now.
-        if (delayed && currentLevel < IMPLICIT_DEFAULT_FOCUS) {
-            LazyLayoutView lazyLayoutView = findLazyLayoutView(root);
-            if (lazyLayoutView != null && !lazyLayoutView.isLayoutCompleted()) {
-                initFocusDelayed(lazyLayoutView);
-                return false;
-            }
-        }
-
-        // If the previously focused view has lower priority than the default focus, try to focus
-        // on the previously focused view.
-        if (defaultFocusOverridesHistory && requestFocus(cachedFocusedView)) {
-            return true;
-        }
-
-        // Try to focus on other views with low focus levels.
-        if (currentLevel < REGULAR_FOCUS && focusOnFirstRegularView(root)) {
-            return true;
-        }
-        if (currentLevel < SCROLLABLE_CONTAINER_FOCUS) {
-            return focusOnScrollableContainer(root);
-        }
-        return false;
-    }
-
-    /**
-     * If the {code lazyLayoutView} has a focusable descendant and no visible view is focused,
-     * focuses on the descendant. Otherwise tries again when the {code lazyLayoutView} completes
-     * layout or after a timeout, whichever comes first.
-     */
-    public static void initFocus(@NonNull LazyLayoutView lazyLayoutView) {
-        if (initFocusImmediately(lazyLayoutView)) {
-            return;
-        }
-        initFocusDelayed(lazyLayoutView);
-    }
-
-    private static void initFocusDelayed(@NonNull LazyLayoutView lazyLayoutView) {
-        if (!(lazyLayoutView instanceof View)) {
-            return;
-        }
-        View lazyView = (View) lazyLayoutView;
-        Runnable[] onLayoutCompleteListener = new Runnable[1];
-        Runnable delayedTask = () -> {
-            lazyLayoutView.removeOnLayoutCompleteListener(onLayoutCompleteListener[0]);
-            initFocusImmediately(lazyLayoutView);
-        };
-        onLayoutCompleteListener[0] = () -> {
-            if (initFocusImmediately(lazyLayoutView)) {
-                // Remove the delayedTask only when onLayoutCompleteListener has initialized the
-                // focus succefully, because the delayedTask needs to kick in when it fails, such
-                // as the lazyLayoutView is still loading after a timeout, or it's loaded but has
-                // no descendants to take focus.
-                lazyView.removeCallbacks(delayedTask);
-                lazyLayoutView.removeOnLayoutCompleteListener(onLayoutCompleteListener[0]);
-            }
-        };
-        lazyLayoutView.addOnLayoutCompleteListener(onLayoutCompleteListener[0]);
-        lazyView.postDelayed(delayedTask, RESTORE_FOCUS_RETRY_DELAY_MS);
-    }
-
-    private static boolean initFocusImmediately(@NonNull LazyLayoutView lazyLayoutView) {
-        if (!(lazyLayoutView instanceof View)) {
-            return false;
-        }
-        View lazyView = (View) lazyLayoutView;
-        View focusedView = lazyView.getRootView().findFocus();
-        // If the currently focused view won't draw, it's not a valid focus.
-        View visibleFocusedView =
-                focusedView != null && !focusedView.willNotDraw() ? focusedView : null;
-        // If there is a visible view focused, just return true.
-        if (visibleFocusedView != null && !(visibleFocusedView instanceof FocusParkingView)) {
-            return true;
-        }
-
-        return ViewUtils.adjustFocusImmediately(lazyView, visibleFocusedView);
-    }
-
-    @VisibleForTesting
-    @FocusLevel
-    static int getFocusLevel(@Nullable View view) {
-        if (view == null || view instanceof FocusParkingView || !view.isShown()) {
-            return NO_FOCUS;
-        }
-        if (view.isFocusedByDefault()) {
-            return FOCUSED_BY_DEFAULT;
-        }
-        if (isDefaultFocus(view)) {
-            return DEFAULT_FOCUS;
-        }
-        if (isImplicitDefaultFocusView(view)) {
-            return IMPLICIT_DEFAULT_FOCUS;
-        }
-        if (isScrollableContainer(view)) {
-            return SCROLLABLE_CONTAINER_FOCUS;
-        }
-        return REGULAR_FOCUS;
-    }
-
-    /** Returns whether the {@code view} is a {@code app:defaultFocus} view. */
-    private static boolean isDefaultFocus(@NonNull View view) {
-        FocusArea parent = getAncestorFocusArea(view);
-        return parent != null && view == parent.getDefaultFocusView();
-    }
-
-    /**
-     * Returns whether the {@code view} is an implicit default focus view, i.e., the selected
-     * item or the first focusable item in a rotary container.
-     */
-    @VisibleForTesting
-    static boolean isImplicitDefaultFocusView(@NonNull View view) {
-        ViewGroup rotaryContainer = null;
-        ViewParent parent = view.getParent();
-        while (parent != null && parent instanceof ViewGroup) {
-            ViewGroup viewGroup = (ViewGroup) parent;
-            if (isRotaryContainer(viewGroup)) {
-                rotaryContainer = viewGroup;
-                break;
-            }
-            parent = parent.getParent();
-        }
-        if (rotaryContainer == null) {
-            return false;
-        }
-        return findFirstSelectedFocusableDescendant(rotaryContainer) == view
-                || findFirstFocusableDescendant(rotaryContainer) == view;
-    }
-
-    private static boolean isRotaryContainer(@NonNull View view) {
-        CharSequence contentDescription = view.getContentDescription();
-        return TextUtils.equals(contentDescription, ROTARY_CONTAINER)
-                || TextUtils.equals(contentDescription, ROTARY_VERTICALLY_SCROLLABLE)
-                || TextUtils.equals(contentDescription, ROTARY_HORIZONTALLY_SCROLLABLE);
-    }
-
-    private static boolean isScrollableContainer(@NonNull View view) {
-        CharSequence contentDescription = view.getContentDescription();
-        return TextUtils.equals(contentDescription, ROTARY_VERTICALLY_SCROLLABLE)
-                || TextUtils.equals(contentDescription, ROTARY_HORIZONTALLY_SCROLLABLE);
-    }
-
-    private static boolean isFocusDelegatingContainer(@NonNull View view) {
-        CharSequence contentDescription = view.getContentDescription();
-        return TextUtils.equals(contentDescription, ROTARY_FOCUS_DELEGATING_CONTAINER);
-    }
-
-    /**
-     * Focuses on the first {@code app:defaultFocus} view in the view tree, if any.
-     *
-     * @param root the root of the view tree
-     * @return whether succeeded
-     */
-    private static boolean focusOnDefaultFocusView(@NonNull View root) {
-        View defaultFocus = findDefaultFocusView(root);
-        return requestFocus(defaultFocus);
-    }
-
-    /**
-     * Focuses on the first {@code android:focusedByDefault} view in the view tree, if any.
-     *
-     * @param root the root of the view tree
-     * @return whether succeeded
-     */
-    private static boolean focusOnFocusedByDefaultView(@NonNull View root) {
-        View focusedByDefault = findFocusedByDefaultView(root);
-        return requestFocus(focusedByDefault);
-    }
-
-    /**
-     * Focuses on the first implicit default focus view in the view tree, if any.
-     *
-     * @param root the root of the view tree
-     * @return whether succeeded
-     */
-    private static boolean focusOnImplicitDefaultFocusView(@NonNull View root) {
-        View implicitDefaultFocus = findImplicitDefaultFocusView(root);
-        return requestFocus(implicitDefaultFocus);
-    }
-
-    /**
-     * Tries to focus on the first focusable view in the view tree in depth first order, excluding
-     * the FocusParkingView and scrollable containers. If focusing on the first such view fails,
-     * keeps trying other views in depth first order until succeeds or there are no more such views.
-     *
-     * @param root the root of the view tree
-     * @return whether succeeded
-     */
-    private static boolean focusOnFirstRegularView(@NonNull View root) {
-        View focusedView = ViewUtils.depthFirstSearch(root,
-                /* targetPredicate= */
-                v -> !isScrollableContainer(v) && canTakeFocus(v) && requestFocus(v),
-                /* skipPredicate= */ v -> !v.isShown());
-        return focusedView != null;
-    }
-
-    /**
-     * Focuses on the first scrollable container in the view tree, if any.
-     *
-     * @param root the root of the view tree
-     * @return whether succeeded
-     */
-    private static boolean focusOnScrollableContainer(@NonNull View root) {
-        View focusedView = ViewUtils.depthFirstSearch(root,
-                /* targetPredicate= */ v -> isScrollableContainer(v) && canTakeFocus(v),
-                /* skipPredicate= */ v -> !v.isShown());
-        return requestFocus(focusedView);
-    }
-
-    /**
-     * Searches the {@code root}'s descendants in depth first order, and returns the first
-     * {@code app:defaultFocus} view that can take focus. Returns null if not found.
-     */
-    @Nullable
-    private static View findDefaultFocusView(@NonNull View view) {
-        if (!view.isShown()) {
-            return null;
-        }
-        if (view instanceof FocusArea) {
-            FocusArea focusArea = (FocusArea) view;
-            View defaultFocus = focusArea.getDefaultFocusView();
-            if (defaultFocus != null && canTakeFocus(defaultFocus)) {
-                return defaultFocus;
-            }
-        } else if (view instanceof ViewGroup) {
-            ViewGroup parent = (ViewGroup) view;
-            for (int i = 0; i < parent.getChildCount(); i++) {
-                View child = parent.getChildAt(i);
-                View defaultFocus = findDefaultFocusView(child);
-                if (defaultFocus != null) {
-                    return defaultFocus;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Searches the {@code view} and its descendants in depth first order, and returns the first
-     * {@code android:focusedByDefault} view that can take focus. Returns null if not found.
-     */
-    @VisibleForTesting
-    @Nullable
-    static View findFocusedByDefaultView(@NonNull View view) {
-        return depthFirstSearch(view,
-                /* targetPredicate= */ v -> v.isFocusedByDefault() && canTakeFocus(v),
-                /* skipPredicate= */ v -> !v.isShown());
-    }
-
-    /**
-     * Searches the {@code view} and its descendants in depth first order, and returns the first
-     * implicit default focus view, i.e., the selected item or the first focusable item in the
-     * first rotary container. Returns null if not found.
-     */
-    @VisibleForTesting
-    @Nullable
-    static View findImplicitDefaultFocusView(@NonNull View view) {
-        View rotaryContainer = findRotaryContainer(view);
-        if (rotaryContainer == null) {
-            return null;
-        }
-
-        View selectedItem = findFirstSelectedFocusableDescendant(rotaryContainer);
-
-        return selectedItem != null
-                ? selectedItem
-                : findFirstFocusableDescendant(rotaryContainer);
-    }
-
-    /**
-     * Searches the {@code view}'s descendants in depth first order, and returns the first view
-     * that can take focus, or null if not found.
-     */
-    @VisibleForTesting
-    @Nullable
-    static View findFirstFocusableDescendant(@NonNull View view) {
-        return depthFirstSearch(view,
-                /* targetPredicate= */ v -> v != view && canTakeFocus(v),
-                /* skipPredicate= */ v -> !v.isShown());
-    }
-
-    /**
-     * Searches the {@code view}'s descendants in depth first order, and returns the first view
-     * that is selected and can take focus, or null if not found.
-     */
-    @VisibleForTesting
-    @Nullable
-    static View findFirstSelectedFocusableDescendant(@NonNull View view) {
-        return depthFirstSearch(view,
-                /* targetPredicate= */ v -> v != view && v.isSelected() && canTakeFocus(v),
-                /* skipPredicate= */ v -> !v.isShown());
-    }
-
-    /**
-     * Searches the {@code view} and its descendants in depth first order, and returns the first
-     * rotary container shown on the screen. Returns null if not found.
-     */
-    @Nullable
-    private static View findRotaryContainer(@NonNull View view) {
-        return depthFirstSearch(view,
-                /* targetPredicate= */ v -> isRotaryContainer(v),
-                /* skipPredicate= */ v -> !v.isShown());
-    }
-
-    /**
-     * Searches the {@code view} and its descendants in depth first order, and returns the first
-     * LazyLayoutView shown on the screen. Returns null if not found.
-     */
-    @Nullable
-    private static LazyLayoutView findLazyLayoutView(@NonNull View view) {
-        return (LazyLayoutView) depthFirstSearch(view,
-                /* targetPredicate= */ v -> v instanceof LazyLayoutView,
-                /* skipPredicate= */ v -> !v.isShown());
-    }
-
-    /**
-     * Searches the {@code view} and its descendants in depth first order, skips the views that
-     * match {@code skipPredicate} and their descendants, and returns the first view that matches
-     * {@code targetPredicate}. Returns null if not found.
-     */
-    @Nullable
-    private static View depthFirstSearch(@NonNull View view,
-            @NonNull Predicate<View> targetPredicate,
-            @Nullable Predicate<View> skipPredicate) {
-        if (skipPredicate != null && skipPredicate.test(view)) {
-            return null;
-        }
-        if (targetPredicate.test(view)) {
-            return view;
-        }
-        if (view instanceof ViewGroup) {
-            ViewGroup parent = (ViewGroup) view;
-            for (int i = 0; i < parent.getChildCount(); i++) {
-                View child = parent.getChildAt(i);
-                View target = depthFirstSearch(child, targetPredicate, skipPredicate);
-                if (target != null) {
-                    return target;
-                }
-            }
-        }
-        return null;
-    }
-
-    /** Returns whether {@code view} can be focused. */
-    private static boolean canTakeFocus(@NonNull View view) {
-        boolean focusable = view.isFocusable() || isFocusDelegatingContainer(view);
-        return focusable && view.isEnabled() && view.isShown()
-                && view.getWidth() > 0 && view.getHeight() > 0 && view.isAttachedToWindow()
-                && !(view instanceof FocusParkingView)
-                // If it's a scrollable container, it can be focused only when it has no focusable
-                // descendants. We focus on it so that the rotary controller can scroll it.
-                && (!isScrollableContainer(view) || findFirstFocusableDescendant(view) == null);
-    }
-
-    /**
-     * Enables rotary scrolling for {@code view}, either vertically (if {@code isVertical} is true)
-     * or horizontally (if {@code isVertical} is false). With rotary scrolling enabled, rotating the
-     * rotary controller will scroll rather than moving the focus when moving the focus would cause
-     * a lot of scrolling. Rotary scrolling should be enabled for scrolling views which contain
-     * content which the user may want to see but can't interact with, either alone or along with
-     * interactive (focusable) content.
-     */
-    public static void setRotaryScrollEnabled(@NonNull View view, boolean isVertical) {
-        view.setContentDescription(
-                isVertical ? ROTARY_VERTICALLY_SCROLLABLE : ROTARY_HORIZONTALLY_SCROLLABLE);
-    }
-}
diff --git a/car-ui-lib/car-rotary-lib/src/main/res-overlayable/values/overlayable.xml b/car-ui-lib/car-rotary-lib/src/main/res-overlayable/values/overlayable.xml
deleted file mode 100644
index 985b3d4..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res-overlayable/values/overlayable.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!--Copyright (C) 2021 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.-->
-<!-- THIS FILE WAS AUTO GENERATED, DO NOT EDIT MANUALLY. -->
-<resources>
-  <overlayable name="rotary-ui">
-    <policy type="public">
-      <item type="bool" name="car_ui_clear_focus_area_history_when_rotating"/>
-      <item type="bool" name="car_ui_enable_focus_area_background_highlight"/>
-      <item type="bool" name="car_ui_enable_focus_area_foreground_highlight"/>
-      <item type="bool" name="car_ui_focus_area_default_focus_overrides_history"/>
-      <item type="color" name="car_ui_rotary_focus_fill_color"/>
-      <item type="color" name="car_ui_rotary_focus_fill_secondary_color"/>
-      <item type="color" name="car_ui_rotary_focus_pressed_fill_color"/>
-      <item type="color" name="car_ui_rotary_focus_pressed_fill_secondary_color"/>
-      <item type="color" name="car_ui_rotary_focus_pressed_stroke_color"/>
-      <item type="color" name="car_ui_rotary_focus_pressed_stroke_secondary_color"/>
-      <item type="color" name="car_ui_rotary_focus_stroke_color"/>
-      <item type="color" name="car_ui_rotary_focus_stroke_secondary_color"/>
-      <item type="dimen" name="car_ui_rotary_focus_pressed_stroke_width"/>
-      <item type="dimen" name="car_ui_rotary_focus_stroke_width"/>
-      <item type="drawable" name="car_ui_focus_area_background_highlight"/>
-      <item type="drawable" name="car_ui_focus_area_foreground_highlight"/>
-      <item type="integer" name="car_ui_focus_area_history_cache_type"/>
-      <item type="integer" name="car_ui_focus_area_history_expiration_period_ms"/>
-      <item type="integer" name="car_ui_focus_history_cache_type"/>
-      <item type="integer" name="car_ui_focus_history_expiration_period_ms"/>
-    </policy>
-  </overlayable>
-</resources>
diff --git a/car-ui-lib/car-rotary-lib/src/main/res/drawable/car_ui_focus_area_background_highlight.xml b/car-ui-lib/car-rotary-lib/src/main/res/drawable/car_ui_focus_area_background_highlight.xml
deleted file mode 100644
index 7dd6341..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res/drawable/car_ui_focus_area_background_highlight.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <solid android:color="#2994CBFF"/>
-</shape>
diff --git a/car-ui-lib/car-rotary-lib/src/main/res/drawable/car_ui_focus_area_foreground_highlight.xml b/car-ui-lib/car-rotary-lib/src/main/res/drawable/car_ui_focus_area_foreground_highlight.xml
deleted file mode 100644
index 94de514..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res/drawable/car_ui_focus_area_foreground_highlight.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <stroke android:width="1dp"
-            android:color="@color/car_ui_rotary_focus_stroke_color"/>
-</shape>
diff --git a/car-ui-lib/car-rotary-lib/src/main/res/values/attrs.xml b/car-ui-lib/car-rotary-lib/src/main/res/values/attrs.xml
deleted file mode 100644
index 9aa880c..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,140 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-  <!-- Attributes for FocusArea. -->
-  <declare-styleable name="FocusArea">
-    <!-- The ID of the default focus view. The view will be prioritized when searching for a
-         focus target.
-         (1) When the user nudges the rotary controller, it will search for a target FocusArea,
-             then search for a target view within the target FocusArea, and focus on the target
-             view. The target view is chosen in the following order:
-               1. the "android:focusedByDefault" view, if any
-               2. the "app:defaultFocus" view, if any
-               3. the selected item in a scrollable container, if any
-               4. the first focusable item in a scrollable container, if any
-               5. previously focused view, if any and the cache is not stale
-               6. the first focusable view, if any
-             Note that 5 will be prioritized over 1, 2, 3, and 4 when
-             "app:defaultFocusOverridesHistory" is true.
-         (2) When it needs to initialize the focus (such as when a window is opened), it will
-             search for a view in the window and focus on it. The view is chosen in the
-             following order:
-               1. the first "android:focusedByDefault" view, if any
-               2. the first "app:defaultFocus" view, if any
-               3. the selected item in a scrollable container, if any
-               4. the first focusable item in a scrollable container, if any
-               5. the first focusable view that is not a FocusParkingView, if any
-         If there is only one FocusArea that needs to set default focus, you can use either
-         "app:defaultFocus" or "android:focusedByDefault". If there are more than one, you
-         should use "android:focusedByDefault" in the primary FocusArea, and use
-         "app:defaultFocus" in other FocusAreas. -->
-    <attr name="defaultFocus" format="reference"/>
-
-    <!-- Whether to focus on the default focus view when nudging to the FocusArea, even if there
-         was another view in the FocusArea focused before. -->
-    <attr name="defaultFocusOverridesHistory" format="boolean"/>
-
-    <!-- The paddings of FocusArea highlight. It does't impact the paddings on its child views,
-         or vice versa. -->
-    <!-- The start padding of the FocusArea highlight. -->
-    <attr name="highlightPaddingStart" format="dimension"/>
-    <!-- The end padding of the FocusArea highlight. -->
-    <attr name="highlightPaddingEnd" format="dimension"/>
-    <!-- The top padding of the FocusArea highlight. -->
-    <attr name="highlightPaddingTop" format="dimension"/>
-    <!-- The bottom padding of the FocusArea highlight. -->
-    <attr name="highlightPaddingBottom" format="dimension"/>
-    <!-- The horizontal padding of the FocusArea highlight. It can be overridden by
-         highlightPaddingStart or highlightPaddingEnd. -->
-    <attr name="highlightPaddingHorizontal" format="dimension"/>
-    <!-- The vertical padding of the FocusArea highlight.  It can be overridden by
-         highlightPaddingTop or highlightPaddingBottom. -->
-    <attr name="highlightPaddingVertical" format="dimension"/>
-
-    <!-- The offset of the FocusArea's bounds. It only affects the perceived bounds for the
-         purposes of finding the nudge target. It doesn't affect the FocusArea's view bounds or
-         highlight bounds. The offset should only be used when FocusAreas are overlapping and
-         nudge interaction is ambiguous. -->
-    <!-- The offset of the FocusArea's start bound. -->
-    <attr name="startBoundOffset" format="dimension"/>
-    <!-- The offset of the FocusArea's end bound. -->
-    <attr name="endBoundOffset" format="dimension"/>
-    <!-- The offset of the FocusArea's top bound. -->
-    <attr name="topBoundOffset" format="dimension"/>
-    <!-- The offset of the FocusArea's bottom bound. -->
-    <attr name="bottomBoundOffset" format="dimension"/>
-    <!-- The offset of the FocusArea's horizontal bounds. It can be overridden by
-         startBoundOffset or endBoundOffset. -->
-    <attr name="horizontalBoundOffset" format="dimension"/>
-    <!-- The offset of the FocusArea's vertical bounds. It can be overridden by topBoundOffset
-         or bottomBoundOffset. -->
-    <attr name="verticalBoundOffset" format="dimension"/>
-
-    <!-- New attributes for nudge shortcuts. Usually nudge is used to navigate to another
-         FocusArea, but when a nudge shortcut is specified, it's used to navigate to the
-         given view within the same FocusArea. A nudge shortcut can be specified for each
-         direction. -->
-    <!-- The ID of the nudge left shortcut view. -->
-    <attr name="nudgeLeftShortcut" format="reference"/>
-    <!-- The ID of the nudge right shortcut view. -->
-    <attr name="nudgeRightShortcut" format="reference"/>
-    <!-- The ID of the nudge up shortcut view. -->
-    <attr name="nudgeUpShortcut" format="reference"/>
-    <!-- The ID of the nudge down shortcut view. -->
-    <attr name="nudgeDownShortcut" format="reference"/>
-
-    <!-- Legacy attributes for nudge shortcut. Usually nudge is used to navigate to another
-         FocusArea, but when a nudge shortcut is specified, it's used to navigate to the given
-         view within the same FocusArea. If using these legacy attributes, the two must be
-         specified together and the new attributes cannot be used. -->
-    <!-- The ID of the nudge shortcut view. -->
-    <attr name="nudgeShortcut" format="reference"/>
-    <!-- The direction of the nudge shortcut. -->
-    <attr name="nudgeShortcutDirection">
-      <!-- View.FOCUS_LEFT -->
-      <flag name="left" value="0x11" />
-      <!-- View.FOCUS_RIGHT -->
-      <flag name="right" value="0x42" />
-      <!-- View.FOCUS_UP -->
-      <flag name="up" value="0x21" />
-      <!-- View.FOCUS_DOWN -->
-      <flag name="down" value="0x82" />
-    </attr>
-
-    <!-- Attributes to specify the target FocusArea for a nudge. -->
-    <!-- The ID of the target FocusArea when nudging to the left. -->
-    <attr name="nudgeLeft" format="reference"/>
-    <!-- The ID of the target FocusArea when nudging to the right. -->
-    <attr name="nudgeRight" format="reference"/>
-    <!-- The ID of the target FocusArea when nudging up. -->
-    <attr name="nudgeUp" format="reference"/>
-    <!-- The ID of the target FocusArea when nudging down. -->
-    <attr name="nudgeDown" format="reference"/>
-
-    <!-- Whether rotation wraps around. When true, rotation wraps around, staying within the
-         FocusArea, when it reaches the first or last focusable view in the FocusArea. When
-         false, rotation does nothing in this case. -->
-    <attr name="wrapAround" format="boolean"/>
-  </declare-styleable>
-
-  <!-- Attributes for FocusParkingView. -->
-  <declare-styleable name="FocusParkingView">
-    <!-- Whether to restore focus when the frameworks wants to focus the FocusParkingView. When
-         false, the FocusParkingView allows itself to be focused instead. This should be false
-         for the FocusParkingView in an ActivityView. The default value is true. -->
-    <attr name="shouldRestoreFocus" format="boolean"/>
-  </declare-styleable>
-</resources>
diff --git a/car-ui-lib/car-rotary-lib/src/main/res/values/bools.xml b/car-ui-lib/car-rotary-lib/src/main/res/values/bools.xml
deleted file mode 100644
index 6e557a1..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res/values/bools.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
-
-  <!-- FocusArea -->
-
-  <!-- Whether to draw highlight (car_ui_focus_area_foreground_highlight) on top of the FocusArea
-       and its children when the FocusArea's descendant gets focused. -->
-  <bool name="car_ui_enable_focus_area_foreground_highlight">false</bool>
-  <!-- Whether to draw highlight (car_ui_focus_area_background_highlight) on top of the FocusArea
-       but behind its children when the FocusArea's descendant gets focused. -->
-  <bool name="car_ui_enable_focus_area_background_highlight">false</bool>
-  <!-- Deprecated. -->
-  <bool name="car_ui_focus_area_default_focus_overrides_history">false</bool>
-  <!-- Whether to clear FocusArea history when the user rotates the rotary controller. -->
-  <bool name="car_ui_clear_focus_area_history_when_rotating">true</bool>
-
-</resources>
diff --git a/car-ui-lib/car-rotary-lib/src/main/res/values/colors.xml b/car-ui-lib/car-rotary-lib/src/main/res/values/colors.xml
deleted file mode 100644
index 766d50e..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-  <!-- Rotary focus -->
-
-  <color name="car_ui_rotary_focus_stroke_color">#94CBFF</color>
-  <color name="car_ui_rotary_focus_fill_color">#3D94CBFF</color>
-  <color name="car_ui_rotary_focus_pressed_stroke_color">#94CBFF</color>
-  <color name="car_ui_rotary_focus_pressed_fill_color">#8A94CBFF</color>
-  <color name="car_ui_rotary_focus_stroke_secondary_color">#0059B3</color>
-  <color name="car_ui_rotary_focus_fill_secondary_color">#3D0059B3</color>
-  <color name="car_ui_rotary_focus_pressed_stroke_secondary_color">#0041BE</color>
-  <color name="car_ui_rotary_focus_pressed_fill_secondary_color">#8A0041BE</color>
-
-</resources>
diff --git a/car-ui-lib/car-rotary-lib/src/main/res/values/dimens.xml b/car-ui-lib/car-rotary-lib/src/main/res/values/dimens.xml
deleted file mode 100644
index 69c6a45..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-  <!-- Rotary focus highlight  -->
-
-  <dimen name="car_ui_rotary_focus_stroke_width">8dp</dimen>
-  <dimen name="car_ui_rotary_focus_pressed_stroke_width">4dp</dimen>
-
-</resources>
diff --git a/car-ui-lib/car-rotary-lib/src/main/res/values/integers.xml b/car-ui-lib/car-rotary-lib/src/main/res/values/integers.xml
deleted file mode 100644
index 0ba9f93..0000000
--- a/car-ui-lib/car-rotary-lib/src/main/res/values/integers.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
-  <!-- Type of FocusHistoryCache. The values are defined in RotaryCache. 1 means the cache
-  is disabled, 2 means entries in the cache will expire after a period of time, and 3 means
-  elements in the cache will never expire. -->
-  <integer name="car_ui_focus_history_cache_type">2</integer>
-  <!-- How many milliseconds before the entry in FocusHistoryCache expires. Must be positive value
-   when car_ui_focus_history_cache_type is 2. -->
-  <integer name="car_ui_focus_history_expiration_period_ms">300000</integer>
-
-  <!-- Type of FocusAreaHistoryCache. The values are defined in RotaryCache. 1 means the
-  cache is disabled, 2 means entries in the cache will expire after a period of time, and 3 means
-  elements in the cache will never expire. -->
-  <integer name="car_ui_focus_area_history_cache_type">2</integer>
-  <!-- How many milliseconds before an entry in FocusAreaHistoryCache expires. Must be positive
-  value when car_ui_focus_area_history_cache_type is 2. -->
-  <integer name="car_ui_focus_area_history_expiration_period_ms">3000</integer>
-</resources>
diff --git a/car-ui-lib/car-ui-androidx/Android.bp b/car-ui-lib/car-ui-androidx/Android.bp
deleted file mode 100644
index ca51962..0000000
--- a/car-ui-lib/car-ui-androidx/Android.bp
+++ /dev/null
@@ -1,604 +0,0 @@
-//
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_library {
-    name: "car-ui-lib-androidx",
-    srcs: [],
-    resource_dirs: [],
-    sdk_version: "system_current",
-    optimize: {
-        enabled: false,
-    },
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-activity",
-        "car-ui-androidx-appcompat",
-        "car-ui-androidx-appcompat-resources",
-        "car-ui-androidx-asynclayoutinflater",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-constraintlayout",
-        "car-ui-androidx-constraintlayout-solver",
-        "car-ui-androidx-core",
-        "car-ui-androidx-core-common",
-        "car-ui-androidx-core-runtime",
-        "car-ui-androidx-customview",
-        "car-ui-androidx-drawerlayout",
-        "car-ui-androidx-fragment",
-        "car-ui-androidx-lifecycle-common",
-        "car-ui-androidx-lifecycle-livedata-core",
-        "car-ui-androidx-lifecycle-runtime",
-        "car-ui-androidx-lifecycle-viewmodel",
-        "car-ui-androidx-loader",
-        "car-ui-androidx-preference",
-        "car-ui-androidx-recyclerview",
-        "car-ui-androidx-savedstate",
-        "car-ui-androidx-vectordrawable",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-constraintlayout-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx-constraintlayout_constraintlayout-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-constraintlayout.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-constraintlayout",
-    aars: [":car-ui-androidx-constraintlayout-nodeps"],
-    static_libs: [
-        "car-ui-androidx-appcompat",
-        "car-ui-androidx-core",
-        "car-ui-androidx-constraintlayout-solver",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-constraintlayout-solver-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx-constraintlayout_constraintlayout-solver-nodeps{.jar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-constraintlayout-solver.jar"],
-}
-
-java_import {
-    name: "car-ui-androidx-constraintlayout-solver",
-    jars: [":car-ui-androidx-constraintlayout-solver-nodeps"],
-}
-
-genrule {
-    name: "car-ui-androidx-preference-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.preference_preference-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-preference.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-preference",
-    aars: [":car-ui-androidx-preference-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-appcompat",
-        "car-ui-androidx-core",
-        "car-ui-androidx-fragment",
-        "car-ui-androidx-recyclerview",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-recyclerview-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.recyclerview_recyclerview-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-recyclerview.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-recyclerview",
-    aars: [":car-ui-androidx-recyclerview-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-core",
-        "car-ui-androidx-customview",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-asynclayoutinflater-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.asynclayoutinflater_asynclayoutinflater-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-asynclayoutinflater.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-asynclayoutinflater",
-    aars: [":car-ui-androidx-asynclayoutinflater-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-core",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-appcompat-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.appcompat_appcompat-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-appcompat.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-appcompat",
-    aars: [":car-ui-androidx-appcompat-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-core",
-        "car-ui-androidx-cursoradapter",
-        "car-ui-androidx-activity",
-        "car-ui-androidx-fragment",
-        "car-ui-androidx-appcompat-resources",
-        "car-ui-androidx-drawerlayout",
-        "car-ui-androidx-savedstate",
-        "car-ui-androidx-lifecycle-runtime",
-        "car-ui-androidx-lifecycle-viewmodel",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-cursoradapter-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.cursoradapter_cursoradapter-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-cursoradapter.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-cursoradapter",
-    aars: [":car-ui-androidx-cursoradapter-nodeps"],
-    static_libs: [
-        "androidx.annotation_annotation",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-fragment-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.fragment_fragment-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-fragment.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-fragment",
-    aars: [":car-ui-androidx-fragment-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-core",
-        "car-ui-androidx-viewpager",
-        "car-ui-androidx-loader",
-        "car-ui-androidx-activity",
-        "car-ui-androidx-lifecycle-livedata-core",
-        "car-ui-androidx-lifecycle-viewmodel",
-        "car-ui-androidx-lifecycle-viewmodel-savedstate",
-        "car-ui-androidx-savedstate",
-        // "androidx.annotation_annotation-experimental",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-loader-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.loader_loader-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-loader.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-loader",
-    aars: [":car-ui-androidx-loader-nodeps"],
-    static_libs: [
-        "androidx.annotation_annotation",
-        "androidx.collection_collection",
-        "androidx.lifecycle_lifecycle-viewmodel",
-        "androidx.core_core",
-        "androidx.lifecycle_lifecycle-livedata-core",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-viewpager-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.viewpager_viewpager-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-viewpager.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-viewpager",
-    aars: [":car-ui-androidx-viewpager-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-customview",
-        "car-ui-androidx-core",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-activity-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.activity_activity-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-activity.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-activity",
-    aars: [":car-ui-androidx-activity-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-core",
-        "car-ui-androidx-lifecycle-runtime",
-        "car-ui-androidx-lifecycle-viewmodel",
-        "car-ui-androidx-savedstate",
-        "car-ui-androidx-lifecycle-viewmodel-savedstate",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-lifecycle-viewmodel-savedstate-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.lifecycle_lifecycle-viewmodel-savedstate-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-lifecycle-viewmodel-savedstate.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-lifecycle-viewmodel-savedstate",
-    aars: [":car-ui-androidx-lifecycle-viewmodel-savedstate-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-savedstate",
-        "car-ui-androidx-lifecycle-livedata-core",
-        "car-ui-androidx-lifecycle-viewmodel",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-drawerlayout-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.drawerlayout_drawerlayout-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-drawerlayout.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-drawerlayout",
-    aars: [":car-ui-androidx-drawerlayout-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-core",
-        "car-ui-androidx-customview",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-customview-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.customview_customview-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-customview.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-customview",
-    aars: [":car-ui-androidx-customview-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-core",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-savedstate-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.savedstate_savedstate-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-savedstate.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-savedstate",
-    aars: [":car-ui-androidx-savedstate-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-core-common",
-        "car-ui-androidx-lifecycle-common",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-appcompat-resources-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.appcompat_appcompat-resources-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-appcompat-resources.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-appcompat-resources",
-    aars: [":car-ui-androidx-appcompat-resources-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-core",
-        "car-ui-androidx-vectordrawable",
-        // "car-ui-androidx-vectordrawable-animated",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-vectordrawable-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.vectordrawable_vectordrawable-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-vectordrawable.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-vectordrawable",
-    aars: [":car-ui-androidx-vectordrawable-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-core",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-core-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.core_core-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-core.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-core",
-    aars: [":car-ui-androidx-core-nodeps"],
-    static_libs: [
-        "car-ui-androidx-annotation",
-        "car-ui-androidx-collection",
-        "car-ui-androidx-lifecycle-runtime",
-        //"car-ui-androidx-versionedparcelable"
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-lifecycle-livedata-core-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.lifecycle_lifecycle-livedata-core-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-lifecycle-livedata-core.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-lifecycle-livedata-core",
-    aars: [":car-ui-androidx-lifecycle-livedata-core-nodeps"],
-    static_libs: [
-        "car-ui-androidx-lifecycle-common",
-        "car-ui-androidx-core-common",
-        "car-ui-androidx-core-runtime",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-lifecycle-viewmodel-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.lifecycle_lifecycle-viewmodel-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-lifecycle-viewmodel.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-lifecycle-viewmodel",
-    aars: [":car-ui-androidx-lifecycle-viewmodel-nodeps"],
-    sdk_version: "current",
-    static_libs: [
-        "car-ui-androidx-annotation",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-lifecycle-runtime-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.lifecycle_lifecycle-runtime-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-lifecycle-runtime.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-lifecycle-runtime",
-    aars: [":car-ui-androidx-lifecycle-runtime-nodeps"],
-    sdk_version: "current",
-    static_libs: [
-        "car-ui-androidx-lifecycle-common",
-        "car-ui-androidx-core-runtime",
-        "car-ui-androidx-core-common",
-        "car-ui-androidx-annotation",
-    ],
-}
-
-genrule {
-    name: "car-ui-androidx-lifecycle-common-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.lifecycle_lifecycle-common-nodeps{.jar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-lifecycle-common.jar"],
-}
-
-java_import {
-    name: "car-ui-androidx-lifecycle-common",
-    jars: [":car-ui-androidx-lifecycle-common-nodeps"],
-    sdk_version: "current",
-}
-
-genrule {
-    name: "car-ui-androidx-core-runtime-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.arch.core_core-runtime-nodeps{.aar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-core-runtime.aar"],
-}
-
-android_library_import {
-    name: "car-ui-androidx-core-runtime",
-    aars: [":car-ui-androidx-core-runtime-nodeps"],
-    sdk_version: "current",
-}
-
-genrule {
-    name: "car-ui-androidx-core-common-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.arch.core_core-common-nodeps{.jar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-core-common.aar"],
-}
-
-java_import {
-    name: "car-ui-androidx-core-common",
-    jars: [":car-ui-androidx-core-common-nodeps"],
-    sdk_version: "current",
-}
-
-java_genrule {
-    name: "car-ui-androidx-annotation-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.annotation_annotation-nodeps{.jar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-annotation.jar"],
-    host_supported: true,
-}
-
-java_import {
-    name: "car-ui-androidx-annotation",
-    jars: [":car-ui-androidx-annotation-nodeps"],
-    sdk_version: "current",
-    host_supported: true,
-}
-
-genrule {
-    name: "car-ui-androidx-collection-nodeps",
-    tools: ["jetifier"],
-    srcs: [
-        ":androidx.collection_collection-nodeps{.jar}",
-        "car-ui-jetifier-reverse.cfg",
-    ],
-    cmd: "$(location jetifier) -i $(in) -o $(out) -r -c $(location car-ui-jetifier-reverse.cfg)",
-    out: ["car-ui-androidx-collection.jar"],
-}
-
-java_import {
-    name: "car-ui-androidx-collection",
-    jars: [":car-ui-androidx-collection-nodeps"],
-    sdk_version: "current",
-}
diff --git a/car-ui-lib/car-ui-androidx/AndroidManifest.xml b/car-ui-lib/car-ui-androidx/AndroidManifest.xml
deleted file mode 100644
index 4b60871..0000000
--- a/car-ui-lib/car-ui-androidx/AndroidManifest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.car.ui.androidx">
-  <uses-sdk
-      android:minSdkVersion="29"
-      android:targetSdkVersion="30" />
-    <application>
-    </application>
-</manifest>
diff --git a/car-ui-lib/car-ui-androidx/README.md b/car-ui-lib/car-ui-androidx/README.md
deleted file mode 100644
index f9e821f..0000000
--- a/car-ui-lib/car-ui-androidx/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Android Automotive 'Chassis' re-packaged androidx
-Please refer to [Android Automotive 'Chassiss' shared library](../sharedlibrary/README.md)
-
-All the applications that are using both shared library version of car-ui-lib and and AndroidX will end up having 2 copies of AndroidX in their class path. One copy from the shared library and one version from the application itself. At runtime, the Android class loader finds the AndroidX classes from the shared library first. This could lead to compatibility issues, for example when the two versions are not compatible. In order to avoid that we're repackaging AndroidX binaries from `androiodx.*` to `androidx.car.ui.*`. `car-ui-lib-androidx` build target will be used with shared library version of car-ui-lib.
-
-car-ui-jetifier-reverse.cfg file is a manually edited file to match the requirements. This file needs maintainance as AndroidX adds more classes to the packages that are currently used by car-ui and/or if any new AndroidX package is needed by car-ui that's not listed there.
diff --git a/car-ui-lib/car-ui-androidx/car-ui-jetifier-reverse.cfg b/car-ui-lib/car-ui-androidx/car-ui-jetifier-reverse.cfg
deleted file mode 100644
index 558ba50..0000000
--- a/car-ui-lib/car-ui-androidx/car-ui-jetifier-reverse.cfg
+++ /dev/null
@@ -1,2963 +0,0 @@
-# Copyright (C) 2018 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
-
-# DO NOT EDIT MANUALLY! This file was auto-generated using Jetifier preprocessor.
-# To make some changes in the configuration edit "default.config" and run
-# preprocessor/scripts/processDefaultConfig.sh script to update this file.
-
-{
-  "restrictToPackagePrefixes": [
-    "android/support/",
-    "android/arch/",
-    "android/databinding/",
-    "com/android/databinding/library/baseAdapters/"
-  ],
-  "reversedRestrictToPackagePrefixes": [
-    "androidx/",
-    "com/google/android/material/"
-  ],
-  "rules": [
-    {
-      "from": "(.*)BuildConfig",
-      "to": "ignoreInPreprocessorOnly"
-    },
-    {
-      "from": "(.*)/package-info",
-      "to": "ignoreInPreprocessorOnly"
-    },
-    {
-      "from": "android/support/exifinterface/test/R(.*)",
-      "to": "ignore"
-    },
-    {
-      "from": "android/support/test/((.*)/)?internal/(.*)",
-      "to": "ignore"
-    },
-    {
-      "from": "android/support/v4/os/ResultReceiver(.*)",
-      "to": "ignore"
-    },
-    {
-      "from": "(.*)Parcelizer",
-      "to": "{0}Parcelizer"
-    },
-    {
-      "from": "androidx/car/ui/core/R(.*)",
-      "to": "androidx/core/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/R(.*)",
-      "to": "androidx/recyclerview/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/appcompat/R(.*)",
-      "to": "androidx/appcompat/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/savedstate/R(.*)",
-      "to": "androidx/savedstate/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/vectordrawable/R(.*)",
-      "to": "androidx/vectordrawable/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/preference/R(.*)",
-      "to": "androidx/preference/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/loader/R(.*)",
-      "to": "androidx/loader/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/viewmodel/R(.*)",
-      "to": "androidx/lifecycle/viewmodel/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/runtime/R(.*)",
-      "to": "androidx/lifecycle/runtime/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/livedata/core/R(.*)",
-      "to": "androidx/lifecycle/livedata/core/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/R(.*)",
-      "to": "androidx/fragment/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/drawerlayout/R(.*)",
-      "to": "androidx/drawerlayout/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/customview/R(.*)",
-      "to": "androidx/customview/R{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/AdapterHelper(.*)",
-      "to": "androidx/recyclerview/widget/AdapterHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/ChildHelper(.*)",
-      "to": "androidx/recyclerview/widget/ChildHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/DefaultItemAnimator(.*)",
-      "to": "androidx/recyclerview/widget/DefaultItemAnimator{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/DividerItemDecoration(.*)",
-      "to": "androidx/recyclerview/widget/DividerItemDecoration{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/FastScroller(.*)",
-      "to": "androidx/recyclerview/widget/FastScroller{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/GapWorker(.*)",
-      "to": "androidx/recyclerview/widget/GapWorker{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/GridLayoutManager(.*)",
-      "to": "androidx/recyclerview/widget/GridLayoutManager{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/LayoutState(.*)",
-      "to": "androidx/recyclerview/widget/LayoutState{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/LinearLayoutManager(.*)",
-      "to": "androidx/recyclerview/widget/LinearLayoutManager{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/LinearSmoothScroller(.*)",
-      "to": "androidx/recyclerview/widget/LinearSmoothScroller{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/LinearSnapHelper(.*)",
-      "to": "androidx/recyclerview/widget/LinearSnapHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/OpReorderer(.*)",
-      "to": "androidx/recyclerview/widget/OpReorderer{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/OrientationHelper(.*)",
-      "to": "androidx/recyclerview/widget/OrientationHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/PagerSnapHelper(.*)",
-      "to": "androidx/recyclerview/widget/PagerSnapHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/PositionMap(.*)",
-      "to": "androidx/recyclerview/widget/PositionMap{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/RecyclerViewAccessibilityDelegate(.*)",
-      "to": "androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/RecyclerView(.*)",
-      "to": "androidx/recyclerview/widget/RecyclerView{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/ScrollbarHelper(.*)",
-      "to": "androidx/recyclerview/widget/ScrollbarHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/SimpleItemAnimator(.*)",
-      "to": "androidx/recyclerview/widget/SimpleItemAnimator{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/SnapHelper(.*)",
-      "to": "androidx/recyclerview/widget/SnapHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/StaggeredGridLayoutManager(.*)",
-      "to": "androidx/recyclerview/widget/StaggeredGridLayoutManager{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/ViewBoundsCheck(.*)",
-      "to": "androidx/recyclerview/widget/ViewBoundsCheck{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/ViewInfoStore(.*)",
-      "to": "androidx/recyclerview/widget/ViewInfoStore{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/(.*)",
-      "to": "androidx/recyclerview/widget/{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/helper/(.*)",
-      "to": "androidx/recyclerview/widget/{0}"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview/widget/util/(.*)",
-      "to": "androidx/recyclerview/widget/{0}"
-    },
-    {
-      "from": "androidx/car/ui/preference/(.*)",
-      "to": "androidx/preference/{0}"
-    },
-    {
-      "from": "androidx/car/ui/preference/internal/PreferenceImageView(.*)",
-      "to": "androidx/preference/internal/PreferenceImageView{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/content/res/GrowingArrayUtils(.*)",
-      "to": "androidx/core/content/res/GrowingArrayUtils{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/content/res/GrowingArrayUtils(.*)",
-      "to": "androidx/core/content/res/GrowingArrayUtils{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/content/res/ColorStateListInflaterCompat(.*)",
-      "to": "androidx/core/content/res/ColorStateListInflaterCompat{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/content/res/ColorStateListInflaterCompat(.*)",
-      "to": "androidx/core/content/res/ColorStateListInflaterCompat{0}"
-    },
-    {
-      "from": "androidx/car/ui/appcompat/(.*)",
-      "to": "androidx/appcompat/{0}"
-    },
-    {
-      "from": "androidx/car/ui/vectordrawable/graphics/drawable/(.*)",
-      "to": "androidx/vectordrawable/graphics/drawable/{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/view/animation/PathInterpolatorApi14(.*)",
-      "to": "androidx/core/view/animation/PathInterpolatorApi14{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/view/animation/PathInterpolatorCompat(.*)",
-      "to": "androidx/core/view/animation/PathInterpolatorCompat{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/app/ComponentActivity(.*)",
-      "to": "androidx/core/app/ComponentActivity{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/app/Fragment(.*)",
-      "to": "androidx/fragment/app/Fragment{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/app/BaseFragment(.*)",
-      "to": "androidx/fragment/app/BaseFragment{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/app/BackStack(.*)",
-      "to": "androidx/fragment/app/BackStack{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/app/DialogFragment(.*)",
-      "to": "androidx/fragment/app/DialogFragment{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/app/ListFragment(.*)",
-      "to": "androidx/fragment/app/ListFragment{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/app/OneShotPreDrawListener(.*)",
-      "to": "androidx/fragment/app/OneShotPreDrawListener{0}"
-    },
-    {
-      "from": "androidx/car/ui/fragment/app/SuperNotCalledException(.*)",
-      "to": "androidx/fragment/app/SuperNotCalledException{0}"
-    },
-    {
-      "from": "androidx/car/ui/app/LoaderManager(.*)",
-      "to": "androidx/loader/app/LoaderManager{0}"
-    },
-    {
-      "from": "androidx/car/ui/content/Loader(.*)",
-      "to": "androidx/loader/content/Loader{0}"
-    },
-    {
-      "from": "androidx/car/ui/content/CursorLoader(.*)",
-      "to": "androidx/loader/content/CursorLoader{0}"
-    },
-    {
-      "from": "androidx/car/ui/content/AsyncTaskLoader(.*)",
-      "to": "androidx/loader/content/AsyncTaskLoader{0}"
-    },
-    {
-      "from": "androidx/car/ui/content/ModernAsyncTask(.*)",
-      "to": "androidx/loader/content/ModernAsyncTask{0}"
-    },
-    {
-      "from": "androidx/car/ui/customview/view/AbsSavedState(.*)",
-      "to": "androidx/customview/view/AbsSavedState{0}"
-    },
-    {
-      "from": "androidx/car/ui/customview/widget/ExploreByTouchHelper(.*)",
-      "to": "androidx/customview/widget/ExploreByTouchHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/customview/widget/FocusStrategy(.*)",
-      "to": "androidx/customview/widget/FocusStrategy{0}"
-    },
-    {
-      "from": "androidx/car/ui/customview/widget/ViewDragHelper(.*)",
-      "to": "androidx/customview/widget/ViewDragHelper{0}"
-    },
-    {
-      "from": "androidx/car/ui/drawerlayout/widget/DrawerLayout(.*)",
-      "to": "androidx/drawerlayout/widget/DrawerLayout{0}"
-    },
-    {
-      "from": "androidx/car/ui/asynclayoutinflater/view/AsyncLayoutInflater(.*)",
-      "to": "androidx/asynclayoutinflater/view/AsyncLayoutInflater{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/ArrayMap(.*)",
-      "to": "androidx/collection/ArrayMap{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/ArraySet(.*)",
-      "to": "androidx/collection/ArraySet{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/CircularArray(.*)",
-      "to": "androidx/collection/CircularArray{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/CircularIntArray(.*)",
-      "to": "androidx/collection/CircularIntArray{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/ContainerHelpers(.*)",
-      "to": "androidx/collection/ContainerHelpers{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/LongSparseArray(.*)",
-      "to": "androidx/collection/LongSparseArray{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/LruCache(.*)",
-      "to": "androidx/collection/LruCache{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/MapCollections(.*)",
-      "to": "androidx/collection/MapCollections{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/SimpleArrayMap(.*)",
-      "to": "androidx/collection/SimpleArrayMap{0}"
-    },
-    {
-      "from": "androidx/car/ui/collection/SparseArray(.*)",
-      "to": "androidx/collection/SparseArray{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/(.*)",
-      "to": "androidx/core/{0}"
-    },
-    {
-      "from": "androidx/car/ui/core/(.*)",
-      "to": "androidx/core/{0}"
-    },
-    {
-      "from": "androidx/car/ui/arch/core/(.*)",
-      "to": "androidx/arch/core/{0}"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/(.*)",
-      "to": "androidx/lifecycle/{0}"
-    },
-    {
-      "from": "androidx/car/ui/arch/core/executor/testing/(.*)",
-      "to": "androidx/arch/core/executor/testing/{0}"
-    },
-    {
-      "from": "androidx/car/ui/constraintlayout/solver/(.*)",
-      "to": "androidx/constraintlayout/solver/{0}"
-    },
-    {
-      "from": "androidx/car/ui/constraintlayout/widget/(.*)",
-      "to": "androidx/constraintlayout/widget/{0}"
-    },
-    {
-      "from": "androidx/car/ui/constraintlayout/core/(.*)",
-      "to": "androidx/constraintlayout/core/{0}"
-    },
-    {
-      "from": "androidx/versionedparcelable/(.*)",
-      "to": "androidx/versionedparcelable/{0}"
-    },
-    {
-      "from": "android/support/design/widget/AppBarLayout(.*)",
-      "to": "com/google/android/material/appbar/AppBarLayout{0}"
-    },
-    {
-      "from": "android/support/design/widget/BaseTransientBottomBar(.*)",
-      "to": "com/google/android/material/snackbar/BaseTransientBottomBar{0}"
-    },
-    {
-      "from": "android/support/design/widget/BottomNavigationView(.*)",
-      "to": "com/google/android/material/bottomnavigation/BottomNavigationView{0}"
-    },
-    {
-      "from": "android/support/design/widget/BottomSheet(.*)",
-      "to": "com/google/android/material/bottomsheet/BottomSheet{0}"
-    },
-    {
-      "from": "android/support/design/widget/CheckableImageButton(.*)",
-      "to": "com/google/android/material/internal/CheckableImageButton{0}"
-    },
-    {
-      "from": "android/support/design/widget/CircularBorderDrawable(.*)",
-      "to": "com/google/android/material/internal/CircularBorderDrawable{0}"
-    },
-    {
-      "from": "android/support/design/widget/CollapsingTextHelper(.*)",
-      "to": "com/google/android/material/internal/CollapsingTextHelper{0}"
-    },
-    {
-      "from": "android/support/design/widget/CollapsingToolbarLayout(.*)",
-      "to": "com/google/android/material/appbar/CollapsingToolbarLayout{0}"
-    },
-    {
-      "from": "android/support/design/widget/CutoutDrawable(.*)",
-      "to": "com/google/android/material/textfield/CutoutDrawable{0}"
-    },
-    {
-      "from": "android/support/design/widget/DescendantOffsetUtils(.*)",
-      "to": "com/google/android/material/internal/DescendantOffsetUtils{0}"
-    },
-    {
-      "from": "android/support/design/widget/DrawableUtils(.*)",
-      "to": "com/google/android/material/internal/DrawableUtils{0}"
-    },
-    {
-      "from": "android/support/design/widget/FloatingActionButton(.*)",
-      "to": "com/google/android/material/floatingactionbutton/FloatingActionButton{0}"
-    },
-    {
-      "from": "android/support/design/widget/HeaderBehavior(.*)",
-      "to": "com/google/android/material/appbar/HeaderBehavior{0}"
-    },
-    {
-      "from": "android/support/design/widget/HeaderScrollingViewBehavior(.*)",
-      "to": "com/google/android/material/appbar/HeaderScrollingViewBehavior{0}"
-    },
-    {
-      "from": "android/support/design/widget/HideBottomViewOnScrollBehavior(.*)",
-      "to": "com/google/android/material/behavior/HeaderScrollingViewBehavior{0}"
-    },
-    {
-      "from": "android/support/design/widget/IndicatorViewController(.*)",
-      "to": "com/google/android/material/textfield/IndicatorViewController{0}"
-    },
-    {
-      "from": "android/support/design/widget/MathUtils(.*)",
-      "to": "com/google/android/material/math/MathUtils{0}"
-    },
-    {
-      "from": "android/support/design/widget/NavigationView(.*)",
-      "to": "com/google/android/material/navigation/NavigationView{0}"
-    },
-    {
-      "from": "android/support/design/widget/Shadow(.*)",
-      "to": "com/google/android/material/shadow/Shadow{0}"
-    },
-    {
-      "from": "android/support/design/widget/Snackbar(.*)",
-      "to": "com/google/android/material/snackbar/Snackbar{0}"
-    },
-    {
-      "from": "android/support/design/widget/SnackbarManager(.*)",
-      "to": "com/google/android/material/snackbar/SnackbarManager{0}"
-    },
-    {
-      "from": "android/support/design/widget/StateListAnimator(.*)",
-      "to": "com/google/android/material/internal/StateListAnimator{0}"
-    },
-    {
-      "from": "android/support/design/widget/SwipeDismissBehavior(.*)",
-      "to": "com/google/android/material/behavior/SwipeDismissBehavior{0}"
-    },
-    {
-      "from": "android/support/design/widget/Tab(.*)",
-      "to": "com/google/android/material/tabs/Tab{0}"
-    },
-    {
-      "from": "android/support/design/widget/TextInput(.*)",
-      "to": "com/google/android/material/textfield/TextInput{0}"
-    },
-    {
-      "from": "android/support/design/widget/ViewOffsetBehavior(.*)",
-      "to": "com/google/android/material/appbar/ViewOffsetBehavior{0}"
-    },
-    {
-      "from": "android/support/design/widget/ViewOffsetHelper(.*)",
-      "to": "com/google/android/material/appbar/ViewOffsetHelper{0}"
-    },
-    {
-      "from": "android/support/design/widget/ViewUtilsLollipop(.*)",
-      "to": "com/google/android/material/appbar/ViewUtilsLollipop{0}"
-    },
-    {
-      "from": "android/support/design/widget/VisibilityAwareImageButton(.*)",
-      "to": "com/google/android/material/internal/VisibilityAwareImageButton{0}"
-    },
-    {
-      "from": "android/support/design/internal/BottomNavigation(.*)",
-      "to": "com/google/android/material/bottomnavigation/BottomNavigation{0}"
-    },
-    {
-      "from": "android/support/design/internal/SnackbarContentLayout(.*)",
-      "to": "com/google/android/material/snackbar/SnackbarContentLayout{0}"
-    },
-    {
-      "from": "android/support/design/R(.*)",
-      "to": "com/google/android/material/R{0}"
-    },
-    {
-      "from": "android/support/design/(.*)",
-      "to": "com/google/android/material/{0}"
-    },
-    {
-      "from": "androidx/car/ui/test/(.*)",
-      "to": "androidx/test/{0}"
-    },
-    {
-        "from": "androidx/car/ui/annotation/(.*)",
-        "to": "androidx/annotation/{0}"
-    },
-  ],
-  "slRules": [
-    {
-      "from": "androidx/recyclerview/selection/(.*)",
-      "to": "androidx/car/ui/recyclerview/selection/{0}"
-    },
-    {
-      "from": "androidx/(.*)/ktx/(.*)",
-      "to": "ignore"
-    },
-    {
-      "from": "androidx/(.*)/(.*)-ktx/(.*)",
-      "to": "ignore"
-    },
-    {
-      "from": "androidx/(.*)/lint/(.*)",
-      "to": "androidx/car/ui/{0}/lint/{1}"
-    },
-    {
-      "from": "androidx/(.*)/(.*)-lint/(.*)",
-      "to": "androidx/car/ui/{0}/{1}-lint/{2}"
-    },
-    {
-      "from": "androidx/drawerlayout/widget/annotations",
-      "to": "androidx/car/ui/drawerlayout/widget/annotations"
-    },
-    {
-      "from": "androidx/fragment/app/annotations",
-      "to": "androidx/car/ui/fragment/app/annotations"
-    },
-    {
-      "from": "androidx/activity/result/annotations",
-      "to": "androidx/car/ui/activity/result/annotations"
-    }
-  ],
-  "packageMap": [
-    {
-      "from": "androidx/car/ui/recyclerview/selection",
-      "to": "androidx/recyclerview/selection"
-    },
-    {
-      "from": "androidx/car/ui/asynclayoutinflater",
-      "to": "androidx/asynclayoutinflater"
-    },
-    {
-      "from": "androidx/car/ui/customview",
-      "to": "androidx/customview"
-    },
-    {
-      "from": "androidx/car/ui/loader",
-      "to": "androidx/loader"
-    },
-    {
-      "from": "androidx/car/ui/appcompat",
-      "to": "androidx/appcompat"
-    },
-    {
-      "from": "androidx/car/ui/recyclerview",
-      "to": "androidx/recyclerview"
-    },
-    {
-      "from": "androidx/car/ui/preference",
-      "to": "androidx/preference"
-    },
-    {
-      "from": "androidx/car/ui/core",
-      "to": "androidx/core"
-    },
-    {
-      "from": "androidx/car/ui/fragment",
-      "to": "androidx/fragment"
-    },
-    {
-      "from": "androidx/car/ui/drawerlayout",
-      "to": "androidx/drawerlayout"
-    },
-    {
-      "from": "androidx/car/ui/arch/core/testing",
-      "to": "androidx/arch/core/testing"
-    },
-    {
-      "from": "androidx/car/ui/arch/core",
-      "to": "androidx/arch/core"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/extensions",
-      "to": "androidx/lifecycle/extensions"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/testing",
-      "to": "androidx/lifecycle/testing"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/livedata/core",
-      "to": "androidx/lifecycle/livedata/core"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle",
-      "to": "androidx/lifecycle"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/viewmodel",
-      "to": "androidx/lifecycle/viewmodel"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/livedata",
-      "to": "androidx/lifecycle/livedata"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/reactivestreams",
-      "to": "androidx/lifecycle/reactivestreams"
-    },
-    {
-      "from": "androidx/car/ui/constraintlayout/widget",
-      "to": "androidx/constraintlayout/widget"
-    },
-    {
-      "from": "androidx/car/ui/lifecycle/runtime",
-      "to": "androidx/lifecycle/runtime"
-    },
-    {
-      "from": "androidx/car/ui/appcompat/resources",
-      "to": "androidx/appcompat/resources"
-    },
-    {
-      "from": "androidx/car/ui/activity",
-      "to": "androidx/activity"
-    },
-    {
-      "from": "androidx/car/ui/savedstate",
-      "to": "androidx/savedstate"
-    },
-    {
-      "from": "androidx/car/ui/vectordrawable",
-      "to": "androidx/vectordrawable"
-    }
-  ],
-  "pomRules": [
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "animated-vector-drawable",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.vectordrawable",
-        "artifactId": "vectordrawable-animated",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "appcompat-v7",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.appcompat",
-        "artifactId": "appcompat",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "cardview-v7",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.cardview",
-        "artifactId": "cardview",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "customtabs",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.browser",
-        "artifactId": "browser",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "design",
-        "version": "{oldMaterialVersion}"
-      },
-      "to": {
-        "groupId": "com.google.android.material",
-        "artifactId": "material",
-        "version": "{newMaterialVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "exifinterface",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.exifinterface",
-        "artifactId": "exifinterface",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "gridlayout-v7",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.gridlayout",
-        "artifactId": "gridlayout",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "leanback-v17",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.leanback",
-        "artifactId": "leanback",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "mediarouter-v7",
-        "version": "{oldMediarouterVersion}"
-      },
-      "to": {
-        "groupId": "androidx.mediarouter",
-        "artifactId": "mediarouter",
-        "version": "{newMediarouterVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "multidex",
-        "version": "1.0.3"
-      },
-      "to": {
-        "groupId": "androidx.multidex",
-        "artifactId": "multidex",
-        "version": "2.0.0"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "multidex-instrumentation",
-        "version": "1.0.3"
-      },
-      "to": {
-        "groupId": "androidx.multidex",
-        "artifactId": "multidex-instrumentation",
-        "version": "2.0.0"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "palette-v7",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.palette",
-        "artifactId": "palette",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "percent",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.percentlayout",
-        "artifactId": "percentlayout",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "preference-leanback-v17",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.leanback",
-        "artifactId": "leanback-preference",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "preference-v14",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.legacy",
-        "artifactId": "legacy-preference-v14",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "preference-v7",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.preference",
-        "artifactId": "preference",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "recommendation",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.recommendation",
-        "artifactId": "recommendation",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "recyclerview-v7",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.recyclerview",
-        "artifactId": "recyclerview",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-annotations",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.annotation",
-        "artifactId": "annotation",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-compat",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.core",
-        "artifactId": "core",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-content",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.contentpager",
-        "artifactId": "contentpager",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-core-ui",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.legacy",
-        "artifactId": "legacy-support-core-ui",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-core-utils",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.legacy",
-        "artifactId": "legacy-support-core-utils",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-dynamic-animation",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.dynamicanimation",
-        "artifactId": "dynamicanimation",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-emoji",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.emoji",
-        "artifactId": "emoji",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-emoji-appcompat",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.emoji",
-        "artifactId": "emoji-appcompat",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-emoji-bundled",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.emoji",
-        "artifactId": "emoji-bundled",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-fragment",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.fragment",
-        "artifactId": "fragment",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-media-compat",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.media",
-        "artifactId": "media",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-tv-provider",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.tvprovider",
-        "artifactId": "tvprovider",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-v13",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.legacy",
-        "artifactId": "legacy-support-v13",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-v4",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.legacy",
-        "artifactId": "legacy-support-v4",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "support-vector-drawable",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.vectordrawable",
-        "artifactId": "vectordrawable",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "textclassifier",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.textclassifier",
-        "artifactId": "textclassifier",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "transition",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.transition",
-        "artifactId": "transition",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "wear",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.wear",
-        "artifactId": "wear",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "asynclayoutinflater",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.asynclayoutinflater",
-        "artifactId": "asynclayoutinflater",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "collections",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.collection",
-        "artifactId": "collection",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "coordinatorlayout",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.coordinatorlayout",
-        "artifactId": "coordinatorlayout",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "cursoradapter",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.cursoradapter",
-        "artifactId": "cursoradapter",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "customview",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.customview",
-        "artifactId": "customview",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "documentfile",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.documentfile",
-        "artifactId": "documentfile",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "drawerlayout",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.drawerlayout",
-        "artifactId": "drawerlayout",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "interpolator",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.interpolator",
-        "artifactId": "interpolator",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "loader",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.loader",
-        "artifactId": "loader",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "localbroadcastmanager",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.localbroadcastmanager",
-        "artifactId": "localbroadcastmanager",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "print",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.print",
-        "artifactId": "print",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "slidingpanelayout",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.slidingpanelayout",
-        "artifactId": "slidingpanelayout",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "swiperefreshlayout",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.swiperefreshlayout",
-        "artifactId": "swiperefreshlayout",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "viewpager",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.viewpager",
-        "artifactId": "viewpager",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.databinding",
-        "artifactId": "adapters",
-        "version": "undefined"
-      },
-      "to": {
-        "groupId": "androidx.databinding",
-        "artifactId": "databinding-adapters",
-        "version": "{newDataBindingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.databinding",
-        "artifactId": "baseLibrary",
-        "version": "undefined"
-      },
-      "to": {
-        "groupId": "androidx.databinding",
-        "artifactId": "databinding-common",
-        "version": "{newDataBindingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.databinding",
-        "artifactId": "compiler",
-        "version": "undefined"
-      },
-      "to": {
-        "groupId": "androidx.databinding",
-        "artifactId": "databinding-compiler",
-        "version": "{newDataBindingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.databinding",
-        "artifactId": "compilerCommon",
-        "version": "undefined"
-      },
-      "to": {
-        "groupId": "androidx.databinding",
-        "artifactId": "databinding-compiler-common",
-        "version": "{newDataBindingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.databinding",
-        "artifactId": "library",
-        "version": "undefined"
-      },
-      "to": {
-        "groupId": "androidx.databinding",
-        "artifactId": "databinding-runtime",
-        "version": "{newDataBindingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "versionedparcelable",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.versionedparcelable",
-        "artifactId": "versionedparcelable",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.work",
-        "artifactId": "work-runtime",
-        "version": "{oldWorkManagerVersion}"
-      },
-      "to": {
-        "groupId": "androidx.work",
-        "artifactId": "work-runtime",
-        "version": "{newWorkManagerVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.work",
-        "artifactId": "work-runtime-ktx",
-        "version": "{oldWorkManagerVersion}"
-      },
-      "to": {
-        "groupId": "androidx.work",
-        "artifactId": "work-runtime-ktx",
-        "version": "{newWorkManagerVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.work",
-        "artifactId": "work-rxjava2",
-        "version": "{oldWorkManagerVersion}"
-      },
-      "to": {
-        "groupId": "androidx.work",
-        "artifactId": "work-rxjava2",
-        "version": "{newWorkManagerVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.work",
-        "artifactId": "work-testing",
-        "version": "{oldWorkManagerVersion}"
-      },
-      "to": {
-        "groupId": "androidx.work",
-        "artifactId": "work-testing",
-        "version": "{newWorkManagerVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-common",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-common",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-common-ktx",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-common-ktx",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-fragment",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-fragment",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-fragment-ktx",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-fragment-ktx",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-runtime",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-runtime",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-runtime-ktx",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-runtime-ktx",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-ui",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-ui",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.navigation",
-        "artifactId": "navigation-ui-ktx",
-        "version": "{oldNavigationVersion}"
-      },
-      "to": {
-        "groupId": "androidx.navigation",
-        "artifactId": "navigation-ui-ktx",
-        "version": "{newNavigationVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.core",
-        "artifactId": "common",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.arch.core",
-        "artifactId": "core-common",
-        "version": "{newArchCoreVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.core",
-        "artifactId": "core",
-        "version": "1.0.0-alpha3"
-      },
-      "to": {
-        "groupId": "androidx.arch.core",
-        "artifactId": "core",
-        "version": "{newArchCoreVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.core",
-        "artifactId": "core-testing",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.arch.core",
-        "artifactId": "core-testing",
-        "version": "{newArchCoreVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.core",
-        "artifactId": "runtime",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.arch.core",
-        "artifactId": "core-runtime",
-        "version": "{newArchCoreVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "common",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-common",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "common-java8",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-common-java8",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "compiler",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-compiler",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "extensions",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-extensions",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "reactivestreams",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-reactivestreams",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "runtime",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-runtime",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "viewmodel",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-viewmodel",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "livedata",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-livedata",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.lifecycle",
-        "artifactId": "livedata-core",
-        "version": "1.1.1"
-      },
-      "to": {
-        "groupId": "androidx.lifecycle",
-        "artifactId": "lifecycle-livedata-core",
-        "version": "{newLifecycleVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.paging",
-        "artifactId": "common",
-        "version": "1.0.0"
-      },
-      "to": {
-        "groupId": "androidx.paging",
-        "artifactId": "paging-common",
-        "version": "{newPagingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.paging",
-        "artifactId": "runtime",
-        "version": "1.0.0"
-      },
-      "to": {
-        "groupId": "androidx.paging",
-        "artifactId": "paging-runtime",
-        "version": "{newPagingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.paging",
-        "artifactId": "rxjava2",
-        "version": "1.0.0-alpha1"
-      },
-      "to": {
-        "groupId": "androidx.paging",
-        "artifactId": "paging-rxjava2",
-        "version": "{newPagingVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence",
-        "artifactId": "db",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.sqlite",
-        "artifactId": "sqlite",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence",
-        "artifactId": "db-framework",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.sqlite",
-        "artifactId": "sqlite-framework",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence.room",
-        "artifactId": "common",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.room",
-        "artifactId": "room-common",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence.room",
-        "artifactId": "compiler",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.room",
-        "artifactId": "room-compiler",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence.room",
-        "artifactId": "migration",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.room",
-        "artifactId": "room-migration",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence.room",
-        "artifactId": "runtime",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.room",
-        "artifactId": "room-runtime",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence.room",
-        "artifactId": "rxjava2",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.room",
-        "artifactId": "room-rxjava2",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence.room",
-        "artifactId": "testing",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.room",
-        "artifactId": "room-testing",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "android.arch.persistence.room",
-        "artifactId": "guava",
-        "version": "{oldRoomVersion}"
-      },
-      "to": {
-        "groupId": "androidx.room",
-        "artifactId": "room-guava",
-        "version": "{newRoomVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.constraint",
-        "artifactId": "constraint-layout",
-        "version": "1.1.0"
-      },
-      "to": {
-        "groupId": "androidx.constraintlayout",
-        "artifactId": "constraintlayout",
-        "version": "1.1.3"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.constraint",
-        "artifactId": "constraint-layout-solver",
-        "version": "1.1.0"
-      },
-      "to": {
-        "groupId": "androidx.constraintlayout",
-        "artifactId": "constraintlayout-solver",
-        "version": "1.1.3"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test",
-        "artifactId": "orchestrator",
-        "version": "1.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test",
-        "artifactId": "orchestrator",
-        "version": "{newTestsVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test",
-        "artifactId": "rules",
-        "version": "1.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test",
-        "artifactId": "rules",
-        "version": "{newTestsVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test",
-        "artifactId": "runner",
-        "version": "1.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test",
-        "artifactId": "runner",
-        "version": "{newTestsVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test",
-        "artifactId": "monitor",
-        "version": "1.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test",
-        "artifactId": "monitor",
-        "version": "{newTestsVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso",
-        "artifactId": "espresso-accessibility",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso",
-        "artifactId": "espresso-accessibility",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso",
-        "artifactId": "espresso-contrib",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso",
-        "artifactId": "espresso-contrib",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso",
-        "artifactId": "espresso-core",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso",
-        "artifactId": "espresso-core",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso",
-        "artifactId": "espresso-idling-resource",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso",
-        "artifactId": "espresso-idling-resource",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso",
-        "artifactId": "espresso-intents",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso",
-        "artifactId": "espresso-intents",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso",
-        "artifactId": "espresso-remote",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso",
-        "artifactId": "espresso-remote",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso",
-        "artifactId": "espresso-web",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso",
-        "artifactId": "espresso-web",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso.idling",
-        "artifactId": "idling-concurrent",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso.idling",
-        "artifactId": "idling-concurrent",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.espresso.idling",
-        "artifactId": "idling-net",
-        "version": "3.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test.espresso.idling",
-        "artifactId": "idling-net",
-        "version": "{newEspressoVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.janktesthelper",
-        "artifactId": "janktesthelper",
-        "version": "1.0.1"
-      },
-      "to": {
-        "groupId": "androidx.test.jank",
-        "artifactId": "janktesthelper",
-        "version": "{newJankTestHelperVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.services",
-        "artifactId": "test-services",
-        "version": "1.0.2"
-      },
-      "to": {
-        "groupId": "androidx.test",
-        "artifactId": "test-services",
-        "version": "{newTestsVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support.test.uiautomator",
-        "artifactId": "uiautomator",
-        "version": "2.1.3"
-      },
-      "to": {
-        "groupId": "androidx.test.uiautomator",
-        "artifactId": "uiautomator",
-        "version": "{newUiAutomatorVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "car",
-        "version": "{oldCarVersion}"
-      },
-      "to": {
-        "groupId": "androidx.car",
-        "artifactId": "car",
-        "version": "{newCarVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "slices-core",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.slice",
-        "artifactId": "slice-core",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "slices-builders",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.slice",
-        "artifactId": "slice-builders",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "slices-view",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.slice",
-        "artifactId": "slice-view",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "heifwriter",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.heifwriter",
-        "artifactId": "heifwriter",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "recyclerview-selection",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.recyclerview",
-        "artifactId": "recyclerview-selection",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "webkit",
-        "version": "{oldSlVersion}"
-      },
-      "to": {
-        "groupId": "androidx.webkit",
-        "artifactId": "webkit",
-        "version": "{newSlVersion}"
-      }
-    },
-    {
-      "from": {
-        "groupId": "com.android.support",
-        "artifactId": "biometric",
-        "version": "{oldBiometricVersion}"
-      },
-      "to": {
-        "groupId": "androidx.biometric",
-        "artifactId": "biometric",
-        "version": "{newBiometricVersion}"
-      }
-    }
-  ],
-  "versions": {
-    "latestReleased": {
-      "oldSlVersion": "28.0.0",
-      "oldMaterialVersion": "28.0.0",
-      "oldRoomVersion": "1.1.0",
-      "oldCarVersion": "28.0.0-alpha5",
-      "oldMediarouterVersion": "28.0.0-alpha5",
-      "oldMedia2Version": "28.0.0-alpha03",
-      "oldExoplayerVersion": "28.0.0-alpha01",
-      "oldBiometricVersion": "28.0.0-alpha03",
-      "oldNavigationVersion": "1.0.0",
-      "oldWorkManagerVersion": "1.0.0",
-      "newSlVersion": "1.0.0",
-      "newMaterialVersion": "1.0.0",
-      "newArchCoreVersion": "2.0.0",
-      "newLifecycleVersion": "2.0.0",
-      "newPagingVersion": "2.0.0",
-      "newRoomVersion": "2.0.0",
-      "newEspressoVersion": "3.1.0-alpha3",
-      "newTestsVersion": "1.1.0-alpha3",
-      "newJankTestHelperVersion": "1.0.1-alpha3",
-      "newUiAutomatorVersion": "2.2.0-alpha3",
-      "newCarVersion": "1.0.0-alpha5",
-      "newMediarouterVersion": "1.0.0-alpha5",
-      "newMedia2Version": "1.0.0-alpha03",
-      "newExoplayerVersion": "1.0.0-alpha01",
-      "newBiometricVersion": "1.0.0-alpha03",
-      "newDataBindingVersion": "undefined",
-      "newNavigationVersion": "2.0.0",
-      "newWorkManagerVersion": "2.0.0"
-    }
-  },
-  "map": {
-    "types": {
-      "androidx/car/ui/arch/core/executor/AppToolkitTaskExecutor": "androidx/arch/core/executor/AppToolkitTaskExecutor",
-      "androidx/car/ui/arch/core/executor/ArchTaskExecutor": "androidx/arch/core/executor/ArchTaskExecutor",
-      "androidx/car/ui/arch/core/executor/DefaultTaskExecutor": "androidx/arch/core/executor/DefaultTaskExecutor",
-      "androidx/car/ui/arch/core/executor/JunitTaskExecutorRule": "androidx/arch/core/executor/JunitTaskExecutorRule",
-      "androidx/car/ui/arch/core/executor/TaskExecutor": "androidx/arch/core/executor/TaskExecutor",
-      "androidx/car/ui/arch/core/executor/TaskExecutorWithFakeMainThread": "androidx/arch/core/executor/TaskExecutorWithFakeMainThread",
-      "androidx/car/ui/arch/core/executor/testing/CountingTaskExecutorRule": "androidx/arch/core/executor/testing/CountingTaskExecutorRule",
-      "androidx/car/ui/arch/core/executor/testing/InstantTaskExecutorRule": "androidx/arch/core/executor/testing/InstantTaskExecutorRule",
-      "androidx/car/ui/arch/core/internal/FastSafeIterableMap": "androidx/arch/core/internal/FastSafeIterableMap",
-      "androidx/car/ui/arch/core/internal/SafeIterableMap": "androidx/arch/core/internal/SafeIterableMap",
-      "androidx/car/ui/arch/core/util/Function": "androidx/arch/core/util/Function",
-      "androidx/car/ui/lifecycle/AndroidViewModel": "androidx/lifecycle/AndroidViewModel",
-      "androidx/car/ui/lifecycle/ClassesInfoCache": "androidx/lifecycle/ClassesInfoCache",
-      "androidx/car/ui/lifecycle/CompositeGeneratedAdaptersObserver": "androidx/lifecycle/CompositeGeneratedAdaptersObserver",
-      "androidx/car/ui/lifecycle/ComputableLiveData": "androidx/lifecycle/ComputableLiveData",
-      "androidx/car/ui/lifecycle/DefaultLifecycleObserver": "androidx/lifecycle/DefaultLifecycleObserver",
-      "androidx/car/ui/lifecycle/Elements_extKt": "androidx/lifecycle/Elements_extKt",
-      "androidx/car/ui/lifecycle/EmptyActivityLifecycleCallbacks": "androidx/lifecycle/EmptyActivityLifecycleCallbacks",
-      "androidx/car/ui/lifecycle/ErrorMessages": "androidx/lifecycle/ErrorMessages",
-      "androidx/car/ui/lifecycle/FullLifecycleObserver": "androidx/lifecycle/FullLifecycleObserver",
-      "androidx/car/ui/lifecycle/FullLifecycleObserverAdapter": "androidx/lifecycle/FullLifecycleObserverAdapter",
-      "androidx/car/ui/lifecycle/GeneratedAdapter": "androidx/lifecycle/GeneratedAdapter",
-      "androidx/car/ui/lifecycle/GenericLifecycleObserver": "androidx/lifecycle/GenericLifecycleObserver",
-      "androidx/car/ui/lifecycle/HolderFragment": "androidx/lifecycle/HolderFragment",
-      "androidx/car/ui/lifecycle/Input_collectorKt": "androidx/lifecycle/Input_collectorKt",
-      "androidx/car/ui/lifecycle/Lifecycle": "androidx/lifecycle/Lifecycle",
-      "androidx/car/ui/lifecycle/LifecycleDispatcher": "androidx/lifecycle/LifecycleDispatcher",
-      "androidx/car/ui/lifecycle/LifecycleObserver": "androidx/lifecycle/LifecycleObserver",
-      "androidx/car/ui/lifecycle/LifecycleOwner": "androidx/lifecycle/LifecycleOwner",
-      "androidx/car/ui/lifecycle/LifecycleProcessor": "androidx/lifecycle/LifecycleProcessor",
-      "androidx/car/ui/lifecycle/LifecycleRegistry": "androidx/lifecycle/LifecycleRegistry",
-      "androidx/car/ui/lifecycle/LifecycleRegistryOwner": "androidx/lifecycle/LifecycleRegistryOwner",
-      "androidx/car/ui/lifecycle/LifecycleService": "androidx/lifecycle/LifecycleService",
-      "androidx/car/ui/lifecycle/Lifecycling": "androidx/lifecycle/Lifecycling",
-      "androidx/car/ui/lifecycle/LiveData": "androidx/lifecycle/LiveData",
-      "androidx/car/ui/lifecycle/LiveDataReactiveStreams": "androidx/lifecycle/LiveDataReactiveStreams",
-      "androidx/car/ui/lifecycle/MediatorLiveData": "androidx/lifecycle/MediatorLiveData",
-      "androidx/car/ui/lifecycle/MethodCallsLogger": "androidx/lifecycle/MethodCallsLogger",
-      "androidx/car/ui/lifecycle/MutableLiveData": "androidx/lifecycle/MutableLiveData",
-      "androidx/car/ui/lifecycle/Observer": "androidx/lifecycle/Observer",
-      "androidx/car/ui/lifecycle/ObserversCollector": "androidx/lifecycle/ObserversCollector",
-      "androidx/car/ui/lifecycle/OnLifecycleEvent": "androidx/lifecycle/OnLifecycleEvent",
-      "androidx/car/ui/lifecycle/ProcessLifecycleOwner": "androidx/lifecycle/ProcessLifecycleOwner",
-      "androidx/car/ui/lifecycle/ProcessLifecycleOwnerInitializer": "androidx/lifecycle/ProcessLifecycleOwnerInitializer",
-      "androidx/car/ui/lifecycle/ReflectiveGenericLifecycleObserver": "androidx/lifecycle/ReflectiveGenericLifecycleObserver",
-      "androidx/car/ui/lifecycle/ReportFragment": "androidx/lifecycle/ReportFragment",
-      "androidx/car/ui/lifecycle/ServiceLifecycleDispatcher": "androidx/lifecycle/ServiceLifecycleDispatcher",
-      "androidx/car/ui/lifecycle/SingleGeneratedAdapterObserver": "androidx/lifecycle/SingleGeneratedAdapterObserver",
-      "androidx/car/ui/lifecycle/TransformationKt": "androidx/lifecycle/TransformationKt",
-      "androidx/car/ui/lifecycle/Transformations": "androidx/lifecycle/Transformations",
-      "androidx/car/ui/lifecycle/Validator": "androidx/lifecycle/Validator",
-      "androidx/car/ui/lifecycle/ViewModel": "androidx/lifecycle/ViewModel",
-      "androidx/car/ui/lifecycle/ViewModelProvider": "androidx/lifecycle/ViewModelProvider",
-      "androidx/car/ui/lifecycle/ViewModelProviders": "androidx/lifecycle/ViewModelProviders",
-      "androidx/car/ui/lifecycle/ViewModelStore": "androidx/lifecycle/ViewModelStore",
-      "androidx/car/ui/lifecycle/ViewModelStoreOwner": "androidx/lifecycle/ViewModelStoreOwner",
-      "androidx/car/ui/lifecycle/ViewModelStores": "androidx/lifecycle/ViewModelStores",
-      "androidx/car/ui/lifecycle/WriterKt": "androidx/lifecycle/WriterKt",
-      "androidx/car/ui/lifecycle/model/AdapterClass": "androidx/lifecycle/model/AdapterClass",
-      "androidx/car/ui/lifecycle/model/AdapterClassKt": "androidx/lifecycle/model/AdapterClassKt",
-      "androidx/car/ui/lifecycle/model/EventMethod": "androidx/lifecycle/model/EventMethod",
-      "androidx/car/ui/lifecycle/model/EventMethodCall": "androidx/lifecycle/model/EventMethodCall",
-      "androidx/car/ui/lifecycle/model/InputModel": "androidx/lifecycle/model/InputModel",
-      "androidx/car/ui/lifecycle/model/LifecycleObserverInfo": "androidx/lifecycle/model/LifecycleObserverInfo",
-      "androidx/car/ui/annotation/AnimRes": "androidx/annotation/AnimRes",
-      "androidx/car/ui/annotation/AnimatorRes": "androidx/annotation/AnimatorRes",
-      "androidx/car/ui/annotation/AnyRes": "androidx/annotation/AnyRes",
-      "androidx/car/ui/annotation/AnyThread": "androidx/annotation/AnyThread",
-      "androidx/car/ui/annotation/ArrayRes": "androidx/annotation/ArrayRes",
-      "androidx/car/ui/annotation/AttrRes": "androidx/annotation/AttrRes",
-      "androidx/car/ui/annotation/BinderThread": "androidx/annotation/BinderThread",
-      "androidx/car/ui/annotation/BoolRes": "androidx/annotation/BoolRes",
-      "androidx/car/ui/annotation/CallSuper": "androidx/annotation/CallSuper",
-      "androidx/car/ui/annotation/CheckResult": "androidx/annotation/CheckResult",
-      "androidx/car/ui/annotation/ColorInt": "androidx/annotation/ColorInt",
-      "androidx/car/ui/annotation/ColorLong": "androidx/annotation/ColorLong",
-      "androidx/car/ui/annotation/ColorRes": "androidx/annotation/ColorRes",
-      "androidx/car/ui/annotation/DimenRes": "androidx/annotation/DimenRes",
-      "androidx/car/ui/annotation/Dimension": "androidx/annotation/Dimension",
-      "androidx/car/ui/annotation/DrawableRes": "androidx/annotation/DrawableRes",
-      "androidx/car/ui/annotation/FloatRange": "androidx/annotation/FloatRange",
-      "androidx/car/ui/annotation/FontRes": "androidx/annotation/FontRes",
-      "androidx/car/ui/annotation/FractionRes": "androidx/annotation/FractionRes",
-      "androidx/car/ui/annotation/GuardedBy": "androidx/annotation/GuardedBy",
-      "androidx/car/ui/annotation/HalfFloat": "androidx/annotation/HalfFloat",
-      "androidx/car/ui/annotation/IdRes": "androidx/annotation/IdRes",
-      "androidx/car/ui/annotation/IntDef": "androidx/annotation/IntDef",
-      "androidx/car/ui/annotation/IntRange": "androidx/annotation/IntRange",
-      "androidx/car/ui/annotation/IntegerRes": "androidx/annotation/IntegerRes",
-      "androidx/car/ui/annotation/InterpolatorRes": "androidx/annotation/InterpolatorRes",
-      "androidx/car/ui/annotation/Keep": "androidx/annotation/Keep",
-      "androidx/car/ui/annotation/LayoutRes": "androidx/annotation/LayoutRes",
-      "androidx/car/ui/annotation/LongDef": "androidx/annotation/LongDef",
-      "androidx/car/ui/annotation/MainThread": "androidx/annotation/MainThread",
-      "androidx/car/ui/annotation/MenuRes": "androidx/annotation/MenuRes",
-      "androidx/car/ui/annotation/NavigationRes": "androidx/annotation/NavigationRes",
-      "androidx/car/ui/annotation/NonNull": "androidx/annotation/NonNull",
-      "androidx/car/ui/annotation/Nullable": "androidx/annotation/Nullable",
-      "androidx/car/ui/annotation/PluralsRes": "androidx/annotation/PluralsRes",
-      "androidx/car/ui/annotation/Px": "androidx/annotation/Px",
-      "androidx/car/ui/annotation/RawRes": "androidx/annotation/RawRes",
-      "androidx/car/ui/annotation/RequiresApi": "androidx/annotation/RequiresApi",
-      "androidx/car/ui/annotation/RequiresFeature": "androidx/annotation/RequiresFeature",
-      "androidx/car/ui/annotation/RequiresPermission": "androidx/annotation/RequiresPermission",
-      "androidx/car/ui/annotation/RestrictTo": "androidx/annotation/RestrictTo",
-      "androidx/car/ui/annotation/Size": "androidx/annotation/Size",
-      "androidx/car/ui/annotation/StringDef": "androidx/annotation/StringDef",
-      "androidx/car/ui/annotation/StringRes": "androidx/annotation/StringRes",
-      "androidx/car/ui/annotation/StyleRes": "androidx/annotation/StyleRes",
-      "androidx/car/ui/annotation/StyleableRes": "androidx/annotation/StyleableRes",
-      "androidx/car/ui/annotation/TransitionRes": "androidx/annotation/TransitionRes",
-      "androidx/car/ui/annotation/UiThread": "androidx/annotation/UiThread",
-      "androidx/car/ui/annotation/VisibleForTesting": "androidx/annotation/VisibleForTesting",
-      "androidx/car/ui/annotation/WorkerThread": "androidx/annotation/WorkerThread",
-      "androidx/car/ui/annotation/XmlRes": "androidx/annotation/XmlRes",
-      "android/support/app/recommendation/ContentRecommendation": "androidx/recommendation/app/ContentRecommendation",
-      "android/support/app/recommendation/RecommendationExtender": "androidx/recommendation/app/RecommendationExtender",
-      "androidx/car/ui/core/R": "androidx/core/R",
-      "androidx/car/ui/constraintlayout/widget/Barrier": "androidx/constraintlayout/widget/Barrier",
-      "androidx/car/ui/constraintlayout/widget/ConstraintHelper": "androidx/constraintlayout/widget/ConstraintHelper",
-      "androidx/car/ui/constraintlayout/widget/ConstraintLayout": "androidx/constraintlayout/widget/ConstraintLayout",
-      "androidx/car/ui/constraintlayout/widget/ConstraintSet": "androidx/constraintlayout/widget/ConstraintSet",
-      "androidx/car/ui/constraintlayout/widget/Constraints": "androidx/constraintlayout/widget/Constraints",
-      "androidx/car/ui/constraintlayout/widget/Group": "androidx/constraintlayout/widget/Group",
-      "androidx/car/ui/constraintlayout/widget/Guideline": "androidx/constraintlayout/widget/Guideline",
-      "androidx/car/ui/constraintlayout/widget/Placeholder": "androidx/constraintlayout/widget/Placeholder",
-      "androidx/car/ui/constraintlayout/widget/R": "androidx/constraintlayout/widget/R",
-      "androidx/car/ui/constraintlayout/solver/ArrayLinkedVariables": "androidx/constraintlayout/solver/ArrayLinkedVariables",
-      "androidx/car/ui/constraintlayout/solver/ArrayRow": "androidx/constraintlayout/solver/ArrayRow",
-      "androidx/car/ui/constraintlayout/solver/Cache": "androidx/constraintlayout/solver/Cache",
-      "androidx/car/ui/constraintlayout/solver/GoalRow": "androidx/constraintlayout/solver/GoalRow",
-      "androidx/car/ui/constraintlayout/solver/LinearSystem": "androidx/constraintlayout/solver/LinearSystem",
-      "androidx/car/ui/constraintlayout/solver/Metrics": "androidx/constraintlayout/solver/Metrics",
-      "androidx/car/ui/constraintlayout/solver/Pools": "androidx/constraintlayout/solver/Pools",
-      "androidx/car/ui/constraintlayout/solver/SolverVariable": "androidx/constraintlayout/solver/SolverVariable",
-      "androidx/car/ui/constraintlayout/solver/widgets/Analyzer": "androidx/constraintlayout/solver/widgets/Analyzer",
-      "androidx/car/ui/constraintlayout/solver/widgets/Barrier": "androidx/constraintlayout/solver/widgets/Barrier",
-      "androidx/car/ui/constraintlayout/solver/widgets/Chain": "androidx/constraintlayout/solver/widgets/Chain",
-      "androidx/car/ui/constraintlayout/solver/widgets/ChainHead": "androidx/constraintlayout/solver/widgets/ChainHead",
-      "androidx/car/ui/constraintlayout/solver/widgets/ConstraintAnchor": "androidx/constraintlayout/solver/widgets/ConstraintAnchor",
-      "androidx/car/ui/constraintlayout/solver/widgets/ConstraintHorizontalLayout": "androidx/constraintlayout/solver/widgets/ConstraintHorizontalLayout",
-      "androidx/car/ui/constraintlayout/solver/widgets/ConstraintTableLayout": "androidx/constraintlayout/solver/widgets/ConstraintTableLayout",
-      "androidx/car/ui/constraintlayout/solver/widgets/ConstraintWidget": "androidx/constraintlayout/solver/widgets/ConstraintWidget",
-      "androidx/car/ui/constraintlayout/solver/widgets/ConstraintWidgetContainer": "androidx/constraintlayout/solver/widgets/ConstraintWidgetContainer",
-      "androidx/car/ui/constraintlayout/solver/widgets/ConstraintWidgetGroup": "androidx/constraintlayout/solver/widgets/ConstraintWidgetGroup",
-      "androidx/car/ui/constraintlayout/solver/widgets/Guideline": "androidx/constraintlayout/solver/widgets/Guideline",
-      "androidx/car/ui/constraintlayout/solver/widgets/Helper": "androidx/constraintlayout/solver/widgets/Helper",
-      "androidx/car/ui/constraintlayout/solver/widgets/Optimizer": "androidx/constraintlayout/solver/widgets/Optimizer",
-      "androidx/car/ui/constraintlayout/solver/widgets/Rectangle": "androidx/constraintlayout/solver/widgets/Rectangle",
-      "androidx/car/ui/constraintlayout/solver/widgets/ResolutionAnchor": "androidx/constraintlayout/solver/widgets/ResolutionAnchor",
-      "androidx/car/ui/constraintlayout/solver/widgets/ResolutionDimension": "androidx/constraintlayout/solver/widgets/ResolutionDimension",
-      "androidx/car/ui/constraintlayout/solver/widgets/ResolutionNode": "androidx/constraintlayout/solver/widgets/ResolutionNode",
-      "androidx/car/ui/constraintlayout/solver/widgets/Snapshot": "androidx/constraintlayout/solver/widgets/Snapshot",
-      "androidx/car/ui/constraintlayout/solver/widgets/WidgetContainer": "androidx/constraintlayout/solver/widgets/WidgetContainer",
-      "androidx/car/ui/constraintlayout/helper/widget/Flow": "androidx/constraintlayout/helper/widget/Flow",
-      "androidx/car/ui/constraintlayout/helper/widget/Layer": "androidx/constraintlayout/helper/widget/Layer",
-      "androidx/car/ui/constraintlayout/motion/utils/ArcCurveFit": "androidx/constraintlayout/motion/utils/ArcCurveFit",
-      "androidx/car/ui/constraintlayout/motion/utils/CurveFit": "androidx/constraintlayout/motion/utils/CurveFit",
-      "androidx/car/ui/constraintlayout/motion/utils/Easing": "androidx/constraintlayout/motion/utils/Easing",
-      "androidx/car/ui/constraintlayout/motion/utils/HyperSpline": "androidx/constraintlayout/motion/utils/HyperSpline",
-      "androidx/car/ui/constraintlayout/motion/utils/LinearCurveFit": "androidx/constraintlayout/motion/utils/LinearCurveFit",
-      "androidx/car/ui/constraintlayout/motion/utils/MonotonicCurveFit": "androidx/constraintlayout/motion/utils/MonotonicCurveFit",
-      "androidx/car/ui/constraintlayout/motion/utils/Oscillator": "androidx/constraintlayout/motion/utils/Oscillator",
-      "androidx/car/ui/constraintlayout/motion/utils/StopLogic": "androidx/constraintlayout/motion/utils/StopLogic",
-      "androidx/car/ui/constraintlayout/motion/utils/VelocityMatrix": "androidx/constraintlayout/motion/utils/VelocityMatrix",
-      "androidx/car/ui/constraintlayout/motion/widget/Animatable": "androidx/constraintlayout/motion/widget/Animatable",
-      "androidx/car/ui/constraintlayout/motion/widget/CustomFloatAttributes": "androidx/constraintlayout/motion/widget/CustomFloatAttributes",
-      "androidx/car/ui/constraintlayout/motion/widget/Debug": "androidx/constraintlayout/motion/widget/Debug",
-      "androidx/car/ui/constraintlayout/motion/widget/DesignTool": "androidx/constraintlayout/motion/widget/DesignTool",
-      "androidx/car/ui/constraintlayout/motion/widget/Key": "androidx/constraintlayout/motion/widget/Key",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyAttributes": "androidx/constraintlayout/motion/widget/KeyAttributes",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyCache": "androidx/constraintlayout/motion/widget/KeyCache",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyCycle": "androidx/constraintlayout/motion/widget/KeyCycle",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyCycleOscillator": "androidx/constraintlayout/motion/widget/KeyCycleOscillator",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyFrames": "androidx/constraintlayout/motion/widget/KeyFrames",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyPosition": "androidx/constraintlayout/motion/widget/KeyPosition",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyPositionBase": "androidx/constraintlayout/motion/widget/KeyPositionBase",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyTimeCycle": "androidx/constraintlayout/motion/widget/KeyTimeCycle",
-      "androidx/car/ui/constraintlayout/motion/widget/KeyTrigger": "androidx/constraintlayout/motion/widget/KeyTrigger",
-      "androidx/car/ui/constraintlayout/motion/widget/MotionConstrainedPoint": "androidx/constraintlayout/motion/widget/MotionConstrainedPoint",
-      "androidx/car/ui/constraintlayout/motion/widget/MotionController": "androidx/constraintlayout/motion/widget/MotionController",
-      "androidx/car/ui/constraintlayout/motion/widget/MotionHelper": "androidx/constraintlayout/motion/widget/MotionHelper",
-      "androidx/car/ui/constraintlayout/motion/widget/MotionInterpolator": "androidx/constraintlayout/motion/widget/MotionInterpolator",
-      "androidx/car/ui/constraintlayout/motion/widget/MotionPaths": "androidx/constraintlayout/motion/widget/MotionPaths",
-      "androidx/car/ui/constraintlayout/motion/widget/MotionScene": "androidx/constraintlayout/motion/widget/MotionScene",
-      "androidx/car/ui/constraintlayout/motion/widget/ProxyInterface": "androidx/constraintlayout/motion/widget/ProxyInterface",
-      "androidx/car/ui/constraintlayout/motion/widget/SplineSet": "androidx/constraintlayout/motion/widget/SplineSet",
-      "androidx/car/ui/constraintlayout/motion/widget/TimeCycleSplineSet": "androidx/constraintlayout/motion/widget/TimeCycleSplineSet",
-      "androidx/car/ui/constraintlayout/motion/widget/TouchResponse": "androidx/constraintlayout/motion/widget/TouchResponse",
-      "androidx/car/ui/constraintlayout/motion/widget/TransitionAdapter": "androidx/constraintlayout/motion/widget/TransitionAdapter",
-      "androidx/car/ui/constraintlayout/motion/widget/TransitionBuilder": "androidx/constraintlayout/motion/widget/TransitionBuilder",
-      "androidx/car/ui/constraintlayout/motion/widget/MotionLayout": "androidx/constraintlayout/motion/widget/MotionLayout",
-      "androidx/car/ui/constraintlayout/utils/widget/MockView": "androidx/constraintlayout/utils/widget/MockView",
-      "androidx/car/ui/constraintlayout/utils/widget/MotionTelltales": "androidx/constraintlayout/utils/widget/MotionTelltales",
-      "androidx/car/ui/constraintlayout/core/ArrayLinkedVariables": "androidx/constraintlayout/core/ArrayLinkedVariables",
-      "androidx/car/ui/constraintlayout/core/ArrayRow": "androidx/constraintlayout/core/ArrayRow",
-      "androidx/car/ui/constraintlayout/core/Cache": "androidx/constraintlayout/core/Cache",
-      "androidx/car/ui/constraintlayout/core/GoalRow": "androidx/constraintlayout/core/GoalRow",
-      "androidx/car/ui/constraintlayout/core/LinearSystem": "androidx/constraintlayout/core/LinearSystem",
-      "androidx/car/ui/constraintlayout/core/Metrics": "androidx/constraintlayout/core/Metrics",
-      "androidx/car/ui/constraintlayout/core/Pools": "androidx/constraintlayout/core/Pools",
-      "androidx/car/ui/constraintlayout/core/SolverVariable": "androidx/constraintlayout/core/SolverVariable",
-      "androidx/car/ui/constraintlayout/core/state/ConstraintReference": "androidx/constraintlayout/core/state/ConstraintReference",
-      "androidx/car/ui/constraintlayout/core/state/Dimension": "androidx/constraintlayout/core/state/Dimension",
-      "androidx/car/ui/constraintlayout/core/state/HelperReference": "androidx/constraintlayout/core/state/HelperReference",
-      "androidx/car/ui/constraintlayout/core/state/Reference": "androidx/constraintlayout/core/state/Reference",
-      "androidx/car/ui/constraintlayout/core/state/State": "androidx/constraintlayout/core/state/State",
-      "androidx/car/ui/constraintlayout/core/state/helpers/AlignHorizontallyReference": "androidx/constraintlayout/core/state/helpers/AlignHorizontallyReference",
-      "androidx/car/ui/constraintlayout/core/state/helpers/AlignVerticallyReference": "androidx/constraintlayout/core/state/helpers/AlignVerticallyReference",
-      "androidx/car/ui/constraintlayout/core/state/helpers/BarrierReference": "androidx/constraintlayout/core/state/helpers/BarrierReference",
-      "androidx/car/ui/constraintlayout/core/state/helpers/ChainReference": "androidx/constraintlayout/core/state/helpers/ChainReference",
-      "androidx/car/ui/constraintlayout/core/state/helpers/GuidelineReference": "androidx/constraintlayout/core/state/helpers/GuidelineReference",
-      "androidx/car/ui/constraintlayout/core/state/helpers/HorizontalChainReference": "androidx/constraintlayout/core/state/helpers/HorizontalChainReference",
-      "androidx/car/ui/constraintlayout/core/state/helpers/VerticalChainReference": "androidx/constraintlayout/core/state/helpers/VerticalChainReference",
-      "androidx/car/ui/constraintlayout/core/widget/Barrier": "androidx/constraintlayout/core/widget/Barrier",
-      "androidx/car/ui/constraintlayout/core/widget/Chain": "androidx/constraintlayout/core/widget/Chain",
-      "androidx/car/ui/constraintlayout/core/widget/ChainHead": "androidx/constraintlayout/core/widget/ChainHead",
-      "androidx/car/ui/constraintlayout/core/widget/ConstraintAnchor": "androidx/constraintlayout/core/widget/ConstraintAnchor",
-      "androidx/car/ui/constraintlayout/core/widget/ConstraintWidget": "androidx/constraintlayout/core/widget/ConstraintWidget",
-      "androidx/car/ui/constraintlayout/core/widget/ConstraintWidgetContainer": "androidx/constraintlayout/core/widget/ConstraintWidgetContainer",
-      "androidx/car/ui/constraintlayout/core/widget/Flow": "androidx/constraintlayout/core/widget/Flow",
-      "androidx/car/ui/constraintlayout/core/widget/Guideline": "androidx/constraintlayout/core/widget/Guideline",
-      "androidx/car/ui/constraintlayout/core/widget/Helper": "androidx/constraintlayout/core/widget/Helper",
-      "androidx/car/ui/constraintlayout/core/widget/HelperWidget": "androidx/constraintlayout/core/widget/HelperWidget",
-      "androidx/car/ui/constraintlayout/core/widget/Optimizer": "androidx/constraintlayout/core/widget/Optimizer",
-      "androidx/car/ui/constraintlayout/core/widget/Rectangle": "androidx/constraintlayout/core/widget/Rectangle",
-      "androidx/car/ui/constraintlayout/core/widget/VirtualLayout": "androidx/constraintlayout/core/widget/VirtualLayout",
-      "androidx/car/ui/constraintlayout/core/widget/WidgetContainer": "androidx/constraintlayout/core/widget/WidgetContainer",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/BaselineDimensionDependency": "androidx/constraintlayout/core/widget/analyzer/BaselineDimensionDependency",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/BasicMeasure": "androidx/constraintlayout/core/widget/analyzer/BasicMeasure",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/ChainRun": "androidx/constraintlayout/core/widget/analyzer/ChainRun",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/Dependency": "androidx/constraintlayout/core/widget/analyzer/Dependency",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/DependencyGraph": "androidx/constraintlayout/core/widget/analyzer/DependencyGraph",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/DependencyNode": "androidx/constraintlayout/core/widget/analyzer/DependencyNode",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/DimensionDependency": "androidx/constraintlayout/core/widget/analyzer/DimensionDependency",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/GuidelineReference": "androidx/constraintlayout/core/widget/analyzer/GuidelineReference",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/HelperReferences": "androidx/constraintlayout/core/widget/analyzer/HelperReferences",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/HorizontalWidgetRun": "androidx/constraintlayout/core/widget/analyzer/HorizontalWidgetRun",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/RunGroup": "androidx/constraintlayout/core/widget/analyzer/RunGroup",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/VerticalWidgetRun": "androidx/constraintlayout/core/widget/analyzer/VerticalWidgetRun",
-      "androidx/car/ui/constraintlayout/core/widget/analyzer/WidgetRun": "androidx/constraintlayout/core/widget/analyzer/WidgetRun",
-      "androidx/car/ui/vectordrawable/graphics/drawable/AndroidResources": "androidx/vectordrawable/graphics/drawable/AndroidResources",
-      "androidx/car/ui/vectordrawable/graphics/drawable/Animatable2Compat": "androidx/vectordrawable/graphics/drawable/Animatable2Compat",
-      "androidx/car/ui/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat": "androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat",
-      "androidx/car/ui/vectordrawable/graphics/drawable/AnimationUtilsCompat": "androidx/vectordrawable/graphics/drawable/AnimationUtilsCompat",
-      "androidx/car/ui/vectordrawable/graphics/drawable/AnimatorInflaterCompat": "androidx/vectordrawable/graphics/drawable/AnimatorInflaterCompat",
-      "androidx/car/ui/vectordrawable/graphics/drawable/ArgbEvaluator": "androidx/vectordrawable/graphics/drawable/ArgbEvaluator",
-      "androidx/car/ui/vectordrawable/graphics/drawable/PathInterpolatorCompat": "androidx/vectordrawable/graphics/drawable/PathInterpolatorCompat",
-      "androidx/car/ui/vectordrawable/graphics/drawable/VectorDrawableCommon": "androidx/vectordrawable/graphics/drawable/VectorDrawableCommon",
-      "androidx/car/ui/vectordrawable/graphics/drawable/VectorDrawableCompat": "androidx/vectordrawable/graphics/drawable/VectorDrawableCompat",
-      "androidx/car/ui/core/view/DragAndDropPermissionsCompat": "androidx/core/view/DragAndDropPermissionsCompat",
-      "androidx/car/ui/core/view/DragStartHelper": "androidx/core/view/DragStartHelper",
-      "androidx/car/ui/core/view/inputmethod/EditorInfoCompat": "androidx/core/view/inputmethod/EditorInfoCompat",
-      "androidx/car/ui/core/view/inputmethod/InputConnectionCompat": "androidx/core/view/inputmethod/InputConnectionCompat",
-      "androidx/car/ui/core/view/inputmethod/InputContentInfoCompat": "androidx/core/view/inputmethod/InputContentInfoCompat",
-      "androidx/car/ui/preference/EditTextPreferenceDialogFragment": "androidx/preference/EditTextPreferenceDialogFragment",
-      "androidx/car/ui/preference/ListPreferenceDialogFragment": "androidx/preference/ListPreferenceDialogFragment",
-      "androidx/car/ui/preference/MultiSelectListPreference": "androidx/preference/MultiSelectListPreference",
-      "androidx/car/ui/preference/MultiSelectListPreferenceDialogFragment": "androidx/preference/MultiSelectListPreferenceDialogFragment",
-      "androidx/car/ui/preference/PreferenceDialogFragment": "androidx/preference/PreferenceDialogFragment",
-      "androidx/car/ui/preference/PreferenceFragment": "androidx/preference/PreferenceFragment",
-      "androidx/car/ui/preference/SwitchPreference": "androidx/preference/SwitchPreference",
-      "androidx/car/ui/core/accessibilityservice/AccessibilityServiceInfoCompat": "androidx/core/accessibilityservice/AccessibilityServiceInfoCompat",
-      "androidx/car/ui/core/app/ActivityCompat": "androidx/core/app/ActivityCompat",
-      "androidx/car/ui/core/app/ActivityManagerCompat": "androidx/core/app/ActivityManagerCompat",
-      "androidx/car/ui/core/app/ActivityOptionsCompat": "androidx/core/app/ActivityOptionsCompat",
-      "androidx/car/ui/core/app/AlarmManagerCompat": "androidx/core/app/AlarmManagerCompat",
-      "androidx/car/ui/core/app/AppComponentFactory": "androidx/core/app/AppComponentFactory",
-      "androidx/car/ui/core/app/AppLaunchChecker": "androidx/core/app/AppLaunchChecker",
-      "androidx/car/ui/core/app/AppOpsManagerCompat": "androidx/core/app/AppOpsManagerCompat",
-      "androidx/car/ui/fragment/app/BackStackRecord": "androidx/fragment/app/BackStackRecord",
-      "androidx/car/ui/fragment/app/BackStackState": "androidx/fragment/app/BackStackState",
-      "androidx/car/ui/core/app/BundleCompat": "androidx/core/app/BundleCompat",
-      "androidx/car/ui/core/app/CoreComponentFactory": "androidx/core/app/CoreComponentFactory",
-      "androidx/car/ui/fragment/app/DialogFragment": "androidx/fragment/app/DialogFragment",
-      "androidx/car/ui/fragment/app/Fragment": "androidx/fragment/app/Fragment",
-      "androidx/car/ui/fragment/app/FragmentActivity": "androidx/fragment/app/FragmentActivity",
-      "androidx/car/ui/fragment/app/FragmentContainer": "androidx/fragment/app/FragmentContainer",
-      "androidx/car/ui/fragment/app/FragmentController": "androidx/fragment/app/FragmentController",
-      "androidx/car/ui/fragment/app/FragmentHostCallback": "androidx/fragment/app/FragmentHostCallback",
-      "androidx/car/ui/fragment/app/FragmentManager": "androidx/fragment/app/FragmentManager",
-      "androidx/car/ui/fragment/app/FragmentManagerImpl": "androidx/fragment/app/FragmentManagerImpl",
-      "androidx/car/ui/fragment/app/FragmentManagerNonConfig": "androidx/fragment/app/FragmentManagerNonConfig",
-      "androidx/car/ui/fragment/app/FragmentManagerState": "androidx/fragment/app/FragmentManagerState",
-      "androidx/car/ui/fragment/app/FragmentPagerAdapter": "androidx/fragment/app/FragmentPagerAdapter",
-      "androidx/car/ui/fragment/app/FragmentState": "androidx/fragment/app/FragmentState",
-      "androidx/car/ui/fragment/app/FragmentStatePagerAdapter": "androidx/fragment/app/FragmentStatePagerAdapter",
-      "androidx/car/ui/fragment/app/FragmentTabHost": "androidx/fragment/app/FragmentTabHost",
-      "androidx/car/ui/fragment/app/FragmentTransaction": "androidx/fragment/app/FragmentTransaction",
-      "androidx/car/ui/fragment/app/FragmentTransition": "androidx/fragment/app/FragmentTransition",
-      "androidx/car/ui/fragment/app/FragmentTransitionCompat21": "androidx/fragment/app/FragmentTransitionCompat21",
-      "androidx/car/ui/fragment/app/FragmentTransitionImpl": "androidx/fragment/app/FragmentTransitionImpl",
-      "androidx/car/ui/core/app/FrameMetricsAggregator": "androidx/core/app/FrameMetricsAggregator",
-      "androidx/car/ui/core/app/INotificationSideChannel": "androidx/core/app/INotificationSideChannel",
-      "androidx/car/ui/core/app/JobIntentService": "androidx/core/app/JobIntentService",
-      "androidx/car/ui/fragment/app/ListFragment": "androidx/fragment/app/ListFragment",
-      "androidx/car/ui/app/LoaderManager": "androidx/loader/app/LoaderManager",
-      "androidx/car/ui/app/LoaderManagerImpl": "androidx/loader/app/LoaderManagerImpl",
-      "androidx/car/ui/core/app/NavUtils": "androidx/core/app/NavUtils",
-      "androidx/car/ui/core/app/NotificationBuilderWithBuilderAccessor": "androidx/core/app/NotificationBuilderWithBuilderAccessor",
-      "androidx/car/ui/core/app/NotificationCompat": "androidx/core/app/NotificationCompat",
-      "androidx/car/ui/core/app/NotificationCompatBuilder": "androidx/core/app/NotificationCompatBuilder",
-      "androidx/car/ui/core/app/NotificationCompatExtras": "androidx/core/app/NotificationCompatExtras",
-      "androidx/car/ui/core/app/NotificationCompatJellybean": "androidx/core/app/NotificationCompatJellybean",
-      "androidx/car/ui/core/app/NotificationCompatSideChannelService": "androidx/core/app/NotificationCompatSideChannelService",
-      "androidx/car/ui/core/app/NotificationManagerCompat": "androidx/core/app/NotificationManagerCompat",
-      "androidx/car/ui/fragment/app/OneShotPreDrawListener": "androidx/fragment/app/OneShotPreDrawListener",
-      "androidx/car/ui/core/app/Person": "androidx/core/app/Person",
-      "androidx/car/ui/core/app/RemoteInput": "androidx/core/app/RemoteInput",
-      "androidx/car/ui/core/app/ServiceCompat": "androidx/core/app/ServiceCompat",
-      "androidx/car/ui/core/app/ShareCompat": "androidx/core/app/ShareCompat",
-      "androidx/car/ui/core/app/SharedElementCallback": "androidx/core/app/SharedElementCallback",
-      "androidx/car/ui/fragment/app/SuperNotCalledException": "androidx/fragment/app/SuperNotCalledException",
-      "androidx/car/ui/fragment/app/DefaultSpecialEffectsController": "androidx/fragment/app/DefaultSpecialEffectsController",
-      "androidx/car/ui/fragment/app/LogWriter": "androidx/fragment/app/LogWriter",
-      "androidx/car/ui/fragment/app/SpecialEffectsController": "androidx/fragment/app/SpecialEffectsController",
-      "androidx/car/ui/fragment/app/SpecialEffectsControllerFactory": "androidx/fragment/app/SpecialEffectsControllerFactory",
-      "androidx/car/ui/fragment/R": "androidx/fragment/R",
-      "androidx/car/ui/core/app/ComponentActivity": "androidx/core/app/ComponentActivity",
-      "androidx/car/ui/core/app/TaskStackBuilder": "androidx/core/app/TaskStackBuilder",
-      "androidx/car/ui/content/AsyncTaskLoader": "androidx/loader/content/AsyncTaskLoader",
-      "androidx/car/ui/core/content/ContentResolverCompat": "androidx/core/content/ContentResolverCompat",
-      "androidx/car/ui/core/content/ContextCompat": "androidx/core/content/ContextCompat",
-      "androidx/car/ui/content/CursorLoader": "androidx/loader/content/CursorLoader",
-      "androidx/car/ui/core/content/FileProvider": "androidx/core/content/FileProvider",
-      "androidx/car/ui/core/content/IntentCompat": "androidx/core/content/IntentCompat",
-      "androidx/car/ui/content/Loader": "androidx/loader/content/Loader",
-      "androidx/car/ui/core/content/MimeTypeFilter": "androidx/core/content/MimeTypeFilter",
-      "androidx/car/ui/content/ModernAsyncTask": "androidx/loader/content/ModernAsyncTask",
-      "androidx/car/ui/core/content/PermissionChecker": "androidx/core/content/PermissionChecker",
-      "androidx/car/ui/core/content/SharedPreferencesCompat": "androidx/core/content/SharedPreferencesCompat",
-      "androidx/car/ui/core/content/pm/ActivityInfoCompat": "androidx/core/content/pm/ActivityInfoCompat",
-      "androidx/car/ui/core/content/pm/PackageInfoCompat": "androidx/core/content/pm/PackageInfoCompat",
-      "androidx/car/ui/core/content/pm/PermissionInfoCompat": "androidx/core/content/pm/PermissionInfoCompat",
-      "androidx/car/ui/core/content/pm/ShortcutInfoCompat": "androidx/core/content/pm/ShortcutInfoCompat",
-      "androidx/car/ui/core/content/pm/ShortcutManagerCompat": "androidx/core/content/pm/ShortcutManagerCompat",
-      "androidx/car/ui/core/content/res/ColorStateListInflaterCompat": "androidx/core/content/res/ColorStateListInflaterCompat",
-      "androidx/car/ui/core/content/res/ComplexColorCompat": "androidx/core/content/res/ComplexColorCompat",
-      "androidx/car/ui/core/content/res/ConfigurationHelper": "androidx/core/content/res/ConfigurationHelper",
-      "androidx/car/ui/core/content/res/FontResourcesParserCompat": "androidx/core/content/res/FontResourcesParserCompat",
-      "androidx/car/ui/core/content/res/GradientColorInflaterCompat": "androidx/core/content/res/GradientColorInflaterCompat",
-      "androidx/car/ui/core/content/res/GrowingArrayUtils": "androidx/core/content/res/GrowingArrayUtils",
-      "androidx/car/ui/core/content/res/ResourcesCompat": "androidx/core/content/res/ResourcesCompat",
-      "androidx/car/ui/core/content/res/TypedArrayUtils": "androidx/core/content/res/TypedArrayUtils",
-      "androidx/car/ui/core/database/CursorWindowCompat": "androidx/core/database/CursorWindowCompat",
-      "androidx/car/ui/core/database/DatabaseUtilsCompat": "androidx/core/database/DatabaseUtilsCompat",
-      "androidx/car/ui/core/database/sqlite/SQLiteCursorCompat": "androidx/core/database/sqlite/SQLiteCursorCompat",
-      "androidx/car/ui/core/graphics/BitmapCompat": "androidx/core/graphics/BitmapCompat",
-      "androidx/car/ui/core/graphics/ColorUtils": "androidx/core/graphics/ColorUtils",
-      "androidx/car/ui/core/graphics/PaintCompat": "androidx/core/graphics/PaintCompat",
-      "androidx/car/ui/core/graphics/PathParser": "androidx/core/graphics/PathParser",
-      "androidx/car/ui/core/graphics/PathSegment": "androidx/core/graphics/PathSegment",
-      "androidx/car/ui/core/graphics/PathUtils": "androidx/core/graphics/PathUtils",
-      "androidx/car/ui/core/graphics/TypefaceCompat": "androidx/core/graphics/TypefaceCompat",
-      "androidx/car/ui/core/graphics/TypefaceCompatApi21Impl": "androidx/core/graphics/TypefaceCompatApi21Impl",
-      "androidx/car/ui/core/graphics/TypefaceCompatApi24Impl": "androidx/core/graphics/TypefaceCompatApi24Impl",
-      "androidx/car/ui/core/graphics/TypefaceCompatApi26Impl": "androidx/core/graphics/TypefaceCompatApi26Impl",
-      "androidx/car/ui/core/graphics/TypefaceCompatApi28Impl": "androidx/core/graphics/TypefaceCompatApi28Impl",
-      "androidx/car/ui/core/graphics/TypefaceCompatBaseImpl": "androidx/core/graphics/TypefaceCompatBaseImpl",
-      "androidx/car/ui/core/graphics/TypefaceCompatUtil": "androidx/core/graphics/TypefaceCompatUtil",
-      "androidx/car/ui/core/graphics/drawable/DrawableCompat": "androidx/core/graphics/drawable/DrawableCompat",
-      "androidx/car/ui/core/graphics/drawable/IconCompat": "androidx/core/graphics/drawable/IconCompat",
-      "androidx/car/ui/core/graphics/drawable/IconCompatParcelizer": "androidx/core/graphics/drawable/IconCompatParcelizer",
-      "androidx/car/ui/core/app/RemoteActionCompatParcelizer": "androidx/core/app/RemoteActionCompatParcelizer",
-      "androidx/car/ui/core/graphics/drawable/RoundedBitmapDrawable": "androidx/core/graphics/drawable/RoundedBitmapDrawable",
-      "androidx/car/ui/core/graphics/drawable/RoundedBitmapDrawable21": "androidx/core/graphics/drawable/RoundedBitmapDrawable21",
-      "androidx/car/ui/core/graphics/drawable/RoundedBitmapDrawableFactory": "androidx/core/graphics/drawable/RoundedBitmapDrawableFactory",
-      "androidx/car/ui/core/graphics/drawable/TintAwareDrawable": "androidx/core/graphics/drawable/TintAwareDrawable",
-      "androidx/car/ui/core/graphics/drawable/WrappedDrawable": "androidx/core/graphics/drawable/WrappedDrawable",
-      "androidx/car/ui/core/graphics/drawable/WrappedDrawableApi14": "androidx/core/graphics/drawable/WrappedDrawableApi14",
-      "androidx/car/ui/core/graphics/drawable/WrappedDrawableApi21": "androidx/core/graphics/drawable/WrappedDrawableApi21",
-      "androidx/car/ui/core/hardware/display/DisplayManagerCompat": "androidx/core/hardware/display/DisplayManagerCompat",
-      "androidx/car/ui/core/hardware/fingerprint/FingerprintManagerCompat": "androidx/core/hardware/fingerprint/FingerprintManagerCompat",
-      "androidx/car/ui/core/internal/view/SupportMenu": "androidx/core/internal/view/SupportMenu",
-      "androidx/car/ui/core/internal/view/SupportMenuItem": "androidx/core/internal/view/SupportMenuItem",
-      "androidx/car/ui/core/internal/view/SupportSubMenu": "androidx/core/internal/view/SupportSubMenu",
-      "androidx/car/ui/core/math/MathUtils": "androidx/core/math/MathUtils",
-      "androidx/car/ui/core/net/ConnectivityManagerCompat": "androidx/core/net/ConnectivityManagerCompat",
-      "androidx/car/ui/core/net/DatagramSocketWrapper": "androidx/core/net/DatagramSocketWrapper",
-      "androidx/car/ui/core/net/TrafficStatsCompat": "androidx/core/net/TrafficStatsCompat",
-      "androidx/car/ui/core/os/BuildCompat": "androidx/core/os/BuildCompat",
-      "androidx/car/ui/core/os/CancellationSignal": "androidx/core/os/CancellationSignal",
-      "androidx/car/ui/core/os/ConfigurationCompat": "androidx/core/os/ConfigurationCompat",
-      "androidx/car/ui/core/os/EnvironmentCompat": "androidx/core/os/EnvironmentCompat",
-      "androidx/car/ui/core/os/HandlerCompat": "androidx/core/os/HandlerCompat",
-      "androidx/car/ui/core/os/IResultReceiver": "androidx/core/os/IResultReceiver",
-      "androidx/car/ui/core/os/LocaleHelper": "androidx/core/os/LocaleHelper",
-      "androidx/car/ui/core/os/LocaleListCompat": "androidx/core/os/LocaleListCompat",
-      "androidx/car/ui/core/os/LocaleListHelper": "androidx/core/os/LocaleListHelper",
-      "androidx/car/ui/core/os/LocaleListInterface": "androidx/core/os/LocaleListInterface",
-      "androidx/car/ui/core/os/OperationCanceledException": "androidx/core/os/OperationCanceledException",
-      "androidx/car/ui/core/os/ParcelCompat": "androidx/core/os/ParcelCompat",
-      "androidx/car/ui/core/os/ParcelableCompat": "androidx/core/os/ParcelableCompat",
-      "androidx/car/ui/core/os/ParcelableCompatCreatorCallbacks": "androidx/core/os/ParcelableCompatCreatorCallbacks",
-      "androidx/car/ui/core/os/TraceCompat": "androidx/core/os/TraceCompat",
-      "androidx/car/ui/core/os/UserManagerCompat": "androidx/core/os/UserManagerCompat",
-      "androidx/car/ui/core/provider/FontRequest": "androidx/core/provider/FontRequest",
-      "androidx/car/ui/core/provider/FontsContractCompat": "androidx/core/provider/FontsContractCompat",
-      "androidx/car/ui/core/provider/SelfDestructiveThread": "androidx/core/provider/SelfDestructiveThread",
-      "androidx/car/ui/core/text/BidiFormatter": "androidx/core/text/BidiFormatter",
-      "androidx/car/ui/core/text/HtmlCompat": "androidx/core/text/HtmlCompat",
-      "androidx/car/ui/core/text/ICUCompat": "androidx/core/text/ICUCompat",
-      "androidx/car/ui/core/text/PrecomputedTextCompat": "androidx/core/text/PrecomputedTextCompat",
-      "androidx/car/ui/core/text/TextDirectionHeuristicCompat": "androidx/core/text/TextDirectionHeuristicCompat",
-      "androidx/car/ui/core/text/TextDirectionHeuristicsCompat": "androidx/core/text/TextDirectionHeuristicsCompat",
-      "androidx/car/ui/core/text/TextUtilsCompat": "androidx/core/text/TextUtilsCompat",
-      "androidx/car/ui/core/text/util/FindAddress": "androidx/core/text/util/FindAddress",
-      "androidx/car/ui/core/text/util/LinkifyCompat": "androidx/core/text/util/LinkifyCompat",
-      "androidx/car/ui/collection/ArrayMap": "androidx/collection/ArrayMap",
-      "androidx/car/ui/collection/ArraySet": "androidx/collection/ArraySet",
-      "androidx/car/ui/core/util/AtomicFile": "androidx/core/util/AtomicFile",
-      "androidx/car/ui/collection/CircularArray": "androidx/collection/CircularArray",
-      "androidx/car/ui/collection/CircularIntArray": "androidx/collection/CircularIntArray",
-      "androidx/car/ui/core/util/Consumer": "androidx/core/util/Consumer",
-      "androidx/car/ui/collection/ContainerHelpers": "androidx/collection/ContainerHelpers",
-      "androidx/car/ui/core/util/DebugUtils": "androidx/core/util/DebugUtils",
-      "androidx/car/ui/core/util/LogWriter": "androidx/core/util/LogWriter",
-      "androidx/car/ui/collection/LongSparseArray": "androidx/collection/LongSparseArray",
-      "androidx/car/ui/collection/LruCache": "androidx/collection/LruCache",
-      "androidx/car/ui/collection/MapCollections": "androidx/collection/MapCollections",
-      "androidx/car/ui/core/util/ObjectsCompat": "androidx/core/util/ObjectsCompat",
-      "androidx/car/ui/core/util/Pair": "androidx/core/util/Pair",
-      "androidx/car/ui/core/util/PatternsCompat": "androidx/core/util/PatternsCompat",
-      "androidx/car/ui/core/util/Pools": "androidx/core/util/Pools",
-      "androidx/car/ui/core/util/Preconditions": "androidx/core/util/Preconditions",
-      "androidx/car/ui/collection/SimpleArrayMap": "androidx/collection/SimpleArrayMap",
-      "androidx/car/ui/collection/SparseArrayCompat": "androidx/collection/SparseArrayCompat",
-      "androidx/car/ui/collection/IndexBasedArrayIterator": "androidx/collection/IndexBasedArrayIterator",
-      "androidx/car/ui/core/util/TimeUtils": "androidx/core/util/TimeUtils",
-      "androidx/car/ui/customview/view/AbsSavedState": "androidx/customview/view/AbsSavedState",
-      "androidx/car/ui/core/view/AccessibilityDelegateCompat": "androidx/core/view/AccessibilityDelegateCompat",
-      "androidx/car/ui/core/view/ActionProvider": "androidx/core/view/ActionProvider",
-      "androidx/car/ui/asynclayoutinflater/view/AsyncLayoutInflater": "androidx/asynclayoutinflater/view/AsyncLayoutInflater",
-      "androidx/car/ui/core/view/DisplayCutoutCompat": "androidx/core/view/DisplayCutoutCompat",
-      "androidx/car/ui/core/view/GestureDetectorCompat": "androidx/core/view/GestureDetectorCompat",
-      "androidx/car/ui/core/view/GravityCompat": "androidx/core/view/GravityCompat",
-      "androidx/car/ui/core/view/InputDeviceCompat": "androidx/core/view/InputDeviceCompat",
-      "androidx/car/ui/core/view/KeyEventDispatcher": "androidx/core/view/KeyEventDispatcher",
-      "androidx/car/ui/core/view/LayoutInflaterCompat": "androidx/core/view/LayoutInflaterCompat",
-      "androidx/car/ui/core/view/LayoutInflaterFactory": "androidx/core/view/LayoutInflaterFactory",
-      "androidx/car/ui/core/view/MarginLayoutParamsCompat": "androidx/core/view/MarginLayoutParamsCompat",
-      "androidx/car/ui/core/view/MenuCompat": "androidx/core/view/MenuCompat",
-      "androidx/car/ui/core/view/MenuItemCompat": "androidx/core/view/MenuItemCompat",
-      "androidx/car/ui/core/view/MotionEventCompat": "androidx/core/view/MotionEventCompat",
-      "androidx/car/ui/core/view/NestedScrollingChild": "androidx/core/view/NestedScrollingChild",
-      "androidx/car/ui/core/view/NestedScrollingChild2": "androidx/core/view/NestedScrollingChild2",
-      "androidx/car/ui/core/view/NestedScrollingChildHelper": "androidx/core/view/NestedScrollingChildHelper",
-      "androidx/car/ui/core/view/NestedScrollingParent": "androidx/core/view/NestedScrollingParent",
-      "androidx/car/ui/core/view/NestedScrollingParent2": "androidx/core/view/NestedScrollingParent2",
-      "androidx/car/ui/core/view/NestedScrollingParentHelper": "androidx/core/view/NestedScrollingParentHelper",
-      "androidx/car/ui/core/view/OnApplyWindowInsetsListener": "androidx/core/view/OnApplyWindowInsetsListener",
-      "androidx/car/ui/core/view/PointerIconCompat": "androidx/core/view/PointerIconCompat",
-      "androidx/car/ui/core/view/ScaleGestureDetectorCompat": "androidx/core/view/ScaleGestureDetectorCompat",
-      "androidx/car/ui/core/view/ScrollingView": "androidx/core/view/ScrollingView",
-      "androidx/car/ui/core/view/TintableBackgroundView": "androidx/core/view/TintableBackgroundView",
-      "androidx/car/ui/core/view/VelocityTrackerCompat": "androidx/core/view/VelocityTrackerCompat",
-      "androidx/car/ui/core/view/ViewCompat": "androidx/core/view/ViewCompat",
-      "androidx/car/ui/core/view/ViewConfigurationCompat": "androidx/core/view/ViewConfigurationCompat",
-      "androidx/car/ui/core/view/ViewGroupCompat": "androidx/core/view/ViewGroupCompat",
-      "androidx/car/ui/core/view/ViewParentCompat": "androidx/core/view/ViewParentCompat",
-      "androidx/car/ui/core/view/ViewPropertyAnimatorCompat": "androidx/core/view/ViewPropertyAnimatorCompat",
-      "androidx/car/ui/core/view/ViewPropertyAnimatorListener": "androidx/core/view/ViewPropertyAnimatorListener",
-      "androidx/car/ui/core/view/ViewPropertyAnimatorListenerAdapter": "androidx/core/view/ViewPropertyAnimatorListenerAdapter",
-      "androidx/car/ui/core/view/ViewPropertyAnimatorUpdateListener": "androidx/core/view/ViewPropertyAnimatorUpdateListener",
-      "androidx/car/ui/core/view/WindowCompat": "androidx/core/view/WindowCompat",
-      "androidx/car/ui/core/view/WindowInsetsCompat": "androidx/core/view/WindowInsetsCompat",
-      "androidx/car/ui/core/view/accessibility/AccessibilityEventCompat": "androidx/core/view/accessibility/AccessibilityEventCompat",
-      "androidx/car/ui/core/view/accessibility/AccessibilityManagerCompat": "androidx/core/view/accessibility/AccessibilityManagerCompat",
-      "androidx/car/ui/core/view/accessibility/AccessibilityNodeInfoCompat": "androidx/core/view/accessibility/AccessibilityNodeInfoCompat",
-      "androidx/car/ui/core/view/accessibility/AccessibilityNodeProviderCompat": "androidx/core/view/accessibility/AccessibilityNodeProviderCompat",
-      "androidx/car/ui/core/view/accessibility/AccessibilityRecordCompat": "androidx/core/view/accessibility/AccessibilityRecordCompat",
-      "androidx/car/ui/core/view/accessibility/AccessibilityWindowInfoCompat": "androidx/core/view/accessibility/AccessibilityWindowInfoCompat",
-      "androidx/car/ui/core/view/animation/PathInterpolatorApi14": "androidx/core/view/animation/PathInterpolatorApi14",
-      "androidx/car/ui/core/view/animation/PathInterpolatorCompat": "androidx/core/view/animation/PathInterpolatorCompat",
-      "androidx/car/ui/core/widget/AutoScrollHelper": "androidx/core/widget/AutoScrollHelper",
-      "androidx/car/ui/core/widget/AutoSizeableTextView": "androidx/core/widget/AutoSizeableTextView",
-      "androidx/car/ui/core/widget/CompoundButtonCompat": "androidx/core/widget/CompoundButtonCompat",
-      "androidx/car/ui/core/widget/ContentLoadingProgressBar": "androidx/core/widget/ContentLoadingProgressBar",
-      "androidx/car/ui/drawerlayout/widget/DrawerLayout": "androidx/drawerlayout/widget/DrawerLayout",
-      "androidx/car/ui/core/widget/EdgeEffectCompat": "androidx/core/widget/EdgeEffectCompat",
-      "androidx/car/ui/customview/widget/ExploreByTouchHelper": "androidx/customview/widget/ExploreByTouchHelper",
-      "androidx/car/ui/customview/widget/FocusStrategy": "androidx/customview/widget/FocusStrategy",
-      "androidx/car/ui/core/widget/ImageViewCompat": "androidx/core/widget/ImageViewCompat",
-      "androidx/car/ui/core/widget/ListPopupWindowCompat": "androidx/core/widget/ListPopupWindowCompat",
-      "androidx/car/ui/core/widget/ListViewAutoScrollHelper": "androidx/core/widget/ListViewAutoScrollHelper",
-      "androidx/car/ui/core/widget/ListViewCompat": "androidx/core/widget/ListViewCompat",
-      "androidx/car/ui/core/widget/NestedScrollView": "androidx/core/widget/NestedScrollView",
-      "androidx/car/ui/core/widget/PopupMenuCompat": "androidx/core/widget/PopupMenuCompat",
-      "androidx/car/ui/core/widget/PopupWindowCompat": "androidx/core/widget/PopupWindowCompat",
-      "androidx/car/ui/core/widget/ScrollerCompat": "androidx/core/widget/ScrollerCompat",
-      "androidx/car/ui/core/widget/TextViewCompat": "androidx/core/widget/TextViewCompat",
-      "androidx/car/ui/core/widget/TintableCompoundButton": "androidx/core/widget/TintableCompoundButton",
-      "androidx/car/ui/core/widget/TintableImageSourceView": "androidx/core/widget/TintableImageSourceView",
-      "androidx/car/ui/customview/widget/ViewDragHelper": "androidx/customview/widget/ViewDragHelper",
-      "androidx/car/ui/customview/widget/Openable": "androidx/customview/widget/Openable",
-      "androidx/car/ui/appcompat/app/ActionBar": "androidx/appcompat/app/ActionBar",
-      "androidx/car/ui/appcompat/app/ActionBarDrawerToggle": "androidx/appcompat/app/ActionBarDrawerToggle",
-      "androidx/car/ui/appcompat/app/ActionBarDrawerToggleHoneycomb": "androidx/appcompat/app/ActionBarDrawerToggleHoneycomb",
-      "androidx/car/ui/appcompat/app/AlertController": "androidx/appcompat/app/AlertController",
-      "androidx/car/ui/appcompat/app/AlertDialog": "androidx/appcompat/app/AlertDialog",
-      "androidx/car/ui/appcompat/app/AppCompatActivity": "androidx/appcompat/app/AppCompatActivity",
-      "androidx/car/ui/appcompat/app/AppCompatCallback": "androidx/appcompat/app/AppCompatCallback",
-      "androidx/car/ui/appcompat/app/AppCompatDelegate": "androidx/appcompat/app/AppCompatDelegate",
-      "androidx/car/ui/appcompat/app/AppCompatDelegateImpl": "androidx/appcompat/app/AppCompatDelegateImpl",
-      "androidx/car/ui/appcompat/app/AppCompatDialog": "androidx/appcompat/app/AppCompatDialog",
-      "androidx/car/ui/appcompat/app/AppCompatDialogFragment": "androidx/appcompat/app/AppCompatDialogFragment",
-      "androidx/car/ui/appcompat/app/AppCompatViewInflater": "androidx/appcompat/app/AppCompatViewInflater",
-      "androidx/car/ui/appcompat/app/NavItemSelectedListener": "androidx/appcompat/app/NavItemSelectedListener",
-      "androidx/car/ui/appcompat/app/ResourcesFlusher": "androidx/appcompat/app/ResourcesFlusher",
-      "androidx/car/ui/appcompat/app/ToolbarActionBar": "androidx/appcompat/app/ToolbarActionBar",
-      "androidx/car/ui/appcompat/app/TwilightCalculator": "androidx/appcompat/app/TwilightCalculator",
-      "androidx/car/ui/appcompat/app/TwilightManager": "androidx/appcompat/app/TwilightManager",
-      "androidx/car/ui/appcompat/app/WindowDecorActionBar": "androidx/appcompat/app/WindowDecorActionBar",
-      "androidx/car/ui/appcompat/R": "androidx/appcompat/R",
-      "androidx/car/ui/appcompat/content/res/AppCompatResources": "androidx/appcompat/content/res/AppCompatResources",
-      "androidx/car/ui/appcompat/graphics/drawable/AnimatedStateListDrawableCompat": "androidx/appcompat/graphics/drawable/AnimatedStateListDrawableCompat",
-      "androidx/car/ui/appcompat/graphics/drawable/DrawableContainer": "androidx/appcompat/graphics/drawable/DrawableContainer",
-      "androidx/car/ui/appcompat/graphics/drawable/DrawableWrapper": "androidx/appcompat/graphics/drawable/DrawableWrapper",
-      "androidx/car/ui/appcompat/graphics/drawable/DrawerArrowDrawable": "androidx/appcompat/graphics/drawable/DrawerArrowDrawable",
-      "androidx/car/ui/appcompat/graphics/drawable/StateListDrawable": "androidx/appcompat/graphics/drawable/StateListDrawable",
-      "androidx/car/ui/preference/internal/PreferenceImageView": "androidx/preference/internal/PreferenceImageView",
-      "androidx/car/ui/preference/AndroidResources": "androidx/preference/AndroidResources",
-      "androidx/car/ui/preference/CheckBoxPreference": "androidx/preference/CheckBoxPreference",
-      "androidx/car/ui/preference/CollapsiblePreferenceGroupController": "androidx/preference/CollapsiblePreferenceGroupController",
-      "androidx/car/ui/preference/DialogPreference": "androidx/preference/DialogPreference",
-      "androidx/car/ui/preference/DropDownPreference": "androidx/preference/DropDownPreference",
-      "androidx/car/ui/preference/EditTextPreference": "androidx/preference/EditTextPreference",
-      "androidx/car/ui/preference/EditTextPreferenceDialogFragmentCompat": "androidx/preference/EditTextPreferenceDialogFragmentCompat",
-      "androidx/car/ui/preference/ListPreference": "androidx/preference/ListPreference",
-      "androidx/car/ui/preference/ListPreferenceDialogFragmentCompat": "androidx/preference/ListPreferenceDialogFragmentCompat",
-      "androidx/car/ui/preference/MultiSelectListPreferenceDialogFragmentCompat": "androidx/preference/MultiSelectListPreferenceDialogFragmentCompat",
-      "androidx/car/ui/preference/Preference": "androidx/preference/Preference",
-      "androidx/car/ui/preference/PreferenceCategory": "androidx/preference/PreferenceCategory",
-      "androidx/car/ui/preference/PreferenceDataStore": "androidx/preference/PreferenceDataStore",
-      "androidx/car/ui/preference/PreferenceDialogFragmentCompat": "androidx/preference/PreferenceDialogFragmentCompat",
-      "androidx/car/ui/preference/PreferenceFragmentCompat": "androidx/preference/PreferenceFragmentCompat",
-      "androidx/car/ui/preference/PreferenceGroup": "androidx/preference/PreferenceGroup",
-      "androidx/car/ui/preference/PreferenceGroupAdapter": "androidx/preference/PreferenceGroupAdapter",
-      "androidx/car/ui/preference/PreferenceInflater": "androidx/preference/PreferenceInflater",
-      "androidx/car/ui/preference/PreferenceManager": "androidx/preference/PreferenceManager",
-      "androidx/car/ui/preference/PreferenceRecyclerViewAccessibilityDelegate": "androidx/preference/PreferenceRecyclerViewAccessibilityDelegate",
-      "androidx/car/ui/preference/PreferenceScreen": "androidx/preference/PreferenceScreen",
-      "androidx/car/ui/preference/PreferenceViewHolder": "androidx/preference/PreferenceViewHolder",
-      "androidx/car/ui/preference/R": "androidx/preference/R",
-      "androidx/car/ui/preference/SeekBarPreference": "androidx/preference/SeekBarPreference",
-      "androidx/car/ui/preference/SwitchPreferenceCompat": "androidx/preference/SwitchPreferenceCompat",
-      "androidx/car/ui/preference/TwoStatePreference": "androidx/preference/TwoStatePreference",
-      "androidx/car/ui/preference/UnPressableLinearLayout": "androidx/preference/UnPressableLinearLayout",
-      "androidx/car/ui/preference/internal/AbstractMultiSelectListPreference": "androidx/preference/internal/AbstractMultiSelectListPreference",
-      "androidx/car/ui/preference/ExpandButton": "androidx/preference/ExpandButton",
-      "androidx/car/ui/recyclerview/R": "androidx/recyclerview/R",
-      "androidx/car/ui/recyclerview/widget/AsyncDifferConfig": "androidx/recyclerview/widget/AsyncDifferConfig",
-      "androidx/car/ui/recyclerview/widget/AsyncListDiffer": "androidx/recyclerview/widget/AsyncListDiffer",
-      "androidx/car/ui/recyclerview/widget/ListAdapter": "androidx/recyclerview/widget/ListAdapter",
-      "androidx/car/ui/appcompat/text/AllCapsTransformationMethod": "androidx/appcompat/text/AllCapsTransformationMethod",
-      "androidx/car/ui/recyclerview/widget/AdapterListUpdateCallback": "androidx/recyclerview/widget/AdapterListUpdateCallback",
-      "androidx/car/ui/recyclerview/widget/AsyncListUtil": "androidx/recyclerview/widget/AsyncListUtil",
-      "androidx/car/ui/recyclerview/widget/BatchingListUpdateCallback": "androidx/recyclerview/widget/BatchingListUpdateCallback",
-      "androidx/car/ui/recyclerview/widget/DiffUtil": "androidx/recyclerview/widget/DiffUtil",
-      "androidx/car/ui/recyclerview/widget/ListUpdateCallback": "androidx/recyclerview/widget/ListUpdateCallback",
-      "androidx/car/ui/recyclerview/widget/MessageThreadUtil": "androidx/recyclerview/widget/MessageThreadUtil",
-      "androidx/car/ui/recyclerview/widget/SortedList": "androidx/recyclerview/widget/SortedList",
-      "androidx/car/ui/recyclerview/widget/ThreadUtil": "androidx/recyclerview/widget/ThreadUtil",
-      "androidx/car/ui/recyclerview/widget/TileList": "androidx/recyclerview/widget/TileList",
-      "androidx/car/ui/appcompat/view/ActionBarPolicy": "androidx/appcompat/view/ActionBarPolicy",
-      "androidx/car/ui/appcompat/view/ActionMode": "androidx/appcompat/view/ActionMode",
-      "androidx/car/ui/appcompat/view/CollapsibleActionView": "androidx/appcompat/view/CollapsibleActionView",
-      "androidx/car/ui/appcompat/view/ContextThemeWrapper": "androidx/appcompat/view/ContextThemeWrapper",
-      "androidx/car/ui/appcompat/view/StandaloneActionMode": "androidx/appcompat/view/StandaloneActionMode",
-      "androidx/car/ui/appcompat/view/SupportActionModeWrapper": "androidx/appcompat/view/SupportActionModeWrapper",
-      "androidx/car/ui/appcompat/view/SupportMenuInflater": "androidx/appcompat/view/SupportMenuInflater",
-      "androidx/car/ui/appcompat/view/ViewPropertyAnimatorCompatSet": "androidx/appcompat/view/ViewPropertyAnimatorCompatSet",
-      "androidx/car/ui/appcompat/view/WindowCallbackWrapper": "androidx/appcompat/view/WindowCallbackWrapper",
-      "androidx/car/ui/appcompat/view/menu/ActionMenuItem": "androidx/appcompat/view/menu/ActionMenuItem",
-      "androidx/car/ui/appcompat/view/menu/ActionMenuItemView": "androidx/appcompat/view/menu/ActionMenuItemView",
-      "androidx/car/ui/appcompat/view/menu/BaseMenuPresenter": "androidx/appcompat/view/menu/BaseMenuPresenter",
-      "androidx/car/ui/appcompat/view/menu/BaseMenuWrapper": "androidx/appcompat/view/menu/BaseMenuWrapper",
-      "androidx/car/ui/appcompat/view/menu/BaseWrapper": "androidx/appcompat/view/menu/BaseWrapper",
-      "androidx/car/ui/appcompat/view/menu/CascadingMenuPopup": "androidx/appcompat/view/menu/CascadingMenuPopup",
-      "androidx/car/ui/appcompat/view/menu/ExpandedMenuView": "androidx/appcompat/view/menu/ExpandedMenuView",
-      "androidx/car/ui/appcompat/view/menu/ListMenuItemView": "androidx/appcompat/view/menu/ListMenuItemView",
-      "androidx/car/ui/appcompat/view/menu/ListMenuPresenter": "androidx/appcompat/view/menu/ListMenuPresenter",
-      "androidx/car/ui/appcompat/view/menu/MenuAdapter": "androidx/appcompat/view/menu/MenuAdapter",
-      "androidx/car/ui/appcompat/view/menu/MenuBuilder": "androidx/appcompat/view/menu/MenuBuilder",
-      "androidx/car/ui/appcompat/view/menu/MenuDialogHelper": "androidx/appcompat/view/menu/MenuDialogHelper",
-      "androidx/car/ui/appcompat/view/menu/MenuHelper": "androidx/appcompat/view/menu/MenuHelper",
-      "androidx/car/ui/appcompat/view/menu/MenuItemImpl": "androidx/appcompat/view/menu/MenuItemImpl",
-      "androidx/car/ui/appcompat/view/menu/MenuItemWrapperICS": "androidx/appcompat/view/menu/MenuItemWrapperICS",
-      "androidx/car/ui/appcompat/view/menu/MenuItemWrapperJB": "androidx/appcompat/view/menu/MenuItemWrapperJB",
-      "androidx/car/ui/appcompat/view/menu/MenuPopup": "androidx/appcompat/view/menu/MenuPopup",
-      "androidx/car/ui/appcompat/view/menu/MenuPopupHelper": "androidx/appcompat/view/menu/MenuPopupHelper",
-      "androidx/car/ui/appcompat/view/menu/MenuPresenter": "androidx/appcompat/view/menu/MenuPresenter",
-      "androidx/car/ui/appcompat/view/menu/MenuView": "androidx/appcompat/view/menu/MenuView",
-      "androidx/car/ui/appcompat/view/menu/MenuWrapperFactory": "androidx/appcompat/view/menu/MenuWrapperFactory",
-      "androidx/car/ui/appcompat/view/menu/MenuWrapperICS": "androidx/appcompat/view/menu/MenuWrapperICS",
-      "androidx/car/ui/appcompat/view/menu/ShowableListMenu": "androidx/appcompat/view/menu/ShowableListMenu",
-      "androidx/car/ui/appcompat/view/menu/StandardMenuPopup": "androidx/appcompat/view/menu/StandardMenuPopup",
-      "androidx/car/ui/appcompat/view/menu/SubMenuBuilder": "androidx/appcompat/view/menu/SubMenuBuilder",
-      "androidx/car/ui/appcompat/view/menu/SubMenuWrapperICS": "androidx/appcompat/view/menu/SubMenuWrapperICS",
-      "androidx/car/ui/appcompat/widget/AbsActionBarView": "androidx/appcompat/widget/AbsActionBarView",
-      "androidx/car/ui/appcompat/widget/ActionBarBackgroundDrawable": "androidx/appcompat/widget/ActionBarBackgroundDrawable",
-      "androidx/car/ui/appcompat/widget/ActionBarContainer": "androidx/appcompat/widget/ActionBarContainer",
-      "androidx/car/ui/appcompat/widget/ActionBarContextView": "androidx/appcompat/widget/ActionBarContextView",
-      "androidx/car/ui/appcompat/widget/ActionBarOverlayLayout": "androidx/appcompat/widget/ActionBarOverlayLayout",
-      "androidx/car/ui/appcompat/widget/ActionMenuPresenter": "androidx/appcompat/widget/ActionMenuPresenter",
-      "androidx/car/ui/appcompat/widget/ActionMenuView": "androidx/appcompat/widget/ActionMenuView",
-      "androidx/car/ui/appcompat/widget/ActivityChooserModel": "androidx/appcompat/widget/ActivityChooserModel",
-      "androidx/car/ui/appcompat/widget/ActivityChooserView": "androidx/appcompat/widget/ActivityChooserView",
-      "androidx/car/ui/recyclerview/widget/AdapterHelper": "androidx/recyclerview/widget/AdapterHelper",
-      "androidx/car/ui/appcompat/widget/AlertDialogLayout": "androidx/appcompat/widget/AlertDialogLayout",
-      "androidx/car/ui/appcompat/widget/AppCompatAutoCompleteTextView": "androidx/appcompat/widget/AppCompatAutoCompleteTextView",
-      "androidx/car/ui/appcompat/widget/AppCompatBackgroundHelper": "androidx/appcompat/widget/AppCompatBackgroundHelper",
-      "androidx/car/ui/appcompat/widget/AppCompatButton": "androidx/appcompat/widget/AppCompatButton",
-      "androidx/car/ui/appcompat/widget/AppCompatCheckBox": "androidx/appcompat/widget/AppCompatCheckBox",
-      "androidx/car/ui/appcompat/widget/AppCompatCheckedTextView": "androidx/appcompat/widget/AppCompatCheckedTextView",
-      "androidx/car/ui/appcompat/widget/AppCompatCompoundButtonHelper": "androidx/appcompat/widget/AppCompatCompoundButtonHelper",
-      "androidx/car/ui/appcompat/widget/AppCompatDrawableManager": "androidx/appcompat/widget/AppCompatDrawableManager",
-      "androidx/car/ui/appcompat/widget/AppCompatEditText": "androidx/appcompat/widget/AppCompatEditText",
-      "androidx/car/ui/appcompat/widget/AppCompatHintHelper": "androidx/appcompat/widget/AppCompatHintHelper",
-      "androidx/car/ui/appcompat/widget/AppCompatImageButton": "androidx/appcompat/widget/AppCompatImageButton",
-      "androidx/car/ui/appcompat/widget/AppCompatImageHelper": "androidx/appcompat/widget/AppCompatImageHelper",
-      "androidx/car/ui/appcompat/widget/AppCompatImageView": "androidx/appcompat/widget/AppCompatImageView",
-      "androidx/car/ui/appcompat/widget/AppCompatMultiAutoCompleteTextView": "androidx/appcompat/widget/AppCompatMultiAutoCompleteTextView",
-      "androidx/car/ui/appcompat/widget/AppCompatPopupWindow": "androidx/appcompat/widget/AppCompatPopupWindow",
-      "androidx/car/ui/appcompat/widget/AppCompatProgressBarHelper": "androidx/appcompat/widget/AppCompatProgressBarHelper",
-      "androidx/car/ui/appcompat/widget/AppCompatRadioButton": "androidx/appcompat/widget/AppCompatRadioButton",
-      "androidx/car/ui/appcompat/widget/AppCompatRatingBar": "androidx/appcompat/widget/AppCompatRatingBar",
-      "androidx/car/ui/appcompat/widget/AppCompatSeekBar": "androidx/appcompat/widget/AppCompatSeekBar",
-      "androidx/car/ui/appcompat/widget/AppCompatSeekBarHelper": "androidx/appcompat/widget/AppCompatSeekBarHelper",
-      "androidx/car/ui/appcompat/widget/AppCompatSpinner": "androidx/appcompat/widget/AppCompatSpinner",
-      "androidx/car/ui/appcompat/widget/AppCompatTextHelper": "androidx/appcompat/widget/AppCompatTextHelper",
-      "androidx/car/ui/appcompat/widget/AppCompatTextView": "androidx/appcompat/widget/AppCompatTextView",
-      "androidx/car/ui/appcompat/widget/AppCompatTextViewAutoSizeHelper": "androidx/appcompat/widget/AppCompatTextViewAutoSizeHelper",
-      "androidx/car/ui/appcompat/widget/ButtonBarLayout": "androidx/appcompat/widget/ButtonBarLayout",
-      "androidx/car/ui/recyclerview/widget/ChildHelper": "androidx/recyclerview/widget/ChildHelper",
-      "androidx/car/ui/appcompat/widget/ContentFrameLayout": "androidx/appcompat/widget/ContentFrameLayout",
-      "androidx/car/ui/appcompat/widget/DecorContentParent": "androidx/appcompat/widget/DecorContentParent",
-      "androidx/car/ui/appcompat/widget/DecorToolbar": "androidx/appcompat/widget/DecorToolbar",
-      "androidx/car/ui/recyclerview/widget/DefaultItemAnimator": "androidx/recyclerview/widget/DefaultItemAnimator",
-      "androidx/car/ui/appcompat/widget/DialogTitle": "androidx/appcompat/widget/DialogTitle",
-      "androidx/car/ui/recyclerview/widget/DividerItemDecoration": "androidx/recyclerview/widget/DividerItemDecoration",
-      "androidx/car/ui/appcompat/widget/DrawableUtils": "androidx/appcompat/widget/DrawableUtils",
-      "androidx/car/ui/appcompat/widget/DropDownListView": "androidx/appcompat/widget/DropDownListView",
-      "androidx/car/ui/recyclerview/widget/FastScroller": "androidx/recyclerview/widget/FastScroller",
-      "androidx/car/ui/appcompat/widget/FitWindowsFrameLayout": "androidx/appcompat/widget/FitWindowsFrameLayout",
-      "androidx/car/ui/appcompat/widget/FitWindowsLinearLayout": "androidx/appcompat/widget/FitWindowsLinearLayout",
-      "androidx/car/ui/appcompat/widget/FitWindowsViewGroup": "androidx/appcompat/widget/FitWindowsViewGroup",
-      "androidx/car/ui/appcompat/widget/ForwardingListener": "androidx/appcompat/widget/ForwardingListener",
-      "androidx/car/ui/recyclerview/widget/GapWorker": "androidx/recyclerview/widget/GapWorker",
-      "androidx/car/ui/recyclerview/widget/GridLayoutManager": "androidx/recyclerview/widget/GridLayoutManager",
-      "androidx/car/ui/recyclerview/widget/LayoutState": "androidx/recyclerview/widget/LayoutState",
-      "androidx/car/ui/appcompat/widget/LinearLayoutCompat": "androidx/appcompat/widget/LinearLayoutCompat",
-      "androidx/car/ui/recyclerview/widget/LinearLayoutManager": "androidx/recyclerview/widget/LinearLayoutManager",
-      "androidx/car/ui/recyclerview/widget/LinearSmoothScroller": "androidx/recyclerview/widget/LinearSmoothScroller",
-      "androidx/car/ui/recyclerview/widget/LinearSnapHelper": "androidx/recyclerview/widget/LinearSnapHelper",
-      "androidx/car/ui/appcompat/widget/ListPopupWindow": "androidx/appcompat/widget/ListPopupWindow",
-      "androidx/car/ui/appcompat/widget/MenuItemHoverListener": "androidx/appcompat/widget/MenuItemHoverListener",
-      "androidx/car/ui/appcompat/widget/MenuPopupWindow": "androidx/appcompat/widget/MenuPopupWindow",
-      "androidx/car/ui/recyclerview/widget/OpReorderer": "androidx/recyclerview/widget/OpReorderer",
-      "androidx/car/ui/recyclerview/widget/OrientationHelper": "androidx/recyclerview/widget/OrientationHelper",
-      "androidx/car/ui/recyclerview/widget/PagerSnapHelper": "androidx/recyclerview/widget/PagerSnapHelper",
-      "androidx/car/ui/appcompat/widget/PopupMenu": "androidx/appcompat/widget/PopupMenu",
-      "androidx/car/ui/recyclerview/widget/RecyclerView": "androidx/recyclerview/widget/RecyclerView",
-      "androidx/car/ui/recyclerview/widget/RecyclerViewAccessibilityDelegate": "androidx/recyclerview/widget/RecyclerViewAccessibilityDelegate",
-      "androidx/car/ui/appcompat/widget/ResourcesWrapper": "androidx/appcompat/widget/ResourcesWrapper",
-      "androidx/car/ui/appcompat/widget/RtlSpacingHelper": "androidx/appcompat/widget/RtlSpacingHelper",
-      "androidx/car/ui/recyclerview/widget/ScrollbarHelper": "androidx/recyclerview/widget/ScrollbarHelper",
-      "androidx/car/ui/appcompat/widget/ScrollingTabContainerView": "androidx/appcompat/widget/ScrollingTabContainerView",
-      "androidx/car/ui/appcompat/widget/SearchView": "androidx/appcompat/widget/SearchView",
-      "androidx/car/ui/appcompat/widget/ShareActionProvider": "androidx/appcompat/widget/ShareActionProvider",
-      "androidx/car/ui/recyclerview/widget/SimpleItemAnimator": "androidx/recyclerview/widget/SimpleItemAnimator",
-      "androidx/car/ui/recyclerview/widget/SnapHelper": "androidx/recyclerview/widget/SnapHelper",
-      "androidx/car/ui/recyclerview/widget/StaggeredGridLayoutManager": "androidx/recyclerview/widget/StaggeredGridLayoutManager",
-      "androidx/car/ui/appcompat/widget/SuggestionsAdapter": "androidx/appcompat/widget/SuggestionsAdapter",
-      "androidx/car/ui/appcompat/widget/SwitchCompat": "androidx/appcompat/widget/SwitchCompat",
-      "androidx/car/ui/appcompat/widget/ThemeUtils": "androidx/appcompat/widget/ThemeUtils",
-      "androidx/car/ui/appcompat/widget/ThemedSpinnerAdapter": "androidx/appcompat/widget/ThemedSpinnerAdapter",
-      "androidx/car/ui/appcompat/widget/TintContextWrapper": "androidx/appcompat/widget/TintContextWrapper",
-      "androidx/car/ui/appcompat/widget/TintInfo": "androidx/appcompat/widget/TintInfo",
-      "androidx/car/ui/appcompat/widget/TintResources": "androidx/appcompat/widget/TintResources",
-      "androidx/car/ui/appcompat/widget/TintTypedArray": "androidx/appcompat/widget/TintTypedArray",
-      "androidx/car/ui/appcompat/widget/Toolbar": "androidx/appcompat/widget/Toolbar",
-      "androidx/car/ui/appcompat/widget/ToolbarWidgetWrapper": "androidx/appcompat/widget/ToolbarWidgetWrapper",
-      "androidx/car/ui/appcompat/widget/TooltipCompat": "androidx/appcompat/widget/TooltipCompat",
-      "androidx/car/ui/appcompat/widget/TooltipCompatHandler": "androidx/appcompat/widget/TooltipCompatHandler",
-      "androidx/car/ui/appcompat/widget/TooltipPopup": "androidx/appcompat/widget/TooltipPopup",
-      "androidx/car/ui/appcompat/widget/VectorEnabledTintResources": "androidx/appcompat/widget/VectorEnabledTintResources",
-      "androidx/car/ui/recyclerview/widget/ViewBoundsCheck": "androidx/recyclerview/widget/ViewBoundsCheck",
-      "androidx/car/ui/recyclerview/widget/ViewInfoStore": "androidx/recyclerview/widget/ViewInfoStore",
-      "androidx/car/ui/appcompat/widget/ViewStubCompat": "androidx/appcompat/widget/ViewStubCompat",
-      "androidx/car/ui/appcompat/widget/ViewUtils": "androidx/appcompat/widget/ViewUtils",
-      "androidx/car/ui/appcompat/widget/WithHint": "androidx/appcompat/widget/WithHint",
-      "androidx/car/ui/recyclerview/widget/ItemTouchHelper": "androidx/recyclerview/widget/ItemTouchHelper",
-      "androidx/car/ui/recyclerview/widget/ItemTouchUIUtil": "androidx/recyclerview/widget/ItemTouchUIUtil",
-      "androidx/car/ui/recyclerview/widget/ItemTouchUIUtilImpl": "androidx/recyclerview/widget/ItemTouchUIUtilImpl",
-      "androidx/car/ui/recyclerview/widget/SortedListAdapterCallback": "androidx/recyclerview/widget/SortedListAdapterCallback",
-      "androidx/car/ui/activity/Cancellable": "androidx/activity/Cancellable",
-      "androidx/car/ui/activity/ComponentActivity": "androidx/activity/ComponentActivity",
-      "androidx/car/ui/activity/ImmLeaksCleaner": "androidx/activity/ImmLeaksCleaner",
-      "androidx/car/ui/activity/OnBackPressedCallback": "androidx/activity/OnBackPressedCallback",
-      "androidx/car/ui/activity/OnBackPressedDispatcher": "androidx/activity/OnBackPressedDispatcher",
-      "androidx/car/ui/activity/OnBackPressedDispatcherOwner": "androidx/activity/OnBackPressedDispatcherOwner",
-      "androidx/car/ui/activity/result/ActivityResultCallback": "androidx/activity/result/ActivityResultCallback",
-      "androidx/car/ui/activity/result/ActivityResultCaller": "androidx/activity/result/ActivityResultCaller",
-      "androidx/car/ui/activity/result/ActivityResultLauncher": "androidx/activity/result/ActivityResultLauncher",
-      "androidx/car/ui/activity/result/ActivityResultRegistry": "androidx/activity/result/ActivityResultRegistry",
-      "androidx/car/ui/activity/result/ActivityResultRegistryOwner": "androidx/activity/result/ActivityResultRegistryOwner",
-      "androidx/car/ui/activity/result/contract/ActivityResultContract": "androidx/activity/result/contract/ActivityResultContract",
-      "androidx/car/ui/savedstate/Recreator": "androidx/savedstate/Recreator",
-      "androidx/car/ui/savedstate/SavedStateRegistry": "androidx/savedstate/SavedStateRegistry",
-      "androidx/car/ui/savedstate/SavedStateRegistryController": "androidx/savedstate/SavedStateRegistryController",
-      "androidx/car/ui/savedstate/SavedStateRegistryOwner": "androidx/savedstate/SavedStateRegistryOwner",
-      "androidx/car/ui/savedstate/ViewTreeSavedStateRegistryOwner": "androidx/savedstate/ViewTreeSavedStateRegistryOwner"
-    }
-  },
-  "proGuardMap": {
-    "rules": {
-      "androidx/{any}Parcelizer": [
-        "androidx/{any}Parcelizer"
-      ],
-      "android/support/{any}": [
-        "android/support/{any}",
-        "androidx/{any}"
-      ],
-      "android/support{any}": [
-        "android/support{any}",
-        "androidx{any}"
-      ],
-      "android/support/v*/{any}": [
-        "android/support/**",
-        "androidx/{any}"
-      ],
-      "android/support/v4/{any}": [
-        "android/support/v4/{any}",
-        "androidx/{any}"
-      ],
-      "android/support/v4/view/{any}": [
-        "androidx/customview/view/{any}",
-        "androidx/core/view/{any}",
-        "androidx/asynclayoutinflater/{any}",
-        "androidx/viewpager/{any}",
-        "androidx/interpolator/{any}"
-      ],
-      "android/support/v4/media/{any}": [
-        "androidx/media/{any}",
-        "android/support/v4/{any}"
-      ],
-      "android/support/v7/{any}": [
-        "androidx/appcompat/{any}",
-        "androidx/mediarouter/{any}",
-        "androidx/cardview/{any}",
-        "androidx/palette/{any}",
-        "androidx/gridlayout/{any}",
-        "androidx/preference/{any}"
-      ],
-      "android/support/v7/widget/{any}": [
-        "androidx/appcompat/widget/{any}",
-        "androidx/recyclerview/widget/{any}",
-        "androidx/cardview/widget/{any}"
-      ],
-      "android/support/v7/preference/{any}": [
-        "androidx/preference/{any}"
-      ],
-      "android/support/v14/preference/{any}": [
-        "androidx/preference/{any}"
-      ],
-      "android/support/v17/preference/{any}": [
-        "androidx/leanback/preference/{any}"
-      ],
-      "android/support/v17/leanback/{any}": [
-        "androidx/leanback/{any}"
-      ],
-      "android/support/design/widget/{any}": [
-        "androidx/coordinatorlayout/widget/{any}",
-        "com/google/android/material/**"
-      ],
-      "android/support/design/{any}": [
-        "androidx/coordinatorlayout/**",
-        "com/google/android/material/**"
-      ],
-      "android/support/design/internal/{any}": [
-        "com/google/android/material/{any}"
-      ],
-      "android/support/car/{any}": [
-        "androidx/car/{any}"
-      ],
-      "android/arch/persistence/room/paging/{any}": [
-        "androidx/room/paging/{any}"
-      ],
-      "android/support/v7/internal/widget/ActionBarView${any}": [
-        "androidx/appcompat/widget/AbsActionBarView${any}"
-      ],
-      "android/support/v4/view/MenuItemCompat/*": [
-        "androidx/core/view/MenuItemCompat/*"
-      ],
-      "Android{any}": [
-        "Android{any}"
-      ]
-    }
-  },
-  "stringsMap": {
-    "types": {
-      "android/support/v13/view/inputmethod/EditorInfoCompat/CONTENT_MIME_TYPES": "android/support/v13/view/inputmethod/EditorInfoCompat/CONTENT_MIME_TYPES",
-      "android/support/v13/view/inputmethod/InputConnectionCompat/COMMIT_CONTENT": "android/support/v13/view/inputmethod/InputConnectionCompat/COMMIT_CONTENT",
-      "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_DESCRIPTION": "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_DESCRIPTION",
-      "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_FLAGS": "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_FLAGS",
-      "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_LINK_URI": "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_LINK_URI",
-      "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_OPTS": "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_OPTS",
-      "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_RESULT_RECEIVER": "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_RESULT_RECEIVER",
-      "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_URI": "android/support/v13/view/inputmethod/InputConnectionCompat/CONTENT_URI",
-      "android/support/v4/app/EXTRA_CALLING_ACTIVITY": "android/support/v4/app/EXTRA_CALLING_ACTIVITY",
-      "android/support/v4/app/EXTRA_CALLING_PACKAGE": "android/support/v4/app/EXTRA_CALLING_PACKAGE",
-      "androidx/contentpager/content/wakelockid": "androidx/contentpager/content/wakelockid",
-      "androidx/core/app/EXTRA_CALLING_ACTIVITY": "androidx/core/app/EXTRA_CALLING_ACTIVITY",
-      "androidx/core/app/EXTRA_CALLING_PACKAGE": "androidx/core/app/EXTRA_CALLING_PACKAGE",
-      "androidx/core/view/inputmethod/EditorInfoCompat/CONTENT_MIME_TYPES": "androidx/core/view/inputmethod/EditorInfoCompat/CONTENT_MIME_TYPES",
-      "androidx/support/content/wakelockid": "androidx/support/content/wakelockid"
-    }
-  }
-}
diff --git a/car-ui-lib/car-ui-lib/build.gradle b/car-ui-lib/car-ui-lib/build.gradle
deleted file mode 100644
index 478a739..0000000
--- a/car-ui-lib/car-ui-lib/build.gradle
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Library-level build file
-
-apply plugin: 'com.android.library'
-apply plugin: 'jacoco'
-
-android {
-    compileSdkVersion 30
-
-    defaultConfig {
-        minSdkVersion 28
-        targetSdkVersion 30
-        versionCode 1
-        versionName "1.0"
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
-    }
-
-    sourceSets {
-        main {
-            res.srcDirs = [
-                    'src/main/res',
-                    'src/main/res-private'
-            ]
-        }
-    }
-
-    testOptions {
-        unitTests {
-            includeAndroidResources = true
-        }
-        animationsDisabled = true
-    }
-
-    buildTypes {
-        debug {
-            testCoverageEnabled = true
-        }
-    }
-
-    project.gradle.taskGraph.whenReady {
-        connectedDebugAndroidTest {
-            ignoreFailures = true
-        }
-    }
-
-    // This is the gradle equivalent of the libs: ["android.car"] in the Android.bp
-    useLibrary 'android.car'
-
-    useLibrary 'android.test.runner'
-    useLibrary 'android.test.base'
-    useLibrary 'android.test.mock'
-}
-
-dependencies {
-    compileOnly project(':oem-apis')
-    api project(':car-rotary-lib')
-    api 'androidx.annotation:annotation:1.2.0'
-    api 'androidx.appcompat:appcompat:1.2.0'
-    api 'androidx.constraintlayout:constraintlayout:2.0.4'
-    api 'androidx.preference:preference:1.1.1'
-    api 'androidx.recyclerview:recyclerview:1.2.0'
-    api 'androidx.core:core:1.3.2'
-    api "androidx.asynclayoutinflater:asynclayoutinflater:1.0.0"
-    implementation 'com.android.support:support-annotations:28.0.0'
-
-    androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
-    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.3.0'
-    androidTestImplementation "com.google.truth:truth:1.1.2"
-    androidTestImplementation "androidx.test.ext:junit:1.1.2"
-    androidTestImplementation "org.mockito:mockito-core:2.19.0"
-    androidTestImplementation 'androidx.test:runner:1.3.0'
-    androidTestImplementation 'androidx.test:rules:1.3.0'
-    // This is needed to be able to spy certain classes with Mockito
-    // It's major/minor version must match Mockito's.
-    androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito-inline:2.19.0'
-    // Required for instrumented tests
-    androidTestImplementation 'com.android.support:support-annotations:28.0.0'
-}
diff --git a/car-ui-lib/car-ui-lib/proguard-rules-platform.pro b/car-ui-lib/car-ui-lib/proguard-rules-platform.pro
deleted file mode 100644
index eed1e9a..0000000
--- a/car-ui-lib/car-ui-lib/proguard-rules-platform.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-# This was added to fix issues with androidx CREATOR objects being removed.
-# On google3 it is added automatically, so keep it in a separate file
-# and don't use this file in google3.
--keepclassmembers class * implements android.os.Parcelable {
-    static ** CREATOR;
-}
diff --git a/car-ui-lib/car-ui-lib/proguard-rules.pro b/car-ui-lib/car-ui-lib/proguard-rules.pro
deleted file mode 100644
index 6b66955..0000000
--- a/car-ui-lib/car-ui-lib/proguard-rules.pro
+++ /dev/null
@@ -1,38 +0,0 @@
-# required for replacing elements in PreferenceFragment
--keep class com.android.car.ui.preference.CarUiDropDownPreference {*;}
--keep class com.android.car.ui.preference.CarUiListPreference {*;}
--keep class com.android.car.ui.preference.CarUiMultiSelectListPreference {*;}
--keep class com.android.car.ui.preference.CarUiEditTextPreference {*;}
--keep class com.android.car.ui.preference.CarUiSwitchPreference {*;}
--keep class com.android.car.ui.preference.CarUiPreference {*;}
--keep class com.android.car.ui.preference.** extends com.android.car.ui.preference.CarUiPreference {*;}
-
-# required for default scrollbar implementation.
--keep class com.android.car.ui.recyclerview.DefaultScrollBar {*;}
-
-# required for MenuItem click listeners
--keepclasseswithmembers class * extends android.app.Activity {
-  public void * (com.android.car.ui.toolbar.MenuItem);
-}
-
-# We dynamically link the oem apis, and proguard can't see them
-# when running, so it errors out without -dontwarn
--dontwarn com.android.car.ui.sharedlibrary.oemapis.**
-
-# Required because the static lib doesn't call most of the methods
-# on adapters, but instead passes it to the shared lib, where they
-# are called. Since proguard can't even see that those methods are
-# overriding oem api interfaces (since the oem apis are dynmically
-# linked and marked with -dontwarn), it thinks they're unused.
--keep class com.android.car.ui.**AdapterV* {*;}
-
-# required for accessing oem apis
--keep class com.android.car.ui.sharedlibrarysupport.OemApiUtil {*;}
-
-# Required for AppCompat instantiating our layout inflater factory,
-# Otherwise it will be obfuscated and the reference to it in xml won't match
--keep class com.android.car.ui.CarUiLayoutInflaterFactory {*;}
-
-# Required for reflection code in CarUiInstaller
--keep class com.android.car.ui.baselayout.Insets {*;}
--keep class com.android.car.ui.core.BaseLayoutController {*;}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/AndroidManifest.xml b/car-ui-lib/car-ui-lib/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 21c8813..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2020 Google Inc.
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.car.ui.test">
-    <application android:debuggable="true" android:theme="@style/Theme.CarUi.NoToolbar">
-        <uses-library android:name="android.test.runner" />
-        <activity android:name="com.android.car.ui.TrulyEmptyActivity"
-            android:theme="@android:style/Theme.Material.NoActionBar"/>
-        <activity android:name="com.android.car.ui.TestActivity" />
-        <activity android:name="com.android.car.ui.recyclerview.CarUiRecyclerViewTestActivity" />
-        <activity android:name="com.android.car.ui.imewidescreen.CarUiImeWideScreenTestActivity" />
-        <activity android:name="com.android.car.ui.FocusAreaTestActivity" />
-        <activity android:name="com.android.car.ui.FocusParkingViewTestActivity" />
-        <activity android:name="com.android.car.ui.preference.PreferenceTestActivity"
-                  android:theme="@style/Theme.CarUi.WithToolbar"/>
-        <activity
-            android:name="com.android.car.ui.preference.NonFullscreenPreferenceFragmentTest$MyActivity"
-            android:theme="@style/Theme.CarUi.WithToolbar"/>
-        <activity android:name="com.android.car.ui.utils.ViewUtilsTestActivity" />
-        <activity
-            android:name="com.android.car.ui.toolbar.ToolbarTestActivity"
-            android:theme="@style/Theme.CarUi.WithToolbar"/>
-        <provider
-            android:name="com.android.car.ui.core.SearchResultsProvider"
-            android:authorities="${applicationId}.SearchResultsProvider"
-            android:exported="true"
-            android:process="@string/car_ui_installer_process_name"
-            android:readPermission="com.android.car.ui.READ_SEARCH_RESULTS"/>
-    </application>
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.car.ui.test"
-        android:label="Chassis Test Cases">
-    </instrumentation>
-</manifest>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/AlertDialogBuilderTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/AlertDialogBuilderTest.java
deleted file mode 100644
index 119a6fd..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/AlertDialogBuilderTest.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.app.AlertDialog;
-import android.database.Cursor;
-import android.view.View;
-
-import androidx.test.espresso.Root;
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRadioButtonListItem;
-import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter;
-import com.android.car.ui.test.R;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class AlertDialogBuilderTest {
-
-    @Rule
-    public ActivityTestRule<TestActivity> mActivityRule =
-            new ActivityTestRule<>(TestActivity.class);
-
-    @Test
-    public void test_AlertDialogBuilder_works() throws Throwable {
-        String title = "Test message from AlertDialogBuilder";
-        String subtitle = "Subtitle from AlertDialogBuilder";
-        mActivityRule.runOnUiThread(() ->
-                new AlertDialogBuilder(mActivityRule.getActivity())
-                        .setMessage(title)
-                        .setSubtitle(subtitle)
-                        .show());
-
-        AlertDialog dialog = checkDefaultButtonExists(true,
-                new AlertDialogBuilder(mActivityRule.getActivity())
-                        .setMessage(title)
-                        .setSubtitle(subtitle));
-        onView(withText(title))
-                .inRoot(new RootWithDecorMatcher(dialog.getWindow().getDecorView()))
-                .check(matches(isDisplayed()));
-        onView(withText(subtitle))
-                .inRoot(new RootWithDecorMatcher(dialog.getWindow().getDecorView()))
-                .check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void test_showSingleListChoiceItem_StringArray_hidesDefaultButton() throws Throwable {
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setSingleChoiceItems(new CharSequence[]{"Item 1", "Item 2"}, 0,
-                        ((dialog, which) -> {
-                        }));
-
-        checkDefaultButtonExists(false, builder);
-    }
-
-    @Test
-    public void test_showSingleListChoiceItem_StringArrayResource_hidesDefaultButton()
-            throws Throwable {
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setSingleChoiceItems(R.array.test_string_array, 0, ((dialog, which) -> {
-                }));
-
-        checkDefaultButtonExists(false, builder);
-    }
-
-    @Test
-    public void test_showSingleListChoiceItem_CarUiRadioButtonListItemAdapter_forcesDefaultButton()
-            throws Throwable {
-        CarUiRadioButtonListItem item1 = new CarUiRadioButtonListItem();
-        item1.setTitle("Item 1");
-        CarUiRadioButtonListItem item2 = new CarUiRadioButtonListItem();
-        item2.setTitle("Item 2");
-        CarUiRadioButtonListItem item3 = new CarUiRadioButtonListItem();
-        item3.setTitle("Item 3");
-
-        CarUiRadioButtonListItemAdapter adapter = new CarUiRadioButtonListItemAdapter(
-                Arrays.asList(item1, item2, item3));
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setSingleChoiceItems(adapter);
-
-        checkDefaultButtonExists(true, builder);
-    }
-
-    @Test
-    public void test_showSingleListChoiceItem_cursor_hidesDefaultButton() throws Throwable {
-        Cursor cursor = new FakeCursor(Arrays.asList("Item 1", "Item 2"), "ColumnName");
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setTitle("Title")
-                .setAllowDismissButton(false)
-                .setSingleChoiceItems(cursor, 0, "ColumnName", ((dialog, which) -> {
-                }));
-
-        checkDefaultButtonExists(false, builder);
-    }
-
-    @Test
-    public void test_setItems_StringArrayResource_hidesDefaultButton() throws Throwable {
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setItems(R.array.test_string_array, ((dialog, which) -> {
-                }));
-
-        checkDefaultButtonExists(false, builder);
-    }
-
-    @Test
-    public void test_setItems_StringArray_hidesDefaultButton() throws Throwable {
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setItems(new CharSequence[]{"Item 1", "Item 2"}, ((dialog, which) -> {
-                }));
-
-        checkDefaultButtonExists(false, builder);
-    }
-
-    @Test
-    public void test_setAdapter_hidesDefaultButton()
-            throws Throwable {
-        CarUiContentListItem item1 = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item1.setTitle("Item 1");
-        CarUiContentListItem item2 = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item2.setTitle("Item 2");
-        CarUiContentListItem item3 = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item3.setTitle("Item 3");
-
-        CarUiListItemAdapter adapter = new CarUiListItemAdapter(
-                Arrays.asList(item1, item2, item3));
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setAdapter(adapter);
-
-        checkDefaultButtonExists(false, builder);
-    }
-
-    @Test
-    public void test_multichoiceItems_StringArrayResource_forcesDefaultButton()
-            throws Throwable {
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setMultiChoiceItems(R.array.test_string_array, null,
-                        ((dialog, which, isChecked) -> {
-                        }));
-
-        checkDefaultButtonExists(true, builder);
-    }
-
-    @Test
-    public void test_multichoiceItems_StringArray_forcesDefaultButton()
-            throws Throwable {
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setMultiChoiceItems(new CharSequence[]{"Test 1", "Test 2"}, null,
-                        ((dialog, which, isChecked) -> {
-                        }));
-
-        checkDefaultButtonExists(true, builder);
-    }
-
-    @Test
-    public void test_multichoiceItems_Cursor_forcesDefaultButton()
-            throws Throwable {
-        Cursor cursor = new FakeCursor(Arrays.asList("Item 1", "Item 2"), "Label");
-        AlertDialogBuilder builder = new AlertDialogBuilder(mActivityRule.getActivity())
-                .setAllowDismissButton(false)
-                .setMultiChoiceItems(cursor, "isChecked", "Label",
-                        ((dialog, which, isChecked) -> {
-                        }));
-
-        checkDefaultButtonExists(true, builder);
-    }
-
-    private AlertDialog checkDefaultButtonExists(boolean shouldExist, AlertDialogBuilder builder)
-            throws Throwable {
-        AtomicBoolean didThrowException = new AtomicBoolean(false);
-        AlertDialog[] result = new AlertDialog[1];
-        RuntimeException[] exception = new RuntimeException[1];
-        mActivityRule.runOnUiThread(() -> {
-            try {
-                result[0] = builder.create();
-                result[0].show();
-            } catch (RuntimeException e) {
-                exception[0] = e;
-                didThrowException.set(true);
-            }
-        });
-
-        if (didThrowException.get()) {
-            assertNotNull(exception[0]);
-            assertEquals("The dialog must have at least one button to disable the dismiss button",
-                    exception[0].getMessage());
-            assertTrue(shouldExist);
-            return result[0];
-        }
-
-        if (shouldExist) {
-            onView(withText(R.string.car_ui_alert_dialog_default_button))
-                    .inRoot(new RootWithDecorMatcher(result[0].getWindow().getDecorView()))
-                    .check(matches(isDisplayed()));
-        } else {
-            onView(withText(R.string.car_ui_alert_dialog_default_button))
-                    .inRoot(new RootWithDecorMatcher(result[0].getWindow().getDecorView()))
-                    .check(doesNotExist());
-        }
-
-        return result[0];
-    }
-
-    private static class RootWithDecorMatcher extends TypeSafeMatcher<Root> {
-
-        private View mView;
-
-        RootWithDecorMatcher(View view) {
-            mView = view;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("is a root with a certain decor");
-        }
-
-        @Override
-        protected boolean matchesSafely(Root item) {
-            return item.getDecorView() == mView;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FakeCursor.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FakeCursor.java
deleted file mode 100644
index 9f734ea..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FakeCursor.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import android.database.AbstractCursor;
-
-import java.util.List;
-
-public class FakeCursor extends AbstractCursor {
-
-    private final List<String> mRows;
-    private final String mColumnName;
-
-    public FakeCursor(List<String> rows, String columnName) {
-        mRows = rows;
-        mColumnName = columnName;
-    }
-
-    @Override
-    public int getCount() {
-        return mRows.size();
-    }
-
-    @Override
-    public String[] getColumnNames() {
-        return new String[] { "_id", mColumnName };
-    }
-
-    @Override
-    public String getString(int column) {
-        if (column == 1) {
-            return mRows.get(getPosition());
-        }
-
-        return null;
-    }
-
-    @Override
-    public short getShort(int column) {
-        return 0;
-    }
-
-    @Override
-    public int getInt(int column) {
-        return 0;
-    }
-
-    @Override
-    public long getLong(int column) {
-        if (column == 0) {
-            return getPosition();
-        }
-
-        return 0;
-    }
-
-    @Override
-    public float getFloat(int column) {
-        return 0;
-    }
-
-    @Override
-    public double getDouble(int column) {
-        return 0;
-    }
-
-    @Override
-    public boolean isNull(int column) {
-        return getString(column) == null;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/TestActivity.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/TestActivity.java
deleted file mode 100644
index a5f20d5..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/TestActivity.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.car.ui.test.R;
-
-/**
- * An empty activity to be used for testing.
- */
-public class TestActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.empty_test_activity);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/TrulyEmptyActivity.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/TrulyEmptyActivity.java
deleted file mode 100644
index 6085f6c..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/TrulyEmptyActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import android.app.Activity;
-
-/**
- * An empty activity used for testing
- */
-public class TrulyEmptyActivity extends Activity {
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/SetProgressViewAction.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/SetProgressViewAction.java
deleted file mode 100644
index e202bd7..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/SetProgressViewAction.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.actions;
-
-import android.view.View;
-import android.widget.SeekBar;
-
-import androidx.test.espresso.UiController;
-import androidx.test.espresso.ViewAction;
-import androidx.test.espresso.matcher.ViewMatchers;
-
-import org.hamcrest.Matcher;
-
-public class SetProgressViewAction implements ViewAction {
-
-    private int mProgress;
-
-    public SetProgressViewAction(int progress) {
-        mProgress = progress;
-    }
-
-    @Override
-    public void perform(UiController uiController, View view) {
-        SeekBar seekBar = (SeekBar) view;
-        seekBar.setProgress(mProgress);
-    }
-
-    @Override
-    public String getDescription() {
-        return "Set a progress on a SeekBar";
-    }
-
-    @Override
-    public Matcher<View> getConstraints() {
-        return ViewMatchers.isAssignableFrom(SeekBar.class);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/ViewActions.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/ViewActions.java
deleted file mode 100644
index e6847ed..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/ViewActions.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.actions;
-
-import android.view.View;
-
-import androidx.test.espresso.ViewAction;
-
-import org.hamcrest.Matcher;
-
-public class ViewActions {
-
-    public static ViewAction waitForView(Matcher<View> matcher, long waitTimeMillis) {
-        return new WaitForViewAction(matcher, waitTimeMillis);
-    }
-
-    public static ViewAction waitForView(Matcher<View> matcher) {
-        return new WaitForViewAction(matcher, 500);
-    }
-
-    public static ViewAction setProgress(int progress) {
-        return new SetProgressViewAction(progress);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/appstyledview/AppStyledDialogControllerTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/appstyledview/AppStyledDialogControllerTest.java
deleted file mode 100644
index ca5bc1d..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/appstyledview/AppStyledDialogControllerTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.appstyledview;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.app.Dialog;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import androidx.test.espresso.Root;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.ui.TestActivity;
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledDismissListener;
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledVCloseClickListener;
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledViewNavIcon;
-import com.android.car.ui.test.R;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Unit tests for {@link AppStyledDialogController}.
- */
-@RunWith(AndroidJUnit4.class)
-public class AppStyledDialogControllerTest {
-
-    private AppStyledDialogController mAppStyledDialogController;
-
-    @Rule
-    public ActivityTestRule<TestActivity> mActivityRule =
-            new ActivityTestRule<>(TestActivity.class);
-
-    @Before
-    public void setUp() throws Throwable {
-
-        mActivityRule.runOnUiThread(() -> {
-            mAppStyledDialogController = new AppStyledDialogController(mActivityRule.getActivity());
-            mAppStyledDialogController
-                    .setAppStyledViewController(
-                            new AppStyledViewControllerImpl(mActivityRule.getActivity()),
-                            mActivityRule.getActivity());
-        });
-    }
-
-    @Test
-    public void show_shouldDisplayDialog() throws Throwable {
-        LayoutInflater inflator = LayoutInflater.from(mActivityRule.getActivity());
-
-        View appStyledTestView = inflator.inflate(R.layout.app_styled_view_sample, null,
-                false);
-
-        mActivityRule.runOnUiThread(() -> {
-            mAppStyledDialogController.setContentView(appStyledTestView);
-            mAppStyledDialogController.show();
-        });
-
-        String text = "app styled view";
-        Dialog dialog = mAppStyledDialogController.getAppStyledDialog();
-
-        onView(withText(text))
-                .inRoot(new RootWithDecorMatcher(dialog.getWindow().getDecorView()))
-                .check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void setNavIcon_showCloseIcon() throws Throwable {
-        LayoutInflater inflator = LayoutInflater.from(mActivityRule.getActivity());
-
-        View appStyledTestView = inflator.inflate(R.layout.app_styled_view_sample, null,
-                false);
-
-        mActivityRule.runOnUiThread(() -> {
-            mAppStyledDialogController.setContentView(appStyledTestView);
-            mAppStyledDialogController.setNavIcon(AppStyledViewNavIcon.CLOSE);
-            mAppStyledDialogController.show();
-        });
-
-        Dialog dialog = mAppStyledDialogController.getAppStyledDialog();
-
-        onView(withId(R.id.car_ui_app_styled_view_icon_close))
-                .inRoot(new RootWithDecorMatcher(dialog.getWindow().getDecorView()))
-                .check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void setOnCloseClickListener_shouldInvokeCallback() throws Throwable {
-        LayoutInflater inflator = LayoutInflater.from(mActivityRule.getActivity());
-
-        View appStyledTestView = inflator.inflate(R.layout.app_styled_view_sample, null,
-                false);
-
-        AppStyledVCloseClickListener callback = mock(AppStyledVCloseClickListener.class);
-
-        mActivityRule.runOnUiThread(() -> {
-            mAppStyledDialogController.setContentView(appStyledTestView);
-            mAppStyledDialogController.setNavIcon(AppStyledViewNavIcon.BACK);
-            mAppStyledDialogController.setOnCloseClickListener(callback);
-            mAppStyledDialogController.show();
-        });
-
-        Dialog dialog = mAppStyledDialogController.getAppStyledDialog();
-
-        onView(withId(R.id.car_ui_app_styled_view_icon_close))
-                .inRoot(new RootWithDecorMatcher(dialog.getWindow().getDecorView()))
-                .perform(click());
-
-        verify(callback).onClick();
-    }
-
-    @Test
-    public void setOnDismissListener_shouldInvokeCallback() throws Throwable {
-        LayoutInflater inflator = LayoutInflater.from(mActivityRule.getActivity());
-
-        View appStyledTestView = inflator.inflate(R.layout.app_styled_view_sample, null,
-                false);
-
-        AppStyledDismissListener callback = mock(AppStyledDismissListener.class);
-
-        mActivityRule.runOnUiThread(() -> {
-            mAppStyledDialogController.setContentView(appStyledTestView);
-            mAppStyledDialogController.setNavIcon(AppStyledViewNavIcon.BACK);
-            mAppStyledDialogController.setOnDismissListener(callback);
-            mAppStyledDialogController.show();
-        });
-
-        Dialog dialog = mAppStyledDialogController.getAppStyledDialog();
-
-        onView(withId(R.id.car_ui_app_styled_view_icon_close))
-                .inRoot(new RootWithDecorMatcher(dialog.getWindow().getDecorView()))
-                .perform(click());
-
-        verify(callback).onDismiss();
-    }
-
-    private static class RootWithDecorMatcher extends TypeSafeMatcher<Root> {
-
-        private View mView;
-
-        RootWithDecorMatcher(View view) {
-            mView = view;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("is a root with a certain decor");
-        }
-
-        @Override
-        protected boolean matchesSafely(Root item) {
-            return item.getDecorView() == mView;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/CarUiTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/CarUiTest.java
deleted file mode 100644
index 34b082a..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/CarUiTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.core;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-
-import com.android.car.ui.test.R;
-
-import org.junit.Test;
-
-/** A test for {@link com.android.car.ui.core.CarUi} */
-public class CarUiTest {
-
-    @Test
-    public void test_findCarUiComponentById_returnsNullWithNullInput() {
-        assertNull(CarUi.findCarUiComponentById(null, R.id.car_ui_recycler_view));
-    }
-
-    @Test
-    public void test_requireCarUiComponentById_throwsWithNullInput() {
-        assertThrows(NullPointerException.class,
-                () -> CarUi.requireCarUiComponentById(null, R.id.car_ui_recycler_view));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/ResolverRenamingMockContext.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/ResolverRenamingMockContext.java
deleted file mode 100644
index 95bf762..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/ResolverRenamingMockContext.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.core;
-
-import android.content.ContentProvider;
-import android.content.Context;
-import android.test.IsolatedContext;
-import android.test.mock.MockContentResolver;
-import android.test.mock.MockContext;
-
-public class ResolverRenamingMockContext extends IsolatedContext {
-
-    /**
-     * The renaming prefix.
-     */
-    private static final String PREFIX = "test.";
-
-
-    /**
-     * The resolver.
-     */
-    private static final MockContentResolver RESOLVER = new MockContentResolver();
-
-    /**
-     * Constructor.
-     */
-    public ResolverRenamingMockContext(Context context) {
-        super(RESOLVER, new DelegatedMockContext(context));
-    }
-
-    public MockContentResolver getResolver() {
-        return RESOLVER;
-    }
-
-    public void addProvider(String name, ContentProvider provider) {
-        RESOLVER.addProvider(name, provider);
-    }
-
-    /**
-     * The DelegatedMockContext.
-     */
-    private static class DelegatedMockContext extends MockContext {
-
-        private Context mDelegatedContext;
-
-        DelegatedMockContext(Context context) {
-            mDelegatedContext = context;
-        }
-
-        @Override
-        public String getPackageName() {
-            return "com.android.car.ui.test";
-        }
-    }
-
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/SearchResultsProviderTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/SearchResultsProviderTest.java
deleted file mode 100644
index dad8074..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/core/SearchResultsProviderTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.core;
-
-import static com.android.car.ui.core.SearchResultsProvider.ITEM_ID;
-import static com.android.car.ui.core.SearchResultsProvider.PRIMARY_IMAGE_BLOB;
-import static com.android.car.ui.core.SearchResultsProvider.SECONDARY_IMAGE_BLOB;
-import static com.android.car.ui.core.SearchResultsProvider.SECONDARY_IMAGE_ID;
-import static com.android.car.ui.core.SearchResultsProvider.SUBTITLE;
-import static com.android.car.ui.core.SearchResultsProvider.TITLE;
-
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.os.Parcel;
-import android.test.ProviderTestCase2;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.car.ui.test.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Unit tests for {@link SearchResultsProvider}.
- */
-@RunWith(AndroidJUnit4.class)
-public class SearchResultsProviderTest extends ProviderTestCase2<SearchResultsProvider> {
-
-    public static final String AUTHORITY =
-            SearchResultsProvider.getAuthority("com.android.car.ui.test");
-
-    private final Context mContext = ApplicationProvider.getApplicationContext();
-    private ResolverRenamingMockContext mProviderContext;
-    private Class<SearchResultsProvider> mProviderClass;
-    private SearchResultsProvider mProvider;
-
-    public SearchResultsProviderTest() {
-        super(SearchResultsProvider.class, AUTHORITY);
-        setName("ProviderSampleTests");
-        mProviderClass = SearchResultsProvider.class;
-    }
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        mProviderContext = new ResolverRenamingMockContext(getContext());
-        mProvider = mProviderClass.newInstance();
-        assertNotNull(mProvider);
-        mProvider.attachInfo(mProviderContext, null);
-        mProviderContext.addProvider(AUTHORITY, mProvider);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    @Override
-    public SearchResultsProvider getProvider() {
-        return mProvider;
-    }
-
-    @Test
-    public void insert_shouldInsertTheSearchResult() {
-        ContentValues values = getRecord();
-
-        SearchResultsProvider provider = getProvider();
-
-        Uri uri = provider.insert(Uri.parse(AUTHORITY), values);
-        // length - 1
-        assertEquals(0L, ContentUris.parseId(uri));
-    }
-
-    @Test
-    public void query_shouldHaveValidData() {
-        ContentValues values = getRecord();
-
-        SearchResultsProvider provider = getProvider();
-        provider.insert(Uri.parse(AUTHORITY), values);
-        Cursor cursor = provider.query(Uri.parse(AUTHORITY), null, null, null, null);
-
-        assertNotNull(cursor);
-        assertEquals(1, cursor.getCount());
-        assertTrue(cursor.moveToFirst());
-        assertEquals("1", cursor.getString(cursor.getColumnIndex(ITEM_ID)));
-        assertEquals("1", cursor.getString(cursor.getColumnIndex(SECONDARY_IMAGE_ID)));
-        assertNotNull(cursor.getBlob(cursor.getColumnIndex(PRIMARY_IMAGE_BLOB)));
-        assertNotNull(cursor.getBlob(cursor.getColumnIndex(SECONDARY_IMAGE_BLOB)));
-        assertEquals("Title", cursor.getString(cursor.getColumnIndex(TITLE)));
-        assertEquals("SubTitle", cursor.getString(cursor.getColumnIndex(SUBTITLE)));
-    }
-
-    private byte[] bitmapToByteArray(Bitmap bitmap) {
-        Parcel parcel = Parcel.obtain();
-        bitmap.writeToParcel(parcel, 0);
-        byte[] bytes = parcel.marshall();
-        parcel.recycle();
-        return bytes;
-    }
-
-    private ContentValues getRecord() {
-        ContentValues values = new ContentValues();
-        int id = 1;
-        values.put(ITEM_ID, id);
-        values.put(SECONDARY_IMAGE_ID, id);
-        BitmapDrawable icon = (BitmapDrawable) mContext.getDrawable(R.drawable.ic_launcher);
-        values.put(PRIMARY_IMAGE_BLOB,
-                icon != null ? bitmapToByteArray(icon.getBitmap()) : null);
-        values.put(SECONDARY_IMAGE_BLOB,
-                icon != null ? bitmapToByteArray(icon.getBitmap()) : null);
-        values.put(TITLE, "Title");
-        values.put(SUBTITLE, "SubTitle");
-        return values;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java
deleted file mode 100644
index 71d721e..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.imewidescreen;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
-import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.core.SearchResultsProvider.ITEM_ID;
-import static com.android.car.ui.core.SearchResultsProvider.SECONDARY_IMAGE_ID;
-import static com.android.car.ui.core.SearchResultsProvider.SUBTITLE;
-import static com.android.car.ui.core.SearchResultsProvider.TITLE;
-import static com.android.car.ui.core.SearchResultsProviderTest.AUTHORITY;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_DESC_TITLE_TO_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_DESC_TO_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_ERROR_DESC_TO_INPUT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_PACKAGE;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.REQUEST_RENDER_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_ACTION;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_EXTRACTED_TEXT_ICON;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_SEARCH_RESULTS;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenTestActivity.sCarUiImeWideScreenController;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Dialog;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.inputmethodservice.ExtractEditText;
-import android.inputmethodservice.InputMethodService;
-import android.inputmethodservice.InputMethodService.Insets;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.SurfaceControlViewHost;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.Window;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.espresso.contrib.RecyclerViewActions;
-import androidx.test.espresso.matcher.BoundedMatcher;
-import androidx.test.espresso.matcher.ViewMatchers.Visibility;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.car.ui.core.SearchResultsProvider;
-import com.android.car.ui.test.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit tests for {@link CarUiImeWideScreenController}.
- */
-@RunWith(AndroidJUnit4.class)
-public class CarUiImeWideScreenControllerTest {
-
-    private final Context mContext = ApplicationProvider.getApplicationContext();
-    private static final String TEST = "test";
-
-    @Mock
-    private EditorInfo mEditorInfoMock;
-
-    @Mock
-    private Display mDisplayMock;
-
-    @Mock
-    private InputConnection mInputConnectionMock;
-
-    @Mock
-    private SurfaceView mContentAreaSurfaceViewMock;
-
-    @Mock
-    private IBinder mHasTokenMock;
-
-    @Mock
-    private InputMethodService mInputMethodServiceMock;
-
-    @Mock
-    private Dialog mDialogMock;
-
-    @Mock
-    private Window mWindowMock;
-
-    @Rule
-    public ActivityScenarioRule<CarUiImeWideScreenTestActivity> mActivityRule =
-            new ActivityScenarioRule<>(CarUiImeWideScreenTestActivity.class);
-
-    @Rule
-    public ExpectedException mThrownRule = ExpectedException.none();
-
-    private CarUiImeWideScreenTestActivity mActivity;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        ActivityScenario<CarUiImeWideScreenTestActivity> mScenario = mActivityRule.getScenario();
-        mScenario.onActivity(activity -> {
-            mActivity = activity;
-        });
-    }
-
-    @Test
-    public void createWideScreenImeView_shouldWrapTheViewInTemplate() {
-        // make sure view is wrapped in the template.
-        assertNotNull(mActivity.findViewById(R.id.test_ime_input_view_id));
-
-        // check all views in template default visibility.
-        onView(withId(R.id.car_ui_wideScreenDescriptionTitle)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_wideScreenDescription)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_inputExtractActionAutomotive)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_wideScreenSearchResultList)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_wideScreenErrorMessage)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_wideScreenError)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_contentAreaAutomotive)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_ime_surface)).check(matches(not(isDisplayed())));
-
-        onView(withId(R.id.car_ui_wideScreenExtractedTextIcon)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_wideScreenClearData)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_fullscreenArea)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_inputExtractEditTextContainer)).check(matches(isDisplayed()));
-
-        // check if the click listener is installed on the image to clear data.
-        View clearDataIcon = mActivity.findViewById(R.id.car_ui_wideScreenClearData);
-        assertTrue(clearDataIcon.hasOnClickListeners());
-    }
-
-    @Test
-    public void onComputeInsets_showContentArea_shouldUpdateEntireAreaAsTouchable() {
-        when(mInputMethodServiceMock.getWindow()).thenReturn(mDialogMock);
-        when(mDialogMock.getWindow()).thenReturn(mWindowMock);
-        View view = new FrameLayout(mContext);
-        view.setTop(0);
-        view.setBottom(200);
-        when(mWindowMock.getDecorView()).thenReturn(view);
-
-        InputMethodService.Insets outInsets = new Insets();
-        CarUiImeWideScreenController carUiImeWideScreenController = getController();
-        carUiImeWideScreenController.onComputeInsets(outInsets);
-
-        assertThat(outInsets.touchableInsets, is(InputMethodService.Insets.TOUCHABLE_INSETS_FRAME));
-        assertThat(outInsets.contentTopInsets, is(200));
-        assertThat(outInsets.visibleTopInsets, is(200));
-    }
-
-    @Test
-    public void onComputeInsets_hideContentArea_shouldUpdateRegionAsTouchable() {
-        when(mInputMethodServiceMock.getWindow()).thenReturn(mDialogMock);
-        when(mDialogMock.getWindow()).thenReturn(mWindowMock);
-        View view = new FrameLayout(mActivity);
-        view.setTop(0);
-        view.setBottom(200);
-        when(mWindowMock.getDecorView()).thenReturn(view);
-
-        View imeInputView = LayoutInflater.from(mActivity)
-                .inflate(R.layout.test_ime_input_view, null, false);
-        CarUiImeWideScreenController carUiImeWideScreenController = getController();
-        carUiImeWideScreenController.createWideScreenImeView(imeInputView);
-
-        when(mContentAreaSurfaceViewMock.getDisplay()).thenReturn(mDisplayMock);
-        when(mDisplayMock.getDisplayId()).thenReturn(0);
-        carUiImeWideScreenController.setContentAreaSurfaceView(mContentAreaSurfaceViewMock);
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            carUiImeWideScreenController
-                    .onStartInputView(mEditorInfoMock, mInputConnectionMock, TEST);
-
-            Bundle bundle = new Bundle();
-            bundle.putBoolean(REQUEST_RENDER_CONTENT_AREA, false);
-            carUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_ACTION, bundle);
-        });
-
-        InputMethodService.Insets outInsets = new Insets();
-        carUiImeWideScreenController.onComputeInsets(outInsets);
-
-        assertThat(outInsets.touchableInsets,
-                is(InputMethodService.Insets.TOUCHABLE_INSETS_REGION));
-        assertThat(outInsets.contentTopInsets, is(200));
-        assertThat(outInsets.visibleTopInsets, is(200));
-    }
-
-    @Test
-    public void onAppPrivateCommand_shouldShowTitleAndDesc() {
-        when(mInputMethodServiceMock.getWindow()).thenReturn(mDialogMock);
-        when(mDialogMock.getWindow()).thenReturn(mWindowMock);
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.onStartInputView(mEditorInfoMock, mInputConnectionMock,
-                    TEST);
-
-            Bundle bundle = new Bundle();
-            bundle.putString(ADD_DESC_TITLE_TO_CONTENT_AREA, "Title");
-            bundle.putString(ADD_DESC_TO_CONTENT_AREA, "Description");
-            sCarUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_ACTION, bundle);
-        });
-
-        onView(withId(R.id.car_ui_wideScreenDescriptionTitle)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_wideScreenDescriptionTitle)).check(
-                matches(withText(containsString("Title"))));
-
-        onView(withId(R.id.car_ui_wideScreenDescription)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_wideScreenDescription)).check(
-                matches(withText(containsString("Description"))));
-    }
-
-    @Test
-    public void onAppPrivateCommand_shouldShowErrorMessage() {
-        when(mInputMethodServiceMock.getWindow()).thenReturn(mDialogMock);
-        when(mDialogMock.getWindow()).thenReturn(mWindowMock);
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.onStartInputView(mEditorInfoMock, mInputConnectionMock,
-                    TEST);
-
-            Bundle bundle = new Bundle();
-            bundle.putString(ADD_ERROR_DESC_TO_INPUT_AREA, "Error Message");
-            sCarUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_ACTION, bundle);
-        });
-
-        onView(withId(R.id.car_ui_wideScreenErrorMessage)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_wideScreenErrorMessage)).check(
-                matches(withText(containsString("Error Message"))));
-        onView(withId(R.id.car_ui_wideScreenError)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void isPackageAuthorized_shouldReturnFalse() {
-        CarUiImeWideScreenController carUiImeWideScreenController = getController();
-        boolean res = carUiImeWideScreenController.isPackageAuthorized("xyz");
-
-        assertThat(res, is(false));
-    }
-
-    @Test
-    public void setWideScreenExtractedIcon_shouldSetIcon() {
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.onStartInputView(mEditorInfoMock, mInputConnectionMock,
-                    TEST);
-
-            Bundle bundle = new Bundle();
-            Drawable drawable = mContext.getResources().getDrawable(R.drawable.ic_launcher);
-            Bitmap bitmap = CarUiUtils.drawableToBitmap(drawable);
-            byte[] byteArray = bitmapToByteArray(bitmap);
-
-            bundle.putByteArray(WIDE_SCREEN_EXTRACTED_TEXT_ICON, byteArray);
-            sCarUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_SEARCH_RESULTS, bundle);
-        });
-
-        onView(withId(R.id.car_ui_wideScreenExtractedTextIcon)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void setWideScreenExtractedIconResId0_shouldSetIcon() {
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.onStartInputView(mEditorInfoMock, mInputConnectionMock,
-                    TEST);
-
-            Bundle bundle = new Bundle();
-            bundle.putInt(WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID, 0);
-            sCarUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_SEARCH_RESULTS, bundle);
-        });
-
-        onView(withId(R.id.car_ui_wideScreenExtractedTextIcon)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void setWideScreenExtractedIconResId_shouldSetIcon() {
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.onStartInputView(mEditorInfoMock, mInputConnectionMock,
-                    TEST);
-
-            Bundle bundle = new Bundle();
-            bundle.putInt(WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID, R.drawable.ic_launcher);
-            sCarUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_SEARCH_RESULTS, bundle);
-        });
-
-        onView(withId(R.id.car_ui_wideScreenExtractedTextIcon)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void setWideScreenExtractedIconResId_shouldTHideIcon() {
-        when(mContentAreaSurfaceViewMock.getDisplay()).thenReturn(mDisplayMock);
-        when(mDisplayMock.getDisplayId()).thenReturn(0);
-        sCarUiImeWideScreenController.setContentAreaSurfaceView(mContentAreaSurfaceViewMock);
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.onStartInputView(mEditorInfoMock, mInputConnectionMock,
-                    TEST);
-
-            Bundle bundle = new Bundle();
-            bundle.putInt(WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID, 123);
-
-            sCarUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_SEARCH_RESULTS, bundle);
-        });
-
-        onView(withId(R.id.car_ui_wideScreenExtractedTextIcon)).check(
-                matches(withEffectiveVisibility(
-                        Visibility.GONE)));
-    }
-
-    @Test
-    public void setExtractViewShown_shouldHideExtractView() {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.setExtractViewShown(false);
-        });
-        onView(withId(R.id.car_ui_fullscreenArea)).check(matches(not(isDisplayed())));
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.setExtractViewShown(true);
-        });
-    }
-
-    @Test
-    public void setExtractViewShown_shouldShowExtractView() {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.setExtractViewShown(true);
-        });
-
-        onView(withId(R.id.car_ui_fullscreenArea)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void onAppPrivateCommand_shouldShowSearchResults() {
-        ContentResolver cr = ApplicationProvider.getApplicationContext().getContentResolver();
-        cr.insert(Uri.parse(AUTHORITY), getRecord());
-
-        when(mInputMethodServiceMock.getWindow()).thenReturn(mDialogMock);
-        when(mDialogMock.getWindow()).thenReturn(mWindowMock);
-
-        CharSequence charSequence = "test";
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            doReturn(mHasTokenMock).when(mContentAreaSurfaceViewMock).getHostToken();
-            sCarUiImeWideScreenController.setContentAreaSurfaceView(mContentAreaSurfaceViewMock);
-            sCarUiImeWideScreenController
-                    .onStartInputView(mEditorInfoMock, mInputConnectionMock, charSequence);
-        });
-
-        CarUiImeWideScreenController spy = Mockito.spy(sCarUiImeWideScreenController);
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            doReturn("com.android.car.ui.test").when(spy).getPackageName(ArgumentMatchers.any());
-            doNothing().when(spy).onItemClicked(ArgumentMatchers.any());
-            Bundle bundle = new Bundle();
-            spy.onAppPrivateCommand(WIDE_SCREEN_SEARCH_RESULTS, bundle);
-        });
-
-        onView(withId(R.id.car_ui_wideScreenSearchResultList)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_wideScreenSearchResultList))
-                .check(matches(atPosition(0, hasDescendant(withText("Title")))));
-        onView(withId(R.id.car_ui_wideScreenSearchResultList))
-                .check(matches(atPosition(0, hasDescendant(withText("SubTitle")))));
-        onView(withId(R.id.car_ui_wideScreenSearchResultList))
-                .perform(RecyclerViewActions.actionOnItem(hasDescendant(withText("Title")),
-                        click()));
-
-        verify(spy, times(1)).onItemClicked("1");
-    }
-
-    @Test
-    public void onAppPrivateCommand_shouldShowSurfaceView() {
-        when(mInputMethodServiceMock.getWindow()).thenReturn(mDialogMock);
-        when(mDialogMock.getWindow()).thenReturn(mWindowMock);
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            sCarUiImeWideScreenController.onStartInputView(mEditorInfoMock, mInputConnectionMock,
-                    TEST);
-
-            Bundle bundle = new Bundle();
-            // can't be inline to avoid ambiguity of constructors in SurfaceControlViewHost.
-            IBinder hostToken = null;
-            SurfaceControlViewHost surfaceControlViewHost = new SurfaceControlViewHost(mContext,
-                    null, hostToken);
-            bundle.putParcelable(CONTENT_AREA_SURFACE_PACKAGE,
-                    surfaceControlViewHost.getSurfacePackage());
-            sCarUiImeWideScreenController.onAppPrivateCommand(WIDE_SCREEN_ACTION, bundle);
-        });
-
-        onView(withId(R.id.car_ui_ime_surface)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void onEvaluateFullscreenMode_shouldReturnTrue() {
-        boolean result = sCarUiImeWideScreenController.onEvaluateFullscreenMode(false);
-        assertThat(result, is(true));
-    }
-
-    @Test
-    public void onEvaluateFullscreenMode_inWidescreenMode_shouldReturnTrue() {
-        boolean result = sCarUiImeWideScreenController.onEvaluateFullscreenMode(true);
-        assertThat(result, is(true));
-    }
-
-    private ContentValues getRecord() {
-        ContentValues values = new ContentValues();
-        int id = 1;
-        values.put(ITEM_ID, id);
-        values.put(SECONDARY_IMAGE_ID, id);
-        values.put(TITLE, "Title");
-        values.put(SUBTITLE, "SubTitle");
-
-        String idString = String.valueOf(id);
-        values.put(SearchResultsProvider.ITEM_ID, id);
-        values.put(SearchResultsProvider.SECONDARY_IMAGE_ID, id);
-        BitmapDrawable icon = (BitmapDrawable) mContext.getResources()
-                .getDrawable(R.drawable.ic_launcher);
-        values.put(SearchResultsProvider.PRIMARY_IMAGE_BLOB,
-                icon != null ? bitmapToByteArray(icon.getBitmap()) : null);
-        BitmapDrawable supplementalIcon = (BitmapDrawable) mContext.getResources()
-                .getDrawable(R.drawable.ic_launcher);
-        values.put(SearchResultsProvider.SECONDARY_IMAGE_BLOB,
-                supplementalIcon != null ? bitmapToByteArray(supplementalIcon.getBitmap())
-                        : null);
-        return values;
-    }
-
-    private byte[] bitmapToByteArray(Bitmap bitmap) {
-        Parcel parcel = Parcel.obtain();
-        bitmap.writeToParcel(parcel, 0);
-        byte[] bytes = parcel.marshall();
-        parcel.recycle();
-        return bytes;
-    }
-
-    private static Matcher<View> atPosition(final int position,
-            @NonNull final Matcher<View> itemMatcher) {
-        checkNotNull(itemMatcher);
-        return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("has item at position " + position + ": ");
-                itemMatcher.describeTo(description);
-            }
-
-            @Override
-            protected boolean matchesSafely(final RecyclerView view) {
-                RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(
-                        position);
-                if (viewHolder == null) {
-                    // has no item on such position
-                    return false;
-                }
-                return itemMatcher.matches(viewHolder.itemView);
-            }
-        };
-    }
-
-    private CarUiImeWideScreenController getController() {
-        return new CarUiImeWideScreenController(mActivity, mInputMethodServiceMock) {
-            @Override
-            public boolean isWideScreenMode() {
-                return true;
-            }
-
-            @Override
-            ExtractEditText getExtractEditText() {
-                FrameLayout parent = new FrameLayout(mContext);
-                ExtractEditText extractEditText = new ExtractEditText(mContext);
-                parent.addView(extractEditText);
-                return extractEditText;
-            }
-        };
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenTestActivity.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenTestActivity.java
deleted file mode 100644
index 0a02471..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenTestActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.imewidescreen;
-
-import android.app.Activity;
-import android.inputmethodservice.ExtractEditText;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.RelativeLayout;
-
-import com.android.car.ui.test.R;
-
-/**
- * An {@link Activity} that mimics a wide screen IME and displays the template for testing.
- */
-public class CarUiImeWideScreenTestActivity extends Activity {
-    public static CarUiImeWideScreenController sCarUiImeWideScreenController;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_ime_wide_screen_test_activity);
-
-        FrameLayout root = findViewById(R.id.test_activity);
-
-        sCarUiImeWideScreenController = new CarUiImeWideScreenController(this, null) {
-            @Override
-            public boolean isWideScreenMode() {
-                return true;
-            }
-
-            @Override
-            ExtractEditText getExtractEditText() {
-                FrameLayout parent = new FrameLayout(getApplicationContext());
-                ExtractEditText extractEditText = new ExtractEditText(getApplicationContext());
-                parent.addView(extractEditText);
-                return extractEditText;
-            }
-
-            @Override
-            String getEditorInfoPackageName() {
-                return "com.android.car.ui.test";
-            }
-        };
-
-        View imeInputView = LayoutInflater.from(this)
-                .inflate(R.layout.test_ime_input_view, null, false);
-
-        View templateView = sCarUiImeWideScreenController.createWideScreenImeView(imeInputView);
-
-        root.addView(templateView);
-
-        RelativeLayout carboardArea = findViewById(R.id.car_ui_ime_carboard_area);
-        ViewGroup.LayoutParams lp = carboardArea.getLayoutParams();
-        lp.width = 400;
-        carboardArea.setLayoutParams(lp);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/DrawableMatcher.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/DrawableMatcher.java
deleted file mode 100644
index 2030e0f..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/DrawableMatcher.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.matchers;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-import android.widget.ImageView;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-
-/* package */ class DrawableMatcher extends TypeSafeMatcher<View> {
-
-    private final Bitmap mBitmap;
-
-    DrawableMatcher(@NonNull Context context, @DrawableRes int drawableId) {
-        this(context.getDrawable(drawableId));
-    }
-    DrawableMatcher(Drawable drawable) {
-        mBitmap = drawableToBitmap(drawable);
-    }
-
-    @Override
-    protected boolean matchesSafely(View item) {
-        if (!(item instanceof ImageView) || !item.isShown()) {
-            return false;
-        }
-
-        ImageView imageView = (ImageView) item;
-
-        Bitmap bitmap = drawableToBitmap(imageView.getDrawable());
-        Bitmap otherBitmap = mBitmap;
-
-        if (bitmap == null && otherBitmap == null) {
-            return true;
-        } else if ((bitmap == null) != (otherBitmap == null)) {
-            return false;
-        }
-
-        return bitmap.sameAs(otherBitmap);
-    }
-
-    private Bitmap drawableToBitmap(Drawable drawable) {
-        if (drawable == null) {
-            return null;
-        }
-
-        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
-                drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(bitmap);
-        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
-        drawable.draw(canvas);
-        return bitmap;
-    }
-
-    @Override
-    public void describeTo(Description description) {
-        description.appendText("has a certain drawable");
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/IndexMatcher.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/IndexMatcher.java
deleted file mode 100644
index 8902b7d..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/IndexMatcher.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.matchers;
-
-import android.view.View;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
-
-/**
- * A custom matcher that allows for the specification of an index when multiple views meet the
- * criteria of a matcher.
- */
-public class IndexMatcher extends TypeSafeMatcher<View> {
-
-    private final Matcher<View> mMatcher;
-    private final int mIndex;
-    int mCurrentIndex = 0;
-
-    public IndexMatcher(Matcher<View> matcher, int index) {
-        mMatcher = matcher;
-        mIndex = index;
-    }
-
-    @Override
-    public void describeTo(Description description) {
-        description.appendText("with index: ");
-        description.appendValue(mIndex);
-        mMatcher.describeTo(description);
-    }
-
-    @Override
-    public boolean matchesSafely(View view) {
-        return mMatcher.matches(view) && mCurrentIndex++ == mIndex;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/IsActivatedMatcher.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/IsActivatedMatcher.java
deleted file mode 100644
index b9469cc..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/IsActivatedMatcher.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.matchers;
-
-import android.view.View;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-
-public final class IsActivatedMatcher extends TypeSafeMatcher<View> {
-    public IsActivatedMatcher() {}
-
-    @Override
-    public boolean matchesSafely(View view) {
-        return view.isActivated();
-    }
-
-    @Override
-    public void describeTo(Description description) {
-        description.appendText("is activated");
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/PaddingMatcher.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/PaddingMatcher.java
deleted file mode 100644
index 5ab1a86..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/PaddingMatcher.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.matchers;
-
-import android.view.View;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-
-public class PaddingMatcher extends TypeSafeMatcher<View> {
-
-    public enum Side {
-        TOP,
-        BOTTOM,
-        LEFT,
-        RIGHT,
-        START,
-        END
-    }
-
-    private Side mSide;
-    private int mMin;
-    private int mMax;
-
-    public PaddingMatcher(Side side, int min, int max) {
-        mSide = side;
-        mMin = min;
-        mMax = max;
-    }
-
-    @Override
-    protected boolean matchesSafely(View item) {
-        int padding = 0;
-        switch (mSide) {
-            case TOP:
-                padding = item.getPaddingTop();
-                break;
-            case BOTTOM:
-                padding = item.getPaddingBottom();
-                break;
-            case LEFT:
-                padding = item.getPaddingLeft();
-                break;
-            case RIGHT:
-                padding = item.getPaddingRight();
-                break;
-            case START:
-                padding = item.getPaddingStart();
-                break;
-            case END:
-                padding = item.getPaddingEnd();
-                break;
-        }
-
-        if (mMin >= 0 && padding < mMin) {
-            return false;
-        }
-
-        return mMax < 0 || padding <= mMax;
-    }
-
-    @Override
-    public void describeTo(Description description) {
-        description
-            .appendText("with " + mSide.toString() + " padding between " + mMin + " and " + mMax);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/ProgressBarIndeterminateMatcher.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/ProgressBarIndeterminateMatcher.java
deleted file mode 100644
index 7b264b9..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/ProgressBarIndeterminateMatcher.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.matchers;
-
-import android.view.View;
-import android.widget.ProgressBar;
-
-import androidx.test.espresso.matcher.BoundedMatcher;
-
-import org.hamcrest.Description;
-
-public class ProgressBarIndeterminateMatcher extends BoundedMatcher<View, ProgressBar> {
-    public ProgressBarIndeterminateMatcher() {
-        super(ProgressBar.class);
-    }
-
-    @Override
-    protected boolean matchesSafely(ProgressBar item) {
-        return item.isIndeterminate();
-    }
-
-    @Override
-    public void describeTo(Description description) {
-        description.appendText("is indeterminate");
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/ViewMatchers.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/ViewMatchers.java
deleted file mode 100644
index 43f8663..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/ViewMatchers.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.matchers;
-
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.not;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.test.espresso.ViewAssertion;
-
-import com.android.car.ui.matchers.PaddingMatcher.Side;
-
-import org.hamcrest.Matcher;
-
-public class ViewMatchers {
-    public static Matcher<View> withDrawable(
-            @NonNull Context context, @DrawableRes int drawableId) {
-        return new DrawableMatcher(context, drawableId);
-    }
-
-    public static Matcher<View> nthChildOfView(Matcher<View> parentMatcher, int n) {
-        return new NthChildMatcher(parentMatcher, n);
-    }
-
-    public static Matcher<View> withIndex(Matcher<View> matcher, int index) {
-        return new IndexMatcher(matcher, index);
-    }
-
-    public static Matcher<View> withPadding(Side side, int exactly) {
-        return new PaddingMatcher(side, exactly, exactly);
-    }
-
-    public static Matcher<View> withPaddingAtLeast(Side side, int min) {
-        return new PaddingMatcher(side, min, -1);
-    }
-
-    public static Matcher<View> isActivated() {
-        return new IsActivatedMatcher();
-    }
-
-    public static ViewAssertion doesNotExistOrIsNotDisplayed() {
-        return (view, noViewFoundException) -> {
-            if (view != null) {
-                matches(not(isDisplayed())).check(view, noViewFoundException);
-            }
-        };
-    }
-
-    public static Matcher<View> isDisplayedAnd(Matcher<View> another) {
-        return allOf(isDisplayed(), another);
-    }
-
-
-    public static Matcher<View> hasIndeterminateProgress() {
-        return new ProgressBarIndeterminateMatcher();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/NonFullscreenPreferenceFragmentTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/NonFullscreenPreferenceFragmentTest.java
deleted file mode 100644
index 38a66ad..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/NonFullscreenPreferenceFragmentTest.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.Espresso.pressBack;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.matchers.ViewMatchers.withPadding;
-import static com.android.car.ui.matchers.ViewMatchers.withPaddingAtLeast;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.fragment.app.Fragment;
-import androidx.preference.ListPreference;
-import androidx.preference.MultiSelectListPreference;
-import androidx.preference.PreferenceScreen;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.matchers.PaddingMatcher.Side;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import org.junit.Rule;
-import org.junit.Test;
-
-public class NonFullscreenPreferenceFragmentTest {
-
-    private static final String EXTRA_FULLSCREEN = "fullscreen";
-    private static final String TOOLBAR_DEFAULT_TEXT = "Test!";
-    private static final String PREFERENCE_SCREEN_TITLE = "PreferenceScreen Title";
-    private static final String LIST_PREFERENCE_TITLE = "List Preference";
-    private static final String MULTI_SELECT_LIST_PREFERENCE_TITLE = "MultiSelect List Preference";
-    private static final String BACK_CONTENT_DESCRIPTION = "Back";
-    private static final String[] ITEMS = { "Item 1", "Item 2", "Item 3" };
-
-    @Rule
-    public ActivityScenarioRule<PreferenceTestActivity> mActivityRule =
-            new ActivityScenarioRule<>(PreferenceTestActivity.class);
-
-    @Test
-    public void test_fullscreen_changesTitle() {
-        try (ActivityScenario<MyActivity> scenario =
-                     ActivityScenario.launch(MyActivity.newIntent(true))) {
-
-            onView(withText(TOOLBAR_DEFAULT_TEXT)).check(doesNotExist());
-            onView(withText(PREFERENCE_SCREEN_TITLE)).check(matches(isDisplayed()));
-            onView(isAssignableFrom(RecyclerView.class)).check(
-                    matches(withPaddingAtLeast(Side.TOP, 1)));
-
-            onView(withText(MULTI_SELECT_LIST_PREFERENCE_TITLE)).perform(click());
-            onView(withText(MULTI_SELECT_LIST_PREFERENCE_TITLE)).check(matches(isDisplayed()));
-            onView(withText(ITEMS[0])).check(matches(isDisplayed()));
-            onView(isAssignableFrom(RecyclerView.class)).check(
-                    matches(withPaddingAtLeast(Side.TOP, 1)));
-            onView(withContentDescription(BACK_CONTENT_DESCRIPTION)).perform(click());
-
-            onView(withText(LIST_PREFERENCE_TITLE)).perform(click());
-            onView(withText(LIST_PREFERENCE_TITLE)).check(matches(isDisplayed()));
-            onView(withText(ITEMS[0])).check(matches(isDisplayed()));
-            onView(isAssignableFrom(RecyclerView.class)).check(
-                    matches(withPaddingAtLeast(Side.TOP, 1)));
-            onView(withContentDescription(BACK_CONTENT_DESCRIPTION)).perform(click());
-        }
-    }
-
-    @Test
-    public void test_nonFullscreen_doesntChangeTitle() {
-        try (ActivityScenario<MyActivity> scenario =
-                     ActivityScenario.launch(MyActivity.newIntent(false))) {
-
-            onView(withText(TOOLBAR_DEFAULT_TEXT)).check(matches(isDisplayed()));
-            onView(withText(PREFERENCE_SCREEN_TITLE)).check(doesNotExist());
-            onView(isAssignableFrom(RecyclerView.class)).check(matches(withPadding(Side.TOP, 0)));
-
-            onView(withText(MULTI_SELECT_LIST_PREFERENCE_TITLE)).perform(click());
-            onView(withText(MULTI_SELECT_LIST_PREFERENCE_TITLE)).check(doesNotExist());
-            onView(withText(TOOLBAR_DEFAULT_TEXT)).check(matches(isDisplayed()));
-            onView(withText(ITEMS[0])).check(matches(isDisplayed()));
-            onView(isAssignableFrom(RecyclerView.class)).check(matches(withPadding(Side.TOP, 0)));
-            onView(withContentDescription(BACK_CONTENT_DESCRIPTION)).check(doesNotExist());
-            pressBack();
-
-            onView(withText(LIST_PREFERENCE_TITLE)).perform(click());
-            onView(withText(LIST_PREFERENCE_TITLE)).check(doesNotExist());
-            onView(withText(TOOLBAR_DEFAULT_TEXT)).check(matches(isDisplayed()));
-            onView(withText(ITEMS[0])).check(matches(isDisplayed()));
-            onView(isAssignableFrom(RecyclerView.class)).check(matches(withPadding(Side.TOP, 0)));
-            onView(withContentDescription(BACK_CONTENT_DESCRIPTION)).check(doesNotExist());
-            pressBack();
-        }
-    }
-
-
-    public static class MyActivity extends AppCompatActivity implements InsetsChangedListener {
-
-        private boolean mIsFullScreen = false;
-
-        public static Intent newIntent(boolean isFullScreen) {
-            Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-            Intent intent = new Intent(context, MyActivity.class);
-            intent.putExtra(EXTRA_FULLSCREEN, isFullScreen);
-            return intent;
-        }
-
-        @Override
-        protected void onCreate(@Nullable Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-
-            CarUi.replaceInsetsChangedListenerWith(this, this);
-            ToolbarController toolbar = CarUi.requireToolbar(this);
-            toolbar.setTitle(TOOLBAR_DEFAULT_TEXT);
-
-            mIsFullScreen = getIntent().getBooleanExtra(EXTRA_FULLSCREEN, true);
-            if (savedInstanceState == null) {
-                getSupportFragmentManager()
-                        .beginTransaction()
-                        .replace(android.R.id.content, new MyPreferenceFragment(mIsFullScreen))
-                        .commitNow();
-            }
-        }
-
-        @Override
-        public void onCarUiInsetsChanged(@NonNull Insets insets) {
-            if (!mIsFullScreen) {
-                requireViewById(android.R.id.content).setPadding(insets.getLeft(), insets.getTop(),
-                        insets.getRight(), insets.getBottom());
-                // Don't pass insets to fragment
-            } else {
-                for (Fragment fragment : getSupportFragmentManager().getFragments()) {
-                    if (fragment instanceof InsetsChangedListener) {
-                        ((InsetsChangedListener) fragment).onCarUiInsetsChanged(insets);
-                    }
-                }
-            }
-        }
-    }
-
-    public static class MyPreferenceFragment extends PreferenceFragment {
-
-        private final boolean mIsFullScreen;
-
-        public MyPreferenceFragment(boolean isFullScreen) {
-            mIsFullScreen = isFullScreen;
-        }
-
-        @Override
-        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-            PreferenceScreen screen = getPreferenceManager()
-                    .createPreferenceScreen(requireContext());
-
-            ListPreference listPreference = new CarUiListPreference(getContext());
-            listPreference.setTitle(LIST_PREFERENCE_TITLE);
-            listPreference.setKey(LIST_PREFERENCE_TITLE);
-            listPreference.setEntries(ITEMS);
-            listPreference.setEntryValues(new CharSequence[]{"1", "2", "3"});
-
-            MultiSelectListPreference multiSelectListPreference =
-                    new CarUiMultiSelectListPreference(getContext());
-            multiSelectListPreference.setTitle(MULTI_SELECT_LIST_PREFERENCE_TITLE);
-            multiSelectListPreference.setKey(MULTI_SELECT_LIST_PREFERENCE_TITLE);
-            multiSelectListPreference.setEntries(ITEMS);
-            multiSelectListPreference.setEntryValues(new CharSequence[]{"1", "2", "3"});
-
-            screen.addPreference(listPreference);
-            screen.addPreference(multiSelectListPreference);
-
-            screen.setTitle(PREFERENCE_SCREEN_TITLE);
-            setPreferenceScreen(screen);
-        }
-
-        @Override
-        public ToolbarController getPreferenceToolbar(@NonNull Fragment fragment) {
-            if (mIsFullScreen) {
-                return super.getPreferenceToolbar(fragment);
-            } else {
-                return null;
-            }
-        }
-
-        @Override
-        public Insets getPreferenceInsets(@NonNull Fragment fragment) {
-            if (mIsFullScreen) {
-                return super.getPreferenceInsets(fragment);
-            } else {
-                return null;
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTest.java
deleted file mode 100644
index 0866334..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTest.java
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.action.ViewActions.typeText;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isNotChecked;
-import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.actions.ViewActions.setProgress;
-import static com.android.car.ui.matchers.ViewMatchers.withIndex;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.TestCase.assertEquals;
-import static junit.framework.TestCase.assertTrue;
-
-import static org.hamcrest.Matchers.not;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.view.View;
-
-import androidx.preference.CheckBoxPreference;
-import androidx.preference.DropDownPreference;
-import androidx.preference.EditTextPreference;
-import androidx.preference.Preference;
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.ui.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.function.Consumer;
-
-/**
- * Unit tests for {@link CarUiPreference}.
- */
-public class PreferenceTest {
-
-    private PreferenceTestActivity mActivity;
-    private String[] mEntries;
-    private String[] mEntriesValues;
-
-    @Rule
-    public ActivityTestRule<PreferenceTestActivity> mActivityRule =
-            new ActivityTestRule<>(PreferenceTestActivity.class);
-
-    @Before
-    public void setUp() {
-        mActivity = mActivityRule.getActivity();
-        Resources resources = mActivity.getResources();
-        mEntries = resources.getStringArray(R.array.entries);
-        mEntriesValues = resources.getStringArray(R.array.entry_values);
-    }
-
-    @Test
-    public void testListPreference() {
-        // Scroll until list preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("list"));
-
-        // Display full screen list preference.
-        onView(withText(R.string.title_list_preference)).perform(click());
-
-        Preference.OnPreferenceChangeListener mockListener = mock(
-                Preference.OnPreferenceChangeListener.class);
-        when(mockListener.onPreferenceChange(any(), any())).thenReturn(true);
-        mActivity.setOnPreferenceChangeListener("list", mockListener);
-
-        // Check that no option is initially selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isNotChecked()));
-
-        // Select first option.
-        onView(withText(mEntries[0])).perform(click());
-        // Check that first option is selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 0))
-                .check(matches(isChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isNotChecked()));
-
-        // Press back to save selection.
-        onView(withContentDescription("Back")).perform(click());
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(mEntriesValues[0]));
-
-        onView(withText(R.string.title_list_preference)).perform(click());
-
-        // Check that first option is selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 0))
-                .check(matches(isChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isNotChecked()));
-
-        // Select second option.
-        onView(withText(mEntries[1])).perform(click());
-        // Check that second option is selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 0))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isNotChecked()));
-
-        // Press back to save selection.
-        onView(withContentDescription("Back")).perform(click());
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(mEntriesValues[1]));
-        // Return to list preference screen.
-        onView(withText(R.string.title_list_preference)).perform(click());
-
-        // Check that second option is selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 0))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isNotChecked()));
-    }
-
-    @Test
-    public void testListPreference_uxRestricted() {
-        // Scroll until list preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("list_ux_restricted"));
-
-        // Check that UX restriction is enabled
-        CarUiListPreference preference = (CarUiListPreference) mActivity.findPreference(
-                "list_ux_restricted");
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> clickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(clickListener);
-        assertEquals(clickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_list_preference_ux_restricted)).perform(click());
-        verify(clickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testMultiSelectListPreference() {
-        // Scroll until multi-select preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("multi_select_list"));
-
-        // Display full screen list preference.
-        onView(withText(R.string.title_multi_list_preference)).perform(click());
-
-        Preference.OnPreferenceChangeListener mockListener = mock(
-                Preference.OnPreferenceChangeListener.class);
-        when(mockListener.onPreferenceChange(any(), any())).thenReturn(true);
-        mActivity.setOnPreferenceChangeListener("multi_select_list", mockListener);
-
-        // Check that no option is initially selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 0))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 2))
-                .check(matches(isNotChecked()));
-
-        // Select options 1 and 3.
-        onView(withText(mEntries[0])).perform(click());
-        onView(withText(mEntries[2])).perform(click());
-
-        // Check that selections are correctly reflected.
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 0))
-                .check(matches(isChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 2))
-                .check(matches(isChecked()));
-
-        // Press back to save selection.
-        onView(withContentDescription("Back")).perform(click());
-        Set<String> expectedUpdate = new HashSet<>();
-        expectedUpdate.add(mEntriesValues[0]);
-        expectedUpdate.add(mEntriesValues[2]);
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(expectedUpdate));
-
-        // Return to multi-select list preference screen.
-        onView(withText(R.string.title_multi_list_preference)).perform(click());
-
-        // Check that selections are correctly reflected.
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 0))
-                .check(matches(isChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_checkbox_widget), 2))
-                .check(matches(isChecked()));
-    }
-
-    @Test
-    public void testMultiSelectListPreference_uxRestricted() {
-        // Scroll until list preference is visible
-        mActivity.runOnUiThread(
-                () -> mActivity.scrollToPreference("multi_select_list_ux_restricted"));
-
-        // Check that UX restriction is enabled
-        CarUiMultiSelectListPreference preference =
-                (CarUiMultiSelectListPreference) mActivity.findPreference(
-                        "multi_select_list_ux_restricted");
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> clickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(clickListener);
-        assertEquals(clickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_multi_list_preference_ux_restricted)).perform(click());
-        verify(clickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testCheckboxPreference() {
-        // Create checkbox preference and add it to screen.
-        CheckBoxPreference preference = new CheckBoxPreference(mActivity);
-        preference.setOrder(0);
-        preference.setKey("checkbox");
-        preference.setTitle(R.string.title_checkbox_preference);
-        preference.setSummary(R.string.summary_compound_button_preference);
-        mActivity.addPreference(preference);
-
-        // Scroll until list preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("checkbox"));
-
-        // Check title and summary are displayed as expected.
-        onView(withIndex(withId(android.R.id.title), 0)).check(matches(
-                withText(mActivity.getString(R.string.title_checkbox_preference))));
-        onView(withIndex(withId(android.R.id.summary), 0)).check(matches(
-                withText(mActivity.getString(R.string.summary_compound_button_preference))));
-
-        // Ensure checkbox preference is initially not selected.
-        onView(withId(android.R.id.checkbox)).check(matches(isNotChecked()));
-
-        Preference.OnPreferenceChangeListener mockListener = mock(
-                Preference.OnPreferenceChangeListener.class);
-        when(mockListener.onPreferenceChange(any(), any())).thenReturn(true);
-        mActivity.setOnPreferenceChangeListener("checkbox", mockListener);
-
-        // Select checkbox preference.
-        onView(withText(R.string.title_checkbox_preference)).perform(click());
-
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(true));
-
-        // Verify checkbox preference correctly indicates preference is selected.
-        onView(withId(android.R.id.checkbox)).check(matches(isChecked()));
-
-        // Un-select checkbox preference.
-        onView(withText(R.string.title_checkbox_preference)).perform(click());
-
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(false));
-
-        // Verify checkbox preference correctly indicates preference is selected.
-        onView(withId(android.R.id.checkbox)).check(matches(isNotChecked()));
-    }
-
-    @Test
-    public void testSwitchPreference() {
-        // Create switch preference and add it to screen.
-        CarUiSwitchPreference preference = new CarUiSwitchPreference(mActivity);
-        preference.setOrder(0);
-        preference.setKey("switch");
-        preference.setTitle(R.string.title_switch_preference);
-        preference.setSummary(R.string.summary_compound_button_preference);
-        mActivity.addPreference(preference);
-
-        // Scroll until list preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("switch"));
-
-
-        // Check title and summary are displayed as expected.
-        onView(withIndex(withId(android.R.id.title), 0)).check(matches(
-                withText(mActivity.getString(R.string.title_switch_preference))));
-        onView(withIndex(withId(android.R.id.summary), 0)).check(matches(
-                withText(mActivity.getString(R.string.summary_compound_button_preference))));
-
-        // Ensure switch preference is initially not selected.
-        onView(withId(android.R.id.switch_widget)).check(matches(isNotChecked()));
-
-        Preference.OnPreferenceChangeListener mockListener = mock(
-                Preference.OnPreferenceChangeListener.class);
-        when(mockListener.onPreferenceChange(any(), any())).thenReturn(true);
-        mActivity.setOnPreferenceChangeListener("switch", mockListener);
-
-        // Select switch preference.
-        onView(withText(R.string.title_switch_preference)).perform(click());
-
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(true));
-
-        // Verify switch preference correctly indicates preference is selected.
-        onView(withId(android.R.id.switch_widget)).check(matches(isChecked()));
-
-        // Un-select switch preference.
-        onView(withText(R.string.title_switch_preference)).perform(click());
-
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(false));
-
-        // Verify switch preference correctly indicates preference is selected.
-        onView(withId(android.R.id.switch_widget)).check(matches(isNotChecked()));
-    }
-
-    @Test
-    public void testSwitchPreference_uxRestricted() {
-        // Create switch preference and add it to screen.
-        CarUiSwitchPreference preference = new CarUiSwitchPreference(mActivity);
-        preference.setOrder(0);
-        preference.setKey("switch");
-        preference.setTitle(R.string.title_switch_preference);
-        preference.setSummary(R.string.summary_compound_button_preference);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until switch preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("switch"));
-
-        // Check title and summary are displayed as expected.
-        onView(withIndex(withId(android.R.id.title), 0)).check(matches(
-                withText(mActivity.getString(R.string.title_switch_preference))));
-        onView(withIndex(withId(android.R.id.summary), 0)).check(matches(
-                withText(mActivity.getString(R.string.summary_compound_button_preference))));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> clickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(clickListener);
-        assertEquals(clickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_switch_preference)).perform(click());
-        verify(clickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testRadioPreference() {
-        // Create radio button preference and add it to screen.
-        CarUiRadioButtonPreference preference = new CarUiRadioButtonPreference(mActivity);
-        preference.setOrder(0);
-        preference.setKey("radio_button");
-        preference.setTitle(R.string.title_radio_button_preference);
-        preference.setSummary(R.string.summary_compound_button_preference);
-        mActivity.addPreference(preference);
-
-        // Scroll until list preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("radio_button"));
-
-        // Check title and summary are displayed as expected.
-        onView(withIndex(withId(android.R.id.title), 0)).check(matches(
-                withText(mActivity.getString(R.string.title_radio_button_preference))));
-        onView(withIndex(withId(android.R.id.summary), 0)).check(matches(
-                withText(mActivity.getString(R.string.summary_compound_button_preference))));
-
-        // Ensure radio button preference is initially not selected.
-        onView(withId(R.id.radio_button)).check(matches(isNotChecked()));
-
-        Preference.OnPreferenceChangeListener mockListener = mock(
-                Preference.OnPreferenceChangeListener.class);
-        when(mockListener.onPreferenceChange(any(), any())).thenReturn(true);
-        mActivity.setOnPreferenceChangeListener("radio_button", mockListener);
-
-        // Select radio button preference.
-        onView(withText(R.string.title_radio_button_preference)).perform(click());
-
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(true));
-
-        // Verify radio button preference correctly indicates preference is selected.
-        onView(withId(R.id.radio_button)).check(matches(isChecked()));
-
-        // Un-select radio button preference.
-        onView(withText(R.string.title_radio_button_preference)).perform(click());
-
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(false));
-
-        // Verify radio button preference correctly indicates preference is selected.
-        onView(withId(R.id.radio_button)).check(matches(isNotChecked()));
-    }
-
-    @Test
-    public void testRadioPreference_uxRestricted() {
-        // Create radio button preference and add it to screen.
-        CarUiRadioButtonPreference preference = new CarUiRadioButtonPreference(mActivity);
-        preference.setOrder(0);
-        preference.setKey("radio_button");
-        preference.setTitle(R.string.title_radio_button_preference);
-        preference.setSummary(R.string.summary_compound_button_preference);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until radio button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("radio_button"));
-
-        // Check title and summary are displayed as expected.
-        onView(withIndex(withId(android.R.id.title), 0)).check(matches(
-                withText(mActivity.getString(R.string.title_radio_button_preference))));
-        onView(withIndex(withId(android.R.id.summary), 0)).check(matches(
-                withText(mActivity.getString(R.string.summary_compound_button_preference))));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> clickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(clickListener);
-        assertEquals(clickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_radio_button_preference)).perform(click());
-        verify(clickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testDropDownPreference() {
-        // Create drop-down preference and add it to screen.
-        DropDownPreference preference = new CarUiDropDownPreference(mActivity);
-        preference.setKey("dropdown");
-        preference.setTitle(R.string.title_dropdown_preference);
-        preference.setEntries(mEntries);
-        preference.setEntryValues(mEntriesValues);
-        preference.setOrder(0);
-        mActivity.addPreference(preference);
-
-        // Display full screen list preference.
-        onView(withText(R.string.title_dropdown_preference)).perform(click());
-
-        Preference.OnPreferenceChangeListener mockListener = mock(
-                Preference.OnPreferenceChangeListener.class);
-        when(mockListener.onPreferenceChange(any(), any())).thenReturn(true);
-        mActivity.setOnPreferenceChangeListener("dropdown", mockListener);
-
-        // Check that first option is initially selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 0))
-                .check(matches(isChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isNotChecked()));
-
-        // Select third option.
-        onView(withText(mEntries[2])).perform(click());
-        // Check that first option is selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 0))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isChecked()));
-
-        // Press back to save selection.
-        onView(withContentDescription("Back")).perform(click());
-        // Verify preference value was updated.
-        verify(mockListener, times(1)).onPreferenceChange(any(), eq(mEntriesValues[2]));
-
-        onView(withText(R.string.title_dropdown_preference)).perform(click());
-
-        // Check that first option is selected.
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 0))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 1))
-                .check(matches(isNotChecked()));
-        onView(withIndex(withId(R.id.car_ui_list_item_radio_button_widget), 2))
-                .check(matches(isChecked()));
-    }
-
-    @Test
-    public void testDropDownPreference_uxRestricted() {
-        // Create drop-down preference and add it to screen.
-        CarUiDropDownPreference preference = new CarUiDropDownPreference(mActivity);
-        preference.setKey("dropdown");
-        preference.setTitle(R.string.title_dropdown_preference);
-        preference.setEntries(mEntries);
-        preference.setEntryValues(mEntriesValues);
-        preference.setOrder(0);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until drop-down preference button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("dropdown"));
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_dropdown_preference)).check(matches(isDisplayed()));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> clickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(clickListener);
-        assertEquals(clickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_dropdown_preference)).perform(click());
-        verify(clickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testTwoActionPreference() {
-        // Create CarUiTwoActionPreference preference and add it to screen.
-        CarUiTwoActionPreference preference = new CarUiTwoActionPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        preference.setWidgetLayoutResource(R.layout.details_preference_widget);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-
-        // Hide second action.
-        mActivity.runOnUiThread(() -> preference.showAction(false));
-
-        // Ensure second action isn't displayed.
-        onView(withIndex(withId(com.android.car.ui.R.id.action_widget_container), 0)).check(
-                matches(not(isDisplayed())));
-    }
-
-    @Test
-    public void testTwoActionPreference_uxRestricted() {
-        // Create CarUiTwoActionPreference preference and add it to screen.
-        CarUiTwoActionPreference preference = new CarUiTwoActionPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        preference.setWidgetLayoutResource(R.layout.details_preference_widget);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until CarUiTwoActionPreference preference button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("twoaction"));
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-        onView(withText(R.string.summary_twoaction_preference)).check(matches(isDisplayed()));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> clickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(clickListener);
-        assertEquals(clickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_twoaction_preference)).perform(click());
-        verify(clickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testTwoActionIconPreference() {
-        // Create CarUiTwoActionIconPreference preference and add it to screen.
-        CarUiTwoActionIconPreference preference = new CarUiTwoActionIconPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        preference.setSecondaryActionIcon(R.drawable.avd_show_password);
-        Runnable clickListener = mock(Runnable.class);
-        preference.setOnSecondaryActionClickListener(clickListener);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-        onView(withText(R.string.summary_twoaction_preference)).check(matches(isDisplayed()));
-
-        // Check that clicks on title doesn't fire icon listener
-        onView(withText(R.string.title_twoaction_preference)).perform(click());
-        verify(clickListener, times(0)).run();
-
-        // Click on icon.
-        onView(withIndex(withId(com.android.car.ui.R.id.car_ui_second_action_container),
-                0)).perform(click());
-        verify(clickListener, times(1)).run();
-    }
-
-    @Test
-    public void testTwoActionIconPreference_uxRestricted() {
-        // Create CarUiTwoActionIconPreference preference and add it to screen.
-        CarUiTwoActionIconPreference preference = new CarUiTwoActionIconPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        preference.setSecondaryActionIcon(R.drawable.avd_show_password);
-        Runnable clickListener = mock(Runnable.class);
-        preference.setOnSecondaryActionClickListener(clickListener);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until CarUiTwoActionIconPreference preference button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("twoaction"));
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-        onView(withText(R.string.summary_twoaction_preference)).check(matches(isDisplayed()));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> restrictedClickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(restrictedClickListener);
-        assertEquals(restrictedClickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_twoaction_preference)).perform(click());
-        verify(restrictedClickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testTwoActionTextPreference() {
-        // Create CarUiTwoActionTextPreference preference and add it to screen.
-        CarUiTwoActionTextPreference preference = new CarUiTwoActionTextPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        preference.setSecondaryActionText(R.string.twoaction_secondary_text);
-        Runnable clickListener = mock(Runnable.class);
-        preference.setOnSecondaryActionClickListener(clickListener);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-        onView(withText(R.string.summary_twoaction_preference)).check(matches(isDisplayed()));
-
-        // Check that clicks on title doesn't fire icon listener
-        onView(withText(R.string.title_twoaction_preference)).perform(click());
-        verify(clickListener, times(0)).run();
-
-        // Click on secondary text.
-        onView(withText(R.string.twoaction_secondary_text)).perform(click());
-        verify(clickListener, times(1)).run();
-
-        // Click on secondary text when disabled
-        mActivity.runOnUiThread(() -> preference.setSecondaryActionEnabled(false));
-        onView(withText(R.string.twoaction_secondary_text)).perform(click());
-        assertFalse(preference.isSecondaryActionEnabled());
-        verify(clickListener, times(1)).run();
-
-        // Make secondary text not visible
-        mActivity.runOnUiThread(() -> preference.setSecondaryActionVisible(false));
-        onView(withText(R.string.twoaction_secondary_text)).check(matches(not(isDisplayed())));
-        assertFalse(preference.isSecondaryActionVisible());
-
-        // Use performSecondaryActionClick()
-        mActivity.runOnUiThread(() -> {
-            preference.setSecondaryActionVisible(true);
-            preference.setSecondaryActionEnabled(true);
-        });
-        onView(withText(R.string.twoaction_secondary_text)).check(matches(isDisplayed()));
-        preference.performSecondaryActionClick();
-        verify(clickListener, times(2)).run();
-    }
-
-    @Test
-    public void testTwoActionTextPreference_uxRestricted() {
-        // Create CarUiTwoActionTextPreference preference and add it to screen.
-        CarUiTwoActionTextPreference preference = new CarUiTwoActionTextPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        preference.setSecondaryActionText(R.string.twoaction_secondary_text);
-        Runnable clickListener = mock(Runnable.class);
-        preference.setOnSecondaryActionClickListener(clickListener);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until CarUiTwoActionTextPreference preference button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("twoaction"));
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-        onView(withText(R.string.summary_twoaction_preference)).check(matches(isDisplayed()));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> restrictedClickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(restrictedClickListener);
-        assertEquals(restrictedClickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_twoaction_preference)).perform(click());
-        verify(restrictedClickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testTwoActionSwitchPreference() {
-        // Create CarUiTwoActionSwitchPreference preference and add it to screen.
-        CarUiTwoActionSwitchPreference preference = new CarUiTwoActionSwitchPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        Consumer<Boolean> clickListener = mock(Consumer.class);
-        preference.setOnSecondaryActionClickListener(clickListener);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-        onView(withText(R.string.summary_twoaction_preference)).check(matches(isDisplayed()));
-
-        // Check that clicks on title doesn't fire icon listener
-        onView(withText(R.string.title_twoaction_preference)).perform(click());
-        verify(clickListener, times(0)).accept(anyBoolean());
-
-        // Click on switch.
-        onView(withIndex(withId(com.android.car.ui.R.id.car_ui_second_action_container),
-                0)).perform(click());
-        verify(clickListener, times(1)).accept(true);
-    }
-
-    @Test
-    public void testTwoActionSwitchPreference_uxRestricted() {
-        // Create CarUiTwoActionSwitchPreference preference and add it to screen.
-        CarUiTwoActionSwitchPreference preference = new CarUiTwoActionSwitchPreference(mActivity);
-        preference.setKey("twoaction");
-        preference.setTitle(R.string.title_twoaction_preference);
-        preference.setSummary(R.string.summary_twoaction_preference);
-        preference.setOrder(0);
-        Consumer<Boolean> clickListener = mock(Consumer.class);
-        preference.setOnSecondaryActionClickListener(clickListener);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until CarUiTwoActionSwitchPreference preference button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("twoaction"));
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_twoaction_preference)).check(matches(isDisplayed()));
-        onView(withText(R.string.summary_twoaction_preference)).check(matches(isDisplayed()));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> restrictedClickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(restrictedClickListener);
-        assertEquals(restrictedClickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_twoaction_preference)).perform(click());
-        verify(restrictedClickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testEditTextPreference() {
-        // Create CarUiEditTextPreference preference and add it to screen.
-        CarUiEditTextPreference preference = new CarUiEditTextPreference(mActivity);
-        preference.setKey("editText");
-        preference.setTitle(R.string.title_edit_text_preference);
-        preference.setOrder(0);
-        String positiveButtonText = "Ok";
-        preference.setPositiveButtonText(positiveButtonText);
-        preference.setDialogTitle(R.string.dialog_title_edit_text_preference);
-        preference.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());
-        preference.setDialogIcon(R.drawable.avd_hide_password);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_edit_text_preference)).check(matches(isDisplayed()));
-
-        // Click on preference
-        onView(withText(R.string.title_edit_text_preference)).perform(click());
-        onView(withText(R.string.dialog_title_edit_text_preference)).check(matches(isDisplayed()));
-
-        // Enter value
-        String value = "test value";
-        onView(withId(android.R.id.edit)).perform(typeText(value));
-        onView(withText(positiveButtonText)).perform(click());
-
-        // Confirm value updated by simple summary provider
-        onView(withText(value)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testEditTextPreference_uxRestricted() {
-        // Create CarUiEditTextPreference preference and add it to screen.
-        CarUiEditTextPreference preference = new CarUiEditTextPreference(mActivity);
-        preference.setKey("editText");
-        preference.setTitle(R.string.title_edit_text_preference);
-        preference.setOrder(0);
-        preference.setDialogTitle(R.string.dialog_title_edit_text_preference);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until CarUiEditTextPreference preference button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("editText"));
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_edit_text_preference)).check(matches(isDisplayed()));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> restrictedClickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(restrictedClickListener);
-        assertEquals(restrictedClickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_edit_text_preference)).perform(click());
-        verify(restrictedClickListener, times(1)).accept(preference);
-    }
-
-    @Test
-    public void testSeekBarPreference() {
-        // Create CarUiSeekBarDialogPreference preference and add it to screen.
-        CarUiSeekBarDialogPreference preference = new CarUiSeekBarDialogPreference(mActivity);
-        preference.setKey("seek_bar");
-        preference.setTitle(R.string.title_seek_bar_preference);
-        preference.setOrder(0);
-        String positiveButtonText = "Ok";
-        preference.setPositiveButtonText(positiveButtonText);
-        String negativeButtonText = "Cancel";
-        preference.setNegativeButtonText(negativeButtonText);
-        preference.setDialogTitle(R.string.dialog_title_seek_bar_preference);
-        preference.setMaxProgress(20);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_seek_bar_preference)).check(matches(isDisplayed()));
-
-        // Click on preference
-        onView(withText(R.string.title_seek_bar_preference)).perform(click());
-        onView(withText(R.string.dialog_title_seek_bar_preference)).check(matches(isDisplayed()));
-        onView(withText(positiveButtonText)).check(matches(isDisplayed()));
-        onView(withText(negativeButtonText)).check(matches(isDisplayed()));
-
-        // Confirm progress is set to 0
-        assertEquals(0, preference.getProgress());
-        assertEquals(20, preference.getMaxProgress());
-
-        // Set progress
-        int progress = 10;
-        onView(withId(R.id.seek_bar)).perform(setProgress(progress));
-        assertEquals(progress, preference.getProgress());
-    }
-
-    @Test
-    public void testSeekBarPreference_clickOk_valueSaved() {
-        // Create CarUiSeekBarDialogPreference preference and add it to screen.
-        CarUiSeekBarDialogPreference preference = new CarUiSeekBarDialogPreference(mActivity);
-        preference.setKey("seek_bar");
-        preference.setTitle(R.string.title_seek_bar_preference);
-        preference.setOrder(0);
-        String positiveButtonText = "Ok";
-        preference.setPositiveButtonText(positiveButtonText);
-        String negativeButtonText = "Cancel";
-        preference.setNegativeButtonText(negativeButtonText);
-        preference.setDialogTitle(R.string.dialog_title_seek_bar_preference);
-        preference.setMaxProgress(20);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_seek_bar_preference)).check(matches(isDisplayed()));
-
-        // Click on preference, set progress, then hit ok
-        onView(withText(R.string.title_seek_bar_preference)).perform(click());
-        onView(withId(R.id.seek_bar)).perform(setProgress(10));
-        onView(withText(positiveButtonText)).perform(click());
-        onView(withText(R.string.dialog_title_seek_bar_preference)).check(doesNotExist());
-
-        // Confirm progress is set to 0
-        assertEquals(10, preference.getProgress());
-        assertEquals(20, preference.getMaxProgress());
-    }
-
-    @Test
-    public void testSeekBarPreference_clickCancel_valueNotSaved() {
-        // Create CarUiSeekBarDialogPreference preference and add it to screen.
-        CarUiSeekBarDialogPreference preference = new CarUiSeekBarDialogPreference(mActivity);
-        preference.setKey("seek_bar");
-        preference.setTitle(R.string.title_seek_bar_preference);
-        preference.setOrder(0);
-        String positiveButtonText = "Ok";
-        preference.setPositiveButtonText(positiveButtonText);
-        String negativeButtonText = "Cancel";
-        preference.setNegativeButtonText(negativeButtonText);
-        preference.setDialogTitle(R.string.dialog_title_seek_bar_preference);
-        preference.setMaxProgress(20);
-        mActivity.addPreference(preference);
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_seek_bar_preference)).check(matches(isDisplayed()));
-
-        // Click on preference, set progress, then hit cancel
-        onView(withText(R.string.title_seek_bar_preference)).perform(click());
-        onView(withId(R.id.seek_bar)).perform(setProgress(10));
-        onView(withText(negativeButtonText)).perform(click());
-        onView(withText(R.string.dialog_title_seek_bar_preference)).check(doesNotExist());
-
-        // Confirm progress is set to 0
-        assertEquals(0, preference.getProgress());
-        assertEquals(20, preference.getMaxProgress());
-    }
-
-    @Test
-    public void test_defaultDialogFragmentCallbacks_doNothing() {
-        DialogFragmentCallbacks callbacks = new DialogFragmentCallbacks() {
-        };
-
-        callbacks.onBindDialogView(new View(mActivity));
-        callbacks.onClick(new DialogInterface() {
-            @Override
-            public void cancel() {
-            }
-
-            @Override
-            public void dismiss() {
-            }
-        }, 0);
-        callbacks.onDialogClosed(true);
-        callbacks.onPrepareDialogBuilder(new AlertDialog.Builder(mActivity));
-    }
-
-    @Test
-    public void testSeekBarPreference_uxRestricted() {
-        // Create CarUiSeekBarDialogPreference preference and add it to screen.
-        CarUiSeekBarDialogPreference preference = new CarUiSeekBarDialogPreference(mActivity);
-        preference.setKey("seek_bar");
-        preference.setTitle(R.string.title_seek_bar_preference);
-        preference.setOrder(0);
-        preference.setPositiveButtonText("Ok");
-        preference.setNegativeButtonText("Cancel");
-        preference.setDialogTitle(R.string.dialog_title_seek_bar_preference);
-        preference.setMaxProgress(20);
-        preference.setUxRestricted(true);
-        mActivity.addPreference(preference);
-
-        // Scroll until CarUiEditTextPreference preference button preference is visible
-        mActivity.runOnUiThread(() -> mActivity.scrollToPreference("seek_bar"));
-
-        // Check title is displayed as expected.
-        onView(withText(R.string.title_seek_bar_preference)).check(matches(isDisplayed()));
-
-        assertTrue(preference.isUxRestricted());
-
-        // Set listener
-        Consumer<Preference> restrictedClickListener = mock(Consumer.class);
-        preference.setOnClickWhileRestrictedListener(restrictedClickListener);
-        assertEquals(restrictedClickListener, preference.getOnClickWhileRestrictedListener());
-
-        // Click on ux restricted preference
-        onView(withText(R.string.title_seek_bar_preference)).perform(click());
-        verify(restrictedClickListener, times(1)).accept(preference);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTestActivity.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTestActivity.java
deleted file mode 100644
index ae7d7ab..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTestActivity.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.os.Bundle;
-
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.preference.Preference;
-
-public class PreferenceTestActivity extends AppCompatActivity {
-
-    private PreferenceTestFragment mPreferenceFragment;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Display the fragment as the main content.
-        if (savedInstanceState == null) {
-            mPreferenceFragment = new PreferenceTestFragment();
-
-            getSupportFragmentManager()
-                    .beginTransaction()
-                    .replace(android.R.id.content, mPreferenceFragment)
-                    .commitNow();
-        }
-    }
-
-    public void setOnPreferenceChangeListener(
-            String key, Preference.OnPreferenceChangeListener listener) {
-        mPreferenceFragment.setOnPreferenceChangeListener(key, listener);
-    }
-
-    public void scrollToPreference(String key) {
-        mPreferenceFragment.scrollToPreference(key);
-    }
-
-    public void addPreference(Preference preference) {
-        mPreferenceFragment.addPreference(preference);
-    }
-
-    public Preference findPreference(CharSequence key) {
-        return mPreferenceFragment.findPreference(key);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTestFragment.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTestFragment.java
deleted file mode 100644
index 631911d..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/PreferenceTestFragment.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.os.Bundle;
-
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceDataStore;
-
-import com.android.car.ui.test.R;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Test Fragment to load test preferences.
- */
-public class PreferenceTestFragment extends PreferenceFragment {
-
-    @Override
-    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        getPreferenceManager().setPreferenceDataStore(new TestDataStore());
-        // Load the preferences from an XML resource
-        setPreferencesFromResource(R.xml.test_preferences, rootKey);
-    }
-
-    public void setOnPreferenceChangeListener(
-            String key, Preference.OnPreferenceChangeListener listener) {
-        findPreference(key).setOnPreferenceChangeListener(listener);
-    }
-
-    public void addPreference(Preference preference) {
-        getPreferenceManager().getPreferenceScreen().addPreference(preference);
-    }
-
-    /**
-     * Custom data store to be used for testing as SharedPreferences for instrumentation tests
-     * are not initialized as expected.
-     */
-    public static class TestDataStore extends PreferenceDataStore {
-
-        private final Map<String, Integer> mIntStore = new HashMap<>();
-        private final Map<String, String> mStringStore = new HashMap<>();
-        private final Map<String, Boolean> mBooleanStore = new HashMap<>();
-        private final Map<String, Set<String>> mStringSetStore = new HashMap<>();
-
-        @Override
-        public void putString(String key, @Nullable String value) {
-            mStringStore.put(key, value);
-        }
-
-        @Override
-        public void putStringSet(String key, @Nullable Set<String> values) {
-            mStringSetStore.put(key, values);
-        }
-
-        @Override
-        @Nullable
-        public String getString(String key, @Nullable String defValue) {
-            return mStringStore.getOrDefault(key, defValue);
-        }
-
-        @Override
-        @Nullable
-        public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
-            // Workaround for NullPointerException caused by null string set from custom data store.
-            if (defValues == null) {
-                defValues = new HashSet<>();
-            }
-            return mStringSetStore.getOrDefault(key, defValues);
-        }
-
-        @Override
-        public void putBoolean(String key, boolean value) {
-            mBooleanStore.put(key, value);
-        }
-
-        @Override
-        public boolean getBoolean(String key, boolean defValue) {
-            return mBooleanStore.getOrDefault(key, defValue);
-        }
-
-        @Override
-        public void putInt(String key, int value) {
-            mIntStore.put(key, value);
-        }
-
-        @Override
-        public int getInt(String key, int defValue) {
-            return mIntStore.getOrDefault(key, defValue);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiListItemTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiListItemTest.java
deleted file mode 100644
index aa69a26..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiListItemTest.java
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
-import static androidx.test.espresso.matcher.ViewMatchers.isNotChecked;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.matchers.ViewMatchers.isActivated;
-
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.ForegroundColorSpan;
-import android.widget.TextView;
-
-import androidx.core.content.ContextCompat;
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.CarUiText;
-import com.android.car.ui.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link CarUiListItem}.
- */
-public class CarUiListItemTest {
-    private static final CharSequence LONG_CHAR_SEQUENCE =
-            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "
-                    + "incididunt ut labore et dolore magna aliqua. Netus et malesuada fames ac "
-                    + "turpis egestas maecenas pharetra convallis. At urna condimentum mattis "
-                    + "pellentesque id nibh tortor. Purus in mollis nunc sed id semper risus in. "
-                    + "Turpis massa tincidunt dui ut ornare lectus sit amet. Porttitor lacus "
-                    + "luctus accumsan tortor posuere ac. Augue eget arcu dictum varius. Massa "
-                    + "tempor nec feugiat nisl pretium fusce id velit ut. Fames ac turpis egestas"
-                    + " sed tempus urna et pharetra pharetra. Tellus orci ac auctor augue mauris "
-                    + "augue neque gravida. Purus viverra accumsan in nisl nisi scelerisque eu. "
-                    + "Ut lectus arcu bibendum at varius vel pharetra. Penatibus et magnis dis "
-                    + "parturient montes nascetur ridiculus mus. Suspendisse sed nisi lacus sed "
-                    + "viverra tellus in hac habitasse.";
-    private static final String ELLIPSIS = "…";
-
-    private CarUiRecyclerView mCarUiRecyclerView;
-
-    @Rule
-    public ActivityScenarioRule<CarUiRecyclerViewTestActivity> mActivityRule =
-            new ActivityScenarioRule<>(CarUiRecyclerViewTestActivity.class);
-
-    private ActivityScenario<CarUiRecyclerViewTestActivity> mScenario;
-
-    private CarUiRecyclerViewTestActivity mActivity;
-
-    @Before
-    public void setUp() {
-        mScenario = mActivityRule.getScenario();
-        mScenario.onActivity(activity -> {
-            mActivity = activity;
-            mCarUiRecyclerView = mActivity.requireViewById(R.id.list);
-        });
-    }
-
-    @Test
-    public void testItemVisibility_withTitle() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle("Test title");
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_list_item_icon_container)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_list_item_action_container)).check(matches(not(isDisplayed())));
-    }
-
-    @Test
-    public void testItemVisibility_withBody() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody("Test body");
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(isEnabled()));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(not(isActivated())));
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_list_item_icon_container)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_list_item_action_container)).check(matches(not(isDisplayed())));
-    }
-
-    @Test
-    public void testHeaderItemVisibility() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CharSequence title = "Test title";
-        CharSequence body = "Test body";
-        CarUiListItem item = new CarUiHeaderListItem(title, body);
-        items.add(item);
-
-        CharSequence title2 = "Test title2";
-        item = new CarUiHeaderListItem(title2);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withText(title.toString())).check(matches(isDisplayed()));
-        onView(withText(body.toString())).check(matches(isDisplayed()));
-        onView(withText(title2.toString())).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testItemDisabled() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody("Item that is disabled");
-        item.setEnabled(false);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(not(isEnabled())));
-    }
-
-    @Test
-    public void testItemActivated() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody("Item that is disabled");
-        item.setActivated(true);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(isActivated()));
-    }
-
-    @Test
-    public void testItemVisibility_withChevron() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.CHEVRON);
-        item.setTitle("Test item with chevron");
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_list_item_icon_container)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_list_item_action_container)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testItemVisibility_withTitle_withBodyAndIcon() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle("Test title");
-        item.setBody("Test body");
-        item.setIcon(mActivity.getDrawable(R.drawable.car_ui_icon_close));
-        item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_icon_container)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_action_container)).check(matches(not(isDisplayed())));
-    }
-
-    @Test
-    public void testItem_withCheckbox() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem.OnCheckedChangeListener mockOnCheckedChangeListener = mock(
-                CarUiContentListItem.OnCheckedChangeListener.class);
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
-        item.setTitle("Test item with checkbox");
-        item.setOnCheckedChangeListener(mockOnCheckedChangeListener);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_action_divider)).check(matches(not(isDisplayed())));
-
-        // List item with checkbox should be initially unchecked.
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isNotChecked()));
-        // Clicks anywhere on the item should toggle the checkbox
-        onView(withId(R.id.car_ui_list_item_title)).perform(click());
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isChecked()));
-        // Check that onCheckChangedListener was invoked.
-        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, true);
-
-        // Uncheck checkbox with click on the action container
-        onView(withId(R.id.car_ui_list_item_action_container)).perform(click());
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isNotChecked()));
-        // Check that onCheckChangedListener was invoked.
-        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, false);
-    }
-
-    @Test
-    public void testItem_withCheckboxListItem() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem.OnCheckedChangeListener mockOnCheckedChangeListener = mock(
-                CarUiContentListItem.OnCheckedChangeListener.class);
-
-        CarUiContentListItem item = new CarUiCheckBoxListItem();
-        item.setTitle("Test item with checkbox");
-        item.setOnCheckedChangeListener(mockOnCheckedChangeListener);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_action_divider)).check(matches(not(isDisplayed())));
-
-        // List item with checkbox should be initially unchecked.
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isNotChecked()));
-        // Clicks anywhere on the item should toggle the checkbox
-        onView(withId(R.id.car_ui_list_item_title)).perform(click());
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isChecked()));
-        // Check that onCheckChangedListener was invoked.
-        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, true);
-
-        // Uncheck checkbox with click on the action container
-        onView(withId(R.id.car_ui_list_item_action_container)).perform(click());
-        onView(withId(R.id.car_ui_list_item_checkbox_widget)).check(matches(isNotChecked()));
-        // Check that onCheckChangedListener was invoked.
-        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, false);
-    }
-
-    @Test
-    public void testItem_withSwitch() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
-        item.setBody("Test item with switch");
-        item.setChecked(true);
-        item.setActionDividerVisible(true);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_switch_widget)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_action_divider)).check(matches(isDisplayed()));
-
-        // List item with checkbox should be initially checked.
-        onView(withId(R.id.car_ui_list_item_switch_widget)).check(matches(isChecked()));
-        // Clicks anywhere on the item should toggle the switch
-        onView(withId(R.id.car_ui_list_item_switch_widget)).perform(click());
-        onView(withId(R.id.car_ui_list_item_switch_widget)).check(matches(isNotChecked()));
-        // Uncheck checkbox with click on the action container
-        onView(withId(R.id.car_ui_list_item_body)).perform(click());
-        onView(withId(R.id.car_ui_list_item_switch_widget)).check(matches(isChecked()));
-    }
-
-    @Test
-    public void testItem_withRadioButton() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(
-                CarUiContentListItem.Action.RADIO_BUTTON);
-        item.setTitle("Test item with radio button");
-        item.setChecked(false);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_radio_button_widget)).check(matches(isDisplayed()));
-
-        // List item with checkbox should be initially not checked.
-        onView(withId(R.id.car_ui_list_item_radio_button_widget)).check(matches(isNotChecked()));
-        // Clicks anywhere on the item should toggle the radio button.
-        onView(withId(R.id.car_ui_list_item_radio_button_widget)).perform(click());
-        onView(withId(R.id.car_ui_list_item_radio_button_widget)).check(matches(isChecked()));
-
-        // Repeated clicks on a selected radio button should not toggle the element once checked.
-        onView(withId(R.id.car_ui_list_item_title)).perform(click());
-        onView(withId(R.id.car_ui_list_item_radio_button_widget)).check(matches(isChecked()));
-    }
-
-
-    @Test
-    public void testItem_withCompactLayout() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem item = new CarUiContentListItem(
-                CarUiContentListItem.Action.NONE);
-        String titleText = "Item with compact layout";
-        item.setTitle(titleText);
-        String bodyText = "Test body text";
-        item.setBody(bodyText);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items, true)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(withText(titleText)));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(withText(bodyText)));
-    }
-
-    @Test
-    public void testItem_withListener() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem.OnClickListener mockOnCheckedChangeListener = mock(
-                CarUiContentListItem.OnClickListener.class);
-
-        CarUiContentListItem item = new CarUiContentListItem(
-                CarUiContentListItem.Action.NONE);
-        item.setIcon(mActivity.getDrawable(R.drawable.car_ui_icon_close));
-        item.setPrimaryIconType(CarUiContentListItem.IconType.AVATAR);
-        item.setTitle("Test item with listener");
-        item.setBody("Body text");
-        item.setOnItemClickedListener(mockOnCheckedChangeListener);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-
-        // Clicks anywhere on the item should toggle the listener
-        onView(withId(R.id.car_ui_list_item_title)).perform(click());
-        verify(mockOnCheckedChangeListener, times(1)).onClick(item);
-
-        onView(withId(R.id.car_ui_list_item_body)).perform(click());
-        verify(mockOnCheckedChangeListener, times(2)).onClick(item);
-
-        onView(withId(R.id.car_ui_list_item_icon_container)).perform(click());
-        verify(mockOnCheckedChangeListener, times(3)).onClick(item);
-    }
-
-    @Test
-    public void testItem_withListenerAndSupplementalIconListener() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem.OnClickListener clickListener = mock(
-                CarUiContentListItem.OnClickListener.class);
-        CarUiContentListItem.OnClickListener supplementalIconClickListener = mock(
-                CarUiContentListItem.OnClickListener.class);
-
-        CarUiContentListItem item = new CarUiContentListItem(
-                CarUiContentListItem.Action.ICON);
-        item.setTitle("Test item with two listeners");
-        item.setOnItemClickedListener(clickListener);
-        item.setSupplementalIcon(
-                mActivity.getDrawable(R.drawable.car_ui_icon_close),
-                supplementalIconClickListener);
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-
-        // Clicks anywhere on the item (except supplemental icon) should trigger the item click
-        // listener.
-        onView(withId(R.id.car_ui_list_item_title)).perform(click());
-        verify(clickListener, times(1)).onClick(item);
-        verify(supplementalIconClickListener, times(0)).onClick(item);
-
-        onView(withId(R.id.car_ui_list_item_supplemental_icon)).perform(click());
-        // Check that icon is argument for single call to click listener.
-        verify(supplementalIconClickListener, times(1)).onClick(item);
-
-        // Verify that the standard click listener wasn't also fired.
-        verify(clickListener, times(1)).onClick(item);
-    }
-
-    @Test
-    public void testItem_withSupplementalIcon() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem.OnClickListener mockedItemOnClickListener = mock(
-                CarUiContentListItem.OnClickListener.class);
-
-        CarUiContentListItem item = new CarUiContentListItem(
-                CarUiContentListItem.Action.ICON);
-        item.setSupplementalIcon(mActivity.getDrawable(R.drawable.car_ui_icon_close));
-        item.setOnItemClickedListener(mockedItemOnClickListener);
-        item.setTitle("Test item with listener");
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-
-        // Clicks anywhere on the icon should invoke listener.
-        onView(withId(R.id.car_ui_list_item_action_container)).perform(click());
-        verify(mockedItemOnClickListener, times(1)).onClick(item);
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void testNonIconItem_withSupplementalIcon() {
-        List<CarUiListItem> items = new ArrayList<>();
-        CarUiContentListItem item = new CarUiContentListItem(
-                CarUiContentListItem.Action.SWITCH);
-        item.setSupplementalIcon(mActivity.getDrawable(R.drawable.car_ui_icon_close));
-        item.setTitle("Test item with listener");
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-    }
-
-    @Test
-    public void testItem_withSupplementalIconAndIconOnClickListener() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiContentListItem.OnClickListener mockedItemOnClickListener = mock(
-                CarUiContentListItem.OnClickListener.class);
-        CarUiContentListItem.OnClickListener mockedIconListener = mock(
-                CarUiContentListItem.OnClickListener.class);
-
-        CarUiContentListItem item = new CarUiContentListItem(
-                CarUiContentListItem.Action.ICON);
-        item.setSupplementalIcon(
-                mActivity.getDrawable(R.drawable.car_ui_icon_close),
-                mockedIconListener);
-        item.setOnItemClickedListener(mockedItemOnClickListener);
-        item.setTitle("Test item with listeners");
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_title)).check(matches(isDisplayed()));
-
-        // Clicks anywhere on the item (outside of the icon) should only invoke the item click
-        // listener.
-        onView(withId(R.id.car_ui_list_item_title)).perform(click());
-        verify(mockedItemOnClickListener, times(1)).onClick(item);
-
-        // Clicks anywhere on the icon should invoke both listeners.
-        onView(withId(R.id.car_ui_list_item_action_container)).perform(click());
-        verify(mockedItemOnClickListener, times(1)).onClick(item);
-        verify(mockedIconListener, times(1)).onClick(item);
-    }
-
-    @Test
-    public void testRadioButtonListItemAdapter() {
-        List<CarUiRadioButtonListItem> items = new ArrayList<>();
-
-        CarUiRadioButtonListItem itemOne = new CarUiRadioButtonListItem();
-        String itemOneTitle = "Item 1";
-        itemOne.setTitle(itemOneTitle);
-        items.add(itemOne);
-
-        CarUiRadioButtonListItem itemTwo = new CarUiRadioButtonListItem();
-        String itemTwoTitle = "Item 2";
-        itemTwo.setTitle(itemTwoTitle);
-        items.add(itemTwo);
-
-        CarUiRadioButtonListItem itemThree = new CarUiRadioButtonListItem();
-        String itemThreeTitle = "Item 3";
-        itemThree.setTitle(itemThreeTitle);
-        items.add(itemThree);
-
-        CarUiRadioButtonListItemAdapter adapter = new CarUiRadioButtonListItemAdapter(items);
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(adapter));
-
-        onView(withText(itemOneTitle)).check(matches(isDisplayed()));
-        onView(withText(itemTwoTitle)).check(matches(isDisplayed()));
-        onView(withText(itemThreeTitle)).check(matches(isDisplayed()));
-
-        // All items are initially unchecked.
-        assertFalse(itemOne.isChecked());
-        assertFalse(itemTwo.isChecked());
-        assertFalse(itemThree.isChecked());
-        assertEquals(adapter.getSelectedItemPosition(), -1);
-
-        // Select first item.
-        onView(withText(itemOneTitle)).perform(click());
-        assertTrue(itemOne.isChecked());
-        assertFalse(itemTwo.isChecked());
-        assertFalse(itemThree.isChecked());
-        assertEquals(adapter.getSelectedItemPosition(), 0);
-
-        // Select second item.
-        onView(withText(itemTwoTitle)).perform(click());
-        assertFalse(itemOne.isChecked());
-        assertTrue(itemTwo.isChecked());
-        assertFalse(itemThree.isChecked());
-        assertEquals(adapter.getSelectedItemPosition(), 1);
-
-        // Select third item.
-        onView(withText(itemThreeTitle)).perform(click());
-        assertFalse(itemOne.isChecked());
-        assertFalse(itemTwo.isChecked());
-        assertTrue(itemThree.isChecked());
-        assertEquals(adapter.getSelectedItemPosition(), 2);
-    }
-
-    @Test
-    public void testRadioButtonListItemAdapter_itemInitiallyChecked() {
-        List<CarUiRadioButtonListItem> items = new ArrayList<>();
-
-        CarUiRadioButtonListItem itemOne = new CarUiRadioButtonListItem();
-        String itemOneTitle = "Item 1";
-        itemOne.setChecked(true);
-        itemOne.setTitle(itemOneTitle);
-        items.add(itemOne);
-
-        CarUiRadioButtonListItem itemTwo = new CarUiRadioButtonListItem();
-        String itemTwoTitle = "Item 2";
-        itemTwo.setTitle(itemTwoTitle);
-        items.add(itemTwo);
-
-        CarUiRadioButtonListItemAdapter adapter = new CarUiRadioButtonListItemAdapter(items);
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(adapter));
-
-        onView(withText(itemOneTitle)).check(matches(isDisplayed()));
-        onView(withText(itemTwoTitle)).check(matches(isDisplayed()));
-
-        // Item 1 is initially checked.
-        assertTrue(itemOne.isChecked());
-        assertFalse(itemTwo.isChecked());
-        assertEquals(adapter.getSelectedItemPosition(), 0);
-
-        // Select second item.
-        onView(withText(itemTwoTitle)).perform(click());
-        assertFalse(itemOne.isChecked());
-        assertTrue(itemTwo.isChecked());
-        assertEquals(adapter.getSelectedItemPosition(), 1);
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void testInvalidRadioButtonListItemAdapter() {
-        List<CarUiRadioButtonListItem> items = new ArrayList<>();
-
-        CarUiRadioButtonListItem itemOne = new CarUiRadioButtonListItem();
-        String itemOneTitle = "Item 1";
-        itemOne.setTitle(itemOneTitle);
-        itemOne.setChecked(true);
-        items.add(itemOne);
-
-        CarUiRadioButtonListItem itemTwo = new CarUiRadioButtonListItem();
-        String itemTwoTitle = "Item 2";
-        itemTwo.setTitle(itemTwoTitle);
-        itemTwo.setChecked(true);
-        items.add(itemTwo);
-
-        CarUiRadioButtonListItem itemThree = new CarUiRadioButtonListItem();
-        String itemThreeTitle = "Item 3";
-        itemThree.setTitle(itemThreeTitle);
-        items.add(itemThree);
-
-        CarUiRadioButtonListItemAdapter adapter = new CarUiRadioButtonListItemAdapter(items);
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(adapter));
-    }
-
-    @Test
-    public void testTextTruncation_twoShortLines() {
-        List<CarUiText> lines = new ArrayList<>();
-        lines.add(new CarUiText.Builder("Short text string").setMaxLines(2).build());
-        lines.add(new CarUiText.Builder("Second short string").setMaxLines(2).build());
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for no manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(not(withText(containsString(ELLIPSIS)))));
-    }
-
-    @Test
-    public void testTextTruncation_oneLongOneShort_withMaxLines() {
-        List<CarUiText> lines = new ArrayList<>();
-        lines.add(new CarUiText.Builder(LONG_CHAR_SEQUENCE).setMaxLines(2).build());
-        lines.add(new CarUiText.Builder("Second short string").setMaxLines(2).build());
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString(ELLIPSIS))));
-
-        TextView bodyTextView = mCarUiRecyclerView.requireViewById(R.id.car_ui_list_item_body);
-        assertEquals(3, bodyTextView.getLineCount());
-    }
-
-    @Test
-    public void testTextTruncation_oneLongOneShort_noMaxLines() {
-        List<CarUiText> lines = new ArrayList<>();
-        lines.add(new CarUiText.Builder(LONG_CHAR_SEQUENCE).setMaxLines(Integer.MAX_VALUE).build());
-        lines.add(new CarUiText.Builder("Second short string").setMaxLines(2).build());
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for no manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(not(withText(containsString(ELLIPSIS)))));
-    }
-
-    @Test
-    public void testTextTruncation_twoLong_withMaxLines() {
-        List<CarUiText> lines = new ArrayList<>();
-        lines.add(new CarUiText.Builder(LONG_CHAR_SEQUENCE).setMaxLines(3).build());
-        lines.add(new CarUiText.Builder(LONG_CHAR_SEQUENCE).setMaxLines(3).build());
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString(ELLIPSIS))));
-
-        TextView bodyTextView = mCarUiRecyclerView.requireViewById(R.id.car_ui_list_item_body);
-        assertEquals(6, bodyTextView.getLineCount());
-    }
-
-    @Test
-    public void testTitleTextTruncation_withMaxLines() {
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(new CarUiText.Builder(LONG_CHAR_SEQUENCE).setMaxLines(2).build());
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_title)).check(
-                matches(withText(containsString(ELLIPSIS))));
-
-        TextView bodyTextView = mCarUiRecyclerView.requireViewById(R.id.car_ui_list_item_title);
-        assertEquals(2, bodyTextView.getLineCount());
-    }
-
-    @Test
-    public void testTextTruncation_twoLong_differentMaxLines() {
-        List<CarUiText> lines = new ArrayList<>();
-        lines.add(new CarUiText(LONG_CHAR_SEQUENCE, 1));
-        lines.add(new CarUiText(LONG_CHAR_SEQUENCE, 4));
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString(ELLIPSIS))));
-
-        TextView bodyTextView = mCarUiRecyclerView.requireViewById(R.id.car_ui_list_item_body);
-        assertEquals(5, bodyTextView.getLineCount());
-    }
-
-    @Test
-    public void testMultipleBodyTextLines() {
-        CharSequence line1 = "First short string";
-        CharSequence line2 = "Second short string";
-        CharSequence line3 = "Third short string";
-
-        List<CarUiText> lines = new ArrayList<>();
-        lines.add(new CarUiText.Builder(line1).build());
-        lines.add(new CarUiText.Builder(line2).build());
-        lines.add(new CarUiText.Builder(line3).build());
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        String expectedText = line1 + "\n" + line2 + "\n" + line3;
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString(expectedText))));
-    }
-
-    @Test
-    public void testBodyTextSpans() {
-        int color = ContextCompat.getColor(mCarUiRecyclerView.getContext(),
-                R.color.car_ui_color_accent);
-
-        Spannable line1 = new SpannableString("This text contains color");
-        line1.setSpan(new ForegroundColorSpan(color), 19, 24, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-
-        List<CarUiText> lines = new ArrayList<>();
-        lines.add(new CarUiText(line1, Integer.MAX_VALUE));
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(isDisplayed()));
-        TextView bodyTextView = mCarUiRecyclerView.requireViewById(R.id.car_ui_list_item_body);
-        assertEquals(line1, bodyTextView.getText());
-    }
-
-    @Test
-    public void testTextWithLineBreak() {
-        List<CarUiText> lines = new ArrayList<>();
-        String firstTwoLines = "This is first line\nThis is the second line";
-        String thirdLine = "\nThis is the third line";
-        lines.add(new CarUiText(firstTwoLines + thirdLine, 2));
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(lines);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(withText(firstTwoLines)));
-        onView(withId(R.id.car_ui_list_item_body)).check(matches(not(withText(thirdLine))));
-    }
-
-    @Test
-    public void testTextVariants() {
-        List<CharSequence> variants = new ArrayList<>();
-        variants.add(LONG_CHAR_SEQUENCE);
-        variants.add("Short string");
-        CarUiText text = new CarUiText(variants, 1);
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(text);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for no manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(not(withText(containsString(ELLIPSIS)))));
-
-        TextView bodyTextView = mCarUiRecyclerView.requireViewById(R.id.car_ui_list_item_body);
-        assertEquals(1, bodyTextView.getLineCount());
-    }
-
-    @Test
-    public void testTextVariants_withCharLimit() {
-        List<CharSequence> variants = new ArrayList<>();
-        variants.add("Long string");
-        variants.add("Short");
-        CarUiText text = new CarUiText(variants, 1, 5);
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(text);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for no manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(not(withText(containsString(ELLIPSIS)))));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString("Short"))));
-    }
-
-    @Test
-    public void testTextVariants_withCharLimitNoMaxLines() {
-        List<CharSequence> variants = new ArrayList<>();
-        variants.add("Long string");
-        variants.add("Short");
-        CarUiText text = new CarUiText(variants, Integer.MAX_VALUE, 5);
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(text);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for no manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(not(withText(containsString(ELLIPSIS)))));
-
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString("Short"))));
-    }
-
-    @Test
-    public void testTextVariants_noFit() {
-        List<CharSequence> variants = new ArrayList<>();
-        String marker = "MARKING AS PREFERRED VARIANT";
-        variants.add(marker + LONG_CHAR_SEQUENCE);
-        variants.add(LONG_CHAR_SEQUENCE);
-        variants.add(LONG_CHAR_SEQUENCE);
-        CarUiText text = new CarUiText(variants, 2);
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(text);
-        List<CarUiListItem> items = new ArrayList<>();
-        items.add(item);
-
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
-
-        // Check for manual truncation ellipsis.
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString(ELLIPSIS))));
-
-        TextView bodyTextView = mCarUiRecyclerView.requireViewById(R.id.car_ui_list_item_body);
-        assertEquals(2, bodyTextView.getLineCount());
-
-        onView(withId(R.id.car_ui_list_item_body)).check(
-                matches(withText(containsString(marker))));
-    }
-
-    @Test()
-    public void testListItemAdapter_getCount() {
-        List<CarUiRadioButtonListItem> items = new ArrayList<>();
-
-        CarUiRadioButtonListItem itemOne = new CarUiRadioButtonListItem();
-        String itemOneTitle = "Item 1";
-        itemOne.setTitle(itemOneTitle);
-        items.add(itemOne);
-
-        CarUiRadioButtonListItem itemTwo = new CarUiRadioButtonListItem();
-        String itemTwoTitle = "Item 2";
-        itemTwo.setTitle(itemTwoTitle);
-        items.add(itemTwo);
-
-        CarUiRadioButtonListItem itemThree = new CarUiRadioButtonListItem();
-        String itemThreeTitle = "Item 3";
-        itemThree.setTitle(itemThreeTitle);
-        items.add(itemThree);
-
-        CarUiRadioButtonListItemAdapter adapter = new CarUiRadioButtonListItemAdapter(items);
-        mCarUiRecyclerView.post(
-                () -> mCarUiRecyclerView.setAdapter(adapter));
-
-        onView(withText(itemOneTitle)).check(matches(isDisplayed()));
-        onView(withText(itemTwoTitle)).check(matches(isDisplayed()));
-        onView(withText(itemThreeTitle)).check(matches(isDisplayed()));
-
-        assertEquals(adapter.getItemCount(), 3);
-
-        adapter.setMaxItems(2);
-
-        assertEquals(adapter.getItemCount(), 2);
-    }
-
-    @Test
-    public void testUnknownCarUiListItemType_throwsException() {
-        List<CarUiListItem> items = new ArrayList<>();
-
-        CarUiListItem item = new UnknownCarUiListItem();
-        items.add(item);
-
-        CarUiListItemAdapter adapter = new CarUiListItemAdapter(items);
-
-        assertThrows("Unknown view type.", IllegalStateException.class,
-                () -> adapter.getItemViewType(0));
-    }
-
-    private static class UnknownCarUiListItem extends CarUiListItem {}
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
deleted file mode 100644
index 215c043..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
+++ /dev/null
@@ -1,2160 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static android.car.drivingstate.CarUxRestrictions.UX_RESTRICTIONS_LIMIT_CONTENT;
-
-import static androidx.core.math.MathUtils.clamp;
-import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING;
-import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
-import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_SETTLING;
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.PositionAssertions.isBottomAlignedWith;
-import static androidx.test.espresso.assertion.PositionAssertions.isCompletelyAbove;
-import static androidx.test.espresso.assertion.PositionAssertions.isCompletelyRightOf;
-import static androidx.test.espresso.assertion.PositionAssertions.isLeftAlignedWith;
-import static androidx.test.espresso.assertion.PositionAssertions.isRightAlignedWith;
-import static androidx.test.espresso.assertion.PositionAssertions.isTopAlignedWith;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition;
-import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
-import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
-import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.actions.LowLevelActions.performDrag;
-import static com.android.car.ui.actions.LowLevelActions.pressAndHold;
-import static com.android.car.ui.actions.LowLevelActions.release;
-import static com.android.car.ui.actions.LowLevelActions.touchDownAndUp;
-import static com.android.car.ui.actions.ViewActions.waitForView;
-import static com.android.car.ui.recyclerview.CarUiRecyclerView.ItemCap.UNLIMITED;
-import static com.android.car.ui.utils.ViewUtils.setRotaryScrollEnabled;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.lessThan;
-import static org.hamcrest.Matchers.lessThanOrEqualTo;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import static java.lang.Math.max;
-
-import android.car.drivingstate.CarUxRestrictions;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.LinearSnapHelper;
-import androidx.recyclerview.widget.OrientationHelper;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.LayoutManager;
-import androidx.recyclerview.widget.RecyclerView.LayoutParams;
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.espresso.IdlingRegistry;
-import androidx.test.espresso.IdlingResource;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.TestActivity;
-import com.android.car.ui.recyclerview.decorations.grid.GridDividerItemDecoration;
-import com.android.car.ui.test.R;
-import com.android.car.ui.utils.CarUxRestrictionsUtil;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Unit tests for {@link CarUiRecyclerView}.
- */
-public class CarUiRecyclerViewTest {
-
-    @Rule
-    public ActivityScenarioRule<TestActivity> mActivityRule =
-            new ActivityScenarioRule<>(TestActivity.class);
-
-    ActivityScenario<TestActivity> mScenario;
-
-    private TestActivity mActivity;
-    private Context mTestableContext;
-    private Resources mTestableResources;
-
-    @Before
-    public void setUp() {
-        mScenario = mActivityRule.getScenario();
-        mScenario.onActivity(activity -> {
-            mActivity = activity;
-            mTestableContext = spy(mActivity);
-            mTestableResources = spy(mActivity.getResources());
-        });
-
-        when(mTestableContext.getResources()).thenReturn(mTestableResources);
-    }
-
-    @After
-    public void tearDown() {
-        for (IdlingResource idlingResource : IdlingRegistry.getInstance().getResources()) {
-            IdlingRegistry.getInstance().unregister(idlingResource);
-        }
-    }
-
-    @Test
-    public void testIsScrollbarPresent_scrollbarEnabled() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testIsScrollbarPresent_scrollbarDisabled() {
-        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(doesNotExist());
-    }
-
-    @Test
-    public void testPadding() {
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        int padding = 100;
-        carUiRecyclerView.setPadding(padding, 0, padding, 0);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        assertEquals(padding, carUiRecyclerView.getPaddingLeft());
-        assertEquals(padding, carUiRecyclerView.getPaddingRight());
-    }
-
-    @Test
-    public void testGridLayout() {
-        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
-                null, R.styleable.CarUiRecyclerView));
-
-        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
-                any(),
-                eq(R.styleable.CarUiRecyclerView),
-                anyInt(),
-                anyInt());
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_layoutStyle), anyInt()))
-                .thenReturn(CarUiRecyclerView.CarUiRecyclerViewLayout.GRID);
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_numOfColumns), anyInt()))
-                .thenReturn(3);
-
-        // Ensure the CarUiRecyclerViewLayout constant matches the styleable attribute enum value
-        assertEquals(CarUiRecyclerView.CarUiRecyclerViewLayout.GRID, 1);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(4);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof GridLayoutManager);
-
-        // Check that all items in the first row are top-aligned.
-        onView(withText(adapter.getItemText(0))).check(
-                isTopAlignedWith(withText(adapter.getItemText(1))));
-        onView(withText(adapter.getItemText(1))).check(
-                isTopAlignedWith(withText(adapter.getItemText(2))));
-
-        // Check that all items in the first row are bottom-aligned.
-        onView(withText(adapter.getItemText(0))).check(
-                isBottomAlignedWith(withText(adapter.getItemText(1))));
-        onView(withText(adapter.getItemText(1))).check(
-                isBottomAlignedWith(withText(adapter.getItemText(2))));
-
-        // Check that items in second row are rendered correctly below the first row.
-        onView(withText(adapter.getItemText(0))).check(
-                isCompletelyAbove(withText(adapter.getItemText(3))));
-        onView(withText(adapter.getItemText(0))).check(
-                isLeftAlignedWith(withText(adapter.getItemText(3))));
-        onView(withText(adapter.getItemText(0))).check(
-                isRightAlignedWith(withText(adapter.getItemText(3))));
-    }
-
-    @Test
-    public void testLinearLayout() {
-        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
-                null, R.styleable.CarUiRecyclerView));
-
-        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
-                any(),
-                eq(R.styleable.CarUiRecyclerView),
-                anyInt(),
-                anyInt());
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_layoutStyle), anyInt()))
-                .thenReturn(CarUiRecyclerView.CarUiRecyclerViewLayout.LINEAR);
-
-        // Ensure the CarUiRecyclerViewLayout constant matches the styleable attribute enum value
-        assertEquals(CarUiRecyclerView.CarUiRecyclerViewLayout.LINEAR, 0);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(4);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof LinearLayoutManager);
-
-        // Check that item views are laid out linearly.
-        onView(withText(adapter.getItemText(0))).check(
-                isCompletelyAbove(withText(adapter.getItemText(1))));
-        onView(withText(adapter.getItemText(1))).check(
-                isCompletelyAbove(withText(adapter.getItemText(2))));
-        onView(withText(adapter.getItemText(2))).check(
-                isCompletelyAbove(withText(adapter.getItemText(3))));
-    }
-
-    @Test
-    public void testLayoutManagerSetInXml() {
-        // Inflate activity where a LayoutManger is set for a CarUiRecyclerView through a
-        // styleable attribute.
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(
-                        R.layout.car_ui_recycler_view_layout_manager_xml_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(3);
-        mActivity.runOnUiThread(() -> {
-            setRotaryScrollEnabled(carUiRecyclerView, /* isVertical= */ true);
-            carUiRecyclerView.setAdapter(adapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-        });
-
-        // Check that items in are displayed.
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(1))).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(2))).check(matches(isDisplayed()));
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof GridLayoutManager);
-    }
-
-    @Test
-    public void testSetLayoutManager_shouldUpdateItemDecorations() {
-        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
-                null, R.styleable.CarUiRecyclerView));
-
-        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
-                any(),
-                eq(R.styleable.CarUiRecyclerView),
-                anyInt(),
-                anyInt());
-        when(typedArray.getBoolean(eq(R.styleable.CarUiRecyclerView_enableDivider), anyBoolean()))
-                .thenReturn(true);
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_layoutStyle), anyInt()))
-                .thenReturn(CarUiRecyclerView.CarUiRecyclerViewLayout.GRID);
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_numOfColumns), anyInt()))
-                .thenReturn(3);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(4);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof GridLayoutManager);
-        assertEquals(carUiRecyclerView.getItemDecorationCount(), 3);
-        assertTrue(carUiRecyclerView.getItemDecorationAt(0) instanceof GridDividerItemDecoration);
-
-        carUiRecyclerView.setLayoutManager(new LinearLayoutManager(mTestableContext));
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof LinearLayoutManager);
-        assertEquals(carUiRecyclerView.getItemDecorationCount(), 3);
-        assertFalse(carUiRecyclerView.getItemDecorationAt(0) instanceof GridDividerItemDecoration);
-    }
-
-    @Test
-    public void testVisibility_goneAtInflationWithChangeToVisible() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(
-                        R.layout.car_ui_recycler_view_gone_test_activity));
-
-        onView(withId(R.id.list)).check(matches(not(isDisplayed())));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(3);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(adapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-        });
-
-        // Check that items in are displayed.
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(1))).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(2))).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testVisibility_invisibleAtInflationWithChangeToVisible() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(
-                        R.layout.car_ui_recycler_view_invisible_test_activity));
-
-        onView(withId(R.id.list)).check(matches(not(isDisplayed())));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(3);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(adapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-        });
-
-        // Check that items in are displayed.
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(1))).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(2))).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testFirstItemAtTop_onInitialLoad() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(25);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LinearLayoutManager layoutManager =
-                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
-        assertEquals(layoutManager.findFirstVisibleItemPosition(), 0);
-    }
-
-    @Test
-    public void testPageUpAndDownMoveSameDistance() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-
-        // Can't use OrientationHelper here, because it returns 0 when calling getTotalSpace methods
-        // until LayoutManager's onLayoutComplete is called. In this case waiting until the first
-        // item of the list is displayed guarantees that OrientationHelper is initialized properly.
-        int totalSpace = carUiRecyclerView.getHeight()
-                - carUiRecyclerView.getPaddingTop()
-                - carUiRecyclerView.getPaddingBottom();
-        PerfectFitTestAdapter adapter = new PerfectFitTestAdapter(5, totalSpace);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LinearLayoutManager layoutManager =
-                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
-
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-        assertEquals(totalSpace, orientationHelper.getTotalSpace());
-
-        // Move down one page so there will be sufficient pages for up and downs.
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        int topPosition = layoutManager.findFirstVisibleItemPosition();
-
-        for (int i = 0; i < 3; i++) {
-            onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-            onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-        }
-
-        assertEquals(layoutManager.findFirstVisibleItemPosition(), topPosition);
-    }
-
-    @Test
-    public void testContinuousScroll() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(50);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LinearLayoutManager layoutManager =
-                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
-
-        // Press and hold the down button for 2 seconds to scroll the list to bottom.
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(pressAndHold());
-        onView(isRoot()).perform(waitForView(withText("Sample item #49"), 3000));
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(release());
-
-        assertEquals(layoutManager.findLastCompletelyVisibleItemPosition(), 49);
-    }
-
-    @Test
-    public void testAlphaJumpToMiddleForThumbWhenTrackClicked() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(50);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        View trackView = mActivity.requireViewById(R.id.car_ui_scrollbar_track);
-        // scroll to the middle
-        onView(withId(R.id.car_ui_scrollbar_track)).perform(
-                touchDownAndUp(0f, (trackView.getHeight() / 2f)));
-        onView(withText(adapter.getItemText(25))).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testAlphaJumpToEndAndStartForThumbWhenTrackClicked() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(50);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        View trackView = mActivity.requireViewById(R.id.car_ui_scrollbar_track);
-        View thumbView = mActivity.requireViewById(R.id.car_ui_scrollbar_thumb);
-        // scroll to the end
-        onView(withId(R.id.car_ui_scrollbar_track)).perform(
-                touchDownAndUp(0f, trackView.getHeight() - 1));
-        onView(withText(adapter.getItemText(49))).check(matches(isDisplayed()));
-
-        // scroll to the start
-        onView(withId(R.id.car_ui_scrollbar_track)).perform(
-                touchDownAndUp(0f, 1));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testThumbDragToCenter() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        TestAdapter adapter = new TestAdapter(50);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        View trackView = mActivity.requireViewById(R.id.car_ui_scrollbar_track);
-        View thumbView = mActivity.requireViewById(R.id.car_ui_scrollbar_thumb);
-        // if you drag too far in a single step you'll stop selecting the thumb view. Hence, drag
-        // 5 units at a time for 200 intervals and stop at the center of the track by limitY.
-
-        onView(withId(R.id.car_ui_scrollbar_track)).perform(
-                performDrag(0f, (thumbView.getHeight() / 2f), 0,
-                        5, 200, Float.MAX_VALUE,
-                        trackView.getHeight() / 2f));
-        onView(withText(adapter.getItemText(25))).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testPageUpButtonDisabledAtTop() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        //  50, because needs to be big enough to make sure content is scrollable.
-        TestAdapter adapter = new TestAdapter(50);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-
-        // Initially page_up button is disabled.
-        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(not(isEnabled())));
-
-        // Moving down, should enable the up bottom.
-        onView(withId(R.id.car_ui_scrollbar_page_down)).check(matches(isEnabled()));
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(isEnabled()));
-
-        // Move back up; this should disable the up button again.
-        onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click()).check(
-                matches(not(isEnabled())));
-    }
-
-    @Test
-    public void testPageUpScrollsWithoutSnap() {
-        RecyclerView.OnScrollListener scrollListener = mock(RecyclerView.OnScrollListener.class);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-
-        // Scroll down a few pages so that you can perform page up operations.
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        // Set a mocked scroll listener on the CarUiRecyclerView
-        carUiRecyclerView.addOnScrollListener(scrollListener);
-
-        onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-
-        // Verify that scroll operation only settles on the destination once. This means a single
-        // smooth scroll to the destination. If the scroll includes a secondary snap after an
-        // initial scroll, this callback will have more than one invocation.
-        verify(scrollListener, times(1)).onScrollStateChanged(carUiRecyclerView,
-                SCROLL_STATE_SETTLING);
-
-        onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-
-        // Make same verification as above for a second page up operation.
-        verify(scrollListener, times(2)).onScrollStateChanged(carUiRecyclerView,
-                SCROLL_STATE_SETTLING);
-    }
-
-    @Test
-    public void testPageDownScrollsWithoutSnap() {
-        RecyclerView.OnScrollListener scrollListener = mock(RecyclerView.OnScrollListener.class);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-
-        // Set a mocked scroll listener on the CarUiRecyclerView
-        carUiRecyclerView.addOnScrollListener(scrollListener);
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        // Verify that scroll operation only settles on the destination once. This means a single
-        // smooth scroll to the destination. If the scroll includes a secondary snap after an
-        // initial scroll, this callback will have more than one invocation.
-        verify(scrollListener, times(1)).onScrollStateChanged(carUiRecyclerView,
-                SCROLL_STATE_SETTLING);
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        // Make same verification as above for a second page down operation.
-        verify(scrollListener, times(2)).onScrollStateChanged(carUiRecyclerView,
-                SCROLL_STATE_SETTLING);
-    }
-
-    @Test
-    public void testPageDownScrollsOverLongItem() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        // Position the long item in the middle.
-        int longItemPosition = itemCount / 2;
-
-        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
-        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.TALL);
-        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-        int screenHeight = orientationHelper.getTotalSpace();
-        // Scroll to a position where long item is partially visible.
-        // Scrolling from top, scrollToPosition() aligns the pos-1 item to bottom.
-        onView(withId(R.id.list)).perform(scrollToPosition(longItemPosition - 1));
-        // Scroll by half the height of the screen so the long item is partially visible.
-        mActivity.runOnUiThread(() -> carUiRecyclerView.scrollBy(0, screenHeight / 2));
-        // This is needed to make sure scroll is finished before looking for the long item.
-        onView(withText(adapter.getItemText(longItemPosition - 1))).check(matches(isDisplayed()));
-
-        // Verify long item is partially shown.
-        View longItem = getLongItem(carUiRecyclerView);
-        assertThat(
-                orientationHelper.getDecoratedStart(longItem),
-                is(greaterThan(orientationHelper.getStartAfterPadding())));
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        // Verify long item is snapped to top.
-        assertThat(orientationHelper.getDecoratedStart(longItem),
-                is(equalTo(orientationHelper.getStartAfterPadding())));
-        assertThat(orientationHelper.getDecoratedEnd(longItem),
-                is(greaterThan(orientationHelper.getEndAfterPadding())));
-
-        // Set a limit to avoid test stuck in non-moving state.
-        while (orientationHelper.getDecoratedEnd(longItem)
-                > orientationHelper.getEndAfterPadding()) {
-            onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        }
-
-        // Verify long item end is aligned to bottom.
-        assertThat(orientationHelper.getDecoratedEnd(longItem),
-                is(equalTo(orientationHelper.getEndAfterPadding())));
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        // Verify that the long item is no longer visible; Should be on the next child
-        assertThat(
-                orientationHelper.getDecoratedStart(longItem),
-                is(lessThan(orientationHelper.getStartAfterPadding())));
-    }
-
-    @Test
-    public void testPageDownScrollsOverLongItemAtTheEnd() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        // Position the long item at the end.
-        int longItemPosition = itemCount - 1;
-
-        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
-        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.TALL);
-        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            // Setting top padding to any number greater than 0.
-            // Not having padding will make this test pass all the time.
-            // Also adding bottom padding to make sure the padding
-            // after the last content is considered in calculations.
-            carUiRecyclerView.setPadding(0, 1, 0, 1);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-
-        // 20 is just an arbitrary number to make sure we reach the end of the recyclerview.
-        for (int i = 0; i < 20; i++) {
-            onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        }
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).check(matches(not(isEnabled())));
-
-        View longItem = getLongItem(carUiRecyclerView);
-        // Making sure we've reached end of the recyclerview, after
-        // adding bottom padding
-        assertThat(orientationHelper.getDecoratedEnd(longItem),
-                is(equalTo(orientationHelper.getEndAfterPadding())));
-    }
-
-    @Test
-    public void testPageUpScrollsOverLongItem() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        // Position the long item in the middle.
-        int longItemPosition = itemCount / 2;
-
-        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
-        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.TALL);
-        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-
-        // Scroll to a position just below the long item.
-        onView(withId(R.id.list)).perform(scrollToPosition(longItemPosition + 1));
-
-        // Verify long item is off-screen.
-        View longItem = getLongItem(carUiRecyclerView);
-
-        assertThat(
-                orientationHelper.getDecoratedEnd(longItem),
-                is(lessThanOrEqualTo(orientationHelper.getEndAfterPadding())));
-
-        if (orientationHelper.getStartAfterPadding() - orientationHelper.getDecoratedStart(longItem)
-                < orientationHelper.getTotalSpace()) {
-            onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-            assertThat(orientationHelper.getDecoratedStart(longItem),
-                    is(greaterThanOrEqualTo(orientationHelper.getStartAfterPadding())));
-        } else {
-            int topBeforeClick = orientationHelper.getDecoratedStart(longItem);
-
-            onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-
-            // Verify we scrolled 1 screen
-            assertThat(orientationHelper.getStartAfterPadding() - topBeforeClick,
-                    is(equalTo(orientationHelper.getTotalSpace())));
-        }
-    }
-
-    @Test
-    public void testPageDownScrollsOverVeryLongItem() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        // Position the long item in the middle.
-        int longItemPosition = itemCount / 2;
-
-        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
-        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.EXTRA_TALL);
-        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-
-        int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
-        // Scroll to a position where long item is partially visible.
-        // Scrolling from top, scrollToPosition() aligns the pos-1 item to bottom.
-        onView(withId(R.id.list)).perform(scrollToPosition(longItemPosition - 1));
-        // Scroll by half the height of the screen so the long item is partially visible.
-        mActivity.runOnUiThread(() -> carUiRecyclerView.scrollBy(0, screenHeight / 2));
-
-        onView(withText(adapter.getItemText(longItemPosition))).check(matches(isDisplayed()));
-
-        // Verify long item is partially shown.
-        View longItem = getLongItem(carUiRecyclerView);
-        assertThat(
-                orientationHelper.getDecoratedStart(longItem),
-                is(greaterThan(orientationHelper.getStartAfterPadding())));
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        // Verify long item is snapped to top.
-        assertThat(orientationHelper.getDecoratedStart(longItem),
-                is(equalTo(orientationHelper.getStartAfterPadding())));
-        assertThat(orientationHelper.getDecoratedEnd(longItem),
-                is(greaterThan(orientationHelper.getEndAfterPadding())));
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        // Verify long item does not snap to bottom.
-        assertThat(orientationHelper.getDecoratedEnd(longItem),
-                not(equalTo(orientationHelper.getEndAfterPadding())));
-    }
-
-    @Test
-    public void testPageDownScrollsOverVeryLongItemAtTheEnd() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        // Position the long item at the end.
-        int longItemPosition = itemCount - 1;
-
-        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
-        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.EXTRA_TALL);
-        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            // Setting top padding to any number greater than 0.
-            // Not having padding will make this test pass all the time.
-            // Also adding bottom padding to make sure the padding
-            // after the last content is considered in calculations.
-            carUiRecyclerView.setPadding(0, 1, 0, 1);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-
-        // 20 is just an arbitrary number to make sure we reach the end of the recyclerview.
-        for (int i = 0; i < 20; i++) {
-            onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-        }
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).check(matches(not(isEnabled())));
-
-        View longItem = getLongItem(carUiRecyclerView);
-        // Making sure we've reached end of the recyclerview, after
-        // adding bottom padding
-        assertThat(orientationHelper.getDecoratedEnd(longItem),
-                is(equalTo(orientationHelper.getEndAfterPadding())));
-    }
-
-    @Test
-    public void testPageDownMaintainsMinimumScrollThumbTrackHeight() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 25000;
-        TestAdapter adapter = new TestAdapter(itemCount);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        mActivity.runOnUiThread(() -> carUiRecyclerView.requestLayout());
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        // Check that thumb track maintains minimum height
-        int minThumbViewHeight = mActivity.getResources()
-                .getDimensionPixelOffset(R.dimen.car_ui_scrollbar_min_thumb_height);
-        View thumbView = mActivity.requireViewById(R.id.car_ui_scrollbar_thumb);
-        assertThat(thumbView.getHeight(), is(equalTo(minThumbViewHeight)));
-    }
-
-    @Test
-    public void testSetPaddingToRecyclerViewContainerWithScrollbar() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
-
-        carUiRecyclerView.setPadding(10, 10, 10, 10);
-
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
-    }
-
-    @Test
-    public void testSetPaddingToRecyclerViewContainerWithoutScrollbar() {
-        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
-
-        carUiRecyclerView.setPadding(10, 10, 10, 10);
-
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(10)));
-    }
-
-    @Test
-    public void testSetPaddingRelativeToRecyclerViewContainerWithScrollbar() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
-
-        carUiRecyclerView.setPaddingRelative(10, 10, 10, 10);
-
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
-    }
-
-    @Test
-    public void testSetPaddingRelativeToRecyclerViewContainerWithoutScrollbar() {
-        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(0)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
-
-        carUiRecyclerView.setPaddingRelative(10, 10, 10, 10);
-
-        assertThat(carUiRecyclerView.getPaddingTop(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingStart(), is(equalTo(10)));
-        assertThat(carUiRecyclerView.getPaddingEnd(), is(equalTo(10)));
-    }
-
-    @Test
-    public void testSetAlphaToRecyclerViewWithoutScrollbar() {
-        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        assertThat(carUiRecyclerView.getAlpha(), is(equalTo(1.0f)));
-
-        carUiRecyclerView.setAlpha(0.5f);
-
-        assertThat(carUiRecyclerView.getAlpha(), is(equalTo(0.5f)));
-    }
-
-    @Test
-    public void testSetAlphaToRecyclerViewWithScrollbar() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(
-                        R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-
-        ViewGroup container = (ViewGroup) carUiRecyclerView.getParent().getParent();
-
-        assertThat(carUiRecyclerView.getAlpha(), is(equalTo(1.0f)));
-        assertThat(container.getAlpha(), is(equalTo(1.0f)));
-
-        carUiRecyclerView.setAlpha(0.5f);
-
-        assertThat(carUiRecyclerView.getAlpha(), is(equalTo(1.0f)));
-        assertThat(container.getAlpha(), is(equalTo(0.5f)));
-    }
-
-    @Test
-    public void testCallAnimateOnRecyclerViewWithScrollbar() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(matches(isDisplayed()));
-
-        ViewGroup recyclerViewContainer = (ViewGroup) carUiRecyclerView.getParent().getParent();
-
-        assertThat(carUiRecyclerView.animate(), is(equalTo(recyclerViewContainer.animate())));
-    }
-
-    @Test
-    public void testScrollbarVisibility_tooSmallHeight() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        // Set to anything less than 2 * (minTouchSize + margin)
-        // minTouchSize = R.dimen.car_ui_touch_target_size
-        // margin is button up top margin or button down bottom margin
-        int recyclerviewHeight = 1;
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(-1, recyclerviewHeight);
-            container.addView(carUiRecyclerView, lp);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(matches(not(isDisplayed())));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-        int screenHeight = orientationHelper.getTotalSpace();
-
-        assertEquals(recyclerviewHeight, screenHeight);
-    }
-
-    @Test
-    public void testScrollbarVisibility_justEnoughToShowOnlyButtons() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        // R.dimen.car_ui_touch_target_size
-        float minTouchSize = mTestableResources.getDimension(R.dimen.car_ui_touch_target_size);
-        // This value is hardcoded to 15dp in the layout.
-        int margin = (int) dpToPixel(mTestableContext, 15)
-                + (int) mTestableResources.getDimension(R.dimen.car_ui_scrollbar_separator_margin);
-        // Set to 2 * (minTouchSize + margin)
-        int recyclerviewHeight = 2 * (int) (minTouchSize + margin);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(-1, recyclerviewHeight);
-            container.addView(carUiRecyclerView, lp);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_scrollbar_thumb)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_scrollbar_track)).check(matches(not(isDisplayed())));
-        onView(withId(R.id.car_ui_scrollbar_page_down)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(isDisplayed()));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-        int screenHeight = orientationHelper.getTotalSpace();
-
-        assertEquals(recyclerviewHeight, screenHeight);
-    }
-
-    @Test
-    public void testScrollbarVisibility_enoughToShowEverything() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        int minTouchSize = (int) mTestableResources.getDimension(R.dimen.car_ui_touch_target_size);
-        int mScrollbarThumbMinHeight = (int) mTestableResources
-                .getDimension(R.dimen.car_ui_scrollbar_min_thumb_height);
-        // This value is hardcoded to 15dp in the layout.
-        int margin = (int) dpToPixel(mTestableContext, 15)
-                + (int) mTestableResources.getDimension(R.dimen.car_ui_scrollbar_separator_margin);
-        int trackMargin = 2 * (int) mTestableResources
-                .getDimension(R.dimen.car_ui_scrollbar_separator_margin);
-        // Set to anything greater or equal to
-        // 2 * minTouchSize + max(minTouchSize, mScrollbarThumbMinHeight) + 2 * margin
-        int recyclerviewHeight =
-                2 *  minTouchSize
-                + max(minTouchSize, mScrollbarThumbMinHeight)
-                + 2 * margin + trackMargin;
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        container.post(() -> {
-            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(-1, recyclerviewHeight);
-            container.addView(carUiRecyclerView, lp);
-            carUiRecyclerView.setAdapter(new TestAdapter(100));
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_scrollbar_thumb)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_scrollbar_track)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_scrollbar_page_down)).check(matches(isDisplayed()));
-        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(isDisplayed()));
-
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-        int screenHeight = orientationHelper.getTotalSpace();
-
-        assertEquals(recyclerviewHeight, screenHeight);
-    }
-
-    @Test
-    public void testDefaultSize_noScrollbar() {
-        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        int listId = View.generateViewId();
-        TestAdapter adapter = new TestAdapter(50);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setId(listId);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(doesNotExist());
-        onView(withText(adapter.getItemText(0))).check(isLeftAlignedWith(withId(listId)));
-        onView(withText(adapter.getItemText(0))).check(isRightAlignedWith(withId(listId)));
-    }
-
-    @Test
-    public void testLargeSize_withScrollbar() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
-                null, R.styleable.CarUiRecyclerView));
-
-        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
-                any(),
-                eq(R.styleable.CarUiRecyclerView),
-                anyInt(),
-                anyInt());
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_carUiSize),
-                anyInt())).thenReturn(2); // Large size
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        int listId = View.generateViewId();
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setId(listId);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(0))).check(
-                isCompletelyRightOf(withId(R.id.car_ui_scroll_bar)));
-        onView(withText(adapter.getItemText(0))).check(
-                matches(not(isRightAlignedWith(withId(listId)))));
-    }
-
-    @Test
-    public void testMediumSize_withScrollbar() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
-                null, R.styleable.CarUiRecyclerView));
-
-        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
-                any(),
-                eq(R.styleable.CarUiRecyclerView),
-                anyInt(),
-                anyInt());
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_carUiSize),
-                anyInt())).thenReturn(1); // Medium size
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        int listId = View.generateViewId();
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setId(listId);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(matches(isDisplayed()));
-        onView(withText(adapter.getItemText(0))).check(
-                isCompletelyRightOf(withId(R.id.car_ui_scroll_bar)));
-        onView(withText(adapter.getItemText(0))).check(isRightAlignedWith(withId(listId)));
-    }
-
-    @Test
-    public void testSmallSize_withScrollbar() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
-                null, R.styleable.CarUiRecyclerView));
-
-        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
-                any(),
-                eq(R.styleable.CarUiRecyclerView),
-                anyInt(),
-                anyInt());
-        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_carUiSize),
-                anyInt())).thenReturn(0); // Small size
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        int listId = View.generateViewId();
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setId(listId);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withId(R.id.car_ui_scroll_bar)).check(doesNotExist());
-        onView(withText(adapter.getItemText(0))).check(isLeftAlignedWith(withId(listId)));
-        onView(withText(adapter.getItemText(0))).check(isRightAlignedWith(withId(listId)));
-    }
-
-    @Test
-    public void testSameSizeItems_estimateNextPositionDiffForScrollDistance() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        TestAdapter adapter = new TestAdapter(itemCount);
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LayoutManager layoutManager = carUiRecyclerView.getLayoutManager();
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-
-        int firstViewHeight = layoutManager.getChildAt(0).getHeight();
-        int itemsToScroll = 10;
-        CarUiSnapHelper snapHelper  = new CarUiSnapHelper(mActivity);
-        // Get an estimate of how many items CarUiSnaphelpwer says we need to scroll. The scroll
-        // distance is set to 10 * height of the first item. Since all items have the items have
-        // the same height, we're expecting to get exactly 10 back from CarUiSnapHelper.
-        int estimate = snapHelper.estimateNextPositionDiffForScrollDistance(orientationHelper,
-                itemsToScroll * firstViewHeight);
-
-        assertEquals(estimate, itemsToScroll);
-    }
-
-    @Test
-    public void testSameSizeItems_estimateNextPositionDiffForScrollDistance_zeroDistance() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        TestAdapter adapter = new TestAdapter(itemCount);
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LayoutManager layoutManager = carUiRecyclerView.getLayoutManager();
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-
-        int firstViewHeight = layoutManager.getChildAt(0).getHeight();
-        // the scroll distance has to be less than half of the size of the first view so that
-        // recyclerview doesn't snap to the next view
-        int distantToScroll = (firstViewHeight / 2) - 1;
-        CarUiSnapHelper snapHelper  = new CarUiSnapHelper(mActivity);
-        int estimate = snapHelper.estimateNextPositionDiffForScrollDistance(orientationHelper,
-                distantToScroll);
-
-        assertEquals(estimate, 0);
-    }
-
-    @Test
-    public void testSameSizeItems_estimateNextPositionDiffForScrollDistance_zeroHeight() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 1;
-        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
-        heightOverrides.put(0, TestAdapter.ItemHeight.ZERO);
-        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withContentDescription("ZERO")).check(matches(isEnabled()));
-
-        LayoutManager layoutManager = carUiRecyclerView.getLayoutManager();
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-
-        // 10 is an arbitrary number
-        int distantToScroll = 10;
-        CarUiSnapHelper snapHelper  = new CarUiSnapHelper(mActivity);
-        int estimate = snapHelper.estimateNextPositionDiffForScrollDistance(orientationHelper,
-                distantToScroll);
-
-        assertEquals(estimate, 0);
-    }
-
-    @Test
-    public void testSameSizeItems_estimateNextPositionDiffForScrollDistance_zeroItems() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 0;
-        TestAdapter adapter = new TestAdapter(itemCount);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-
-        LayoutManager layoutManager = carUiRecyclerView.getLayoutManager();
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-        CarUiSnapHelper snapHelper  = new CarUiSnapHelper(mActivity);
-        int estimate = snapHelper.estimateNextPositionDiffForScrollDistance(orientationHelper, 50);
-
-        assertEquals(estimate, 50);
-    }
-
-    @Test
-    public void testEmptyList_calculateScrollDistanceClampToScreenSize() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        int itemCount = 0;
-        TestAdapter adapter = new TestAdapter(itemCount);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-
-        LayoutManager layoutManager = carUiRecyclerView.getLayoutManager();
-
-        LinearSnapHelper linearSnapHelper = new LinearSnapHelper();
-        carUiRecyclerView.setOnFlingListener(null);
-        linearSnapHelper.attachToRecyclerView(carUiRecyclerView);
-        // 200 is just an arbitrary number. the intent is to make sure the return value is smaller
-        // than the layoutmanager height.
-        int[] baseOutDist = linearSnapHelper.calculateScrollDistance(200, -200);
-
-        CarUiSnapHelper carUiSnapHelper = new CarUiSnapHelper(mTestableContext);
-        carUiRecyclerView.setOnFlingListener(null);
-        carUiSnapHelper.attachToRecyclerView(carUiRecyclerView);
-        int[] outDist = carUiSnapHelper.calculateScrollDistance(200, -200);
-
-        assertEquals(outDist[0], baseOutDist[0]);
-        assertEquals(outDist[1], baseOutDist[1]);
-    }
-
-    @Test
-    public void testCalculateScrollDistanceClampToScreenSize() {
-        mActivity.runOnUiThread(
-                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        int itemCount = 100;
-        TestAdapter adapter = new TestAdapter(itemCount);
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LayoutManager layoutManager = carUiRecyclerView.getLayoutManager();
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-
-        LinearSnapHelper linearSnapHelper = new LinearSnapHelper();
-        carUiRecyclerView.setOnFlingListener(null);
-        linearSnapHelper.attachToRecyclerView(carUiRecyclerView);
-        // 8000 is just an arbitrary number. the intent is to make sure the return value is bigger
-        // than the layoutmanager height.
-        int[] baseOutDist = linearSnapHelper.calculateScrollDistance(8000, -8000);
-
-        CarUiSnapHelper carUiSnapHelper = new CarUiSnapHelper(mTestableContext);
-        carUiRecyclerView.setOnFlingListener(null);
-        carUiSnapHelper.attachToRecyclerView(carUiRecyclerView);
-        int[] outDist = carUiSnapHelper.calculateScrollDistance(8000, -8000);
-
-        int lastChildPosition = carUiSnapHelper.isAtEnd(layoutManager)
-                ? 0 : layoutManager.getChildCount() - 1;
-        View lastChild = Objects.requireNonNull(layoutManager.getChildAt(lastChildPosition));
-        float percentageVisible = CarUiSnapHelper
-                .getPercentageVisible(lastChild, orientationHelper);
-
-        int maxDistance = layoutManager.getHeight();
-        if (percentageVisible > 0.f) {
-            // The max and min distance is the total height of the RecyclerView minus the height of
-            // the last child. This ensures that each scroll will never scroll more than a single
-            // page on the RecyclerView. That is, the max scroll will make the last child the
-            // first child and vice versa when scrolling the opposite way.
-            maxDistance -= layoutManager.getDecoratedMeasuredHeight(lastChild);
-        }
-        int minDistance = -maxDistance;
-
-        assertEquals(clamp(baseOutDist[0], minDistance, maxDistance), outDist[0]);
-        assertEquals(clamp(baseOutDist[1], minDistance, maxDistance), outDist[1]);
-    }
-
-    @Test
-    public void testContinuousScrollListenerConstructor_negativeInitialDelay() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        doReturn(-1).when(mTestableResources)
-            .getInteger(R.integer.car_ui_scrollbar_longpress_initial_delay);
-
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> carUiRecyclerView.setAdapter(adapter));
-        container.post(() -> assertThrows("negative intervals are not allowed",
-                IllegalArgumentException.class, () -> container.addView(carUiRecyclerView)));
-    }
-
-    @Test
-    public void testContinuousScrollListenerConstructor_negativeRepeatInterval() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        doReturn(-1).when(mTestableResources)
-                .getInteger(R.integer.car_ui_scrollbar_longpress_repeat_interval);
-
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> carUiRecyclerView.setAdapter(adapter));
-        container.post(() -> assertThrows("negative intervals are not allowed",
-                IllegalArgumentException.class, () -> container.addView(carUiRecyclerView)));
-    }
-
-    @Test
-    public void testUnknownClass_createScrollBarFromConfig() {
-        doReturn("random.class").when(mTestableResources)
-                .getString(R.string.car_ui_scrollbar_component);
-
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> carUiRecyclerView.setAdapter(adapter));
-        container.post(() -> assertThrows("Error loading scroll bar component: random.class",
-                RuntimeException.class, () -> container.addView(carUiRecyclerView)));
-    }
-
-    @Test
-    public void testWrongType_createScrollBarFromConfig() {
-        // Basically return any class that exists but doesn't extend ScrollBar
-        doReturn(CarUiRecyclerViewImpl.class.getName()).when(mTestableResources)
-            .getString(R.string.car_ui_scrollbar_component);
-
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> carUiRecyclerView.setAdapter(adapter));
-        container.post(() -> assertThrows("Error loading scroll bar component: "
-                + CarUiRecyclerViewImpl.class.getName(),
-                RuntimeException.class, () -> container.addView(carUiRecyclerView)));
-    }
-
-    @Test
-    public void testSetLinearLayoutStyle_setsLayoutManager() {
-        CarUiLayoutStyle layoutStyle = new CarUiLinearLayoutStyle();
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        carUiRecyclerView.setLayoutStyle(layoutStyle);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof LinearLayoutManager);
-        assertEquals(((LinearLayoutManager) carUiRecyclerView.getLayoutManager()).getOrientation(),
-                layoutStyle.getOrientation());
-        assertEquals(((LinearLayoutManager) carUiRecyclerView.getLayoutManager())
-                .getReverseLayout(), layoutStyle.getReverseLayout());
-    }
-
-    @Test
-    public void testSetGridLayoutStyle_setsLayoutManager() {
-        CarUiLayoutStyle layoutStyle = new CarUiGridLayoutStyle();
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        carUiRecyclerView.setLayoutStyle(layoutStyle);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof GridLayoutManager);
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getOrientation(),
-                layoutStyle.getOrientation());
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getReverseLayout(),
-                layoutStyle.getReverseLayout());
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanCount(),
-                layoutStyle.getSpanCount());
-    }
-
-    @Test
-    public void testNegativeSpanCount_setSpanCount() {
-        CarUiLayoutStyle layoutStyle = new CarUiGridLayoutStyle();
-        assertThrows(AssertionError.class, () -> ((CarUiGridLayoutStyle) layoutStyle)
-                .setSpanCount((-1)));
-    }
-
-    @Test
-    public void testSetGridLayoutStyle_setsLayoutManagerSpanSizeLookup() {
-        CarUiGridLayoutStyle layoutStyle = new CarUiGridLayoutStyle();
-        // has to bigger than span sizes for all the rows
-        layoutStyle.setSpanCount(20);
-        SpanSizeLookup spanSizeLookup = new SpanSizeLookup() {
-            @Override
-            public int getSpanSize(int position) {
-                switch(position) {
-                    case 0:
-                        return 10;
-                    case 1:
-                        return 20;
-                    default:
-                        return 15;
-                }
-            }
-        };
-        layoutStyle.setSpanSizeLookup(spanSizeLookup);
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        carUiRecyclerView.setLayoutStyle(layoutStyle);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof GridLayoutManager);
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanSizeLookup()
-                .getSpanSize(0), spanSizeLookup.getSpanSize(0));
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanSizeLookup()
-                .getSpanSize(1), spanSizeLookup.getSpanSize(1));
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanSizeLookup()
-                .getSpanSize(2), spanSizeLookup.getSpanSize(2));
-    }
-
-    @Test
-    public void testCarUiGridLayoutStyle_LayoutManagerFrom() {
-        GridLayoutManager layoutManager =
-                new GridLayoutManager(mTestableContext, 20, RecyclerView.VERTICAL, true);
-        layoutManager.setSpanSizeLookup(new SpanSizeLookup() {
-            @Override
-            public int getSpanSize(int position) {
-                switch(position) {
-                    case 0:
-                        return 10;
-                    case 1:
-                        return 20;
-                    default:
-                        return 15;
-                }
-            }
-        });
-        CarUiGridLayoutStyle layoutStyle = CarUiGridLayoutStyle.from(layoutManager);
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        carUiRecyclerView.setLayoutStyle(layoutStyle);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof GridLayoutManager);
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getOrientation(),
-                layoutManager.getOrientation());
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getReverseLayout(),
-                layoutManager.getReverseLayout());
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanCount(),
-                layoutManager.getSpanCount());
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanSizeLookup()
-                .getSpanSize(0), layoutManager.getSpanSizeLookup().getSpanSize(0));
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanSizeLookup()
-                .getSpanSize(1), layoutManager.getSpanSizeLookup().getSpanSize(1));
-        assertEquals(((GridLayoutManager) carUiRecyclerView.getLayoutManager()).getSpanSizeLookup()
-                .getSpanSize(2), layoutManager.getSpanSizeLookup().getSpanSize(2));
-    }
-
-    @Test
-    public void testCarUiGridLayoutStyle_fromLinearLayout_throwsException() {
-        LinearLayoutManager layoutManager = new LinearLayoutManager(mTestableContext);
-        assertThrows(AssertionError.class, () -> CarUiGridLayoutStyle.from(layoutManager));
-    }
-
-    @Test
-    public void testCarUiGridLayoutStyle_fromNull() {
-        assertNull(CarUiGridLayoutStyle.from(null));
-    }
-
-    @Test
-    public void testCarUiLinearLayoutStyle_LayoutManagerFrom() {
-        LinearLayoutManager layoutManager =
-                new LinearLayoutManager(mTestableContext, RecyclerView.VERTICAL, true);
-        CarUiLinearLayoutStyle layoutStyle = CarUiLinearLayoutStyle.from(layoutManager);
-        CarUiRecyclerView carUiRecyclerView = CarUiRecyclerView.create(mTestableContext);
-        carUiRecyclerView.setLayoutStyle(layoutStyle);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(50);
-
-        container.post(() -> {
-            container.addView(carUiRecyclerView);
-            carUiRecyclerView.setAdapter(adapter);
-        });
-
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        assertTrue(carUiRecyclerView.getLayoutManager() instanceof LinearLayoutManager);
-        assertEquals(((LinearLayoutManager) carUiRecyclerView.getLayoutManager()).getOrientation(),
-                layoutManager.getOrientation());
-        assertEquals(((LinearLayoutManager) carUiRecyclerView.getLayoutManager())
-                .getReverseLayout(), layoutManager.getReverseLayout());
-    }
-
-    @Test
-    public void testCarUiLinearLayoutStyle_fromGridLayout_throwsException() {
-        NotLinearLayoutManager layoutManager = new NotLinearLayoutManager(mTestableContext);
-        assertThrows(AssertionError.class, () -> CarUiLinearLayoutStyle.from(layoutManager));
-    }
-
-    @Test
-    public void testCarUiLinearLayoutStyle_fromNull() {
-        assertNull(CarUiGridLayoutStyle.from(null));
-    }
-
-    @Test
-    public void testOnContinuousScrollListener_cancelCallback() {
-        doReturn(0).when(mTestableResources)
-                .getInteger(R.integer.car_ui_scrollbar_longpress_initial_delay);
-        View view = mock(View.class);
-        OnClickListener clickListener = mock(OnClickListener.class);
-        OnContinuousScrollListener listener = new OnContinuousScrollListener(
-                mTestableContext, clickListener);
-        MotionEvent motionEvent = mock(MotionEvent.class);
-        when(motionEvent.getAction()).thenReturn(MotionEvent.ACTION_DOWN);
-        listener.onTouch(view, motionEvent);
-        when(view.isEnabled()).thenReturn(false);
-        when(motionEvent.getAction()).thenReturn(MotionEvent.ACTION_UP);
-        listener.onTouch(view, motionEvent);
-        verify(clickListener, times(1)).onClick(view);
-    }
-
-    @Test
-    public void testUxRestriction_withLimitedContent_setsMaxItems() {
-        CarUxRestrictionsUtil uxRestriction = CarUxRestrictionsUtil.getInstance(mTestableContext);
-        CarUxRestrictions restriction = mock(CarUxRestrictions.class);
-        when(restriction.getActiveRestrictions()).thenReturn(UX_RESTRICTIONS_LIMIT_CONTENT);
-        when(restriction.getMaxCumulativeContentItems()).thenReturn(10);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter.WithItemCap adapter = spy(new TestAdapter.WithItemCap(100));
-        container.post(() -> {
-            uxRestriction.setUxRestrictions(restriction);
-            carUiRecyclerView.setAdapter(adapter);
-            container.addView(carUiRecyclerView);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        verify(adapter, atLeastOnce()).setMaxItems(10);
-    }
-
-    @Test
-    public void testUxRestriction_withoutLimitedContent_setsUnlimitedMaxItems() {
-        CarUxRestrictionsUtil uxRestriction = CarUxRestrictionsUtil.getInstance(mTestableContext);
-        CarUxRestrictions restriction = mock(CarUxRestrictions.class);
-        when(restriction.getMaxCumulativeContentItems()).thenReturn(10);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter.WithItemCap adapter = spy(new TestAdapter.WithItemCap(100));
-        container.post(() -> {
-            uxRestriction.setUxRestrictions(restriction);
-            carUiRecyclerView.setAdapter(adapter);
-            container.addView(carUiRecyclerView);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        verify(adapter, atLeastOnce()).setMaxItems(UNLIMITED);
-    }
-
-    @Test
-    public void testPageUp_returnsWhen_verticalScrollOffsetIsZero() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        doReturn(TestScrollBar.class.getName()).when(mTestableResources)
-            .getString(R.string.car_ui_scrollbar_component);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(100);
-        container.post(() -> {
-            carUiRecyclerView.setAdapter(adapter);
-            container.addView(carUiRecyclerView);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        // Scroll to a position so page up is enabled.
-        container.post(() -> carUiRecyclerView.scrollToPosition(20));
-
-        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(isEnabled()));
-
-        View v = mActivity.findViewById(R.id.car_ui_scroll_bar);
-        TestScrollBar sb = (TestScrollBar) v.getTag();
-        // We set this to simulate a case where layout manager is null
-        sb.mReturnZeroVerticalScrollOffset = true;
-
-        onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-
-        assertFalse(sb.mScrollWasCalled);
-    }
-
-    @Test
-    public void testPageUp_returnsWhen_layoutManagerIsNull() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        doReturn(TestScrollBar.class.getName()).when(mTestableResources)
-                .getString(R.string.car_ui_scrollbar_component);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(100);
-        container.post(() -> {
-            carUiRecyclerView.setAdapter(adapter);
-            container.addView(carUiRecyclerView);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        // Scroll to a position so page up is enabled.
-        container.post(() -> carUiRecyclerView.scrollToPosition(20));
-
-        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(isEnabled()));
-
-        View v = mActivity.findViewById(R.id.car_ui_scroll_bar);
-        TestScrollBar sb = (TestScrollBar) v.getTag();
-        // We set this to simulate a case where layout manager is null
-        sb.mReturnMockLayoutManager = true;
-
-        onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-
-        assertFalse(sb.mScrollWasCalled);
-    }
-
-    @Test
-    public void testPageDown_returnsWhen_layoutManagerIsNullOrEmpty() {
-        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
-        doReturn(TestScrollBar.class.getName()).when(mTestableResources)
-            .getString(R.string.car_ui_scrollbar_component);
-
-        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerViewImpl(mTestableContext);
-
-        ViewGroup container = mActivity.findViewById(R.id.test_container);
-        TestAdapter adapter = new TestAdapter(100);
-        container.post(() -> {
-            carUiRecyclerView.setAdapter(adapter);
-            container.addView(carUiRecyclerView);
-        });
-
-        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
-        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
-
-        // Scroll to a position so page up is enabled.
-        container.post(() -> carUiRecyclerView.scrollToPosition(20));
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).check(matches(isEnabled()));
-
-        View v = mActivity.findViewById(R.id.car_ui_scroll_bar);
-        TestScrollBar sb = (TestScrollBar) v.getTag();
-        // We set this to simulate a case where layout manager is empty
-        sb.mReturnMockLayoutManager = true;
-        sb.mMockLayoutManager = spy(carUiRecyclerView.getLayoutManager());
-        when(sb.mMockLayoutManager.getChildCount()).thenReturn(0);
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        assertFalse(sb.mScrollWasCalled);
-
-        // We set this to simulate a case where layout manager is null
-        sb.mReturnMockLayoutManager = true;
-        sb.mMockLayoutManager = null;
-
-        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
-
-        assertFalse(sb.mScrollWasCalled);
-    }
-
-    static class TestScrollBar extends DefaultScrollBar {
-
-        boolean mReturnMockLayoutManager = false;
-        LayoutManager mMockLayoutManager = null;
-        boolean mScrollWasCalled = false;
-        boolean mReturnZeroVerticalScrollOffset = false;
-
-        @Override
-        public void initialize(RecyclerView rv, View scrollView) {
-            super.initialize(rv, scrollView);
-
-            scrollView.setTag(this);
-        }
-
-        @Override
-        public LayoutManager getLayoutManager() {
-            return mReturnMockLayoutManager ? mMockLayoutManager : super.getLayoutManager();
-        }
-
-        @Override
-        void smoothScrollBy(int dx, int dy) {
-            mScrollWasCalled = true;
-        }
-
-        @Override
-        void smoothScrollToPosition(int max) {
-            mScrollWasCalled = true;
-        }
-
-        @Override
-        int computeVerticalScrollOffset() {
-            return mReturnZeroVerticalScrollOffset ? 0 : super.computeVerticalScrollOffset();
-        }
-    }
-
-    private static float dpToPixel(Context context, int dp) {
-        return TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP,
-                dp,
-                context.getResources().getDisplayMetrics());
-    }
-
-    /**
-     * Returns an item in the current list view whose height is taller than that of the
-     * CarUiRecyclerView. If that item exists, then it is returned; otherwise an {@link
-     * IllegalStateException} is thrown.
-     *
-     * @return An item that is taller than the CarUiRecyclerView.
-     */
-    private View getLongItem(CarUiRecyclerView recyclerView) {
-        OrientationHelper orientationHelper =
-                OrientationHelper.createVerticalHelper(recyclerView.getLayoutManager());
-        for (int i = 0; i < recyclerView.getLayoutManager().getChildCount(); i++) {
-            View item = recyclerView.getLayoutManager().getChildAt(i);
-
-            if (item.getHeight() > orientationHelper.getTotalSpace()) {
-                return item;
-            }
-        }
-
-        throw new IllegalStateException(
-                "No item found that is longer than the height of the CarUiRecyclerView.");
-    }
-
-    /**
-     * A test adapter that handles inflating test views and binding data to it.
-     */
-    private static class TestAdapter extends RecyclerView.Adapter<TestViewHolder> {
-
-        public enum ItemHeight {
-            STANDARD,
-            TALL,
-            EXTRA_TALL,
-            ZERO
-        }
-
-        protected final List<String> mData;
-        private final Map<Integer, ItemHeight> mHeightOverrides;
-
-        TestAdapter(int itemCount, Map<Integer, ItemHeight> overrides) {
-            mHeightOverrides = overrides;
-            mData = new ArrayList<>(itemCount);
-
-            for (int i = 0; i < itemCount; i++) {
-                mData.add(getItemText(i));
-            }
-        }
-
-        TestAdapter(int itemCount) {
-            this(itemCount, new HashMap<>());
-        }
-
-        String getItemText(int position) {
-            if (position > mData.size()) {
-                return null;
-            }
-
-            return String.format("Sample item #%d", position);
-        }
-
-        @NonNull
-        @Override
-        public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-            return new TestViewHolder(inflater, parent);
-        }
-
-        @Override
-        public void onBindViewHolder(@NonNull TestViewHolder holder, int position) {
-            ItemHeight height = ItemHeight.STANDARD;
-
-            if (mHeightOverrides.containsKey(position)) {
-                height = mHeightOverrides.get(position);
-            }
-
-            int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
-
-            switch (height) {
-                case ZERO:
-                    ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
-                    holder.itemView.setContentDescription("ZERO");
-                    lp.height = 0;
-                    holder.itemView.setLayoutParams(lp);
-                    break;
-                case STANDARD:
-                    break;
-                case TALL:
-                    holder.itemView.setMinimumHeight(screenHeight);
-                    break;
-                case EXTRA_TALL:
-                    holder.itemView.setMinimumHeight(screenHeight * 2);
-                    break;
-                default:
-                    throw new IllegalStateException("Unexpected value: " + height);
-            }
-
-            holder.bind(mData.get(position));
-        }
-
-        @Override
-        public int getItemCount() {
-            return mData.size();
-        }
-
-        static class WithItemCap extends TestAdapter implements CarUiRecyclerView.ItemCap {
-
-            private int mMaxitems = -1;
-
-            WithItemCap(int itemCount,
-                    Map<Integer, ItemHeight> overrides) {
-                super(itemCount, overrides);
-            }
-
-            WithItemCap(int itemCount) {
-                super(itemCount);
-            }
-
-            @Override
-            public void setMaxItems(int maxItems) {
-                mMaxitems = maxItems;
-            }
-
-            @Override
-            public int getItemCount() {
-                return mMaxitems >= 0 ? mMaxitems : mData.size();
-            }
-        }
-    }
-
-    private static class PerfectFitTestAdapter extends RecyclerView.Adapter<TestViewHolder> {
-
-        private static final int MIN_HEIGHT = 30;
-        private final List<String> mData;
-        private final int mItemHeight;
-
-        private int getMinHeightPerItemToFitScreen(int screenHeight) {
-            // When the height is a prime number, there can only be 1 item per page
-            int minHeight = screenHeight;
-            for (int i = screenHeight; i >= 1; i--) {
-                if (screenHeight % i == 0 && screenHeight / i >= MIN_HEIGHT) {
-                    minHeight = screenHeight / i;
-                    break;
-                }
-            }
-            return minHeight;
-        }
-
-        PerfectFitTestAdapter(int numOfPages, int recyclerViewHeight) {
-            mItemHeight = getMinHeightPerItemToFitScreen(recyclerViewHeight);
-            int itemsPerPage = recyclerViewHeight / mItemHeight;
-            int itemCount = itemsPerPage * numOfPages;
-            mData = new ArrayList<>(itemCount);
-            for (int i = 0; i < itemCount; i++) {
-                mData.add(getItemText(i));
-            }
-        }
-
-        String getItemText(int position) {
-            return String.format("Sample item #%d", position);
-        }
-
-        @NonNull
-        @Override
-        public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-            return new TestViewHolder(inflater, parent);
-        }
-
-        @Override
-        public void onBindViewHolder(@NonNull TestViewHolder holder, int position) {
-            holder.itemView.setMinimumHeight(mItemHeight);
-            holder.bind(mData.get(position));
-        }
-
-        @Override
-        public int getItemCount() {
-            return mData.size();
-        }
-    }
-
-    private static class TestViewHolder extends RecyclerView.ViewHolder {
-        private TextView mTextView;
-
-        TestViewHolder(LayoutInflater inflater, ViewGroup parent) {
-            super(inflater.inflate(R.layout.test_list_item, parent, false));
-            mTextView = itemView.findViewById(R.id.text);
-        }
-
-        void bind(String text) {
-            mTextView.setText(text);
-        }
-    }
-
-    /**
-     * An {@link IdlingResource} that will prevent assertions from running while the {@link
-     * CarUiRecyclerView} is scrolling.
-     */
-    private static class ScrollIdlingResource implements IdlingResource {
-        private boolean mIdle = true;
-        private ResourceCallback mResourceCallback;
-
-        ScrollIdlingResource(CarUiRecyclerView carUiRecyclerView) {
-            carUiRecyclerView
-                    .addOnScrollListener(
-                            new RecyclerView.OnScrollListener() {
-                                @Override
-                                public void onScrollStateChanged(@NonNull RecyclerView recyclerView,
-                                        int newState) {
-                                    super.onScrollStateChanged(recyclerView, newState);
-                                    mIdle = (newState == SCROLL_STATE_IDLE
-                                            // Treat dragging as idle, or Espresso will
-                                            // block itself when swiping.
-                                            || newState == SCROLL_STATE_DRAGGING);
-                                    if (mIdle && mResourceCallback != null) {
-                                        mResourceCallback.onTransitionToIdle();
-                                    }
-                                }
-
-                                @Override
-                                public void onScrolled(@NonNull RecyclerView recyclerView, int dx,
-                                        int dy) {
-                                }
-                            });
-        }
-
-        @Override
-        public String getName() {
-            return ScrollIdlingResource.class.getName();
-        }
-
-        @Override
-        public boolean isIdleNow() {
-            return mIdle;
-        }
-
-        @Override
-        public void registerIdleTransitionCallback(ResourceCallback callback) {
-            mResourceCallback = callback;
-        }
-    }
-
-    private static class NotLinearLayoutManager extends LayoutManager {
-
-        NotLinearLayoutManager(Context mTestableContext) {}
-
-        @Override
-        public LayoutParams generateDefaultLayoutParams() {
-            return null;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTestActivity.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTestActivity.java
deleted file mode 100644
index 64dd993..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTestActivity.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.car.ui.test.R;
-
-/**
- * An {@link Activity} that contains only an empty {@link CarUiRecyclerView}.
- */
-public class CarUiRecyclerViewTestActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_test_activity);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiSmoothScrollerTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiSmoothScrollerTest.java
deleted file mode 100644
index b93c0ee..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiSmoothScrollerTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import static androidx.recyclerview.widget.LinearSmoothScroller.SNAP_TO_START;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.TestActivity;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CarUiSmoothScroller}.
- */
-public class CarUiSmoothScrollerTest {
-
-    @Rule
-    public ActivityScenarioRule<TestActivity> mActivityRule =
-            new ActivityScenarioRule<>(TestActivity.class);
-
-    private ActivityScenario<TestActivity> mScenario;
-
-    private TestActivity mActivity;
-    private CarUiSmoothScroller mCarUiSmoothScroller;
-
-    @Before
-    public void setUp() {
-        mScenario = mActivityRule.getScenario();
-        mScenario.onActivity(activity -> {
-            mActivity = activity;
-            mCarUiSmoothScroller = new CarUiSmoothScroller(mActivity);
-        });
-    }
-
-    @Test
-    public void calculateTimeForScrolling_shouldInitializeAllValues() {
-        assertThat(mCarUiSmoothScroller.mMillisecondsPerInch).isNotEqualTo(0);
-        assertThat(mCarUiSmoothScroller.mDecelerationTimeDivisor).isNotEqualTo(0);
-        assertThat(mCarUiSmoothScroller.mMillisecondsPerPixel).isNotEqualTo(0);
-        assertThat(mCarUiSmoothScroller.mInterpolator).isNotNull();
-        assertThat(mCarUiSmoothScroller.mDensityDpi).isNotEqualTo(0);
-    }
-
-    @Test
-    public void getVerticalSnapPreference_shouldReturnSnapToStart() {
-        assertThat(mCarUiSmoothScroller.getVerticalSnapPreference()).isEqualTo(SNAP_TO_START);
-    }
-
-    @Test
-    public void calculateTimeForScrolling_shouldReturnMultiplierOfMillisecondsPerPixel() {
-        assertThat(mCarUiSmoothScroller.calculateTimeForScrolling(20)).isEqualTo(
-                (int) Math.ceil(Math.abs(20) * mCarUiSmoothScroller.mMillisecondsPerPixel));
-    }
-
-    @Test
-    public void calculateTimeForDeceleration_shouldReturnNotBeZero() {
-        assertThat(mCarUiSmoothScroller.calculateTimeForDeceleration(20)).isNotEqualTo(0);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/ContentLimitingAdapterTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/ContentLimitingAdapterTest.java
deleted file mode 100644
index ae569d2..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/ContentLimitingAdapterTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-public class ContentLimitingAdapterTest {
-
-    @Rule
-    public ActivityScenarioRule<CarUiRecyclerViewTestActivity> mActivityRule =
-            new ActivityScenarioRule<>(CarUiRecyclerViewTestActivity.class);
-    ActivityScenario<CarUiRecyclerViewTestActivity> mScenario;
-
-    private ContentLimitingAdapter<TestViewHolder> mContentLimitingAdapter;
-    private CarUiRecyclerViewTestActivity mActivity;
-
-    @Before
-    public void setUp() {
-        mScenario = mActivityRule.getScenario();
-        mScenario.onActivity(activity -> {
-            mActivity = activity;
-            mContentLimitingAdapter = new TestContentLimitingAdapter(50);
-        });
-    }
-
-    @Test
-    public void setMaxItem_toLowerThanTotalItems() {
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        RecyclerView.ViewHolder last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-
-        // Switch to limited
-        mContentLimitingAdapter.setMaxItems(20);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(21);
-        RecyclerView.ViewHolder secondToLast = getItemAtPosition(19);
-        isTestViewHolderWithText(secondToLast, "Item 19");
-
-        last = getItemAtPosition(20);
-        assertThat(last).isInstanceOf(ScrollingLimitedViewHolder.class);
-
-        // Switch back to unlimited
-        mContentLimitingAdapter.setMaxItems(-1);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-    }
-
-    @Test
-    public void setMaxItem_toOne() {
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        RecyclerView.ViewHolder last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-
-        mContentLimitingAdapter.setMaxItems(1);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(2);
-        RecyclerView.ViewHolder secondToLast = getItemAtPosition(0);
-        isTestViewHolderWithText(secondToLast, "Item 0");
-
-        last = getItemAtPosition(1);
-        assertThat(last).isInstanceOf(ScrollingLimitedViewHolder.class);
-
-        // Switch back to unlimited
-        mContentLimitingAdapter.setMaxItems(-1);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-    }
-
-    @Test
-    public void setMaxItem_toZero() {
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        RecyclerView.ViewHolder last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-
-        mContentLimitingAdapter.setMaxItems(0);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(1);
-        last = getItemAtPosition(0);
-        assertThat(last).isInstanceOf(ScrollingLimitedViewHolder.class);
-
-        // Switch back to unlimited
-        mContentLimitingAdapter.setMaxItems(-1);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-    }
-
-    @Test
-    public void setMaxItem_toHigherThanTotalItems() {
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        RecyclerView.ViewHolder last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-
-        mContentLimitingAdapter.setMaxItems(70);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        RecyclerView.ViewHolder secondToLast = getItemAtPosition(48);
-        isTestViewHolderWithText(secondToLast, "Item 48");
-
-        last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-
-        // Switch back to unlimited
-        mContentLimitingAdapter.setMaxItems(-1);
-
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        last = getItemAtPosition(49);
-        isTestViewHolderWithText(last, "Item 49");
-    }
-
-    @Test
-    public void testViewHolderText_customMessage() {
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(0);
-            mContentLimitingAdapter.setScrollingLimitedMessageResId(
-                    R.string.scrolling_limited_message);
-        });
-
-        String msg = mActivity.getString(R.string.scrolling_limited_message);
-        onView(withText(msg)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testViewHolderText_changeCustomMessage() {
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(0);
-            mContentLimitingAdapter.setScrollingLimitedMessageResId(
-                    R.string.car_ui_scrolling_limited_message);
-            mContentLimitingAdapter.setScrollingLimitedMessageResId(
-                    R.string.scrolling_limited_message);
-        });
-
-        String msg = mActivity.getString(R.string.scrolling_limited_message);
-        onView(withText(msg)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testViewHolderText_defaultMessage() {
-        assertThat(mContentLimitingAdapter.getItemCount()).isEqualTo(50);
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(0);
-        });
-
-        String msg = mActivity.getString(R.string.car_ui_scrolling_limited_message);
-        onView(withText(msg)).check(matches(isDisplayed()));
-    }
-
-    private RecyclerView.ViewHolder getItemAtPosition(int position) {
-        int viewType = mContentLimitingAdapter.getItemViewType(position);
-        RecyclerView.ViewHolder viewHolder =
-                mContentLimitingAdapter.createViewHolder(
-                        new LinearLayout(mActivity.getApplicationContext()),
-                        viewType);
-        mContentLimitingAdapter.bindViewHolder(viewHolder, position);
-        return viewHolder;
-    }
-
-    private void isTestViewHolderWithText(RecyclerView.ViewHolder secondToLast, String s) {
-        assertThat(secondToLast).isInstanceOf(TestViewHolder.class);
-        TestViewHolder testViewHolder = (TestViewHolder) secondToLast;
-        assertThat(testViewHolder.getText()).isEqualTo(s);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/ContentLimitingAdapterUiTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/ContentLimitingAdapterUiTest.java
deleted file mode 100644
index eae42b8..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/ContentLimitingAdapterUiTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.rule.ActivityTestRule;
-
-import com.android.car.ui.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-public class ContentLimitingAdapterUiTest {
-
-    @Rule
-    public ActivityTestRule<CarUiRecyclerViewTestActivity> mActivityRule =
-            new ActivityTestRule<>(CarUiRecyclerViewTestActivity.class);
-
-    private ContentLimitingAdapter<TestViewHolder> mContentLimitingAdapter;
-    private RecyclerView mCarUiRecyclerView;
-
-    @Before
-    public void setUp() {
-        mContentLimitingAdapter = new TestContentLimitingAdapter(50);
-        mCarUiRecyclerView = mActivityRule.getActivity().requireViewById(R.id.list);
-        mActivityRule.getActivity().runOnUiThread(() -> {
-            mCarUiRecyclerView.setAdapter(mContentLimitingAdapter);
-        });
-    }
-
-    @Test
-    public void setMaxItem_toLowerThanTotalItems() throws Throwable {
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        // Switch to limited
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(20);
-        });
-        Thread.sleep(300);
-        onView(withText("Item 0")).check(matches(isDisplayed()));
-        onView(withId(R.id.list)).perform(scrollToPosition(20));
-        onView(withText("Item 19")).check(matches(isDisplayed()));
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message))
-                .check(matches(isDisplayed()));
-
-        // Switch back to unlimited
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(-1);
-        });
-        Thread.sleep(300);
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message)).check(doesNotExist());
-    }
-
-    @Test
-    public void setMaxItem_toOne() throws Throwable {
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(1);
-        });
-        Thread.sleep(300);
-        onView(withText("Item 0")).check(matches(isDisplayed()));
-        onView(withText("Item 1")).check(doesNotExist());
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message))
-                .check(matches(isDisplayed()));
-
-        // Switch back to unlimited
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(-1);
-        });
-        Thread.sleep(300);
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message)).check(doesNotExist());
-    }
-
-    @Test
-    public void setMaxItem_toZero() throws Throwable {
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(0);
-        });
-        Thread.sleep(300);
-        onView(withText("Item 0")).check(doesNotExist());
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message))
-                .check(matches(isDisplayed()));
-
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(-1);
-        });
-        Thread.sleep(300);
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message)).check(doesNotExist());
-    }
-
-    @Test
-    public void setMaxItem_toHigherThanTotalItems() throws Throwable {
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(70);
-        });
-        Thread.sleep(300);
-        onView(withText("Item 0")).check(matches(isDisplayed()));
-        onView(withId(R.id.list)).perform(scrollToPosition(49));
-        onView(withText("Item 49")).check(matches(isDisplayed()));
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message))
-                .check(doesNotExist());
-
-        // Switch back to unlimited
-        mActivityRule.runOnUiThread(() -> {
-            mContentLimitingAdapter.setMaxItems(-1);
-        });
-        Thread.sleep(300);
-        onView(withId(com.android.car.ui.R.id.car_ui_list_limiting_message)).check(doesNotExist());
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapterTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapterTest.java
deleted file mode 100644
index b3ad0c1..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapterTest.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.view.View;
-
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.OrientationHelper;
-import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.test.R;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-public class DelegatingContentLimitingAdapterTest {
-
-    @Rule
-    public ActivityScenarioRule<CarUiRecyclerViewTestActivity> mActivityRule =
-            new ActivityScenarioRule<>(CarUiRecyclerViewTestActivity.class);
-    ActivityScenario<CarUiRecyclerViewTestActivity> mScenario;
-
-    private DelegatingContentLimitingAdapter<TestViewHolder> mContentLimitingAdapter;
-    private TestDelegatingContentLimitingAdapter mDelegateAdapter;
-    private CarUiRecyclerViewTestActivity mActivity;
-
-    @Before
-    public void setUp() {
-        mScenario = mActivityRule.getScenario();
-        mScenario.onActivity(activity -> mActivity = activity);
-    }
-
-    @Test
-    public void setMaxItem_noScrolling_noContentLimiting() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(10);
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LinearLayoutManager layoutManager =
-                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-
-        View firstChild = Objects.requireNonNull(layoutManager.getChildAt(0));
-        boolean isAtStart = orientationHelper.getDecoratedStart(firstChild)
-                >= orientationHelper.getStartAfterPadding()
-                && layoutManager.getPosition(firstChild) == 0;
-        assertTrue(isAtStart);
-    }
-
-    @Test
-    public void setMaxItem_noScrolling() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter.WithContentLimiting(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(1);
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
-
-        LinearLayoutManager layoutManager =
-                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
-        OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-
-        View firstChild = Objects.requireNonNull(layoutManager.getChildAt(0));
-        boolean isAtStart = orientationHelper.getDecoratedStart(firstChild)
-                >= orientationHelper.getStartAfterPadding()
-                && layoutManager.getPosition(firstChild) == 0;
-        assertTrue(isAtStart);
-    }
-
-    @Test
-    public void setMaxItem_withScrolling() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter.WithContentLimiting(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            ((TestDelegatingContentLimitingAdapter.WithContentLimiting) mDelegateAdapter)
-                    .setScrollPositionWhenRestricted(15);
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(16);
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(15))).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testChangeItem_callsObservers() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        AdapterDataObserver observer = mock(AdapterDataObserver.class);
-        mContentLimitingAdapter.registerAdapterDataObserver(observer);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(10);
-            mDelegateAdapter.changeItemRange(5, 3);
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
-
-        verify(observer).onItemRangeChanged(5, 3, null);
-    }
-
-    @Test
-    public void testInsertItem_callsObservers() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        AdapterDataObserver observer = mock(AdapterDataObserver.class);
-        mContentLimitingAdapter.registerAdapterDataObserver(observer);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(10);
-            mDelegateAdapter.insertItemRange(5, "new item 1", "new item 2");
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
-
-        verify(observer).onItemRangeInserted(5, 2);
-    }
-
-    @Test
-    public void testRemoveItem_callsObservers() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        AdapterDataObserver observer = mock(AdapterDataObserver.class);
-        mContentLimitingAdapter.registerAdapterDataObserver(observer);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(10);
-            mDelegateAdapter.removeItemRange(5, 2);
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
-
-        verify(observer).onItemRangeRemoved(5, 2);
-    }
-
-    @Test
-    public void testMoveItem_callsObservers() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        AdapterDataObserver observer = mock(AdapterDataObserver.class);
-        mContentLimitingAdapter.registerAdapterDataObserver(observer);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(10);
-            mDelegateAdapter.moveItem(5, 2);
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
-
-        verify(observer).onChanged();
-    }
-
-    @Test
-    public void testChangeDataSet_callsObservers() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        AdapterDataObserver observer = mock(AdapterDataObserver.class);
-        mContentLimitingAdapter.registerAdapterDataObserver(observer);
-
-        onView(withId(R.id.list)).check(matches(isDisplayed()));
-
-        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        mActivity.runOnUiThread(() -> {
-            carUiRecyclerView.setAdapter(mContentLimitingAdapter);
-            carUiRecyclerView.setVisibility(View.VISIBLE);
-            mContentLimitingAdapter.setMaxItems(10);
-        });
-
-        onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
-
-        mActivity.runOnUiThread(() -> {
-            ArrayList<String> newItems = new ArrayList<>();
-            for (int i = 0; i < 40; i++) {
-                newItems.add("New Item " + i);
-            }
-            mDelegateAdapter.changeList(newItems);
-        });
-
-        onView(withText("New Item 0")).check(matches(isDisplayed()));
-
-        verify(observer).onChanged();
-    }
-
-    @Test
-    public void testSetHasStableId_setsDelegateToo() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mDelegateAdapter.setHasStableIds(false);
-
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        mContentLimitingAdapter.setHasStableIds(true);
-
-        assertTrue(mDelegateAdapter.hasStableIds());
-    }
-
-    @Test
-    public void testGetIds_callsDelegate() {
-        mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
-        mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
-
-        for (int i = 0; i < 50; i++) {
-            assertEquals(mDelegateAdapter.getItemId(i), mContentLimitingAdapter.getItemId(i));
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/RangeFilterImplTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/RangeFilterImplTest.java
deleted file mode 100644
index 4b2c283..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/RangeFilterImplTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.Adapter;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class RangeFilterImplTest {
-    private static final int EVEN_MAX_ITEMS = 10;
-    private static final int ODD_MAX_ITEMS = 9;
-    private static final int UNRESTRICTED_COUNT = 80;
-    private static final int UNRESTRICTED_SMALL_COUNT = 6;
-
-    @Mock
-    RecyclerView.Adapter mMockAdapter;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @Test
-    public void testRecompute_contentSizeSmallerThanRange_noLimit() {
-        RangeFilterImpl rangeFilter = new RangeFilterImpl(mMockAdapter, EVEN_MAX_ITEMS);
-        int pivotPosition = 0;
-        rangeFilter.recompute(UNRESTRICTED_SMALL_COUNT, pivotPosition);
-        verifyNoClamps(rangeFilter, UNRESTRICTED_SMALL_COUNT);
-    }
-
-    @Test
-    public void testRecompute_pivotPointInTheMiddleWithEvenMaxItems_limitContent() {
-        RangeFilterImpl rangeFilter = new RangeFilterImpl(mMockAdapter, EVEN_MAX_ITEMS);
-        int pivotPosition = 30;
-        rangeFilter.recompute(UNRESTRICTED_COUNT, pivotPosition);
-        verifyClampedBothEnds(rangeFilter, pivotPosition, EVEN_MAX_ITEMS);
-        rangeFilter.applyFilter();
-        verifyFilterBothEnds(mMockAdapter, pivotPosition, EVEN_MAX_ITEMS, UNRESTRICTED_COUNT);
-        rangeFilter.removeFilter();
-        verifyRemoveFilterBothEnds(mMockAdapter, pivotPosition, EVEN_MAX_ITEMS, UNRESTRICTED_COUNT);
-    }
-
-    @Test
-    public void testRecompute_pivotPointInTheMiddleWithOddMaxItems_limitContent() {
-        RangeFilterImpl rangeFilter = new RangeFilterImpl(mMockAdapter, ODD_MAX_ITEMS);
-        int pivotPosition = 30;
-        rangeFilter.recompute(UNRESTRICTED_COUNT, pivotPosition);
-        verifyClampedBothEnds(rangeFilter, pivotPosition, ODD_MAX_ITEMS);
-        rangeFilter.applyFilter();
-        verifyFilterBothEnds(mMockAdapter, pivotPosition, ODD_MAX_ITEMS, UNRESTRICTED_COUNT);
-        rangeFilter.removeFilter();
-        verifyRemoveFilterBothEnds(mMockAdapter, pivotPosition, ODD_MAX_ITEMS, UNRESTRICTED_COUNT);
-    }
-
-    @Test
-    public void testRecompute_pivotPointInTheSecondHalf_clampsHeadOnly() {
-        RangeFilterImpl rangeFilter = new RangeFilterImpl(mMockAdapter, 20);
-        int pivotPosition = 20;
-        rangeFilter.recompute(30, pivotPosition);
-
-        RangeFilterImpl.ListRange range = rangeFilter.getRange();
-        assertThat(range.mClampedHead).isEqualTo(1);
-        assertThat(range.mClampedTail).isEqualTo(0);
-        assertThat(range.mStartIndex).isEqualTo(10);
-        assertThat(range.mEndIndex).isEqualTo(30);
-        assertThat(range.mEndIndex - range.mStartIndex).isEqualTo(20);
-        assertThat(range.mLimitedCount).isEqualTo(20 + 1);
-
-        rangeFilter.applyFilter();
-
-        int firstHalfRemainingItems = 20 / 2;
-        int clampedHeadItemCount = pivotPosition - firstHalfRemainingItems;
-
-        verify(mMockAdapter).notifyItemRangeRemoved(0, clampedHeadItemCount);
-        verify(mMockAdapter).notifyItemInserted(0);
-
-        rangeFilter.removeFilter();
-
-        verify(mMockAdapter).notifyItemRangeInserted(1, clampedHeadItemCount);
-        verify(mMockAdapter).notifyItemRemoved(0);
-    }
-
-    @Test
-    public void testRecompute_pivotPointInTheFirstHalf_clampsTailOnly() {
-        RangeFilterImpl rangeFilter = new RangeFilterImpl(mMockAdapter, 20);
-        int pivotPosition = 10;
-        rangeFilter.recompute(40, pivotPosition);
-
-        RangeFilterImpl.ListRange range = rangeFilter.getRange();
-        assertThat(range.mClampedHead).isEqualTo(0);
-        assertThat(range.mClampedTail).isEqualTo(1);
-        assertThat(range.mStartIndex).isEqualTo(0);
-        assertThat(range.mEndIndex).isEqualTo(20);
-        assertThat(range.mEndIndex - range.mStartIndex).isEqualTo(20);
-        assertThat(range.mLimitedCount).isEqualTo(20 + 1);
-
-        rangeFilter.applyFilter();
-
-        int firstHalfRemainingItems = 20 / 2;
-        int secondHalfRemainingItems = 20 - firstHalfRemainingItems;
-        int clampedHeadItemCount = pivotPosition - firstHalfRemainingItems;
-        int clampedTailItemCount = 40 - clampedHeadItemCount - 20;
-
-        verify(mMockAdapter).notifyItemInserted(40);
-        verify(mMockAdapter).notifyItemRangeRemoved(
-                pivotPosition + secondHalfRemainingItems, clampedTailItemCount);
-
-        rangeFilter.removeFilter();
-
-        verify(mMockAdapter).notifyItemRemoved(20 + 1 - 1);
-        verify(mMockAdapter).notifyItemRangeInserted(20 + 1 - 1, clampedTailItemCount);
-    }
-
-    @Test
-    public void testRecompute_invalidPivotPoint_getsCorrected() {
-        RangeFilterImpl rangeFilter = new RangeFilterImpl(mMockAdapter, 10);
-
-        rangeFilter.recompute(20, -1);
-        assertThat(rangeFilter.mPivotIndex).isEqualTo(0);
-
-        rangeFilter.recompute(20, 30);
-        assertThat(rangeFilter.mPivotIndex).isEqualTo(0);
-    }
-
-    private void verifyClampedBothEnds(
-            RangeFilterImpl rangeFilter, int pivotPoint, int maxItemCount) {
-        RangeFilterImpl.ListRange range = rangeFilter.getRange();
-        int firstHalfCount = maxItemCount / 2;
-        int secondHalfCount = maxItemCount - firstHalfCount;
-        assertThat(range.mClampedHead).isEqualTo(1);
-        assertThat(range.mClampedTail).isEqualTo(1);
-        assertThat(range.mStartIndex).isEqualTo(pivotPoint - firstHalfCount);
-        assertThat(range.mEndIndex).isEqualTo(pivotPoint + secondHalfCount);
-        assertThat(range.mEndIndex - range.mStartIndex).isEqualTo(maxItemCount);
-        assertThat(range.mLimitedCount).isEqualTo(maxItemCount + 2 /* two messages*/);
-
-        assertThat(rangeFilter.positionToIndex(0))
-                .isEqualTo(RangeFilter.INVALID_INDEX);
-        assertThat(rangeFilter.positionToIndex(1))
-                .isEqualTo(range.mStartIndex);
-
-        assertThat(rangeFilter.positionToIndex(maxItemCount))
-                .isEqualTo(range.mEndIndex - 1);
-        assertThat(rangeFilter.positionToIndex(maxItemCount + 1))
-                .isEqualTo(RangeFilter.INVALID_INDEX);
-
-        assertThat(rangeFilter.indexToPosition(range.mStartIndex))
-                .isEqualTo(1);
-
-        assertThat(rangeFilter.indexToPosition(range.mEndIndex - 1))
-                .isEqualTo(maxItemCount /* head message takes an additional position */);
-    }
-
-    private void verifyNoClamps(RangeFilterImpl rangeFilter, int unrestrictedCount) {
-        RangeFilterImpl.ListRange range = rangeFilter.getRange();
-        assertThat(range.mClampedHead).isEqualTo(0);
-        assertThat(range.mClampedTail).isEqualTo(0);
-        assertThat(range.mStartIndex).isEqualTo(0);
-        assertThat(range.mEndIndex).isEqualTo(unrestrictedCount);
-        assertThat(range.mEndIndex - range.mStartIndex).isEqualTo(unrestrictedCount);
-        assertThat(range.mLimitedCount).isEqualTo(unrestrictedCount);
-    }
-
-    private void verifyFilterBothEnds(
-            Adapter adapter,
-            int pivotPosition,
-            int maxCount,
-            int unrestrictedCount) {
-        int firstHalfRemainingItems = maxCount / 2;
-        int secondHalfRemainingItems = maxCount - firstHalfRemainingItems;
-        int clampedHeadItemCount = pivotPosition - firstHalfRemainingItems;
-        int clampedTailItemCount = unrestrictedCount - clampedHeadItemCount - maxCount;
-
-        verify(adapter).notifyItemInserted(unrestrictedCount);
-        verify(adapter).notifyItemRangeRemoved(
-                pivotPosition + secondHalfRemainingItems, clampedTailItemCount);
-        verify(adapter).notifyItemRangeRemoved(0, clampedHeadItemCount);
-        verify(adapter).notifyItemInserted(0);
-    }
-
-    private void verifyRemoveFilterBothEnds(
-            Adapter adapter,
-            int pivotPosition,
-            int maxCount,
-            int unrestrictedCount) {
-        int firstHalfRemainingItems = maxCount / 2;
-        int secondHalfRemainingItems = maxCount - firstHalfRemainingItems;
-        int clampedHeadItemCount = pivotPosition - firstHalfRemainingItems;
-        int clampedTailItemCount = unrestrictedCount - clampedHeadItemCount - maxCount;
-
-        verify(adapter).notifyItemRemoved(maxCount + 1);
-        verify(adapter).notifyItemRangeInserted(maxCount + 1, clampedTailItemCount);
-        verify(adapter).notifyItemRangeInserted(1, clampedHeadItemCount);
-        verify(adapter).notifyItemRemoved(0);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestContentLimitingAdapter.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestContentLimitingAdapter.java
deleted file mode 100644
index 1af9a70..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestContentLimitingAdapter.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.ui.test.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TestContentLimitingAdapter extends ContentLimitingAdapter<TestViewHolder> {
-
-    private final List<String> mItems;
-
-    public TestContentLimitingAdapter(int numItems) {
-        mItems = new ArrayList<>();
-        for (int i = 0; i < numItems; i++) {
-            mItems.add("Item " + i);
-        }
-    }
-
-    @Override
-    protected TestViewHolder onCreateViewHolderImpl(@NonNull ViewGroup parent,
-            int viewType) {
-        View layout = LayoutInflater.from(parent.getContext())
-                .inflate(R.layout.test_car_ui_recycler_view_list_item, parent, false);
-        return new TestViewHolder(layout);
-    }
-
-    @Override
-    protected void onBindViewHolderImpl(TestViewHolder holder, int position) {
-        holder.bind(mItems.get(position));
-    }
-
-    @Override
-    protected int getUnrestrictedItemCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public int getConfigurationId() {
-        return 0;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestDelegatingContentLimitingAdapter.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestDelegatingContentLimitingAdapter.java
deleted file mode 100644
index 4a59c04..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestDelegatingContentLimitingAdapter.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-class TestDelegatingContentLimitingAdapter
-        extends RecyclerView.Adapter<TestViewHolder> {
-
-    private final List<String> mItems;
-
-    TestDelegatingContentLimitingAdapter(int numItems) {
-        mItems = new ArrayList<>();
-        for (int i = 0; i < numItems; i++) {
-            mItems.add("Item " + i);
-        }
-    }
-
-    @NonNull
-    @Override
-    public TestViewHolder onCreateViewHolder(
-            @NonNull ViewGroup parent, int viewType) {
-        View layout = LayoutInflater.from(parent.getContext())
-                .inflate(com.android.car.ui.test.R.layout.test_car_ui_recycler_view_list_item,
-                        parent, false);
-        return new TestViewHolder(layout);
-    }
-
-    @Override
-    public void onBindViewHolder(
-            @NonNull TestViewHolder holder, int position) {
-        holder.bind(mItems.get(position));
-    }
-
-    @Override
-    public int getItemCount() {
-        return mItems.size();
-    }
-
-    public String getItemText(int i) {
-        return "Item " + i;
-    }
-
-    public void changeItemRange(int positionStart, int itemCount) {
-        for (int i = 0; i < itemCount; i++) {
-            mItems.set(i + positionStart, mItems.get(i + positionStart) + "-changed");
-        }
-        notifyItemRangeChanged(positionStart, itemCount);
-    }
-
-    public void insertItemRange(int position, String... items) {
-        for (int i = 0; i < items.length; i++) {
-            mItems.add(position, items[i]);
-        }
-        notifyItemRangeInserted(position, items.length);
-    }
-
-    public void removeItemRange(int positionStart, int itemCount) {
-        for (int i = 0; i < itemCount; i++) {
-            mItems.remove(positionStart + i);
-        }
-        notifyItemRangeRemoved(positionStart, itemCount);
-    }
-
-    public void moveItem(int fromPosition, int toPosition) {
-        String item = mItems.get(fromPosition);
-        if (fromPosition > toPosition) {
-            mItems.remove(fromPosition);
-            mItems.add(toPosition, item);
-        } else {
-            mItems.add(toPosition, item);
-            mItems.remove(fromPosition);
-        }
-        notifyItemMoved(fromPosition, toPosition);
-    }
-
-    public void changeList(List<String> newItems) {
-        mItems.clear();
-        mItems.addAll(newItems);
-        notifyDataSetChanged();
-    }
-
-    static class WithContentLimiting extends TestDelegatingContentLimitingAdapter
-            implements DelegatingContentLimitingAdapter.ContentLimiting {
-
-        private int mScrollPositionWhenRestricted = -1;
-
-        WithContentLimiting(int numItems) {
-            super(numItems);
-        }
-
-        public void setScrollPositionWhenRestricted(int position) {
-            mScrollPositionWhenRestricted = position;
-        }
-
-        @Override
-        public int getScrollToPositionWhenRestricted() {
-            return mScrollPositionWhenRestricted;
-        }
-
-        @Override
-        public int computeAnchorIndexWhenRestricting() {
-            return 0;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestViewHolder.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestViewHolder.java
deleted file mode 100644
index d6b6899..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestViewHolder.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.test.R;
-
-public class TestViewHolder extends RecyclerView.ViewHolder {
-
-    private CharSequence mText;
-
-    TestViewHolder(@NonNull View itemView) {
-        super(itemView);
-    }
-
-    void bind(CharSequence text) {
-        mText = text;
-        TextView textView = itemView.requireViewById(R.id.textTitle);
-        textView.setText(text);
-    }
-
-    CharSequence getText() {
-        return mText;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/sharedlibrarysupport/SharedLibrarySpecifierTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/sharedlibrarysupport/SharedLibrarySpecifierTest.java
deleted file mode 100644
index dfc4e53..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/sharedlibrarysupport/SharedLibrarySpecifierTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.content.pm.PackageInfo;
-
-import androidx.test.core.content.pm.PackageInfoBuilder;
-
-import org.junit.Test;
-
-public class SharedLibrarySpecifierTest {
-
-    @Test
-    public void test_empty_sharedlibraryspecifier_matches_anything() {
-        SharedLibrarySpecifier sharedLibrarySpecifier = SharedLibrarySpecifier.builder()
-                .build();
-
-        PackageInfo packageInfo = PackageInfoBuilder.newBuilder()
-                .setPackageName("com.android.car.testsharedlib").build();
-        packageInfo.setLongVersionCode(100);
-
-        assertTrue(sharedLibrarySpecifier.matches(packageInfo));
-    }
-
-    @Test
-    public void test_sharedlibraryspecifier_doesnt_match_different_package_name() {
-        SharedLibrarySpecifier sharedLibrarySpecifier = SharedLibrarySpecifier.builder()
-                .setPackageName("com.android.car.testsharedlib")
-                .build();
-
-        PackageInfo packageInfo = PackageInfoBuilder.newBuilder()
-                .setPackageName("com.android.car.testsharedlib2").build();
-
-        assertFalse(sharedLibrarySpecifier.matches(packageInfo));
-    }
-
-    @Test
-    public void test_sharedlibraryspecifier_matches_same_package_name() {
-        SharedLibrarySpecifier sharedLibrarySpecifier = SharedLibrarySpecifier.builder()
-                .setPackageName("com.android.car.testsharedlib")
-                .build();
-
-        PackageInfo packageInfo = PackageInfoBuilder.newBuilder()
-                .setPackageName("com.android.car.testsharedlib").build();
-
-        assertTrue(sharedLibrarySpecifier.matches(packageInfo));
-    }
-
-    @Test
-    public void test_sharedlibraryspecifier_doesnt_match_versioncode() {
-        SharedLibrarySpecifier sharedLibrarySpecifier = SharedLibrarySpecifier.builder()
-                .setPackageName("com.android.car.testsharedlib")
-                .setMaxVersion(5)
-                .build();
-
-        PackageInfo packageInfo = PackageInfoBuilder.newBuilder()
-                .setPackageName("com.android.car.testsharedlib").build();
-        packageInfo.setLongVersionCode(6);
-
-        assertFalse(sharedLibrarySpecifier.matches(packageInfo));
-    }
-
-    @Test
-    public void test_sharedlibraryspecifier_matches_versioncode() {
-        SharedLibrarySpecifier sharedLibrarySpecifier = SharedLibrarySpecifier.builder()
-                .setPackageName("com.android.car.testsharedlib")
-                .setMaxVersion(5)
-                .build();
-
-        PackageInfo packageInfo = PackageInfoBuilder.newBuilder()
-                .setPackageName("com.android.car.testsharedlib").build();
-        packageInfo.setLongVersionCode(4);
-
-        assertTrue(sharedLibrarySpecifier.matches(packageInfo));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/EmptyToolbarController.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/EmptyToolbarController.java
deleted file mode 100644
index a984e14..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/EmptyToolbarController.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
-
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-/**
- * A class that implements ToolbarController but does nothing, just to easily get a non-null
- * ToolbarController
- */
-public class EmptyToolbarController implements ToolbarController {
-    @Override
-    public void setTitle(int title) {
-
-    }
-
-    @Override
-    public void setTitle(CharSequence title) {
-
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return null;
-    }
-
-    @Override
-    public void setSubtitle(int title) {
-
-    }
-
-    @Override
-    public void setSubtitle(CharSequence title) {
-
-    }
-
-    @Override
-    public CharSequence getSubtitle() {
-        return null;
-    }
-
-    @Override
-    public void setTabs(@Nullable List<Tab> tabs) {
-
-    }
-
-    @Override
-    public void setTabs(@Nullable List<Tab> tabs,
-            int selectedTab) {
-
-    }
-
-    @Override
-    public List<Tab> getTabs() {
-        return null;
-    }
-
-    @Override
-    public int getTabCount() {
-        return 0;
-    }
-
-    @Override
-    public int getTabPosition(TabLayout.Tab tab) {
-        return 0;
-    }
-
-    @Override
-    public void addTab(TabLayout.Tab tab) {
-
-    }
-
-    @Override
-    public void clearAllTabs() {
-
-    }
-
-    @Override
-    public TabLayout.Tab getTab(int position) {
-        return null;
-    }
-
-    @Override
-    public void selectTab(int position) {
-
-    }
-
-    @Override
-    public int getSelectedTab() {
-        return 0;
-    }
-
-    @Override
-    public void setShowTabsInSubpage(boolean showTabs) {
-
-    }
-
-    @Override
-    public boolean getShowTabsInSubpage() {
-        return false;
-    }
-
-    @Override
-    public void setLogo(int resId) {
-
-    }
-
-    @Override
-    public void setLogo(Drawable drawable) {
-
-    }
-
-    @Override
-    public void setSearchHint(int resId) {
-
-    }
-
-    @Override
-    public void setSearchHint(CharSequence hint) {
-
-    }
-
-    @Override
-    public CharSequence getSearchHint() {
-        return null;
-    }
-
-    @Override
-    public void setSearchIcon(int resId) {
-
-    }
-
-    @Override
-    public void setSearchIcon(Drawable d) {
-
-    }
-
-    @Override
-    public void setSearchMode(SearchMode mode) {
-
-    }
-
-    @Override
-    public void setNavButtonMode(Toolbar.NavButtonMode style) {
-
-    }
-
-    @Override
-    public void setNavButtonMode(NavButtonMode mode) {
-
-    }
-
-    @Override
-    public Toolbar.NavButtonMode getNavButtonMode() {
-        return null;
-    }
-
-    @Override
-    public void setBackgroundShown(boolean shown) {
-
-    }
-
-    @Override
-    public boolean getBackgroundShown() {
-        return false;
-    }
-
-    @Override
-    public void setMenuItems(@Nullable List<MenuItem> items) {
-
-    }
-
-    @Override
-    public List<MenuItem> setMenuItems(int resId) {
-        return null;
-    }
-
-    @NonNull
-    @Override
-    public List<MenuItem> getMenuItems() {
-        return null;
-    }
-
-    @Nullable
-    @Override
-    public MenuItem findMenuItemById(int id) {
-        return null;
-    }
-
-    @NonNull
-    @Override
-    public MenuItem requireMenuItemById(int id) {
-        return null;
-    }
-
-    @Override
-    public void setShowMenuItemsWhileSearching(boolean showMenuItems) {
-
-    }
-
-    @Override
-    public boolean getShowMenuItemsWhileSearching() {
-        return false;
-    }
-
-    @Override
-    public void setSearchQuery(String query) {
-
-    }
-
-    @Override
-    public void setState(Toolbar.State state) {
-
-    }
-
-    @Override
-    public Toolbar.State getState() {
-        return null;
-    }
-
-    @Override
-    public boolean isStateSet() {
-        return false;
-    }
-
-    @Override
-    public void registerOnTabSelectedListener(Toolbar.OnTabSelectedListener listener) {
-
-    }
-
-    @Override
-    public boolean unregisterOnTabSelectedListener(Toolbar.OnTabSelectedListener listener) {
-        return false;
-    }
-
-    @Override
-    public void registerOnSearchListener(Toolbar.OnSearchListener listener) {
-
-    }
-
-    @Override
-    public boolean unregisterOnSearchListener(Toolbar.OnSearchListener listener) {
-        return false;
-    }
-
-    @Override
-    public void registerSearchListener(Consumer<String> listener) {
-
-    }
-
-    @Override
-    public boolean unregisterSearchListener(Consumer<String> listener) {
-        return false;
-    }
-
-    @Override
-    public void setSearchConfig(@Nullable SearchConfig searchConfig) {
-
-    }
-
-    @Override
-    public SearchCapabilities getSearchCapabilities() {
-        return null;
-    }
-
-    @Override
-    public boolean canShowSearchResultItems() {
-        return false;
-    }
-
-    @Override
-    public boolean canShowSearchResultsView() {
-        return false;
-    }
-
-    @Override
-    public void setSearchResultsView(@Nullable View view) {
-
-    }
-
-    @Override
-    public void setSearchResultsInputViewIcon(@NonNull Drawable drawable) {
-
-    }
-
-    @Override
-    public void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems) {
-
-    }
-
-    @Override
-    public void registerOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener) {
-
-    }
-
-    @Override
-    public boolean unregisterOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener) {
-        return false;
-    }
-
-    @Override
-    public void registerSearchCompletedListener(Runnable listener) {
-
-    }
-
-    @Override
-    public boolean unregisterSearchCompletedListener(Runnable listener) {
-        return false;
-    }
-
-    @Override
-    public void registerOnBackListener(Toolbar.OnBackListener listener) {
-
-    }
-
-    @Override
-    public boolean unregisterOnBackListener(Toolbar.OnBackListener listener) {
-        return false;
-    }
-
-    @Override
-    public void registerBackListener(Supplier<Boolean> listener) {
-
-    }
-
-    @Override
-    public boolean unregisterBackListener(Supplier<Boolean> listener) {
-        return false;
-    }
-
-    @Override
-    public ProgressBarController getProgressBar() {
-        return null;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/InstallBaseLayoutAroundTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/InstallBaseLayoutAroundTest.java
deleted file mode 100644
index a09357e..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/InstallBaseLayoutAroundTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.FocusParkingView;
-import com.android.car.ui.TrulyEmptyActivity;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-/** A test of {@link com.android.car.ui.core.CarUi#installBaseLayoutAround} */
-@RunWith(Parameterized.class)
-public class InstallBaseLayoutAroundTest {
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        // It's important to do no shared library first, so that the shared library will
-        // still be enabled when this test finishes
-        return new Object[] { false, true };
-    }
-
-    private final boolean mSharedLibEnabled;
-
-    public InstallBaseLayoutAroundTest(boolean sharedLibEnabled) {
-        mSharedLibEnabled = sharedLibEnabled;
-        SharedLibraryFactorySingleton.setSharedLibEnabled(sharedLibEnabled);
-    }
-
-    @Rule
-    public final ActivityScenarioRule<TrulyEmptyActivity> mScenarioRule =
-            new ActivityScenarioRule<>(TrulyEmptyActivity.class);
-
-    @Test
-    public void test_installBaseLayoutAround_createsToolbar() {
-        onView(isAssignableFrom(FocusParkingView.class)).check(doesNotExist());
-
-        ToolbarController[] toolbar = new ToolbarController[] { null };
-        Insets[] insets = new Insets[] { null };
-        mScenarioRule.getScenario().onActivity(activity -> {
-            toolbar[0] = CarUi.installBaseLayoutAround(
-                    activity.requireViewById(android.R.id.content),
-                    i -> insets[0] = i,
-                    true);
-            if (toolbar[0] != null) {
-                toolbar[0].setTitle("Hello, world!");
-            }
-        });
-
-        assertNotNull(toolbar[0]);
-        onView(withText("Hello, world!")).check(matches(isDisplayed()));
-
-        assertNotNull(insets[0]);
-        // Technically this doesn't have to be true depending on the OEM's customizations
-        assertTrue(insets[0].getTop() > 0);
-        onView(isAssignableFrom(FocusParkingView.class)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void test_installBaseLayoutAround_doesntCreateToolbar() {
-        onView(isAssignableFrom(FocusParkingView.class)).check(doesNotExist());
-
-        ToolbarController[] toolbar = new ToolbarController[] { null };
-        mScenarioRule.getScenario().onActivity(activity ->
-                toolbar[0] = CarUi.installBaseLayoutAround(
-                        activity.requireViewById(android.R.id.content),
-                        i -> {},
-                        false));
-
-        assertNull(toolbar[0]);
-        onView(isAssignableFrom(FocusParkingView.class)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void test_emptyactivity_doesnthaveinsetsortoolbar() {
-        Insets[] insets = new Insets[] { new Insets() };
-        mScenarioRule.getScenario().onActivity(activity -> insets[0] = CarUi.getInsets(activity));
-        assertNull(insets[0]);
-
-        ToolbarController[] toolbar = new ToolbarController[] { new EmptyToolbarController() };
-        mScenarioRule.getScenario().onActivity(activity -> toolbar[0] = CarUi.getToolbar(activity));
-        assertNull(toolbar[0]);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarMenuItemsTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarMenuItemsTest.java
deleted file mode 100644
index f91ed89..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarMenuItemsTest.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
-import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.actions.ViewActions.waitForView;
-import static com.android.car.ui.matchers.ViewMatchers.doesNotExistOrIsNotDisplayed;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.hamcrest.core.IsNot.not;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.car.drivingstate.CarUxRestrictions;
-import android.content.Context;
-import android.view.View;
-import android.widget.Switch;
-
-import androidx.annotation.DrawableRes;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.matchers.ViewMatchers;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-import com.android.car.ui.test.R;
-
-import org.hamcrest.Matcher;
-import org.hamcrest.Matchers;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-@RunWith(Parameterized.class)
-public class ToolbarMenuItemsTest {
-    @Parameterized.Parameters
-    public static Object[] data() {
-        // It's important to do no shared library first, so that the shared library will
-        // still be enabled when this test finishes
-        return new Object[] { false, true };
-    }
-
-    private final boolean mSharedLibEnabled;
-
-    public ToolbarMenuItemsTest(boolean sharedLibEnabled) {
-        mSharedLibEnabled = sharedLibEnabled;
-        SharedLibraryFactorySingleton.setSharedLibEnabled(sharedLibEnabled);
-    }
-
-    @Rule
-    public final ActivityScenarioRule<ToolbarTestActivity> mScenarioRule =
-            new ActivityScenarioRule<>(ToolbarTestActivity.class);
-
-    @Test
-    public void menuItems_findMenuItemById_shouldWork() {
-        MenuItem[] menuItem = new MenuItem[] { null };
-        MenuItem[] foundMenuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Button!")
-                    .setId(5)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-            foundMenuItem[0] = toolbar.requireMenuItemById(5);
-        });
-
-        assertThat(foundMenuItem[0]).isSameInstanceAs(menuItem[0]);
-    }
-
-    @Test
-    public void menuItems_text_shouldShow() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Button!")
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        waitForViewWithText("Button!");
-
-        onView(withText("Button!")).perform(click());
-
-        verify(callback).onClick(menuItem[0]);
-    }
-
-    @Test
-    public void menuItems_icon_shouldShow() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("test_menuitem")
-                    .setIcon(R.drawable.ic_add)
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        assertThat(menuItem[0].isVisible()).isTrue();
-        assertThat(menuItem[0].isTinted()).isTrue();
-        assertThat(menuItem[0].isActivatable()).isFalse();
-        assertThat(menuItem[0].isCheckable()).isFalse();
-        assertThat(menuItem[0].getUxRestrictions()).isEqualTo(
-                CarUxRestrictions.UX_RESTRICTIONS_BASELINE);
-
-        onView(isRoot()).perform(waitForView(withContentDescription("test_menuitem"), 500));
-        onView(withText("test_menuitem")).check(doesNotExistOrIsNotDisplayed());
-        onView(withContentDescription("test_menuitem")).perform(click());
-
-        verify(callback).onClick(menuItem[0]);
-    }
-
-    @Test
-    public void menuItems_textAndIcon_shouldShow() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Test!")
-                    .setIcon(R.drawable.ic_add)
-                    .setShowIconAndTitle(true)
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        onView(isRoot()).perform(waitForView(withText("Test!"), 500));
-        onView(withText("Test!")).perform(click());
-
-        verify(callback).onClick(menuItem[0]);
-
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0].setTitle(R.string.test_string_test_title);
-            menuItem[0].setIcon(R.drawable.ic_launcher);
-        });
-
-        onView(withText("Test!")).check(doesNotExistOrIsNotDisplayed());
-        onView(withText("Test title!")).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void menuItems_removeIcon_shouldShowText() {
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Test!")
-                    .setIcon(R.drawable.ic_add)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        onView(isRoot()).perform(waitForView(withContentDescription("Test!"), 500));
-        onView(withContentDescription("Test!")).check(matches(isDisplayed()));
-        onView(withText("Test!")).check(doesNotExistOrIsNotDisplayed());
-
-        runWithActivityAndToolbar((activity, toolbar) -> menuItem[0].setIcon(0));
-
-        onView(withText("Test!")).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void menuItems_switch_shouldShow() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setCheckable()
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        assertThat(menuItem[0].isCheckable()).isTrue();
-        assertThat(menuItem[0].isChecked()).isFalse();
-
-        onView(isRoot()).perform(waitForView(isSwitch(), 500));
-        onView(isSwitch()).perform(click());
-
-        verify(callback).onClick(menuItem[0]);
-        onView(isSwitch()).check(matches(isChecked()));
-
-        assertThat(menuItem[0].isCheckable()).isTrue();
-        assertThat(menuItem[0].isChecked()).isTrue();
-    }
-
-    @Test
-    public void menuItems_overflowText_shouldWork() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Test title!")
-                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        // Open overflow menu, then click on the MenuItem
-        onView(isRoot()).perform(waitForView(withContentDescription("Overflow")));
-        onView(withContentDescription("Overflow")).perform(click());
-        onView(withText("Test title!")).perform(click());
-        verify(callback).onClick(menuItem[0]);
-
-        // TODO(b/188925810): this currently isn't supported in the referencedesign shared library.
-        if (!mSharedLibEnabled) {
-            // Open overflow menu, change MenuItem's title, then click on the MenuItem
-            onView(withContentDescription("Overflow")).perform(click());
-            runWithToolbar(toolbar -> menuItem[0].setTitle("Test title 2!"));
-            onView(withText("Test title 2!")).perform(click());
-            verify(callback, times(2)).onClick(menuItem[0]);
-        }
-    }
-
-    @Test
-    public void menuItems_overflowIconAndText_shouldWork() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Test title!")
-                    .setIcon(R.drawable.ic_add)
-                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        onView(isRoot()).perform(waitForView(withContentDescription("Overflow")));
-        onView(withContentDescription("Overflow")).perform(click());
-
-        onView(withText("Test title!")).perform(click());
-
-        verify(callback).onClick(menuItem[0]);
-    }
-
-    @Test
-    public void menuItems_getMenuItems_returnsSameMenuItems() {
-        List<MenuItem> menuItems = new ArrayList<>();
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItems.add(MenuItem.builder(activity)
-                    .setTitle("Menu Item 1")
-                    .build());
-            menuItems.add(MenuItem.builder(activity)
-                    .setTitle("Menu Item 2")
-                    .build());
-            toolbar.setMenuItems(menuItems);
-        });
-
-        onView(isRoot()).perform(waitForView(withText("Menu Item 1")));
-
-        boolean[] equal = new boolean[] { false };
-        runWithActivityAndToolbar((activity, toolbar) ->
-                equal[0] = menuItems.equals(toolbar.getMenuItems()));
-
-        assertThat(equal[0]).isTrue();
-    }
-
-    @Test
-    public void menuItems_null_shouldRemoveExistingMenuItems() {
-        runWithActivityAndToolbar((activity, toolbar) ->
-                toolbar.setMenuItems(Arrays.asList(
-                        MenuItem.builder(activity)
-                                .setTitle("Button!")
-                                .build(),
-                        MenuItem.builder(activity)
-                                .setTitle("Button2!")
-                                .build()
-                )));
-        waitForViewWithText("Button!");
-        waitForViewWithText("Button2!");
-
-        onView(withText("Button!")).check(matches(isDisplayed()));
-        onView(withText("Button2!")).check(matches(isDisplayed()));
-
-        runWithToolbar((toolbar) -> toolbar.setMenuItems(null));
-
-        onView(withText("Button!")).check(doesNotExist());
-        onView(withText("Button2!")).check(doesNotExist());
-    }
-
-    @Test
-    public void menuItems_setVisibility_shouldHide() {
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Button!")
-                    .build();
-
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        waitForViewWithText("Button!");
-        onView(withText("Button!")).check(matches(isDisplayed()));
-
-        runWithToolbar((toolbar) -> menuItem[0].setVisible(false));
-
-        onView(withText("Button!")).check(matches(not(isDisplayed())));
-    }
-
-    @Test
-    public void menuItems_setEnabled_shouldDisable() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Test!")
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        onView(isRoot()).perform(waitForView(withText("Test!"), 500));
-        onView(withText("Test!")).perform(click());
-
-        verify(callback, times(1)).onClick(menuItem[0]);
-
-        runWithActivityAndToolbar((activity, toolbar) -> menuItem[0].setEnabled(false));
-
-        onView(withText("Test!")).perform(click());
-
-        verify(callback, times(1)).onClick(menuItem[0]);
-    }
-
-    @Test
-    public void menuItems_activatable_test() {
-        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Test!")
-                    .setIcon(R.drawable.ic_add)
-                    .setActivatable()
-                    .setOnClickListener(callback)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        onView(isRoot()).perform(waitForView(withContentDescription("Test!"), 500));
-
-        assertThat(menuItem[0].isActivated()).isFalse();
-
-        runWithActivityAndToolbar((activity, toolbar) -> menuItem[0].setActivated(true));
-
-        assertThat(menuItem[0].isActivated()).isTrue();
-    }
-
-    @Test
-    public void menuItems_changeOnClickListener_shouldCallNewListener() {
-        MenuItem.OnClickListener callback1 = mock(MenuItem.OnClickListener.class);
-        MenuItem.OnClickListener callback2 = mock(MenuItem.OnClickListener.class);
-        MenuItem[] menuItem = new MenuItem[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            menuItem[0] = MenuItem.builder(activity)
-                    .setTitle("Button!")
-                    .setOnClickListener(callback1)
-                    .build();
-            toolbar.setMenuItems(Collections.singletonList(menuItem[0]));
-        });
-
-        waitForViewWithText("Button!");
-        onView(withText("Button!")).perform(click());
-        verify(callback1, times(1)).onClick(menuItem[0]);
-        verify(callback2, times(0)).onClick(menuItem[0]);
-
-        runWithActivityAndToolbar((activity, toolbar) -> menuItem[0].setOnClickListener(callback2));
-
-        onView(withText("Button!")).perform(click());
-        verify(callback1, times(1)).onClick(menuItem[0]);
-        verify(callback2, times(1)).onClick(menuItem[0]);
-    }
-
-
-    @Test
-    public void menuItems_searchScreen_shouldHideMenuItems() {
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            toolbar.setMenuItems(Arrays.asList(
-                    MenuItem.builder(activity)
-                            .setToSearch()
-                            .build(),
-                    MenuItem.builder(activity)
-                            .setTitle("Button!")
-                            .build()));
-            toolbar.setShowMenuItemsWhileSearching(true);
-            toolbar.setState(Toolbar.State.SEARCH);
-        });
-
-        waitForViewWithText("Button!");
-
-        // Even if not hiding MenuItems while searching, the search MenuItem should still be hidden
-        onView(withText("Button!")).check(matches(isDisplayed()));
-        onView(withContentDescription(R.string.car_ui_toolbar_menu_item_search_title))
-                .check(doesNotExistOrIsNotDisplayed());
-
-        runWithToolbar((toolbar) -> toolbar.setShowMenuItemsWhileSearching(false));
-
-        // All menuitems should be hidden if we're hiding menuitems while searching
-        onView(withText("Button!")).check(doesNotExistOrIsNotDisplayed());
-        onView(withContentDescription(R.string.car_ui_toolbar_menu_item_search_title))
-                .check(doesNotExistOrIsNotDisplayed());
-    }
-
-
-    private void runWithToolbar(Consumer<ToolbarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(toolbar);
-        });
-    }
-
-    private void runWithActivityAndToolbar(
-            BiConsumer<ToolbarTestActivity, ToolbarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(activity, toolbar);
-        });
-    }
-
-    private void waitForViewWithText(String text) {
-        onView(isRoot()).perform(waitForView(withText(text), 500));
-    }
-
-    private Matcher<View> withDrawable(@DrawableRes int drawable) {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        return ViewMatchers.withDrawable(context, com.android.car.ui.test.R.drawable.ic_launcher);
-    }
-
-    private Matcher<View> isSwitch() {
-        return Matchers.allOf(isDisplayed(), isAssignableFrom(Switch.class));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarProgressBarTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarProgressBarTest.java
deleted file mode 100644
index 8583b1f..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarProgressBarTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-
-import static com.android.car.ui.matchers.ViewMatchers.hasIndeterminateProgress;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.hamcrest.Matchers.allOf;
-
-import android.widget.ProgressBar;
-
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-@RunWith(Parameterized.class)
-public class ToolbarProgressBarTest {
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        // It's important to do no shared library first, so that the shared library will
-        // still be enabled when this test finishes
-        return new Object[] { false, true };
-    }
-
-    private final boolean mSharedLibEnabled;
-
-    public ToolbarProgressBarTest(boolean sharedLibEnabled) {
-        mSharedLibEnabled = sharedLibEnabled;
-        SharedLibraryFactorySingleton.setSharedLibEnabled(sharedLibEnabled);
-    }
-
-    @Rule
-    public final ActivityScenarioRule<ToolbarTestActivity> mScenarioRule =
-            new ActivityScenarioRule<>(ToolbarTestActivity.class);
-
-    @Test
-    public void test_showProgressBar_works() {
-        runWithProgressBar((progressBar) -> progressBar.setVisible(true));
-
-        // We don't want to enforce that the shared lib use a ProgressBar class
-        if (!mSharedLibEnabled) {
-            onView(isAssignableFrom(ProgressBar.class)).check(matches(
-                    allOf(isDisplayed(), hasIndeterminateProgress())));
-        }
-    }
-
-    @Test
-    public void test_settersAndGetters_work() {
-        boolean[] isVisible = new boolean[] { true };
-        boolean[] isIndeterminate = new boolean[] { false };
-        int[] min = new int[] { -5 };
-        int[] max = new int[] { -5 };
-        int[] progress = new int[] { -5 };
-
-        runWithProgressBar((progressBar) -> {
-            isVisible[0] = progressBar.isVisible();
-            isIndeterminate[0] = progressBar.isIndeterminate();
-            min[0] = progressBar.getMin();
-            max[0] = progressBar.getMax();
-            progress[0] = progressBar.getProgress();
-        });
-
-        assertThat(isVisible[0]).isFalse();
-        assertThat(isIndeterminate[0]).isTrue();
-        assertThat(min[0]).isEqualTo(0);
-        assertThat(max[0]).isEqualTo(100);
-        assertThat(progress[0]).isEqualTo(0);
-
-        runWithProgressBar((progressBar) -> {
-            progressBar.setVisible(true);
-            progressBar.setIndeterminate(false);
-            progressBar.setMin(50);
-            progressBar.setMax(75);
-            progressBar.setProgress(55);
-
-            isVisible[0] = progressBar.isVisible();
-            isIndeterminate[0] = progressBar.isIndeterminate();
-            min[0] = progressBar.getMin();
-            max[0] = progressBar.getMax();
-            progress[0] = progressBar.getProgress();
-        });
-
-        assertThat(isVisible[0]).isTrue();
-        assertThat(isIndeterminate[0]).isFalse();
-        assertThat(min[0]).isEqualTo(50);
-        assertThat(max[0]).isEqualTo(75);
-        assertThat(progress[0]).isEqualTo(55);
-    }
-
-    private void runWithProgressBar(Consumer<ProgressBarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(toolbar.getProgressBar());
-        });
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarSearchTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarSearchTest.java
deleted file mode 100644
index 132cba8..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarSearchTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.typeText;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withHint;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.matchers.ViewMatchers.doesNotExistOrIsNotDisplayed;
-import static com.android.car.ui.matchers.ViewMatchers.withDrawable;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.widget.EditText;
-
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-import com.android.car.ui.test.R;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.function.Consumer;
-
-/** Unit test for the search functionality in {@link ToolbarController}. */
-@SuppressWarnings("AndroidJdkLibsChecker")
-@RunWith(Parameterized.class)
-public class ToolbarSearchTest {
-    @Parameterized.Parameters
-    public static Object[][] data() {
-        // It's important to do no shared library first, so that the shared library will
-        // still be enabled when this test finishes
-        return new Object[][] {
-            new Object[] {false, SearchMode.SEARCH},
-            new Object[] {false, SearchMode.EDIT},
-            new Object[] {true, SearchMode.SEARCH},
-            new Object[] {true, SearchMode.EDIT},
-        };
-    }
-
-    private final SearchMode mSearchMode;
-
-    public ToolbarSearchTest(boolean sharedLibEnabled, SearchMode searchMode) {
-        SharedLibraryFactorySingleton.setSharedLibEnabled(sharedLibEnabled);
-        mSearchMode = searchMode;
-    }
-
-    @Rule
-    public final ActivityScenarioRule<ToolbarTestActivity> mScenarioRule =
-            new ActivityScenarioRule<>(ToolbarTestActivity.class);
-
-    @Test
-    public void test_setSearchQueryBeforeSearchMode_doesNothing() {
-        runWithToolbar(toolbar -> toolbar.setSearchQuery("Hello, world!"));
-        onView(withText("Hello, world!")).check(doesNotExistOrIsNotDisplayed());
-    }
-
-    @Test
-    public void test_setSearchQueryAfterSearchMode_showsQuery() {
-        runWithToolbar(toolbar -> {
-            toolbar.setSearchMode(mSearchMode);
-            toolbar.setSearchQuery("Hello, world!");
-        });
-        onView(withText("Hello, world!")).check(matches(isDisplayed()));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void test_registerSearchListeners_callsListeners() {
-        Consumer<String> searchListener = mock(Consumer.class);
-        Runnable searchCompletedListener = mock(Runnable.class);
-        runWithToolbar(toolbar -> {
-            toolbar.setSearchMode(mSearchMode);
-            toolbar.registerSearchListener(searchListener);
-            toolbar.registerSearchCompletedListener(searchCompletedListener);
-        });
-        onView(isAssignableFrom(EditText.class)).perform(typeText("hello\n"));
-
-        verify(searchListener).accept("h");
-        verify(searchListener).accept("he");
-        verify(searchListener).accept("hel");
-        verify(searchListener).accept("hell");
-        verify(searchListener).accept("hello");
-        verify(searchCompletedListener).run();
-    }
-
-    @Test
-    public void test_setSearchIcon_showsIcon() {
-        runWithToolbar(toolbar -> {
-            toolbar.setSearchMode(mSearchMode);
-            toolbar.setLogo(R.drawable.ic_launcher);
-            toolbar.setSearchIcon(R.drawable.ic_settings_gear);
-        });
-
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        onView(withDrawable(context, R.drawable.ic_launcher)).check(matches(isDisplayed()));
-        if (mSearchMode == SearchMode.SEARCH) {
-            onView(withDrawable(context, R.drawable.ic_settings_gear))
-                .check(matches(isDisplayed()));
-        } else {
-            onView(withDrawable(context, R.drawable.ic_settings_gear))
-                .check(doesNotExistOrIsNotDisplayed());
-        }
-    }
-
-    @Test
-    public void test_setSearchIconTo0_removesIcon() {
-        runWithToolbar(toolbar -> {
-            toolbar.setSearchMode(mSearchMode);
-            toolbar.setSearchIcon(R.drawable.ic_settings_gear);
-            toolbar.setSearchIcon(0);
-        });
-
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        onView(withDrawable(context, R.drawable.ic_settings_gear))
-            .check(doesNotExistOrIsNotDisplayed());
-    }
-
-    @Test
-    public void test_setSearchModeDisabled_hidesSearchBox() {
-        runWithToolbar(toolbar -> toolbar.setSearchMode(mSearchMode));
-        onView(isAssignableFrom(EditText.class)).check(matches(isDisplayed()));
-
-        runWithToolbar(toolbar -> toolbar.setSearchMode(SearchMode.DISABLED));
-        onView(isAssignableFrom(EditText.class)).check(doesNotExistOrIsNotDisplayed());
-    }
-
-    @Test
-    public void test_setSearchHint_isDisplayed() {
-        runWithToolbar((toolbar) -> {
-            toolbar.setSearchHint("Test search hint");
-            toolbar.setSearchMode(mSearchMode);
-        });
-
-        onView(withHint("Test search hint")).check(matches(isDisplayed()));
-
-        runWithToolbar((toolbar) -> {
-            toolbar.setSearchHint(R.string.test_string_test_title);
-            toolbar.setSearchMode(mSearchMode);
-        });
-
-        onView(withHint("Test title!")).check(matches(isDisplayed()));
-    }
-
-    private void runWithToolbar(Consumer<ToolbarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(toolbar);
-        });
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTabDeprecatedTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTabDeprecatedTest.java
deleted file mode 100644
index ba19a6e..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTabDeprecatedTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-@RunWith(Parameterized.class)
-public class ToolbarTabDeprecatedTest {
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        // It's important to do no shared library first, so that the shared library will
-        // still be enabled when this test finishes
-        return new Object[] { false, true };
-    }
-
-    public ToolbarTabDeprecatedTest(boolean sharedLibEnabled) {
-        SharedLibraryFactorySingleton.setSharedLibEnabled(sharedLibEnabled);
-    }
-
-    @Rule
-    public final ActivityScenarioRule<ToolbarTestActivity> mScenarioRule =
-            new ActivityScenarioRule<>(ToolbarTestActivity.class);
-
-    @Test
-    public void test_addTab_works() {
-        Toolbar.OnTabSelectedListener tabSelectedListener =
-                mock(Toolbar.OnTabSelectedListener.class);
-
-        List<TabLayout.Tab> tabs = Arrays.asList(
-                new TabLayout.Tab(null, "Tab 1"),
-                new TabLayout.Tab(null, "Tab 2"));
-        runWithToolbar(toolbar -> {
-            toolbar.addTab(tabs.get(0));
-            toolbar.addTab(tabs.get(1));
-            toolbar.registerOnTabSelectedListener(tabSelectedListener);
-        });
-
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 2")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 2")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-
-        // Tab listeners are not recalled when the tab is already selected
-        verify(tabSelectedListener, times(2)).onTabSelected(tabs.get(0));
-        verify(tabSelectedListener, times(2)).onTabSelected(tabs.get(1));
-    }
-
-    @Test
-    public void test_getTabCountAndClearTabs_works() {
-        int[] tabCount = new int[] { -1 };
-
-        runWithToolbar(toolbar -> tabCount[0] = toolbar.getTabCount());
-        assertThat(tabCount[0]).isEqualTo(0);
-
-        runWithToolbar(toolbar -> {
-            toolbar.addTab(new TabLayout.Tab(null, "Tab 1"));
-            toolbar.addTab(new TabLayout.Tab(null, "Tab 2"));
-            tabCount[0] = toolbar.getTabCount();
-        });
-        assertThat(tabCount[0]).isEqualTo(2);
-
-        runWithToolbar(toolbar -> {
-            toolbar.clearAllTabs();
-            tabCount[0] = toolbar.getTabCount();
-        });
-        assertThat(tabCount[0]).isEqualTo(0);
-    }
-
-    private void runWithToolbar(Consumer<ToolbarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(toolbar);
-        });
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTabTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTabTest.java
deleted file mode 100644
index 9cb4e71..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTabTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.matchers.ViewMatchers.doesNotExistOrIsNotDisplayed;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-
-import androidx.core.content.ContextCompat;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-import com.android.car.ui.test.R;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-@RunWith(Parameterized.class)
-public class ToolbarTabTest {
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        // It's important to do no shared library first, so that the shared library will
-        // still be enabled when this test finishes
-        return new Object[] { false, true };
-    }
-
-    public ToolbarTabTest(boolean sharedLibEnabled) {
-        SharedLibraryFactorySingleton.setSharedLibEnabled(sharedLibEnabled);
-    }
-
-    @Rule
-    public final ActivityScenarioRule<ToolbarTestActivity> mScenarioRule =
-            new ActivityScenarioRule<>(ToolbarTestActivity.class);
-
-    @Test
-    public void test_basicTab_settersAndGetters() {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        Consumer<Tab> selectedListener = tab -> {};
-        Tab tab = Tab.builder()
-                .setText("Foo")
-                .setIcon(ContextCompat.getDrawable(context, R.drawable.ic_add))
-                .setSelectedListener(selectedListener)
-                .build();
-        assertThat(tab.getText()).isEqualTo("Foo");
-        assertThat(tab.getIcon()).isNotNull();
-        assertThat(tab.getSelectedListener()).isSameInstanceAs(selectedListener);
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void test_setTabs_areShown() {
-        Consumer<Tab> tabSelectedListener = mock(Consumer.class);
-        List<Tab> tabs = Arrays.asList(
-                Tab.builder()
-                        .setText("Tab 1")
-                        .setSelectedListener(tabSelectedListener)
-                        .build(),
-                Tab.builder()
-                        .setText("Tab 2")
-                        .setSelectedListener(tabSelectedListener)
-                        .build());
-        runWithToolbar(toolbar -> toolbar.setTabs(tabs));
-
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 2")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 2")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-        onView(withText("Tab 1")).perform(click());
-
-        // Tab listeners are not recalled when the tab is already selected
-        verify(tabSelectedListener, times(2)).accept(tabs.get(0));
-        verify(tabSelectedListener, times(2)).accept(tabs.get(1));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void test_selectTab_works() {
-        Consumer<Tab> tabSelectedListener = mock(Consumer.class);
-        List<Tab> tabs = Arrays.asList(
-                Tab.builder()
-                        .setText("Tab 1")
-                        .setSelectedListener(tabSelectedListener)
-                        .build(),
-                Tab.builder()
-                        .setText("Tab 2")
-                        .setSelectedListener(tabSelectedListener)
-                        .build());
-        runWithToolbar(toolbar -> {
-            toolbar.setTabs(tabs);
-            toolbar.selectTab(1);
-        });
-
-        verify(tabSelectedListener, times(1)).accept(tabs.get(1));
-    }
-
-    @Test
-    public void test_clearAllTabs_works() {
-        runWithToolbar(toolbar -> {
-            toolbar.setTabs(Arrays.asList(
-                    Tab.builder()
-                            .setText("Tab 1")
-                            .build(),
-                    Tab.builder()
-                            .setText("Tab 2")
-                            .build()));
-            toolbar.clearAllTabs();
-        });
-
-        onView(withText("Tab 1")).check(doesNotExistOrIsNotDisplayed());
-        onView(withText("Tab 2")).check(doesNotExistOrIsNotDisplayed());
-    }
-
-    private void runWithToolbar(Consumer<ToolbarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(toolbar);
-        });
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTest.java
deleted file mode 100644
index 0971722..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTest.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.car.ui.matchers.ViewMatchers.doesNotExistOrIsNotDisplayed;
-import static com.android.car.ui.matchers.ViewMatchers.withDrawable;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.TestCase.assertEquals;
-
-import android.content.Context;
-
-import androidx.core.content.ContextCompat;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-import com.android.car.ui.test.R;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-/** Unit test for {@link ToolbarController}. */
-@SuppressWarnings("AndroidJdkLibsChecker")
-@RunWith(Parameterized.class)
-public class ToolbarTest {
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        // It's important to do no shared library first, so that the shared library will
-        // still be enabled when this test finishes
-        return new Object[] { false, true };
-    }
-
-    private final boolean mSharedLibEnabled;
-
-    public ToolbarTest(boolean sharedLibEnabled) {
-        mSharedLibEnabled = sharedLibEnabled;
-        SharedLibraryFactorySingleton.setSharedLibEnabled(sharedLibEnabled);
-    }
-
-    @Rule
-    public final ActivityScenarioRule<ToolbarTestActivity> mScenarioRule =
-            new ActivityScenarioRule<>(ToolbarTestActivity.class);
-
-    @Test
-    public void test_setTitle_displaysTitle() {
-        runWithToolbar((toolbar) -> toolbar.setTitle("Test title"));
-        onView(withText("Test title")).check(matches(isDisplayed()));
-
-        // withText() uses the target context, not the instrumentation test's context.
-        String toolbarTitle = InstrumentationRegistry.getInstrumentation().getContext()
-                .getString(R.string.test_string_test_title);
-        runWithToolbar(toolbar -> toolbar.setTitle(R.string.test_string_test_title));
-        onView(withText(toolbarTitle)).check(matches(isDisplayed()));
-
-        runWithToolbar(toolbar -> toolbar.setTitle(0));
-        onView(withText(toolbarTitle)).check(doesNotExistOrIsNotDisplayed());
-    }
-
-    /**
-     * This is somewhat of a bug, but various tests in other apps rely on this functionality.
-     */
-    @Test
-    public void test_setTitle_null_returns_nonNull() {
-        CharSequence[] getTitleResult = new CharSequence[] {"Something obviously incorrect"};
-        runWithToolbar((toolbar) -> {
-            toolbar.setTitle(null);
-            getTitleResult[0] = toolbar.getTitle();
-        });
-
-        assertEquals("", getTitleResult[0]);
-    }
-
-    /**
-     * This is somewhat of a bug, but various tests in other apps rely on this functionality.
-     */
-    @Test
-    public void test_setSubtitle_null_returns_nonNull() {
-        CharSequence[] getTitleResult = new CharSequence[] {"Something obviously incorrect"};
-        runWithToolbar((toolbar) -> {
-            toolbar.setSubtitle(null);
-            getTitleResult[0] = toolbar.getSubtitle();
-        });
-
-        assertEquals("", getTitleResult[0]);
-    }
-
-    @Test
-    public void test_setSubtitle_displaysSubtitle() {
-        runWithToolbar((toolbar) -> toolbar.setSubtitle("Test subtitle"));
-        onView(withText("Test subtitle")).check(matches(isDisplayed()));
-
-        runWithToolbar((toolbar) -> toolbar.setSubtitle(R.string.test_string_test_title));
-        onView(withText("Test title!")).check(matches(isDisplayed()));
-
-        runWithToolbar((toolbar) -> toolbar.setSubtitle(0));
-        onView(withText("Test title!")).check(doesNotExistOrIsNotDisplayed());
-    }
-
-    @Test
-    public void setters_and_getters_test() {
-        runWithToolbar((toolbar) -> {
-            toolbar.setTitle("Foo");
-            toolbar.setSearchHint("Foo2");
-            toolbar.setShowMenuItemsWhileSearching(true);
-            toolbar.setState(Toolbar.State.SUBPAGE);
-            toolbar.setNavButtonMode(Toolbar.NavButtonMode.CLOSE);
-
-            assertThat(toolbar.getTitle().toString()).isEqualTo("Foo");
-            assertThat(toolbar.getSearchHint().toString()).isEqualTo("Foo2");
-            assertThat(toolbar.getShowMenuItemsWhileSearching()).isEqualTo(true);
-            assertThat(toolbar.getState()).isEquivalentAccordingToCompareTo(Toolbar.State.SUBPAGE);
-            assertThat(toolbar.getNavButtonMode()).isEquivalentAccordingToCompareTo(
-                    Toolbar.NavButtonMode.CLOSE);
-        });
-    }
-
-    @Test
-    public void test_setLogo_displaysLogo() {
-        runWithToolbar((toolbar) -> toolbar.setLogo(R.drawable.ic_launcher));
-
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        onView(withDrawable(context, R.drawable.ic_launcher)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void test_setLogoDrawable_displaysLogo() {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        runWithToolbar((toolbar) ->
-                toolbar.setLogo(ContextCompat.getDrawable(context, R.drawable.ic_launcher)));
-
-        onView(withDrawable(context, R.drawable.ic_launcher)).check(matches(isDisplayed()));
-
-        runWithToolbar((toolbar) -> toolbar.setLogo(null));
-
-        onView(withDrawable(context, R.drawable.ic_launcher)).check(doesNotExistOrIsNotDisplayed());
-    }
-
-    @Test
-    public void pressBack_withoutListener_callsActivityOnBack() {
-        ToolbarTestActivity[] savedActivity = new ToolbarTestActivity[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            toolbar.setState(Toolbar.State.SUBPAGE);
-            savedActivity[0] = activity;
-        });
-
-        onView(withContentDescription("Back")).perform(click());
-
-        assertEquals(1, savedActivity[0].getTimesOnBackPressed());
-    }
-
-    @Test
-    public void pressBack_withListenerThatReturnsFalse_callsActivityOnBack() {
-        ToolbarTestActivity[] savedActivity = new ToolbarTestActivity[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            toolbar.setState(Toolbar.State.SUBPAGE);
-            toolbar.registerOnBackListener(() -> false);
-            savedActivity[0] = activity;
-        });
-
-        onView(withContentDescription("Back")).perform(click());
-
-        assertEquals(1, savedActivity[0].getTimesOnBackPressed());
-    }
-
-    @Test
-    public void pressBack_withListenerThatReturnsTrue_doesntCallActivityOnBack() {
-        ToolbarTestActivity[] savedActivity = new ToolbarTestActivity[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            toolbar.setState(Toolbar.State.SUBPAGE);
-            toolbar.registerOnBackListener(() -> true);
-            savedActivity[0] = activity;
-        });
-
-        onView(withContentDescription("Back")).perform(click());
-
-        assertEquals(0, savedActivity[0].getTimesOnBackPressed());
-    }
-
-    @Test
-    public void pressBack_withUnregisteredListener_doesntCallActivityOnBack() {
-        ToolbarTestActivity[] savedActivity = new ToolbarTestActivity[] { null };
-        runWithActivityAndToolbar((activity, toolbar) -> {
-            toolbar.setState(Toolbar.State.SUBPAGE);
-            Toolbar.OnBackListener listener = () -> true;
-            toolbar.registerOnBackListener(listener);
-            toolbar.registerOnBackListener(listener);
-            toolbar.unregisterOnBackListener(listener);
-            savedActivity[0] = activity;
-        });
-
-        onView(withContentDescription("Back")).perform(click());
-
-        assertEquals(1, savedActivity[0].getTimesOnBackPressed());
-    }
-
-    @Test
-    public void test_backgroundShown_worksAsExpected() {
-        boolean[] backgroundShown = new boolean[] { false };
-        runWithToolbar((toolbar) -> backgroundShown[0] = toolbar.getBackgroundShown());
-
-        assertThat(backgroundShown[0]).isTrue();
-
-        runWithToolbar((toolbar) -> {
-            toolbar.setBackgroundShown(false);
-            backgroundShown[0] = toolbar.getBackgroundShown();
-        });
-
-        if (mSharedLibEnabled) {
-            // Shared lib doesn't support hiding the background
-            // Temporarily disabled while we're not using the shared lib
-            // assertThat(backgroundShown[0]).isTrue();
-        } else {
-            assertThat(backgroundShown[0]).isFalse();
-        }
-    }
-
-    @Test
-    public void test_requireInsets_returnsInsets() {
-        Insets[] insets = new Insets[] { null };
-        mScenarioRule.getScenario().onActivity(activity ->
-                insets[0] = CarUi.requireInsets(activity));
-        assertNotNull(insets[0]);
-    }
-
-    private void runWithToolbar(Consumer<ToolbarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(toolbar);
-        });
-    }
-
-    private void runWithActivityAndToolbar(
-            BiConsumer<ToolbarTestActivity, ToolbarController> toRun) {
-        mScenarioRule.getScenario().onActivity(activity -> {
-            ToolbarController toolbar = CarUi.requireToolbar(activity);
-            toRun.accept(activity, toolbar);
-        });
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTestActivity.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTestActivity.java
deleted file mode 100644
index 906305e..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/toolbar/ToolbarTestActivity.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.car.ui.test.R;
-
-/** An Activity used for testing {@link ToolbarController}. */
-public class ToolbarTestActivity extends Activity {
-
-    private int mTimesOnBackPressed = 0;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.empty_test_activity);
-    }
-
-    /**
-     * ag/12161937 changes the behavior of pressing back on the top level activity, so
-     * assert the number of times onBackPressed() is called instead of if the activity isFinishing()
-     */
-    public int getTimesOnBackPressed() {
-        return mTimesOnBackPressed;
-    }
-
-    @Override
-    public void onBackPressed() {
-        super.onBackPressed();
-        mTimesOnBackPressed++;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/uxr/DrawableStateViewTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/uxr/DrawableStateViewTest.java
deleted file mode 100644
index e3ccd3a..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/uxr/DrawableStateViewTest.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import static org.junit.Assert.assertNotNull;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.car.ui.TestActivity;
-import com.android.car.ui.test.R;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-@RunWith(Parameterized.class)
-public class DrawableStateViewTest {
-
-    private static final List<Class<? extends DrawableStateView>> ALL_DRAWABLE_STATE_VIEWS =
-            Collections.unmodifiableList(Arrays.asList(
-                    DrawableStateButton.class,
-                    DrawableStateConstraintLayout.class,
-                    DrawableStateFrameLayout.class,
-                    DrawableStateImageView.class,
-                    DrawableStateLinearLayout.class,
-                    DrawableStateRelativeLayout.class,
-                    DrawableStateSwitch.class,
-                    DrawableStateTextView.class,
-                    DrawableStateToggleButton.class));
-
-    @Parameterized.Parameters
-    public static Object[] data() {
-        return ALL_DRAWABLE_STATE_VIEWS.toArray();
-    }
-
-    private final Class<? extends DrawableStateView> mClassToTest;
-
-    public DrawableStateViewTest(Class<? extends DrawableStateView> classToTest) {
-        mClassToTest = classToTest;
-    }
-
-    @Rule
-    public final ActivityScenarioRule<TestActivity> mScenarioRule =
-            new ActivityScenarioRule<>(TestActivity.class);
-
-    @Test
-    public void test_drawablestateview_methods_work() throws ReflectiveOperationException {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        DrawableStateView button = mClassToTest.getDeclaredConstructor(Context.class)
-                .newInstance(context);
-
-        int[] drawableState = runOnUiThread(((View) button)::getDrawableState);
-
-        assertDrawableArrays(
-                drawableState,
-                new int[] { android.R.attr.state_enabled },
-                null);
-
-        drawableState = runOnUiThread(() -> {
-            ((View) button).setEnabled(false);
-            return ((View) button).getDrawableState();
-        });
-
-        assertDrawableArrays(
-                drawableState,
-                null,
-                new int[] { android.R.attr.state_enabled });
-
-        drawableState = runOnUiThread(() -> {
-            ((View) button).setEnabled(true);
-            button.setExtraDrawableState(new int[] { R.attr.state_ux_restricted }, null);
-            return ((View) button).getDrawableState();
-        });
-
-        assertDrawableArrays(
-                drawableState,
-                new int[] {
-                        android.R.attr.state_enabled,
-                        R.attr.state_ux_restricted
-                },
-                null);
-
-
-        drawableState = runOnUiThread(() -> {
-            ((View) button).setEnabled(true);
-            button.setExtraDrawableState(
-                    new int[] { R.attr.state_ux_restricted },
-                    new int[] { android.R.attr.state_enabled });
-            return ((View) button).getDrawableState();
-        });
-
-        assertDrawableArrays(
-                drawableState,
-                new int[] { R.attr.state_ux_restricted },
-                new int[] { android.R.attr.state_enabled });
-    }
-
-    @Test
-    public void test_setExtraDrawableState_calledFirst() throws ReflectiveOperationException {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        DrawableStateView button = mClassToTest.getDeclaredConstructor(Context.class)
-                .newInstance(context);
-
-        int[] drawableState = runOnUiThread(() -> {
-            button.setExtraDrawableState(new int[] { R.attr.state_ux_restricted }, null);
-            return ((View) button).getDrawableState();
-        });
-
-        assertDrawableArrays(
-                drawableState,
-                new int[] { android.R.attr.state_enabled, R.attr.state_ux_restricted },
-                null);
-    }
-
-    @Test
-    public void test_emptyStateToRemove_works() throws ReflectiveOperationException {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        DrawableStateView button = mClassToTest.getDeclaredConstructor(Context.class)
-                .newInstance(context);
-
-        int[] drawableState = runOnUiThread(() -> {
-            button.setExtraDrawableState(null, new int[] {});
-            return ((View) button).getDrawableState();
-        });
-
-        assertDrawableArrays(
-                drawableState,
-                new int[] { android.R.attr.state_enabled },
-                new int[] { R.attr.state_ux_restricted });
-    }
-
-    @Test
-    public void test_constructors_work() throws ReflectiveOperationException {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        assertNotNull(mClassToTest
-                .getDeclaredConstructor(Context.class)
-                .newInstance(context));
-        assertNotNull(mClassToTest
-                .getDeclaredConstructor(Context.class, AttributeSet.class)
-                .newInstance(context, null));
-        assertNotNull(mClassToTest
-                .getDeclaredConstructor(Context.class, AttributeSet.class, int.class)
-                .newInstance(context, null, 0));
-    }
-
-    private int[] runOnUiThread(Supplier<int[]> runnable) {
-        int[][] result = new int[][] {null};
-        mScenarioRule.getScenario().onActivity(activity -> result[0] = runnable.get());
-        return result[0];
-    }
-
-    /**
-     * Checks that a drawable array has some attributes and doesn't have others.
-     *
-     * @param drawableArr The drawable array to check
-     * @param contains An array of attributes that the drawable array must contain.
-     * @param doesntContain An array of attributes the drawable array must not contain.
-     */
-    private static void assertDrawableArrays(
-            int[] drawableArr, int[] contains, int[] doesntContain) {
-        if (contains != null) {
-            for (int contain : contains) {
-                boolean found = false;
-                for (int attr : drawableArr) {
-                    if (attr == contain) {
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
-                    Assert.fail("Drawable array " + drawableArrayToString(drawableArr)
-                            + " did not contain required attribute "
-                            + getResourceName(contain));
-                }
-            }
-        }
-
-        if (doesntContain != null) {
-            for (int notContained : doesntContain) {
-                for (int attr : drawableArr) {
-                    if (attr == notContained) {
-                        Assert.fail("Drawable array " + drawableArrayToString(drawableArr)
-                                + " contained prohibited attribute "
-                                + getResourceName(notContained));
-                    }
-                }
-            }
-        }
-    }
-
-    @NonNull
-    private static String drawableArrayToString(@Nullable int[] arr) {
-        if (arr == null) {
-            return "null";
-        }
-
-        return "[" + Arrays.stream(arr)
-                .mapToObj(DrawableStateViewTest::getResourceName)
-                .collect(Collectors.joining(", ")) + "]";
-    }
-
-    private static String getResourceName(int resource) {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-
-        try {
-            return context.getResources().getResourceName(resource);
-        } catch (Resources.NotFoundException e) {
-            return String.valueOf(resource);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/widget/CarUiTextViewTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/widget/CarUiTextViewTest.java
deleted file mode 100644
index 65c46a4..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/widget/CarUiTextViewTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.widget;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withHint;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.junit.Assert.assertEquals;
-
-import android.graphics.Color;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.style.ForegroundColorSpan;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.test.ext.junit.rules.ActivityScenarioRule;
-
-import com.android.car.ui.CarUiText;
-import com.android.car.ui.TestActivity;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link CarUiTextViewTest}.
- */
-public class CarUiTextViewTest {
-    private static final CharSequence LONG_CHAR_SEQUENCE =
-            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "
-                    + "incididunt ut labore et dolore magna aliqua. Netus et malesuada fames ac "
-                    + "turpis egestas maecenas pharetra convallis. At urna condimentum mattis "
-                    + "pellentesque id nibh tortor. Purus in mollis nunc sed id semper risus in. "
-                    + "Turpis massa tincidunt dui ut ornare lectus sit amet. Porttitor lacus "
-                    + "luctus accumsan tortor posuere ac. Augue eget arcu dictum varius. Massa "
-                    + "tempor nec feugiat nisl pretium fusce id velit ut. Fames ac turpis egestas"
-                    + " sed tempus urna et pharetra pharetra. Tellus orci ac auctor augue mauris "
-                    + "augue neque gravida. Purus viverra accumsan in nisl nisi scelerisque eu. "
-                    + "Ut lectus arcu bibendum at varius vel pharetra. Penatibus et magnis dis "
-                    + "parturient montes nascetur ridiculus mus. Suspendisse sed nisi lacus sed "
-                    + "viverra tellus in hac habitasse.";
-
-    @Rule
-    public ActivityScenarioRule<TestActivity> mActivityRule =
-            new ActivityScenarioRule<>(TestActivity.class);
-
-    private TestActivity mActivity;
-
-    @Before
-    public void setUp() {
-        mActivityRule.getScenario().onActivity(activity -> {
-            mActivity = activity;
-        });
-    }
-
-    @Test
-    public void testTruncateToVariant_startAsViewGone() {
-        CarUiTextView textView = CarUiTextView.create(mActivity);
-        List<CharSequence> list = new ArrayList<>();
-        list.add(LONG_CHAR_SEQUENCE);
-        String variant = "Second string";
-        list.add(variant);
-        textView.setText(new CarUiText.Builder(list).setMaxLines(1).build());
-        ViewGroup container = mActivity.findViewById(
-                com.android.car.ui.test.R.id.test_container);
-        container.post(() -> container.setVisibility(View.GONE));
-        container.post(() -> container.addView(textView));
-        container.post(() -> container.setVisibility(View.VISIBLE));
-
-        onView(withText(variant)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testSpanOverLastLine() {
-        CarUiTextView textView = CarUiTextView.create(mActivity);
-        String hint = "Test textView";
-        textView.setHint(hint);
-        SpannableString text = new SpannableString(LONG_CHAR_SEQUENCE);
-        ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
-        text.setSpan(span, 0, text.length() - 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-        textView.setText(new CarUiText.Builder(text).setMaxLines(3).build());
-        ViewGroup container = mActivity.findViewById(
-                com.android.car.ui.test.R.id.test_container);
-        container.post(() -> container.addView(textView));
-
-        onView(withHint(hint)).check(matches(isDisplayed()));
-
-        Spanned displayedText = (Spanned) textView.getText();
-        assertEquals(displayedText.length(), displayedText.getSpanEnd(span));
-    }
-
-    @Test
-    public void testLineBreaks_lineBreakAtEnd() {
-        CarUiTextView textView = CarUiTextView.create(mActivity);
-        String hint = "Test textView";
-        textView.setHint(hint);
-        CharSequence text = "This is line 1\nline2\nand then line\n";
-        textView.setText(new CarUiText.Builder(text).setMaxLines(3).build());
-        ViewGroup container = mActivity.findViewById(
-                com.android.car.ui.test.R.id.test_container);
-        container.post(() -> container.addView(textView));
-
-        onView(withHint(hint)).check(matches(isDisplayed()));
-        assertEquals(3, textView.getLineCount());
-    }
-
-    @Test
-    public void testSpan() {
-        CarUiTextView textView = CarUiTextView.create(mActivity);
-        String hint = "Test textView";
-        SpannableString text = new SpannableString("Test");
-        ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
-        text.setSpan(span, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
-        textView.setHint(hint);
-        textView.setText(new CarUiText.Builder(text).setMaxLines(3).build());
-        ViewGroup container = mActivity.findViewById(
-                com.android.car.ui.test.R.id.test_container);
-        container.post(() -> container.addView(textView));
-
-        onView(withHint(hint)).check(matches(isDisplayed()));
-        assertEquals(text, new SpannableString(textView.getText()));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_add.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_add.xml
deleted file mode 100644
index 33b1ab8..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_add.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<!-- Used in Carboard's toolbar. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="48dp"
-    android:height="48dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_launcher.png b/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_launcher.png
deleted file mode 100644
index 2af53a4..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_settings_gear.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_settings_gear.xml
deleted file mode 100644
index 2b7fa2f..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/drawable/ic_settings_gear.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2020 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="48dp"
-    android:height="48dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0">
-    <path
-        android:fillColor="#fff"
-        android:pathData="M38.86,25.95c0.08,-0.64 0.14,-1.29 0.14,-1.95s-0.06,-1.31 -0.14,-1.95l4.23,-3.31c0.38,-0.3 0.49,-0.84 0.24,-1.28l-4,-6.93c-0.25,-0.43 -0.77,-0.61 -1.22,-0.43l-4.98,2.01c-1.03,-0.79 -2.16,-1.46 -3.38,-1.97L29,4.84c-0.09,-0.47 -0.5,-0.84 -1,-0.84h-8c-0.5,0 -0.91,0.37 -0.99,0.84l-0.75,5.3c-1.22,0.51 -2.35,1.17 -3.38,1.97L9.9,10.1c-0.45,-0.17 -0.97,0 -1.22,0.43l-4,6.93c-0.25,0.43 -0.14,0.97 0.24,1.28l4.22,3.31C9.06,22.69 9,23.34 9,24s0.06,1.31 0.14,1.95l-4.22,3.31c-0.38,0.3 -0.49,0.84 -0.24,1.28l4,6.93c0.25,0.43 0.77,0.61 1.22,0.43l4.98,-2.01c1.03,0.79 2.16,1.46 3.38,1.97l0.75,5.3c0.08,0.47 0.49,0.84 0.99,0.84h8c0.5,0 0.91,-0.37 0.99,-0.84l0.75,-5.3c1.22,-0.51 2.35,-1.17 3.38,-1.97l4.98,2.01c0.45,0.17 0.97,0 1.22,-0.43l4,-6.93c0.25,-0.43 0.14,-0.97 -0.24,-1.28l-4.22,-3.31zM24,31c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/app_styled_view_sample.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/app_styled_view_sample.xml
deleted file mode 100644
index 7c0af08..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/app_styled_view_sample.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-  <TextView
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="app styled view"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_ime_wide_screen_test_activity.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_ime_wide_screen_test_activity.xml
deleted file mode 100644
index e260300..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_ime_wide_screen_test_activity.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/test_activity"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_layout_manager_xml_test_activity.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_layout_manager_xml_test_activity.xml
deleted file mode 100644
index 3d68ca1..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_layout_manager_xml_test_activity.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/list"
-        app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/details_preference_widget.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/details_preference_widget.xml
deleted file mode 100644
index 3912de1..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/details_preference_widget.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2020 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<ImageView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:src="@drawable/ic_settings_gear"/>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_car_ui_recycler_view_list_item.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_car_ui_recycler_view_list_item.xml
deleted file mode 100644
index 8297f6b..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_car_ui_recycler_view_list_item.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="horizontal"
-    android:focusable="true">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="10dp"
-        android:layout_marginBottom="10dp"
-        android:id="@+id/textTitle"
-        android:text="TESTING"/>
-
-</LinearLayout>
-
-
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_ime_input_view.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_ime_input_view.xml
deleted file mode 100644
index 6b1fcb8..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_ime_input_view.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/test_ime_input_view_id"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_list_item.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_list_item.xml
deleted file mode 100644
index 8c36a94..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_list_item.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="horizontal"
-    android:focusable="true">
-
-    <TextView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="10dp"
-        android:layout_marginBottom="10dp"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
-        android:id="@+id/text" />
-
-</LinearLayout>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/values/arrays.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/values/arrays.xml
deleted file mode 100644
index 9606ddd..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/values/arrays.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<resources>
-
-    <!-- Used for the entries in a list preference [CHAR_LIMIT=NONE]-->
-    <string-array name="entries">
-        <!-- The first sample choice [CHAR_LIMIT=NONE]-->
-        <item>Choose me!</item>
-        <!-- The second sample choice [CHAR_LIMIT=NONE]-->
-        <item>No, me!</item>
-        <!-- The third sample choice [CHAR_LIMIT=NONE]-->
-        <item>What about me?!</item>
-    </string-array>
-
-    <!-- Used for the values in a list preference -->
-    <string-array name="entry_values" translatable="false">
-        <!-- The first sample value -->
-        <item>alpha</item>
-        <!-- The second sample value -->
-        <item>beta</item>
-        <!-- The third sample value -->
-        <item>charlie</item>
-    </string-array>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/values/strings.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/values/strings.xml
deleted file mode 100644
index 6eb1fbd..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/values/strings.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<resources>
-    <string name="test_string_test_title">Test title!</string>
-
-    <string name="preferences_screen_title">Preferences</string>
-    <string name="preference_dialog_category">Dialog preferences</string>
-    <string name="title_list_preference">List preference</string>
-    <string name="title_list_preference_ux_restricted">List preference UX restricted</string>
-    <string name="title_edit_text_preference">EditText preference</string>
-    <string name="dialog_title_edit_text_preference">Enter text</string>
-    <string name="title_seek_bar_preference">SeekBar preference</string>
-    <string name="dialog_title_seek_bar_preference">Select required value</string>
-    <string name="dialog_title_list_preference">Choose one option!</string>
-    <string name="title_multi_list_preference">Multi-select list preference</string>
-    <string name="title_multi_list_preference_ux_restricted">Multi-select list preference UX restricted</string>
-    <string name="summary_multi_list_preference">Shows a dialog with multiple choice options</string>
-    <string name="dialog_title_multi_list_preference">Choose some options!</string>
-    <string name="preference_widgets_category">Widgets</string>
-    <string name="title_checkbox_preference">Checkbox preference</string>
-    <string name="summary_compound_button_preference">Tap anywhere in this preference to toggle state</string>
-    <string name="title_switch_preference">Switch preference</string>
-    <string name="title_radio_button_preference">Radio button preference</string>
-    <string name="title_dropdown_preference">Dropdown preference</string>
-    <string name="title_twoaction_preference">TwoAction preference</string>
-    <string name="summary_twoaction_preference">A widget should be visible on the right</string>
-    <string name="twoaction_secondary_text">Secondary text</string>
-
-
-    <string-array name="test_string_array">
-        <item>Item 1</item>
-        <item>Item 2</item>
-        <item>Item 3</item>
-    </string-array>
-
-    <string name="scrolling_limited_message">Test message for Scrolling limited while driving</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/xml/test_preferences.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/xml/test_preferences.xml
deleted file mode 100644
index 8e2d339..0000000
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/xml/test_preferences.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    app:title="@string/preferences_screen_title">
-
-    <PreferenceCategory
-        android:title="@string/preference_dialog_category"
-        android:order="1">
-
-        <ListPreference
-            android:dialogTitle="@string/dialog_title_list_preference"
-            android:entries="@array/entries"
-            android:entryValues="@array/entry_values"
-            android:key="list"
-            android:title="@string/title_list_preference"
-            app:useSimpleSummaryProvider="true"/>
-
-        <MultiSelectListPreference
-            android:dialogTitle="@string/dialog_title_multi_list_preference"
-            android:entries="@array/entries"
-            android:entryValues="@array/entry_values"
-            android:key="multi_select_list"
-            android:summary="@string/summary_multi_list_preference"
-            android:title="@string/title_multi_list_preference"/>
-
-        <com.android.car.ui.preference.CarUiListPreference
-            android:dialogTitle="@string/dialog_title_list_preference"
-            android:entries="@array/entries"
-            android:entryValues="@array/entry_values"
-            android:key="list_ux_restricted"
-            android:title="@string/title_list_preference_ux_restricted"
-            app:car_ui_ux_restricted="true"
-            app:useSimpleSummaryProvider="true"/>
-
-        <com.android.car.ui.preference.CarUiMultiSelectListPreference
-            android:dialogTitle="@string/dialog_title_multi_list_preference"
-            android:entries="@array/entries"
-            android:entryValues="@array/entry_values"
-            android:key="multi_select_list_ux_restricted"
-            android:summary="@string/summary_multi_list_preference"
-            android:title="@string/title_multi_list_preference_ux_restricted"
-            app:car_ui_ux_restricted="true" />
-
-    </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/car-ui-lib/car-ui-lib/src/main/AndroidManifest.xml b/car-ui-lib/car-ui-lib/src/main/AndroidManifest.xml
deleted file mode 100644
index 5c2b9ae..0000000
--- a/car-ui-lib/car-ui-lib/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.car.ui">
-    <queries>
-        <intent>
-            <action android:name="com.android.car.ui.intent.action.SHARED_LIBRARY"/>
-        </intent>
-    </queries>
-    <application>
-        <provider
-            android:name="com.android.car.ui.core.CarUiInstaller"
-            android:authorities="${applicationId}.CarUiInstaller"
-            android:directBootAware="true"
-            android:exported="false"
-            android:process="@string/car_ui_installer_process_name"/>
-        <provider
-            android:name="com.android.car.ui.core.SearchResultsProvider"
-            android:authorities="${applicationId}.SearchResultsProvider"
-            android:exported="true"
-            android:process="@string/car_ui_installer_process_name"
-            android:readPermission="com.android.car.ui.READ_SEARCH_RESULTS"/>
-    </application>
-</manifest>
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/AlertDialogBuilder.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/AlertDialogBuilder.java
deleted file mode 100644
index ef2cb49..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/AlertDialogBuilder.java
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import static android.view.WindowInsets.Type.ime;
-
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_DESC_TITLE_TO_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_DESC_TO_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_ACTION;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.InputFilter;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.method.LinkMovementMethod;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-
-import androidx.annotation.ArrayRes;
-import androidx.annotation.AttrRes;
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.StringRes;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter;
-import com.android.car.ui.utils.CarUiUtils;
-
-/**
- * Wrapper for AlertDialog.Builder
- */
-public class AlertDialogBuilder {
-
-    private AlertDialog.Builder mBuilder;
-    private Context mContext;
-    private boolean mPositiveButtonSet;
-    private boolean mNeutralButtonSet;
-    private boolean mNegativeButtonSet;
-    private CharSequence mTitle;
-    private CharSequence mSubtitle;
-    private Drawable mIcon;
-    private boolean mIconTinted;
-    private EditText mCarUiEditText;
-    private InputMethodManager mInputMethodManager;
-    private String mWideScreenTitle;
-    private String mWideScreenTitleDesc;
-    private ViewGroup mRoot;
-    private boolean mAllowDismissButton = true;
-    private boolean mHasSingleChoiceBodyButton = false;
-
-    private final TextWatcher mTextWatcherWideScreen = new TextWatcher() {
-        @Override
-        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
-        }
-
-        @Override
-        public void onTextChanged(CharSequence s, int start, int before, int count) {
-            Bundle bundle = new Bundle();
-            String titleString = mWideScreenTitle != null ? mWideScreenTitle : mTitle.toString();
-            bundle.putString(ADD_DESC_TITLE_TO_CONTENT_AREA, titleString);
-            bundle.putString(ADD_DESC_TO_CONTENT_AREA, s.toString());
-            mInputMethodManager.sendAppPrivateCommand(mCarUiEditText, WIDE_SCREEN_ACTION,
-                    bundle);
-        }
-
-        @Override
-        public void afterTextChanged(Editable s) {
-
-        }
-    };
-
-    // Whenever the IME is closed and opened again, the title and desc information needs to be
-    // passed to the IME to be rendered. If the information is not passed to the IME the content
-    // area of the IME will render nothing into the content area.
-    private final View.OnApplyWindowInsetsListener mOnApplyWindowInsetsListener = (v, insets) -> {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
-            // WindowInsets.isVisible() is only available on R or above
-            return v.onApplyWindowInsets(insets);
-        }
-
-        if (insets.isVisible(ime())) {
-            Bundle bundle = new Bundle();
-            String title = mWideScreenTitle != null ? mWideScreenTitle : mTitle.toString();
-            bundle.putString(ADD_DESC_TITLE_TO_CONTENT_AREA, title);
-            if (mWideScreenTitleDesc != null) {
-                bundle.putString(ADD_DESC_TO_CONTENT_AREA, mWideScreenTitleDesc);
-            }
-            mInputMethodManager.sendAppPrivateCommand(mCarUiEditText, WIDE_SCREEN_ACTION,
-                    bundle);
-        }
-        return v.onApplyWindowInsets(insets);
-    };
-
-    private final AlertDialog.OnDismissListener mOnDismissListener = dialog -> {
-        if (mRoot != null) {
-            mRoot.setOnApplyWindowInsetsListener(null);
-        }
-    };
-
-    public AlertDialogBuilder(Context context) {
-        // Resource id specified as 0 uses the parent contexts resolved value for alertDialogTheme.
-        this(context, /* themeResId= */0);
-    }
-
-    public AlertDialogBuilder(Context context, int themeResId) {
-        mBuilder = new AlertDialog.Builder(context, themeResId);
-        mInputMethodManager = (InputMethodManager)
-                context.getSystemService(Context.INPUT_METHOD_SERVICE);
-        mContext = context;
-    }
-
-    public Context getContext() {
-        return mBuilder.getContext();
-    }
-
-    /**
-     * Set the title using the given resource id.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setTitle(@StringRes int titleId) {
-        return setTitle(mContext.getText(titleId));
-    }
-
-    /**
-     * Set the title displayed in the {@link Dialog}.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setTitle(CharSequence title) {
-        mTitle = title;
-        mBuilder.setTitle(title);
-        return this;
-    }
-
-    /**
-     * Sets a subtitle to be displayed in the {@link Dialog}.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setSubtitle(@StringRes int subtitle) {
-        return setSubtitle(mContext.getString(subtitle));
-    }
-
-    /**
-     * Sets a subtitle to be displayed in the {@link Dialog}.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setSubtitle(CharSequence subtitle) {
-        mSubtitle = subtitle;
-        return this;
-    }
-
-    /**
-     * Set the message to display using the given resource id.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setMessage(@StringRes int messageId) {
-        mBuilder.setMessage(messageId);
-        return this;
-    }
-
-    /**
-     * Set the message to display.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setMessage(CharSequence message) {
-        mBuilder.setMessage(message);
-        return this;
-    }
-
-    /**
-     * Set the resource id of the {@link Drawable} to be used in the title.
-     * <p>
-     * Takes precedence over values set using {@link #setIcon(Drawable)}.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setIcon(@DrawableRes int iconId) {
-        return setIcon(mContext.getDrawable(iconId));
-    }
-
-    /**
-     * Set the {@link Drawable} to be used in the title.
-     * <p>
-     * <strong>Note:</strong> To ensure consistent styling, the drawable
-     * should be inflated or constructed using the alert dialog's themed
-     * context obtained via {@link #getContext()}.
-     *
-     * @return this Builder object to allow for chaining of calls to set
-     * methods
-     */
-    public AlertDialogBuilder setIcon(Drawable icon) {
-        mIcon = icon;
-        return this;
-    }
-
-    /**
-     * Whether the icon provided by {@link #setIcon(Drawable)} should be
-     * tinted with the default system color.
-     *
-     * @return this Builder object to allow for chaining of calls to set
-     * methods.
-     */
-    public AlertDialogBuilder setIconTinted(boolean tinted) {
-        mIconTinted = tinted;
-        return this;
-    }
-
-    /**
-     * Set an icon as supplied by a theme attribute. e.g.
-     * {@link android.R.attr#alertDialogIcon}.
-     * <p>
-     * Takes precedence over values set using {@link #setIcon(Drawable)}.
-     *
-     * @param attrId ID of a theme attribute that points to a drawable resource.
-     */
-    public AlertDialogBuilder setIconAttribute(@AttrRes int attrId) {
-        mBuilder.setIconAttribute(attrId);
-        return this;
-    }
-
-    /**
-     * Set a listener to be invoked when the positive button of the dialog is pressed.
-     *
-     * @param textId   The resource id of the text to display in the positive button
-     * @param listener The {@link DialogInterface.OnClickListener} to use.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setPositiveButton(@StringRes int textId,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setPositiveButton(textId, listener);
-        mPositiveButtonSet = true;
-        return this;
-    }
-
-    /**
-     * Set a listener to be invoked when the positive button of the dialog is pressed.
-     *
-     * @param text     The text to display in the positive button
-     * @param listener The {@link DialogInterface.OnClickListener} to use.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setPositiveButton(CharSequence text,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setPositiveButton(text, listener);
-        mPositiveButtonSet = true;
-        return this;
-    }
-
-    /**
-     * Set a listener to be invoked when the negative button of the dialog is pressed.
-     *
-     * @param textId   The resource id of the text to display in the negative button
-     * @param listener The {@link DialogInterface.OnClickListener} to use.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setNegativeButton(@StringRes int textId,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setNegativeButton(textId, listener);
-        mNegativeButtonSet = true;
-        return this;
-    }
-
-    /**
-     * Set a listener to be invoked when the negative button of the dialog is pressed.
-     *
-     * @param text     The text to display in the negative button
-     * @param listener The {@link DialogInterface.OnClickListener} to use.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setNegativeButton(CharSequence text,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setNegativeButton(text, listener);
-        mNegativeButtonSet = true;
-        return this;
-    }
-
-    /**
-     * Set a listener to be invoked when the neutral button of the dialog is pressed.
-     *
-     * @param textId   The resource id of the text to display in the neutral button
-     * @param listener The {@link DialogInterface.OnClickListener} to use.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setNeutralButton(@StringRes int textId,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setNeutralButton(textId, listener);
-        mNeutralButtonSet = true;
-        return this;
-    }
-
-    /**
-     * Set a listener to be invoked when the neutral button of the dialog is pressed.
-     *
-     * @param text     The text to display in the neutral button
-     * @param listener The {@link DialogInterface.OnClickListener} to use.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setNeutralButton(CharSequence text,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setNeutralButton(text, listener);
-        mNeutralButtonSet = true;
-        return this;
-    }
-
-    /**
-     * Sets whether the dialog is cancelable or not.  Default is true.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setCancelable(boolean cancelable) {
-        mBuilder.setCancelable(cancelable);
-        return this;
-    }
-
-    /**
-     * Sets the callback that will be called if the dialog is canceled.
-     *
-     * <p>Even in a cancelable dialog, the dialog may be dismissed for reasons other than
-     * being canceled or one of the supplied choices being selected.
-     * If you are interested in listening for all cases where the dialog is dismissed
-     * and not just when it is canceled, see
-     * {@link #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
-     * setOnDismissListener}.</p>
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     * @see #setCancelable(boolean)
-     * @see #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
-     */
-    public AlertDialogBuilder setOnCancelListener(
-            DialogInterface.OnCancelListener onCancelListener) {
-        mBuilder.setOnCancelListener(onCancelListener);
-        return this;
-    }
-
-    /**
-     * Sets the callback that will be called when the dialog is dismissed for any reason.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setOnDismissListener(
-            DialogInterface.OnDismissListener onDismissListener) {
-        mBuilder.setOnDismissListener(onDismissListener);
-        return this;
-    }
-
-    /**
-     * Sets the callback that will be called if a key is dispatched to the dialog.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setOnKeyListener(DialogInterface.OnKeyListener onKeyListener) {
-        mBuilder.setOnKeyListener(onKeyListener);
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content, you will be notified of the
-     * selected item via the supplied listener. This should be an array type i.e. R.array.foo
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setItems(@ArrayRes int itemsId,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setItems(itemsId, listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content, you will be notified of the
-     * selected item via the supplied listener.
-     *
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setItems(CharSequence[] items,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setItems(items, listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * This was not supposed to be in the Chassis API because it allows custom views.
-     *
-     * @deprecated Use {@link #setAdapter(CarUiListItemAdapter)} instead.
-     */
-    @Deprecated
-    public AlertDialogBuilder setAdapter(final ListAdapter adapter,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setAdapter(adapter, listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * Display all the {@link com.android.car.ui.recyclerview.CarUiListItem CarUiListItems} in a
-     * {@link CarUiListItemAdapter}. You should set click listeners on the CarUiListItems as
-     * opposed to a callback in this function.
-     */
-    public AlertDialogBuilder setAdapter(final CarUiListItemAdapter adapter) {
-        setCustomList(adapter);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    private void setCustomList(@NonNull CarUiListItemAdapter adapter) {
-        View customList = LayoutInflater.from(mContext).inflate(
-                R.layout.car_ui_alert_dialog_list, null);
-        RecyclerView mList = CarUiUtils.requireViewByRefId(customList, R.id.list);
-        mList.setLayoutManager(new LinearLayoutManager(mContext));
-        mList.setAdapter(adapter);
-        mBuilder.setView(customList);
-    }
-
-    /**
-     * Set a list of items, which are supplied by the given {@link Cursor}, to be
-     * displayed in the dialog as the content, you will be notified of the
-     * selected item via the supplied listener.
-     *
-     * @param cursor      The {@link Cursor} to supply the list of items
-     * @param listener    The listener that will be called when an item is clicked.
-     * @param labelColumn The column name on the cursor containing the string to display
-     *                    in the label.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setCursor(final Cursor cursor,
-            final DialogInterface.OnClickListener listener,
-            String labelColumn) {
-        mBuilder.setCursor(cursor, listener, labelColumn);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content,
-     * you will be notified of the selected item via the supplied listener.
-     * This should be an array type, e.g. R.array.foo. The list will have
-     * a check mark displayed to the right of the text for each checked
-     * item. Clicking on an item in the list will not dismiss the dialog.
-     * Clicking on a button will dismiss the dialog.
-     *
-     * @param itemsId      the resource id of an array i.e. R.array.foo
-     * @param checkedItems specifies which items are checked. It should be null in which case no
-     *                     items are checked. If non null it must be exactly the same length as the
-     *                     array of
-     *                     items.
-     * @param listener     notified when an item on the list is clicked. The dialog will not be
-     *                     dismissed when an item is clicked. It will only be dismissed if clicked
-     *                     on a
-     *                     button, if no buttons are supplied it's up to the user to dismiss the
-     *                     dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setMultiChoiceItems(@ArrayRes int itemsId, boolean[] checkedItems,
-            final DialogInterface.OnMultiChoiceClickListener listener) {
-        mBuilder.setMultiChoiceItems(itemsId, checkedItems, listener);
-        mHasSingleChoiceBodyButton = false;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content,
-     * you will be notified of the selected item via the supplied listener.
-     * The list will have a check mark displayed to the right of the text
-     * for each checked item. Clicking on an item in the list will not
-     * dismiss the dialog. Clicking on a button will dismiss the dialog.
-     *
-     * @param items        the text of the items to be displayed in the list.
-     * @param checkedItems specifies which items are checked. It should be null in which case no
-     *                     items are checked. If non null it must be exactly the same length as the
-     *                     array of
-     *                     items.
-     * @param listener     notified when an item on the list is clicked. The dialog will not be
-     *                     dismissed when an item is clicked. It will only be dismissed if clicked
-     *                     on a
-     *                     button, if no buttons are supplied it's up to the user to dismiss the
-     *                     dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,
-            final DialogInterface.OnMultiChoiceClickListener listener) {
-        mBuilder.setMultiChoiceItems(items, checkedItems, listener);
-        mHasSingleChoiceBodyButton = false;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content,
-     * you will be notified of the selected item via the supplied listener.
-     * The list will have a check mark displayed to the right of the text
-     * for each checked item. Clicking on an item in the list will not
-     * dismiss the dialog. Clicking on a button will dismiss the dialog.
-     *
-     * @param cursor          the cursor used to provide the items.
-     * @param isCheckedColumn specifies the column name on the cursor to use to determine
-     *                        whether a checkbox is checked or not. It must return an integer value
-     *                        where 1
-     *                        means checked and 0 means unchecked.
-     * @param labelColumn     The column name on the cursor containing the string to display in the
-     *                        label.
-     * @param listener        notified when an item on the list is clicked. The dialog will not be
-     *                        dismissed when an item is clicked. It will only be dismissed if
-     *                        clicked on a
-     *                        button, if no buttons are supplied it's up to the user to dismiss the
-     *                        dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setMultiChoiceItems(Cursor cursor, String isCheckedColumn,
-            String labelColumn,
-            final DialogInterface.OnMultiChoiceClickListener listener) {
-        mBuilder.setMultiChoiceItems(cursor, isCheckedColumn, labelColumn, listener);
-        mHasSingleChoiceBodyButton = false;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content, you will be notified of
-     * the selected item via the supplied listener. This should be an array type i.e.
-     * R.array.foo The list will have a check mark displayed to the right of the text for the
-     * checked item. Clicking on an item in the list will not dismiss the dialog. Clicking on a
-     * button will dismiss the dialog.
-     *
-     * @param itemsId     the resource id of an array i.e. R.array.foo
-     * @param checkedItem specifies which item is checked. If -1 no items are checked.
-     * @param listener    notified when an item on the list is clicked. The dialog will not be
-     *                    dismissed when an item is clicked. It will only be dismissed if clicked on
-     *                    a
-     *                    button, if no buttons are supplied it's up to the user to dismiss the
-     *                    dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setSingleChoiceItems(@ArrayRes int itemsId, int checkedItem,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setSingleChoiceItems(itemsId, checkedItem, listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content, you will be notified of
-     * the selected item via the supplied listener. The list will have a check mark displayed to
-     * the right of the text for the checked item. Clicking on an item in the list will not
-     * dismiss the dialog. Clicking on a button will dismiss the dialog.
-     *
-     * @param cursor      the cursor to retrieve the items from.
-     * @param checkedItem specifies which item is checked. If -1 no items are checked.
-     * @param labelColumn The column name on the cursor containing the string to display in the
-     *                    label.
-     * @param listener    notified when an item on the list is clicked. The dialog will not be
-     *                    dismissed when an item is clicked. It will only be dismissed if clicked on
-     *                    a
-     *                    button, if no buttons are supplied it's up to the user to dismiss the
-     *                    dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setSingleChoiceItems(Cursor cursor, int checkedItem,
-            String labelColumn,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setSingleChoiceItems(cursor, checkedItem, labelColumn, listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content, you will be notified of
-     * the selected item via the supplied listener. The list will have a check mark displayed to
-     * the right of the text for the checked item. Clicking on an item in the list will not
-     * dismiss the dialog. Clicking on a button will dismiss the dialog.
-     *
-     * @param items       the items to be displayed.
-     * @param checkedItem specifies which item is checked. If -1 no items are checked.
-     * @param listener    notified when an item on the list is clicked. The dialog will not be
-     *                    dismissed when an item is clicked. It will only be dismissed if clicked on
-     *                    a
-     *                    button, if no buttons are supplied it's up to the user to dismiss the
-     *                    dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setSingleChoiceItems(CharSequence[] items, int checkedItem,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setSingleChoiceItems(items, checkedItem, listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * This was not supposed to be in the Chassis API because it allows custom views.
-     *
-     * @deprecated Use {@link #setSingleChoiceItems(CarUiRadioButtonListItemAdapter,
-     * DialogInterface.OnClickListener)} instead.
-     */
-    @Deprecated
-    public AlertDialogBuilder setSingleChoiceItems(ListAdapter adapter, int checkedItem,
-            final DialogInterface.OnClickListener listener) {
-        mBuilder.setSingleChoiceItems(adapter, checkedItem, listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content, you will be notified of
-     * the selected item via the supplied listener. The list will have a check mark displayed to
-     * the right of the text for the checked item. Clicking on an item in the list will not
-     * dismiss the dialog. Clicking on a button will dismiss the dialog.
-     *
-     * @param adapter  The {@link CarUiRadioButtonListItemAdapter} to supply the list of items
-     * @param listener notified when an item on the list is clicked. The dialog will not be
-     *                 dismissed when an item is clicked. It will only be dismissed if clicked on a
-     *                 button, if no buttons are supplied it's up to the user to dismiss the dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     * @deprecated Use {@link #setSingleChoiceItems(CarUiRadioButtonListItemAdapter)} instead.
-     */
-    @Deprecated
-    public AlertDialogBuilder setSingleChoiceItems(CarUiRadioButtonListItemAdapter adapter,
-            final DialogInterface.OnClickListener listener) {
-        setCustomList(adapter);
-        mHasSingleChoiceBodyButton = false;
-        return this;
-    }
-
-    /**
-     * Set a list of items to be displayed in the dialog as the content,The list will have a check
-     * mark displayed to the right of the text for the checked item. Clicking on an item in the list
-     * will not dismiss the dialog. Clicking on a button will dismiss the dialog.
-     *
-     * @param adapter The {@link CarUiRadioButtonListItemAdapter} to supply the list of items
-     *                dismissed when an item is clicked. It will only be dismissed if clicked on a
-     *                button, if no buttons are supplied it's up to the user to dismiss the dialog.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setSingleChoiceItems(CarUiRadioButtonListItemAdapter adapter) {
-        setCustomList(adapter);
-        mHasSingleChoiceBodyButton = false;
-        return this;
-    }
-
-    /**
-     * Sets a listener to be invoked when an item in the list is selected.
-     *
-     * @param listener the listener to be invoked
-     * @return this Builder object to allow for chaining of calls to set methods
-     * @see AdapterView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener)
-     */
-    public AlertDialogBuilder setOnItemSelectedListener(
-            final AdapterView.OnItemSelectedListener listener) {
-        mBuilder.setOnItemSelectedListener(listener);
-        mHasSingleChoiceBodyButton = true;
-        return this;
-    }
-
-    /**
-     * Sets a custom edit text box within the alert dialog.
-     *
-     * @param prompt              the string that will be set on the edit text view
-     * @param textChangedListener textWatcher whose methods are called whenever this TextView's text
-     *                            changes {@link null} otherwise.
-     * @param inputFilters        list of input filters, {@link null} if no filter is needed
-     * @param inputType           See {@link EditText#setInputType(int)}, except
-     *                            {@link android.text.InputType#TYPE_NULL} will not be set.
-     * @return this Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setEditBox(String prompt, TextWatcher textChangedListener,
-            InputFilter[] inputFilters, int inputType) {
-        View contentView = LayoutInflater.from(mContext).inflate(
-                R.layout.car_ui_alert_dialog_edit_text, null);
-
-        mCarUiEditText = CarUiUtils.requireViewByRefId(contentView, R.id.textbox);
-        mCarUiEditText.setText(prompt);
-
-        if (textChangedListener != null) {
-            mCarUiEditText.addTextChangedListener(textChangedListener);
-        }
-
-        if (inputFilters != null) {
-            mCarUiEditText.setFilters(inputFilters);
-        }
-
-        if (inputType != 0) {
-            mCarUiEditText.setInputType(inputType);
-        }
-
-        mBuilder.setView(contentView);
-        return this;
-    }
-
-    /**
-     * Sets a custom edit text box within the alert dialog.
-     *
-     * @param prompt              the string that will be set on the edit text view
-     * @param textChangedListener textWatcher whose methods are called whenever this TextView's text
-     *                            changes {@link null} otherwise.
-     * @param inputFilters        list of input filters, {@link null} if no filter is needed
-     * @return this Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setEditBox(String prompt, TextWatcher textChangedListener,
-            InputFilter[] inputFilters) {
-        return setEditBox(prompt, textChangedListener, inputFilters, 0);
-    }
-
-    /**
-     * Sets the title and desc related to the dialog within the IMS templates.
-     *
-     * @param title title to be set.
-     * @param desc  description related to the dialog.
-     * @return this Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setEditTextTitleAndDescForWideScreen(String title, String desc) {
-        mWideScreenTitle = title;
-        mWideScreenTitleDesc = desc;
-
-        return this;
-    }
-
-    /**
-     * By default, the AlertDialogBuilder will just display the static text in the content area of
-     * widescreen IME provided by {@link #setEditTextTitleAndDescForWideScreen(String, String)}. To
-     * display the text typed by the user in the description set this to true.
-     *
-     * @return this Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setAutoDescUpdateForWidescreen(boolean autoUpdateDesc) {
-        if (autoUpdateDesc) {
-            mCarUiEditText.addTextChangedListener(mTextWatcherWideScreen);
-        } else {
-            mCarUiEditText.removeTextChangedListener(mTextWatcherWideScreen);
-        }
-        return this;
-    }
-
-    /**
-     * By default, the AlertDialogBuilder may add a "Dismiss" button if you don't provide
-     * a positive/negative/neutral button. This is so that the dialog is still dismissible
-     * using the rotary controller. If however, you add buttons that can close the dialog via
-     * {@link #setAdapter(CarUiListItemAdapter)} or a similar method, then you may wish to
-     * suppress the addition of the dismiss button, which this method allows for.
-     *
-     * @param allowDismissButton If true, a "Dismiss" button may be added to the dialog.
-     *                           If false, it will never be added.
-     * @return this Builder object to allow for chaining of calls to set methods
-     */
-    public AlertDialogBuilder setAllowDismissButton(boolean allowDismissButton) {
-        mAllowDismissButton = allowDismissButton;
-        return this;
-    }
-
-    /** Final steps common to both {@link #create()} and {@link #show()} */
-    private void prepareDialog() {
-        View customTitle = LayoutInflater.from(mContext).inflate(
-                R.layout.car_ui_alert_dialog_title_with_subtitle, null);
-
-        TextView mTitleView = CarUiUtils.requireViewByRefId(customTitle, R.id.car_ui_alert_title);
-        TextView mSubtitleView =
-                CarUiUtils.requireViewByRefId(customTitle, R.id.car_ui_alert_subtitle);
-        mSubtitleView.setMovementMethod(LinkMovementMethod.getInstance());
-        ImageView mIconView = CarUiUtils.requireViewByRefId(customTitle, R.id.car_ui_alert_icon);
-
-        mTitleView.setText(mTitle);
-        mTitleView.setVisibility(TextUtils.isEmpty(mTitle) ? View.GONE : View.VISIBLE);
-        mSubtitleView.setText(mSubtitle);
-        mSubtitleView.setVisibility(TextUtils.isEmpty(mSubtitle) ? View.GONE : View.VISIBLE);
-        mIconView.setImageDrawable(mIcon);
-        mIconView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
-        if (mIconTinted) {
-            mIconView.setImageTintList(
-                    mContext.getColorStateList(R.color.car_ui_dialog_icon_color));
-        }
-        mBuilder.setCustomTitle(customTitle);
-
-        if (!mAllowDismissButton && !mHasSingleChoiceBodyButton
-                && !mNeutralButtonSet && !mNegativeButtonSet && !mPositiveButtonSet) {
-            throw new RuntimeException(
-                    "The dialog must have at least one button to disable the dismiss button");
-        }
-        if (mContext.getResources().getBoolean(R.bool.car_ui_alert_dialog_force_dismiss_button)
-                && !mNeutralButtonSet && !mNegativeButtonSet && !mPositiveButtonSet
-                && mAllowDismissButton) {
-            String mDefaultButtonText = mContext.getString(
-                    R.string.car_ui_alert_dialog_default_button);
-            mBuilder.setNegativeButton(mDefaultButtonText, (dialog, which) -> {
-            });
-        }
-    }
-
-    /**
-     * Creates an {@link AlertDialog} with the arguments supplied to this
-     * builder.
-     * <p>
-     * Calling this method does not display the dialog. If no additional
-     * processing is needed, {@link #show()} may be called instead to both
-     * create and display the dialog.
-     */
-    public AlertDialog create() {
-        prepareDialog();
-        AlertDialog alertDialog = mBuilder.create();
-
-        // Put a FocusParkingView at the end of dialog window to prevent rotary controller
-        // wrap-around. Android will focus on the first view automatically when the dialog is shown,
-        // and we want it to focus on the title instead of the FocusParkingView, so we put the
-        // FocusParkingView at the end of dialog window.
-        mRoot = (ViewGroup) alertDialog.getWindow().getDecorView().getRootView();
-        FocusParkingView fpv = new FocusParkingView(mContext);
-        mRoot.addView(fpv);
-
-        // apply window insets listener to know when IME is visible so we can set title and desc.
-        mRoot.setOnApplyWindowInsetsListener(mOnApplyWindowInsetsListener);
-        setOnDismissListener(mOnDismissListener);
-
-        return alertDialog;
-    }
-
-    /**
-     * Creates an {@link AlertDialog} with the arguments supplied to this
-     * builder and immediately displays the dialog.
-     */
-    public AlertDialog show() {
-        AlertDialog alertDialog = create();
-        alertDialog.show();
-        return alertDialog;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/CarUiLayoutInflaterFactory.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/CarUiLayoutInflaterFactory.java
deleted file mode 100644
index f87aec1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/CarUiLayoutInflaterFactory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatViewInflater;
-
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-
-/**
- * A custom {@link LayoutInflater.Factory2} that will create CarUi components such as {@link
- * CarUiRecyclerView}. It extends AppCompatViewInflater so that it can still let AppCompat
- * components be created correctly.
- */
-public class CarUiLayoutInflaterFactory extends AppCompatViewInflater
-        implements LayoutInflater.Factory2 {
-
-    @Nullable
-    protected View createView(Context context, String name, AttributeSet attrs) {
-        View view = null;
-
-        // Don't use CarUiTextView.class.getSimpleName(), as when proguard obfuscates the class name
-        // it will no longer match what's in xml.
-        if (CarUiRecyclerView.class.getName().equals(name)) {
-            view = SharedLibraryFactorySingleton.get(context)
-                    .createRecyclerView(context, attrs);
-        } else if (name.contentEquals("CarUiTextView")) {
-            view = SharedLibraryFactorySingleton.get(context).createTextView(context, attrs);
-        }
-
-        return view;
-    }
-
-    @Override
-    public View onCreateView(String name, Context context, AttributeSet attrs) {
-        // Deprecated, do nothing.
-        return null;
-    }
-
-    @Override
-    public View onCreateView(View parent, String name, Context context,
-            AttributeSet attrs) {
-        return createView(context, name, attrs);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/CarUiText.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/CarUiText.java
deleted file mode 100644
index 7e08dfc..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/CarUiText.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import android.text.SpannableStringBuilder;
-
-import androidx.annotation.NonNull;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Text that includes rendering information.
- */
-public class CarUiText {
-    private final int mMaxLines;
-    private final int mMaxChars;
-    private final List<CharSequence> mVariants;
-
-    /**
-     * Convenience method that returns a single {@link CharSequence} that is a combination of the
-     * preferred text of a list of {@link CarUiText}, separated by line breaks.
-     */
-    public static CharSequence combineMultiLine(@NonNull List<CarUiText> lines) {
-        SpannableStringBuilder builder = new SpannableStringBuilder();
-        CharSequence delimiter = "";
-        for (CarUiText line : lines) {
-            builder.append(delimiter)
-                    .append(line.getPreferredText() == null ? " " : line.getPreferredText());
-            delimiter = "\n";
-        }
-        return builder;
-    }
-
-    private CarUiText(Builder builder) {
-        mVariants = builder.mVariants;
-        mMaxChars = builder.mMaxChars;
-        mMaxLines = builder.mMaxLines;
-    }
-
-    /**
-     * Create a new {@link CarUiText}.
-     *
-     * @param text text to display
-     *
-     * @deprecated Use {@link Builder} to instantiate {@link CarUiText} instances
-     */
-    @Deprecated
-    public CarUiText(@NonNull CharSequence text) {
-        this(text, Integer.MAX_VALUE);
-    }
-
-    /**
-     * Create a new {@link CarUiText}.
-     *
-     * @param text     text to display
-     * @param maxLines the maximum number of lines the text should be displayed on when width
-     *                 constraints force the text to be wrapped. Text that exceeds the maximum
-     *                 number of lines is ellipsized
-     *
-     * @deprecated Use {@link Builder} to instantiate {@link CarUiText} instances
-     */
-    @Deprecated
-    public CarUiText(@NonNull CharSequence text, int maxLines) {
-        mVariants = Collections.singletonList(text);
-        mMaxLines = maxLines;
-        mMaxChars = Integer.MAX_VALUE;
-    }
-
-    /**
-     * Create a new {@link CarUiText}.
-     *
-     * @param variants list of text variants. Variants provide alternative text to be used to avoid
-     *                 truncation. Provide variants in order of preference.
-     * @param maxLines the maximum number of lines the text should be displayed on when width
-     *                 constraints force the text to be wrapped. Text that exceeds the maximum
-     *                 number of lines is ellipsized
-     *
-     * @deprecated Use {@link Builder} to instantiate {@link CarUiText} instances
-     */
-    @Deprecated
-    public CarUiText(@NonNull List<CharSequence> variants, int maxLines) {
-        mVariants = variants;
-        mMaxLines = maxLines;
-        mMaxChars = Integer.MAX_VALUE;
-    }
-
-    /**
-     * Create a new {@link CarUiText}.
-     *
-     * @param variants list of text variants. Variants provide alternative text to be used to avoid
-     *                 truncation. Provide variants in order of preference.
-     * @param maxLines the maximum number of lines the text should be displayed on when width
-     *                 constraints force the text to be wrapped. Text that exceeds the maximum
-     *                 number of lines is ellipsized
-     * @param maxChars the maximum number of characters that should be displayed
-     *
-     * @deprecated Use {@link Builder} to instantiate {@link CarUiText} instances
-     */
-    @Deprecated
-    public CarUiText(@NonNull List<CharSequence> variants, int maxLines, int maxChars) {
-        mVariants = variants;
-        mMaxLines = maxLines;
-        mMaxChars = maxChars;
-    }
-
-    /**
-     * Returns the maximum number of lines the text should be displayed on when width constraints
-     * force the text to be wrapped
-     */
-    public int getMaxLines() {
-        return mMaxLines;
-    }
-
-    /**
-     * Returns the maximum number of characters that should be displayed for the text
-     */
-    public int getMaxChars() {
-        return mMaxChars;
-    }
-
-    /**
-     * Returns the list of text variants for this {@link CarUiText}.
-     */
-    public List<CharSequence> getTextVariants() {
-        return mVariants;
-    }
-
-    /**
-     * Returns the preferred text to render for this {@link CarUiText}.
-     */
-    public CharSequence getPreferredText() {
-        return mVariants.get(0);
-    }
-
-    /**
-     * A builder of {@link CarUiText}.
-     */
-    public static final class Builder {
-        private int mMaxLines = Integer.MAX_VALUE;
-        private int mMaxChars = Integer.MAX_VALUE;
-        private final List<CharSequence> mVariants;
-
-        /**
-         * Returns a new instance of a {@link Builder}.
-         *
-         * @param text text to display
-         */
-        public Builder(CharSequence text) {
-            this(Collections.singletonList(text));
-        }
-
-        /**
-         * Returns a new instance of a {@link Builder}.
-         *
-         * @param variants list of text variants. Variants provide alternative text to be used to
-         *                 avoid truncation. Provide variants in order of preference.
-         */
-        public Builder(@NonNull List<CharSequence> variants) {
-            mVariants = variants;
-        }
-
-        /**
-         * Sets the maximum number of characters that should be displayed.
-         */
-        public Builder setMaxChars(int chars) {
-            mMaxChars = chars;
-            return this;
-        }
-
-        /**
-         * Sets the maximum number of lines the text should be displayed on when width constraints
-         * force the text to be wrapped. Text that exceeds the maximum number of lines is
-         * ellipsized.
-         */
-        public Builder setMaxLines(int lines) {
-            mMaxLines = lines;
-            return this;
-        }
-
-        /**
-         * Returns a {@link CarUiText} for this {@link Builder}.
-         */
-        public CarUiText build() {
-            return new CarUiText(this);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusAreaAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusAreaAdapterV1.java
deleted file mode 100644
index c225b54..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusAreaAdapterV1.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.car.ui.sharedlibrary.oemapis.FocusAreaOEMV1;
-
-/**
- * Adapter from {@link FocusArea} to {@link FocusAreaOEMV1}.
- */
-public class FocusAreaAdapterV1 implements FocusAreaOEMV1 {
-    private final FocusArea mFocusArea;
-
-    public FocusAreaAdapterV1(FocusArea focusArea) {
-        mFocusArea = focusArea;
-    }
-
-    @Override
-    public void setHighlightPadding(int left, int top, int right, int bottom) {
-        mFocusArea.setHighlightPadding(left, top, right, bottom);
-    }
-
-    @Override
-    public void setBoundsOffset(int left, int top, int right, int bottom) {
-        mFocusArea.setBoundsOffset(left, top, right, bottom);
-    }
-
-    @Override
-    public void setWrapAround(boolean wrapAround) {
-        mFocusArea.setWrapAround(wrapAround);
-    }
-
-    @Override
-    public void setDefaultFocus(View defaultFocus) {
-        mFocusArea.setDefaultFocus(defaultFocus);
-    }
-
-    @Override
-    public void setNudgeShortcut(int direction, View view) {
-        mFocusArea.setNudgeShortcut(direction, view);
-    }
-
-    @Override
-    public LinearLayout getView() {
-        return mFocusArea;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingViewAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingViewAdapterV1.java
deleted file mode 100644
index 2152e6e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingViewAdapterV1.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui;
-
-import android.view.View;
-
-import com.android.car.ui.sharedlibrary.oemapis.FocusParkingViewOEMV1;
-
-/**
- * Adapter from {@link FocusParkingView} to {@link FocusParkingViewOEMV1}.
- */
-public class FocusParkingViewAdapterV1 implements FocusParkingViewOEMV1 {
-    private final FocusParkingView mFocusParkingView;
-
-    public FocusParkingViewAdapterV1(FocusParkingView focusParkingView) {
-        mFocusParkingView = focusParkingView;
-    }
-
-    @Override
-    public void setShouldRestoreFocus(boolean shouldRestoreFocus) {
-        mFocusParkingView.setShouldRestoreFocus(shouldRestoreFocus);
-    }
-
-    @Override
-    public View getView() {
-        return mFocusParkingView;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledDialog.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledDialog.java
deleted file mode 100644
index 58ebc87..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledDialog.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.appstyledview;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledDismissListener;
-
-/**
- * App styled dialog used to display a view that cannot be customized via OEM. Dialog will inflate a
- * layout and add the view provided by the application into the layout. Everything other than the
- * view within the layout can be customized by OEM.
- *
- * Apps should not use this directly. App's should use {@link AppStyledDialogController}.
- */
-public class AppStyledDialog extends Dialog implements DialogInterface.OnDismissListener {
-
-    private final AppStyledViewController mController;
-    private AppStyledDismissListener mOnDismissListener;
-    private View mContent;
-
-    public AppStyledDialog(@NonNull Context context, AppStyledViewController controller) {
-        super(context);
-        mController = controller;
-        setOnDismissListener(this);
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        requestWindowFeature(Window.FEATURE_NO_TITLE);
-        setContentView(mController.getAppStyledView(mContent));
-
-        WindowManager.LayoutParams params = getWindow().getAttributes();
-        getWindow().setAttributes(mController.getDialogWindowLayoutParam(params));
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        if (mOnDismissListener != null) {
-            mOnDismissListener.onDismiss();
-        }
-    }
-
-    void setContent(View contentView) {
-        mContent = contentView;
-    }
-
-    void setOnDismissListener(AppStyledDismissListener listener) {
-        mOnDismissListener = listener;
-    }
-
-    WindowManager.LayoutParams getWindowLayoutParams() {
-        return getWindow().getAttributes();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledDialogController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledDialogController.java
deleted file mode 100644
index 87e4d73..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledDialogController.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.appstyledview;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledDismissListener;
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledVCloseClickListener;
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledViewNavIcon;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-
-import java.util.Objects;
-
-/**
- * Controller to interact with the app styled view UI.
- */
-public final class AppStyledDialogController {
-
-    @NonNull
-    private AppStyledViewController mAppStyledViewController;
-    @NonNull
-    private AppStyledDialog mDialog;
-
-    public AppStyledDialogController(@NonNull Context context) {
-        Objects.requireNonNull(context);
-        mAppStyledViewController = SharedLibraryFactorySingleton.get(context)
-                .createAppStyledView(context);
-        mDialog = new AppStyledDialog(context, mAppStyledViewController);
-    }
-
-    @VisibleForTesting
-    void setAppStyledViewController(AppStyledViewController controller, Context context) {
-        mAppStyledViewController = controller;
-        mDialog = new AppStyledDialog(context, mAppStyledViewController);
-    }
-
-    /**
-     * Sets the content view to de displayed in AppStyledView.
-     */
-    public void setContentView(@NonNull View contentView) {
-        Objects.requireNonNull(contentView);
-
-        mDialog.setContent(contentView);
-        mAppStyledViewController.setOnCloseClickListener(mDialog::dismiss);
-    }
-
-    /**
-     * Sets the nav icon to be used.
-     */
-    public void setNavIcon(@AppStyledViewNavIcon int navIcon) {
-        mAppStyledViewController.setNavIcon(navIcon);
-    }
-
-    /**
-     * Displays the dialog to the user with the custom view provided by the app.
-     */
-    public void show() {
-        mDialog.show();
-    }
-
-    /**
-     * Sets the {@link AppStyledVCloseClickListener}
-     */
-    public void setOnCloseClickListener(@NonNull AppStyledVCloseClickListener listener) {
-        mAppStyledViewController.setOnCloseClickListener(() -> {
-            mDialog.dismiss();
-            listener.onClick();
-        });
-    }
-
-    /**
-     * Sets the {@link AppStyledDismissListener}
-     */
-    public void setOnDismissListener(@NonNull AppStyledDismissListener listener) {
-        mDialog.setOnDismissListener(listener);
-    }
-
-    /**
-     * Returns the width of the AppStyledView
-     */
-    public int getAppStyledViewDialogWidth() {
-        return mAppStyledViewController.getDialogWindowLayoutParam(
-                mDialog.getWindowLayoutParams()).width;
-    }
-
-    /**
-     * Returns the height of the AppStyledView
-     */
-    public int getAppStyledViewDialogHeight() {
-        return mAppStyledViewController.getDialogWindowLayoutParam(
-                mDialog.getWindowLayoutParams()).height;
-    }
-
-    @VisibleForTesting
-    AppStyledDialog getAppStyledDialog() {
-        return mDialog;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledRecyclerViewAdapter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledRecyclerViewAdapter.java
deleted file mode 100644
index ed2f1b8..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledRecyclerViewAdapter.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.appstyledview;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-import com.android.car.ui.appstyledview.AppStyledRecyclerViewAdapter.AppStyledRecyclerViewHolder;
-
-/**
- * Adapter for app styled dialog.
- */
-public class AppStyledRecyclerViewAdapter extends
-        RecyclerView.Adapter<AppStyledRecyclerViewHolder> {
-
-    private View mContent;
-
-    public AppStyledRecyclerViewAdapter(View content) {
-        mContent = content;
-    }
-
-    @NonNull
-    @Override
-    public AppStyledRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
-        LayoutInflater inflator = LayoutInflater.from(parent.getContext());
-        View view = inflator.inflate(R.layout.car_ui_app_styled_view_item, parent, false);
-        return new AppStyledRecyclerViewHolder(view);
-    }
-
-    @Override
-    public void onBindViewHolder(@NonNull AppStyledRecyclerViewHolder holder, int position) {
-        FrameLayout frameLayout = holder.mView.findViewById(R.id.car_ui_app_styled_item);
-        frameLayout.addView(mContent);
-    }
-
-    @Override
-    public int getItemCount() {
-        return 1;
-    }
-
-    /**
-     * Holds views for each element in the list.
-     */
-    public static class AppStyledRecyclerViewHolder extends RecyclerView.ViewHolder {
-
-        View mView;
-
-        AppStyledRecyclerViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mView = itemView;
-        }
-    }
-}
-
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewController.java
deleted file mode 100644
index 7280773..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewController.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.appstyledview;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.view.View;
-import android.view.WindowManager;
-
-import androidx.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-
-/**
- * An interface for accessing a Chassis AppStyledView, regardless of how the underlying views are
- * represented.
- */
-public interface AppStyledViewController {
-
-    /**
-     * Callback to be invoked when the close icon is clicked.
-     */
-    interface AppStyledVCloseClickListener {
-
-        /**
-         * Called when the close icon is clicked.
-         */
-        void onClick();
-    }
-
-    /**
-     * Callback to be invoked when the dialog is dismissed.
-     */
-    interface AppStyledDismissListener {
-
-        /**
-         * Called when the dialog is dismissed.
-         */
-        void onDismiss();
-    }
-
-    /**
-     * The possible values for AppStyledViewNavIcon.
-     */
-    @IntDef({
-            AppStyledViewNavIcon.BACK,
-            AppStyledViewNavIcon.CLOSE,
-    })
-    @Retention(SOURCE)
-    @interface AppStyledViewNavIcon {
-
-        /**
-         * Show a back icon
-         */
-        int BACK = 0;
-
-        /**
-         * Show a close icon
-         */
-        int CLOSE = 1;
-    }
-
-    /**
-     * Creates a app styled view.
-     *
-     * @return the view used for app styled view.
-     */
-    View getAppStyledView(View contentView);
-
-    /**
-     * Sets the nav icon to be used.
-     */
-    void setNavIcon(@AppStyledViewNavIcon int navIcon);
-
-    /**
-     * Sets the {@link AppStyledVCloseClickListener}
-     */
-    void setOnCloseClickListener(AppStyledVCloseClickListener listener);
-
-    /**
-     * Returns the layout params for the AppStyledView dialog
-     */
-    WindowManager.LayoutParams getDialogWindowLayoutParam(WindowManager.LayoutParams params);
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewControllerAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewControllerAdapterV1.java
deleted file mode 100644
index 0422b0b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewControllerAdapterV1.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.appstyledview;
-
-import android.view.View;
-import android.view.WindowManager.LayoutParams;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.ui.sharedlibrary.oemapis.appstyledview.AppStyledViewControllerOEMV1;
-
-/**
- * Adapts a {@link AppStyledViewControllerOEMV1} into a {@link AppStyledViewController}
- */
-public class AppStyledViewControllerAdapterV1 implements AppStyledViewController {
-
-    @NonNull
-    private final AppStyledViewControllerOEMV1 mOemController;
-
-    public AppStyledViewControllerAdapterV1(AppStyledViewControllerOEMV1 controllerOEMV1) {
-        mOemController = controllerOEMV1;
-    }
-
-    /**
-     * Returns the view that will be displayed on the screen.
-     */
-    @Override
-    public View getAppStyledView(View contentView) {
-        return mOemController.getAppStyledView(contentView);
-    }
-
-    @Override
-    public void setNavIcon(int navIcon) {
-        mOemController.setNavIcon(navIcon);
-    }
-
-    @Override
-    public void setOnCloseClickListener(AppStyledVCloseClickListener listener) {
-        mOemController.setOnCloseClickListener(listener::onClick);
-    }
-
-    @Override
-    public LayoutParams getDialogWindowLayoutParam(LayoutParams params) {
-        return mOemController.getDialogWindowLayoutParam(params);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewControllerImpl.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewControllerImpl.java
deleted file mode 100644
index 50ded45..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/appstyledview/AppStyledViewControllerImpl.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.appstyledview;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.util.DisplayMetrics;
-import android.view.ContextThemeWrapper;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.CarUiLayoutInflaterFactory;
-import com.android.car.ui.R;
-
-/**
- * Controller to interact with the app styled view.
- */
-public class AppStyledViewControllerImpl implements AppStyledViewController {
-
-    private static final double VISIBLE_SCREEN_PERCENTAGE = 0.9;
-
-    private final Context mContext;
-    @AppStyledViewNavIcon
-    private int mAppStyleViewNavIcon;
-    private AppStyledVCloseClickListener mAppStyledVCloseClickListener = null;
-
-    public AppStyledViewControllerImpl(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public void setNavIcon(@AppStyledViewNavIcon int navIcon) {
-        mAppStyleViewNavIcon = navIcon;
-    }
-
-    /**
-     * Sets the AppStyledVCloseClickListener on the close icon.
-     */
-    @Override
-    public void setOnCloseClickListener(AppStyledVCloseClickListener listener) {
-        mAppStyledVCloseClickListener = listener;
-    }
-
-    @Override
-    public LayoutParams getDialogWindowLayoutParam(LayoutParams params) {
-
-        DisplayMetrics displayMetrics = new DisplayMetrics();
-        WindowManager wm = mContext.getSystemService(WindowManager.class);
-        wm.getDefaultDisplay().getMetrics(displayMetrics);
-
-        int maxWidth = mContext.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_app_styled_dialog_width_max);
-        int maxHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_app_styled_dialog_height_max);
-
-        int displayWidth = (int) (displayMetrics.widthPixels * VISIBLE_SCREEN_PERCENTAGE);
-        int displayHeight = (int) (displayMetrics.heightPixels * VISIBLE_SCREEN_PERCENTAGE);
-
-        if (mContext.getResources().getConfiguration()
-                .orientation == Configuration.ORIENTATION_LANDSCAPE && maxWidth < displayWidth) {
-            params.gravity = Gravity.START;
-        }
-
-        int width = mContext.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_app_styled_dialog_width);
-        int height = mContext.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_app_styled_dialog_height);
-
-        params.width = width != 0 ? width : Math.min(displayWidth, maxWidth);
-        params.height = height != 0 ? height : Math.min(displayHeight, maxHeight);
-
-        int posX = mContext.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_app_styled_dialog_position_x);
-        int posY = mContext.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_app_styled_dialog_position_y);
-
-        if (posX != 0 || posY != 0) {
-            params.gravity = Gravity.TOP | Gravity.START;
-            params.x = posX;
-            params.y = posY;
-        }
-
-        return params;
-    }
-
-    @Override
-    public View getAppStyledView(View contentView) {
-        // create ContextThemeWrapper from the original Activity Context with the custom theme
-        final Context contextThemeWrapper = new ContextThemeWrapper(mContext, R.style.Theme_CarUi);
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        if (inflater.getFactory2() == null) {
-            inflater.setFactory2(new CarUiLayoutInflaterFactory());
-        }
-        // clone the inflater using the ContextThemeWrapper
-        LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);
-
-        View appStyleView = localInflater.inflate(R.layout.car_ui_app_styled_view, null, false);
-        appStyleView.setClipToOutline(true);
-        RecyclerView rv = appStyleView.findViewById(R.id.car_ui_app_styled_content);
-
-        AppStyledRecyclerViewAdapter adapter = new AppStyledRecyclerViewAdapter(contentView);
-        rv.setLayoutManager(new LinearLayoutManager(mContext));
-        rv.setAdapter(adapter);
-
-        ImageView close = appStyleView.findViewById(R.id.car_ui_app_styled_view_icon_close);
-        if (mAppStyleViewNavIcon == AppStyledViewNavIcon.BACK) {
-            close.setImageResource(R.drawable.car_ui_icon_arrow_back);
-        } else if (mAppStyleViewNavIcon == AppStyledViewNavIcon.CLOSE) {
-            close.setImageResource(R.drawable.car_ui_icon_close);
-        } else {
-            close.setImageResource(R.drawable.car_ui_icon_close);
-        }
-
-        FrameLayout navContainer =
-                appStyleView.findViewById(R.id.car_ui_app_styled_view_nav_icon_container);
-        if (mAppStyledVCloseClickListener != null && navContainer != null) {
-            navContainer.setOnClickListener((v) -> {
-                mAppStyledVCloseClickListener.onClick();
-            });
-        }
-
-        return appStyleView;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/BaseLayoutController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/BaseLayoutController.java
deleted file mode 100644
index 3d415dc..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/BaseLayoutController.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.core;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.app.Activity;
-import android.content.res.TypedArray;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.car.ui.R;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.Map;
-import java.util.WeakHashMap;
-
-/**
- * BaseLayoutController accepts an {@link Activity} and sets up the base layout inside of it.
- * It also exposes a {@link ToolbarController} to access the toolbar. This may be null if
- * used with a base layout without a Toolbar.
- */
-public final class BaseLayoutController {
-
-    private static final Map<Activity, BaseLayoutController> sBaseLayoutMap = new WeakHashMap<>();
-
-    private InsetsUpdater mInsetsUpdater;
-
-    /**
-     * Gets a BaseLayoutController for the given {@link Activity}. Must have called
-     * {@link #build(Activity)} with the same activity earlier, otherwise will return null.
-     */
-    @Nullable
-    /* package */ static BaseLayoutController getBaseLayoutController(@Nullable Activity activity) {
-        return sBaseLayoutMap.get(activity);
-    }
-
-    @Nullable
-    private ToolbarController mToolbarController;
-
-    private BaseLayoutController(Activity activity) {
-        installBaseLayout(activity);
-    }
-
-    /**
-     * Create a new BaseLayoutController for the given {@link Activity}.
-     *
-     * <p>You can get a reference to it by calling {@link #getBaseLayoutController(Activity)}.
-     */
-    /* package */
-    static void build(Activity activity) {
-        if (getThemeBoolean(activity, R.attr.carUiBaseLayout)) {
-            sBaseLayoutMap.put(activity, new BaseLayoutController(activity));
-        }
-    }
-
-    /**
-     * Destroy the BaseLayoutController for the given {@link Activity}.
-     */
-    /* package */
-    static void destroy(Activity activity) {
-        sBaseLayoutMap.remove(activity);
-    }
-
-    /**
-     * Gets the {@link ToolbarController} for activities created with carUiBaseLayout and
-     * carUiToolbar set to true.
-     */
-    @Nullable
-    /* package */ ToolbarController getToolbarController() {
-        return mToolbarController;
-    }
-
-    /* package */ Insets getInsets() {
-        return mInsetsUpdater.getInsets();
-    }
-
-    /* package */ void dispatchNewInsets(Insets insets) {
-        mInsetsUpdater.onCarUiInsetsChanged(insets);
-    }
-
-    /* package */ void replaceInsetsChangedListenerWith(InsetsChangedListener listener) {
-        mInsetsUpdater.replaceInsetsChangedListenerWith(listener);
-    }
-
-    /**
-     * Installs the base layout into an activity, moving its content view under the base layout.
-     *
-     * <p>This function must be called during the onCreate() of the {@link Activity}.
-     *
-     * @param activity The {@link Activity} to install a base layout in.
-     */
-    private void installBaseLayout(Activity activity) {
-        boolean toolbarEnabled = getThemeBoolean(activity, R.attr.carUiToolbar);
-
-        View contentView =
-                requireViewByRefId(activity.getWindow().getDecorView(), android.R.id.content);
-
-        mInsetsUpdater = new InsetsUpdater(activity, contentView);
-        mToolbarController = SharedLibraryFactorySingleton.get(activity)
-                .installBaseLayoutAround(
-                        contentView,
-                        mInsetsUpdater,
-                        toolbarEnabled,
-                        true);
-    }
-
-    /**
-     * Gets the boolean value of an Attribute from an {@link Activity Activity's}
-     * {@link android.content.res.Resources.Theme}.
-     */
-    private static boolean getThemeBoolean(Activity activity, int attr) {
-        TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{attr});
-
-        try {
-            return a.getBoolean(0, false);
-        } finally {
-            a.recycle();
-        }
-    }
-
-    /**
-     * InsetsUpdater waits for layout changes, and when there is one, calculates the appropriate
-     * insets into the content view.
-     *
-     * <p>It then calls {@link InsetsChangedListener#onCarUiInsetsChanged(Insets)} on the
-     * {@link Activity} and any {@link Fragment Fragments} the Activity might have. If
-     * none of the Activity/Fragments implement {@link InsetsChangedListener}, it will set
-     * padding on the content view equal to the insets.
-     */
-    public static final class InsetsUpdater implements InsetsChangedListener {
-        private InsetsChangedListener mInsetsChangedListenerDelegate;
-
-        @Nullable
-        private Activity mActivity;
-        private View mContentView;
-
-        @NonNull
-        private Insets mInsets = new Insets();
-
-        /**
-         * Constructs an InsetsUpdater that calculates and dispatches insets to an {@link Activity}.
-         *
-         * @param activity    The activity that is using base layouts. Used to dispatch insets to if
-         *                    it implements {@link InsetsChangedListener}
-         * @param contentView The android.R.id.content View
-         */
-        InsetsUpdater(
-                @Nullable Activity activity,
-                @NonNull View contentView) {
-            mActivity = activity;
-            mContentView = contentView;
-        }
-
-        @NonNull
-        Insets getInsets() {
-            return mInsets;
-        }
-
-        public void replaceInsetsChangedListenerWith(InsetsChangedListener listener) {
-            mInsetsChangedListenerDelegate = listener;
-        }
-
-        @Override
-        public void onCarUiInsetsChanged(@NonNull Insets insets) {
-            if (mInsets.equals(insets)) {
-                return;
-            }
-
-            mInsets = insets;
-
-            boolean handled = false;
-            if (mInsetsChangedListenerDelegate != null) {
-                mInsetsChangedListenerDelegate.onCarUiInsetsChanged(insets);
-                handled = true;
-            } else {
-                // If an explicit InsetsChangedListener is not provided,
-                // pass the insets to activities and fragments
-                if (mActivity instanceof InsetsChangedListener) {
-                    ((InsetsChangedListener) mActivity).onCarUiInsetsChanged(insets);
-                    handled = true;
-                }
-
-                if (mActivity instanceof FragmentActivity) {
-                    for (Fragment fragment : ((FragmentActivity) mActivity)
-                            .getSupportFragmentManager().getFragments()) {
-                        if (fragment instanceof InsetsChangedListener) {
-                            ((InsetsChangedListener) fragment).onCarUiInsetsChanged(insets);
-                            handled = true;
-                        }
-                    }
-                }
-            }
-
-            if (!handled) {
-                mContentView.setPadding(insets.getLeft(), insets.getTop(),
-                        insets.getRight(), insets.getBottom());
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/CarUi.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/CarUi.java
deleted file mode 100644
index a780498..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/CarUi.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.core;
-
-import static com.android.car.ui.core.BaseLayoutController.getBaseLayoutController;
-
-import android.app.Activity;
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Public interface for general CarUi static functions.
- */
-public class CarUi {
-
-    /** Prevent instantiating this class */
-    private CarUi() {}
-
-    /**
-     * Gets a CarUi component, such as {@link com.android.car.ui.button.CarUiButton}, from the
-     * view hierarchy. The interfaces for these components don't extend View, so you can't
-     * get them through findViewById().
-     *
-     * @param view The parent view. Its descendants will be searched for the component.
-     * @param id The id of the component.
-     * @param <T> The resulting type of the component, such as
-     *            {@link com.android.car.ui.button.CarUiButton}
-     * @return The component found, or null.
-     */
-    @Nullable
-    @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
-    public static <T> T findCarUiComponentById(@Nullable View view, int id) {
-        if (view == null) {
-            return null;
-        }
-        View componentView = view.findViewById(id);
-        return componentView != null
-                ? (T) componentView.getTag(R.id.car_ui_component_reference)
-                : null;
-    }
-
-    /**
-     * Same as {@link #findCarUiComponentById(View, int)}, but will throw an exception
-     * if the result is null.
-     */
-    @NonNull
-    public static <T> T requireCarUiComponentById(View view, int id) {
-        return Objects.requireNonNull(findCarUiComponentById(view, id));
-    }
-
-    /**
-     * Gets the {@link ToolbarController} for an activity. Requires that the Activity uses
-     * Theme.CarUi.WithToolbar, or otherwise sets carUiBaseLayout and carUiToolbar to true.
-     *
-     * See also: {@link #requireToolbar(Activity)}
-     */
-    @Nullable
-    public static ToolbarController getToolbar(@Nullable Activity activity) {
-        BaseLayoutController controller = getBaseLayoutController(activity);
-        if (controller != null) {
-            return controller.getToolbarController();
-        }
-        return null;
-    }
-
-    /**
-     * Use this method to create an instance of a {@link RecyclerView.Adapter} for a list of {@link
-     * CarUiListItem} objects.
-     */
-    public static RecyclerView.Adapter<? extends RecyclerView.ViewHolder> createListItemAdapter(
-            Context context, List<? extends CarUiListItem> items) {
-        return SharedLibraryFactorySingleton.get(context).createListItemAdapter(items);
-    }
-
-
-    /**
-     * Gets the {@link ToolbarController} for an activity. Requires that the Activity uses
-     * Theme.CarUi.WithToolbar, or otherwise sets carUiBaseLayout and carUiToolbar to true.
-     *
-     * <p>See also: {@link #getToolbar(Activity)}
-     *
-     * @throws IllegalArgumentException When the CarUi Toolbar cannot be found.
-     */
-    @NonNull
-    public static ToolbarController requireToolbar(@NonNull Activity activity) {
-        ToolbarController result = getToolbar(activity);
-        if (result == null) {
-            throw new IllegalArgumentException("Activity " + activity
-                    + " does not have a CarUi Toolbar!"
-                    + " Are you using Theme.CarUi.WithToolbar?");
-        }
-
-        return result;
-    }
-
-    /**
-     * Registering a listener to receive the InsetsChanged updates instead of the Activity.
-     */
-    public static void replaceInsetsChangedListenerWith(Activity activity,
-            InsetsChangedListener listener) {
-        BaseLayoutController controller = getBaseLayoutController(activity);
-        if (controller != null) {
-            controller.replaceInsetsChangedListenerWith(listener);
-        }
-    }
-
-    /**
-     * Gets the current {@link Insets} of the given {@link Activity}. Only applies to Activities
-     * using the base layout, ie have the theme attribute "carUiBaseLayout" set to true.
-     *
-     * <p>Note that you likely don't want to use this without also using
-     * {@link com.android.car.ui.baselayout.InsetsChangedListener}, as without it the Insets
-     * will automatically be applied to your Activity's content view.
-     */
-    @Nullable
-    public static Insets getInsets(@Nullable Activity activity) {
-        BaseLayoutController controller = getBaseLayoutController(activity);
-        if (controller != null) {
-            return controller.getInsets();
-        }
-        return null;
-    }
-
-    /**
-     * Gets the current {@link Insets} of the given {@link Activity}. Only applies to Activities
-     * using the base layout, ie have the theme attribute "carUiBaseLayout" set to true.
-     *
-     * <p>Note that you likely don't want to use this without also using
-     * {@link com.android.car.ui.baselayout.InsetsChangedListener}, as without it the Insets
-     * will automatically be applied to your Activity's content view.
-     *
-     * @throws IllegalArgumentException When the activity is not using base layouts.
-     */
-    @NonNull
-    public static Insets requireInsets(@NonNull Activity activity) {
-        Insets result = getInsets(activity);
-        if (result == null) {
-            throw new IllegalArgumentException("Activity " + activity
-                    + " does not have a base layout!"
-                    + " Are you using Theme.CarUi.WithToolbar or Theme.CarUi.NoToolbar?");
-        }
-
-        return result;
-    }
-
-    /**
-     * Most apps should not use this method, but instead rely on CarUi automatically
-     * installing the base layout into their activities. See {@link #requireToolbar(Activity)}.
-     *
-     * This method installs the base layout *around* the provided view. As a result, this view
-     * must have a parent ViewGroup.
-     *
-     * When using this method, you can't use the other activity-based methods.
-     * ({@link #requireToolbar(Activity)}, {@link #requireInsets(Activity)}, ect.)
-     *
-     * @see #installBaseLayoutAround(View, InsetsChangedListener, boolean, boolean)
-     *
-     * @param view The view to wrap inside a base layout.
-     * @param hasToolbar if there should be a toolbar in the base layout.
-     * @return The {@link ToolbarController}, which will be null if hasToolbar is false.
-     */
-    @Nullable
-    public static ToolbarController installBaseLayoutAround(
-            View view,
-            InsetsChangedListener insetsChangedListener,
-            boolean hasToolbar) {
-        return installBaseLayoutAround(view, insetsChangedListener, hasToolbar, true);
-    }
-
-    /**
-     * Most apps should not use this method, but instead rely on CarUi automatically
-     * installing the base layout into their activities. See {@link #requireToolbar(Activity)}.
-     *
-     * This method installs the base layout *around* the provided view. As a result, this view
-     * must have a parent ViewGroup.
-     *
-     * When using this method, you can't use the other activity-based methods.
-     * ({@link #requireToolbar(Activity)}, {@link #requireInsets(Activity)}, ect.)
-     *
-     * @param view The view to wrap inside a base layout.
-     * @param hasToolbar if there should be a toolbar in the base layout.
-     * @param fullscreen A hint specifying whether this view we're installing around takes up
-     *                   the whole screen or not. Used to know if putting decorations around
-     *                   the edges is appropriate.
-     * @return The {@link ToolbarController}, which will be null if hasToolbar is false.
-     */
-    @Nullable
-    public static ToolbarController installBaseLayoutAround(
-            View view,
-            InsetsChangedListener insetsChangedListener,
-            boolean hasToolbar,
-            boolean fullscreen) {
-        return SharedLibraryFactorySingleton.get(view.getContext())
-                .installBaseLayoutAround(view, insetsChangedListener, hasToolbar, fullscreen);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/CarUiInstaller.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/CarUiInstaller.java
deleted file mode 100644
index 887ba3f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/CarUiInstaller.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.core;
-
-import android.app.Activity;
-import android.app.Application;
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatDelegate;
-
-import com.android.car.ui.CarUiLayoutInflaterFactory;
-import com.android.car.ui.baselayout.Insets;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Locale;
-
-/**
- * {@link ContentProvider ContentProvider's} onCreate() methods are "called for all registered
- * content providers on the application main thread at application launch time." This means we
- * can use a content provider to register for Activity lifecycle callbacks before any activities
- * have started, for installing the CarUi base layout into all activities.
- *
- * Notice that in many of the methods in this class we're using reflection to make method calls.
- * As it's explained in (b/156532465), {@link CarUiInstaller} is loaded from
- * GMSCore's ContainerActivity classloader which is different than the classloader of the Activity
- * that's passed as an argument to these methods. This happens when the Activity's module is loaded
- * dynamically. That means {@link CarUiInstaller} will have a different classloader than the
- * Activity. Hence we will need to use the Activity's classloader to load
- * {@link BaseLayoutController} class otherwise the base layout will be loaded
- * by the wrong classloader. And then calls to {@see CarUi#getToolbar(Activity)} will return null.
- */
-public class CarUiInstaller extends ContentProvider {
-
-    private static final String TAG = "CarUiInstaller";
-    private static final String CAR_UI_INSET_LEFT = "CAR_UI_INSET_LEFT";
-    private static final String CAR_UI_INSET_RIGHT = "CAR_UI_INSET_RIGHT";
-    private static final String CAR_UI_INSET_TOP = "CAR_UI_INSET_TOP";
-    private static final String CAR_UI_INSET_BOTTOM = "CAR_UI_INSET_BOTTOM";
-
-    private static final boolean IS_DEBUG_DEVICE =
-            Build.TYPE.toLowerCase(Locale.ROOT).contains("debug")
-                    || Build.TYPE.toLowerCase(Locale.ROOT).equals("eng");
-
-    @Override
-    public boolean onCreate() {
-        Context context = getContext();
-        if (context == null) {
-            Log.e(TAG, "CarUiInstaller had a null context!");
-            return false;
-        }
-        Log.i(TAG, "CarUiInstaller started for " + context.getPackageName());
-
-        Application application = (Application) context.getApplicationContext();
-        application.registerActivityLifecycleCallbacks(
-                new Application.ActivityLifecycleCallbacks() {
-                    private Insets mInsets = null;
-                    private boolean mIsActivityStartedForFirstTime = false;
-
-                    @Override
-                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
-                        injectLayoutInflaterFactory(activity);
-
-                        callMethodReflective(
-                                activity.getClassLoader(),
-                                BaseLayoutController.class,
-                                "build",
-                                null,
-                                activity);
-
-                        if (savedInstanceState != null) {
-                            int inset_left = savedInstanceState.getInt(CAR_UI_INSET_LEFT);
-                            int inset_top = savedInstanceState.getInt(CAR_UI_INSET_TOP);
-                            int inset_right = savedInstanceState.getInt(CAR_UI_INSET_RIGHT);
-                            int inset_bottom = savedInstanceState.getInt(CAR_UI_INSET_BOTTOM);
-                            mInsets = new Insets(inset_left, inset_top, inset_right, inset_bottom);
-                        }
-
-                        mIsActivityStartedForFirstTime = true;
-                    }
-
-                    @Override
-                    public void onActivityPostStarted(Activity activity) {
-                        Object controller = callMethodReflective(
-                                activity.getClassLoader(),
-                                BaseLayoutController.class,
-                                "getBaseLayoutController",
-                                null,
-                                activity);
-                        if (mInsets != null && controller != null
-                                && mIsActivityStartedForFirstTime) {
-                            callMethodReflective(
-                                    activity.getClassLoader(),
-                                    BaseLayoutController.class,
-                                    "dispatchNewInsets",
-                                    controller,
-                                    changeInsetsClassLoader(activity.getClassLoader(), mInsets));
-                            mIsActivityStartedForFirstTime = false;
-                        }
-                    }
-
-                    @Override
-                    public void onActivityStarted(Activity activity) {
-                    }
-
-                    @Override
-                    public void onActivityResumed(Activity activity) {
-                    }
-
-                    @Override
-                    public void onActivityPaused(Activity activity) {
-                    }
-
-                    @Override
-                    public void onActivityStopped(Activity activity) {
-                    }
-
-                    @Override
-                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
-                        Object controller = callMethodReflective(
-                                activity.getClassLoader(),
-                                BaseLayoutController.class,
-                                "getBaseLayoutController",
-                                null,
-                                activity);
-                        if (controller != null) {
-                            Object insets = callMethodReflective(
-                                    activity.getClassLoader(),
-                                    BaseLayoutController.class,
-                                    "getInsets",
-                                    controller);
-                            outState.putInt(CAR_UI_INSET_LEFT,
-                                    (int) callMethodReflective(
-                                            activity.getClassLoader(),
-                                            Insets.class,
-                                            "getLeft",
-                                            insets));
-                            outState.putInt(CAR_UI_INSET_TOP,
-                                    (int) callMethodReflective(
-                                            activity.getClassLoader(),
-                                            Insets.class,
-                                            "getTop",
-                                            insets));
-                            outState.putInt(CAR_UI_INSET_RIGHT,
-                                    (int) callMethodReflective(
-                                            activity.getClassLoader(),
-                                            Insets.class,
-                                            "getRight",
-                                            insets));
-                            outState.putInt(CAR_UI_INSET_BOTTOM,
-                                    (int) callMethodReflective(
-                                            activity.getClassLoader(),
-                                            Insets.class,
-                                            "getBottom",
-                                            insets));
-                        }
-                    }
-
-                    @Override
-                    public void onActivityDestroyed(Activity activity) {
-                        callMethodReflective(
-                                activity.getClassLoader(),
-                                BaseLayoutController.class,
-                                "destroy",
-                                null,
-                                activity);
-                    }
-                });
-
-        return true;
-    }
-
-    @Nullable
-    @Override
-    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
-            @Nullable String[] selectionArgs, @Nullable String sortOrder) {
-        return null;
-    }
-
-    @Nullable
-    @Override
-    public String getType(@NonNull Uri uri) {
-        return null;
-    }
-
-    @Nullable
-    @Override
-    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
-        return null;
-    }
-
-    @Override
-    public int delete(@NonNull Uri uri, @Nullable String selection,
-            @Nullable String[] selectionArgs) {
-        return 0;
-    }
-
-    @Override
-    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
-            @Nullable String[] selectionArgs) {
-        return 0;
-    }
-
-    @SuppressWarnings("AndroidJdkLibsChecker")
-    private static Object callMethodReflective(@NonNull ClassLoader cl, @NonNull Class<?> srcClass,
-            @NonNull String methodName, @Nullable Object instance, @Nullable Object... args) {
-        try {
-            Class<?> clazz = cl.loadClass(srcClass.getName());
-            Class<?>[] classArgs = args == null ? null
-                    : Arrays.stream(args)
-                            .map(arg -> arg instanceof Activity ? Activity.class : arg.getClass())
-                            .toArray(Class<?>[]::new);
-            Method method = clazz.getDeclaredMethod(methodName, classArgs);
-            method.setAccessible(true);
-            return method.invoke(instance, args);
-        } catch (ReflectiveOperationException | SecurityException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static Object changeInsetsClassLoader(@NonNull ClassLoader cl, @Nullable Insets src) {
-        if (src == null) {
-            return null;
-        }
-        try {
-            Class<?> insetsClass = cl.loadClass(Insets.class.getName());
-            Constructor<?> cnst = insetsClass.getDeclaredConstructor(
-                    int.class,
-                    int.class,
-                    int.class,
-                    int.class);
-            cnst.setAccessible(true);
-            return cnst.newInstance(
-                    src.getLeft(),
-                    src.getTop(),
-                    src.getRight(),
-                    src.getBottom());
-        } catch (ReflectiveOperationException | SecurityException e) {
-            throw new RuntimeException();
-        }
-    }
-
-    private static void injectLayoutInflaterFactory(Context context) {
-        // For {@link AppCompatActivity} activities our layout inflater
-        // factory is instantiated via viewInflaterClass attribute.
-        LayoutInflater layoutInflater = LayoutInflater.from(context);
-        if (layoutInflater.getFactory2() == null) {
-            layoutInflater.setFactory2(new CarUiLayoutInflaterFactory());
-        } else if (!(layoutInflater.getFactory2()
-                instanceof CarUiLayoutInflaterFactory)
-                        && !(layoutInflater.getFactory2()
-                                instanceof AppCompatDelegate)) {
-            throw new AssertionError(layoutInflater.getFactory2()
-                    + " must extend CarUiLayoutInflaterFactory");
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/SearchResultsProvider.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/SearchResultsProvider.java
deleted file mode 100644
index a2e8c8f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/core/SearchResultsProvider.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.core;
-
-import android.content.ContentProvider;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-
-import androidx.annotation.NonNull;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Content provider for displaying search results. The url looks like:
- * "content://${applicationId}.SearchResultsProvide/search_results"
- */
-public class SearchResultsProvider extends ContentProvider {
-    public static final String ITEM_ID = "primaryId";
-    public static final String SECONDARY_IMAGE_ID = "secondary";
-    public static final String PRIMARY_IMAGE_BLOB = "primary_image";
-    public static final String SECONDARY_IMAGE_BLOB = "secondary_image";
-    public static final String TITLE = "title";
-    public static final String SUBTITLE = "subtitle";
-
-    private final List<ContentValues> mSearchResults = new ArrayList<>();
-
-    /**
-     * Database specific constant declarations
-     */
-    private static final String SEARCH_RESULTS_TABLE_NAME = "search_results";
-
-    /**
-     * Gets the authority of this Content Provider.
-     * @param packageName The package name of the current application.
-     */
-    @NonNull
-    public static String getAuthority(@NonNull String packageName) {
-        return "content://" + packageName + "." + SearchResultsProvider.class.getSimpleName();
-    }
-
-    /**
-     * Gets the Uri to the search results table.
-     * @param context A context used to get the package name of the app.
-     */
-    @NonNull
-    public static Uri getSearchResultsTableUri(@NonNull Context context) {
-        return Uri.parse(getAuthority(context.getPackageName()) + "/" + SEARCH_RESULTS_TABLE_NAME);
-    }
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        mSearchResults.add(values);
-
-        Uri contentUri = getSearchResultsTableUri(getContext());
-        contentUri = ContentUris.withAppendedId(contentUri, mSearchResults.size() - 1);
-        getContext().getContentResolver().notifyChange(contentUri, null);
-        return contentUri;
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder) {
-        MatrixCursor cursor = new MatrixCursor(new String[]{
-                ITEM_ID,
-                SECONDARY_IMAGE_ID,
-                PRIMARY_IMAGE_BLOB,
-                SECONDARY_IMAGE_BLOB,
-                TITLE,
-                SUBTITLE
-        });
-
-        for (ContentValues values : mSearchResults) {
-            cursor.addRow(new Object[]{
-                    values.get(ITEM_ID),
-                    values.get(SECONDARY_IMAGE_ID),
-                    values.get(PRIMARY_IMAGE_BLOB),
-                    values.get(SECONDARY_IMAGE_BLOB),
-                    values.get(TITLE),
-                    values.get(SUBTITLE),
-            });
-        }
-        return cursor;
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        mSearchResults.clear();
-        return 0;
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values,
-            String selection, String[] selectionArgs) {
-        return 0;
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        return null;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeSearchListItem.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeSearchListItem.java
deleted file mode 100644
index 3733dcb..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeSearchListItem.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.imewidescreen;
-
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-
-/**
- * Definition of list items that can be inserted into {@link CarUiListItemAdapter}. This class is
- * used to display the search items in the template for wide screen mode.
- *
- * The class is used to pass application icon resources ids to the IME for rendering in its
- * process. Applications can also pass a unique id for each item and supplemental icon that will be
- * used by the IME to notify the application when a click action is taken on them.
- */
-public class CarUiImeSearchListItem extends CarUiContentListItem {
-
-    private int mIconResId;
-    private int mSupplementalIconResId;
-
-    public CarUiImeSearchListItem(Action action) {
-        super(action);
-    }
-
-    /**
-     * Sets the icon of the item. Icon must be a BitmapDrawable.
-     *
-     * @param icon the icon to display.
-     */
-    @Override
-    public void setIcon(@Nullable Drawable icon) {
-        if (icon instanceof BitmapDrawable || icon == null) {
-            super.setIcon(icon);
-            return;
-        }
-        throw new RuntimeException("icon should be of type BitmapDrawable");
-    }
-
-    /**
-     * Sets supplemental icon to be displayed in a list item. Icon must be a BitmapDrawable.
-     *
-     * @param icon     the Drawable to set as the icon, or null to clear the content.
-     * @param listener the callback that is invoked when the icon is clicked.
-     */
-    @Override
-    public void setSupplementalIcon(@Nullable Drawable icon,
-            @Nullable OnClickListener listener) {
-        if (icon instanceof BitmapDrawable || icon == null) {
-            super.setSupplementalIcon(icon, listener);
-            return;
-        }
-        throw new RuntimeException("icon should be of type BitmapDrawable");
-    }
-
-
-    /**
-     * Returns the icons resource of the item.
-     */
-    public int getIconResId() {
-        return mIconResId;
-    }
-
-    /**
-     * Sets the icons resource of the item.
-     */
-    public void setIconResId(int iconResId) {
-        mIconResId = iconResId;
-    }
-
-    /**
-     * Returns the supplemental icon resource id of the item.
-     */
-    public int getSupplementalIconResId() {
-        return mSupplementalIconResId;
-    }
-
-    /**
-     * Sets supplemental icon resource id.
-     */
-    public void setSupplementalIconResId(int supplementalIconResId) {
-        mSupplementalIconResId = supplementalIconResId;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java
deleted file mode 100644
index 286d621..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.imewidescreen;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.inputmethodservice.ExtractEditText;
-import android.inputmethodservice.InputMethodService;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.SurfaceControlViewHost.SurfacePackage;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.LinearLayoutManager;
-
-import com.android.car.ui.CarUiLayoutInflaterFactory;
-import com.android.car.ui.R;
-import com.android.car.ui.core.SearchResultsProvider;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper class to build an IME that support widescreen mode.
- *
- * <p> This class provides helper methods that should be invoked during the lifecycle of an IME.
- * Usage of these methods are listed below.
- * <ul>
- *      <li>create an instance of {@link CarUiImeWideScreenController} in
- *      {@link InputMethodService#onCreate()}</li>
- *      <li>return {@link #onEvaluateFullscreenMode(boolean)} from
- *      {@link InputMethodService#onEvaluateFullscreenMode()}</li>
- *      <li>return the view created by
- *      {@link #createWideScreenImeView(View)}
- *      from {@link InputMethodService#onCreateInputView()}</li>
- *      <li>{@link #onComputeInsets(InputMethodService.Insets) should be called from
- *      {@link InputMethodService#onComputeInsets(InputMethodService.Insets)}</li>
- *      <li>{@link #onAppPrivateCommand(String, Bundle) should be called from {
- *      @link InputMethodService#onAppPrivateCommand(String, Bundle)}}</li>
- *      <li>{@link #setExtractViewShown(boolean)} should be called from
- *      {@link InputMethodService#setExtractViewShown(boolean)}</li>
- *      <li>{@link #onStartInputView(EditorInfo, InputConnection, CharSequence)} should be called
- *      from {@link InputMethodService#onStartInputView(EditorInfo, boolean)}</li>
- *      <li>{@link #onFinishInputView()} should be called from
- *      {@link InputMethodService#onFinishInputView(boolean)}</li>
- * </ul>
- *
- * <p> All the methods in this class are guarded with a check {@link #isWideScreenMode()}. If
- * wide screen mode is disabled all the method would return without doing anything. Also, IME
- * should check for {@link #isWideScreenMode()} in
- * {@link InputMethodService#setExtractViewShown(boolean)} and return the original value instead
- * of false. for more info see {@link #setExtractViewShown(boolean)}
- */
-public class CarUiImeWideScreenController {
-
-    private static final String TAG = "ImeWideScreenController";
-    private static final String NOT_ASTERISK_OR_CAPTURED_ASTERISK = "[^*]+|(\\*)";
-
-    // Automotive wide screen mode bundle keys.
-
-    // Action name of the action to support wide screen mode templates data.
-    public static final String WIDE_SCREEN_ACTION = "automotive_wide_screen";
-    // Action name of action that will be used by IMS to notify the application to clear the data
-    // in the EditText.
-    public static final String WIDE_SCREEN_CLEAR_DATA_ACTION = "automotive_wide_screen_clear_data";
-    public static final String WIDE_SCREEN_POST_LOAD_SEARCH_RESULTS_ACTION =
-            "automotive_wide_screen_post_load_search_results";
-    // Action name used by applications to notify that new search results are available.
-    public static final String WIDE_SCREEN_SEARCH_RESULTS = "wide_screen_search_results";
-    // Key to provide the resource id for the icon that will be displayed in the input area. If
-    // this is not provided applications icon will be used. Value format is int.
-    public static final String WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID =
-            "extracted_text_icon_res_id";
-    // key to provide the drawable resource for the icon that will be displayed in the input area.
-    // If this is not provided, applications icon will be used. Value format is byteArray.
-    public static final String WIDE_SCREEN_EXTRACTED_TEXT_ICON = "extracted_text_icon";
-    // Key to determine if IME should display the content area or not. Content area is referred to
-    // the area used by IME to display search results, description title and description
-    // provided by the application. By default it will be shown but this value could be ignored
-    // if bool/car_ui_ime_wide_screen_allow_app_hide_content_area is set to false. Value format
-    // is boolean.
-    public static final String REQUEST_RENDER_CONTENT_AREA = "request_render_content_area";
-    // Key used to provide the description title to be rendered in the content area. Value format
-    // is String.
-    public static final String ADD_DESC_TITLE_TO_CONTENT_AREA = "add_desc_title_to_content_area";
-    // Key used to provide the description to be rendered in the content area. Value format is
-    // String.
-    public static final String ADD_DESC_TO_CONTENT_AREA = "add_desc_to_content_area";
-    // Key used to provide the error description to be rendered in the input area. Value format
-    // is String.
-    public static final String ADD_ERROR_DESC_TO_INPUT_AREA = "add_error_desc_to_input_area";
-
-    // wide screen search item keys. Each search item contains a title, sub-title, primary image
-    // and an secondary image. Click actions can be performed on item and secondary image.
-    // Application will be notified with the Ids of item clicked.
-
-    // Each key below represents a list. Search results will be displayed in the same order as
-    // the list provided by the application. For example, to create the search item at index 0
-    // controller will get the information from each lists index 0.
-
-    // Key used to provide list of unique id for each item. This same id will be sent back to
-    // the application when the item is clicked. Value format is ArrayList<String>
-    public static final String SEARCH_RESULT_ITEM_ID_LIST = "search_result_item_id_list";
-
-    public static final String SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST =
-            "search_result_supplemental_icon_id_list";
-    // key used to provide the surface package information by the application to the IME. IME
-    // will send the surface info each time its being displayed.
-    public static final String CONTENT_AREA_SURFACE_PACKAGE = "content_area_surface_package";
-    // key to provide the host token of surface view by IME to the application.
-    public static final String CONTENT_AREA_SURFACE_HOST_TOKEN = "content_area_surface_host_token";
-    // key to provide the display id of surface view by IME to the application.
-    public static final String CONTENT_AREA_SURFACE_DISPLAY_ID = "content_area_surface_display_id";
-    // key to provide the height of surface view by IME to the application.
-    public static final String CONTENT_AREA_SURFACE_HEIGHT = "content_area_surface_height";
-    // key to provide the width of surface view by IME to the application.
-    public static final String CONTENT_AREA_SURFACE_WIDTH = "content_area_surface_width";
-
-    private View mRootView;
-    private final Context mContext;
-    @Nullable
-    private View mExtractActionAutomotive;
-    @NonNull
-    private View mContentAreaAutomotive;
-    // whether to render the content area for automotive when in wide screen mode.
-    private boolean mImeRendersAllContent = true;
-    private boolean mAllowAppToHideContentArea;
-    @Nullable
-    private ArrayList<CarUiContentListItem> mAutomotiveSearchItems;
-    @NonNull
-    private TextView mWideScreenDescriptionTitle;
-    @NonNull
-    private TextView mWideScreenDescription;
-    @NonNull
-    private TextView mWideScreenErrorMessage;
-    @NonNull
-    private ImageView mWideScreenErrorImage;
-    @NonNull
-    private ImageView mWideScreenClearData;
-    @NonNull
-    private CarUiRecyclerView mRecyclerView;
-    @Nullable
-    private ImageView mWideScreenExtractedTextIcon;
-    private boolean mIsExtractIconProvidedByApp;
-    @NonNull
-    private FrameLayout mInputFrame;
-    @NonNull
-    private ExtractEditText mExtractEditText;
-    @NonNull
-    private EditorInfo mInputEditorInfo;
-    private InputConnection mInputConnection;
-    private boolean mExtractViewHidden;
-    @NonNull
-    private View mFullscreenArea;
-    @NonNull
-    private SurfaceView mContentAreaSurfaceView;
-    @NonNull
-    private FrameLayout mInputExtractEditTextContainer;
-    private final InputMethodService mInputMethodService;
-
-    public CarUiImeWideScreenController(@NonNull Context context, @NonNull InputMethodService ims) {
-        mContext = context;
-        mInputMethodService = ims;
-    }
-
-    /**
-     * Create and return the view hierarchy used for the input area in wide screen mode. This method
-     * will inflate the templates with the inputView provided.
-     *
-     * @param inputView view of the keyboard created by application.
-     * @return view to be used by {@link InputMethodService}.
-     */
-    public View createWideScreenImeView(@NonNull View inputView) {
-        if (!isWideScreenMode()) {
-            return inputView;
-        }
-
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        if (inflater.getFactory2() == null) {
-            inflater.setFactory2(new CarUiLayoutInflaterFactory());
-        }
-
-        mRootView = inflater.inflate(R.layout.car_ui_ims_wide_screen_input_view, null);
-
-        mInputFrame = mRootView.requireViewById(R.id.car_ui_wideScreenInputArea);
-        mInputFrame.addView(inputView, new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-
-        mAllowAppToHideContentArea =
-                mContext.getResources().getBoolean(
-                        R.bool.car_ui_ime_wide_screen_allow_app_hide_content_area);
-
-        mContentAreaSurfaceView = mRootView.requireViewById(R.id.car_ui_ime_surface);
-        mContentAreaSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
-            @Override
-            public void surfaceCreated(SurfaceHolder holder) {
-            }
-
-            @Override
-            public void surfaceChanged(SurfaceHolder holder, int format,
-                                       int width, int height) {
-                Bundle bundle = new Bundle();
-                bundle.putInt(CONTENT_AREA_SURFACE_HEIGHT,
-                        mContentAreaSurfaceView.getHeight());
-                bundle.putInt(CONTENT_AREA_SURFACE_WIDTH, mContentAreaSurfaceView.getWidth());
-                mInputConnection.performPrivateCommand(WIDE_SCREEN_ACTION, bundle);
-            }
-
-            @Override
-            public void surfaceDestroyed(SurfaceHolder holder) {
-            }
-        });
-        mContentAreaSurfaceView.setZOrderOnTop(true);
-        mWideScreenDescriptionTitle =
-                mRootView.requireViewById(R.id.car_ui_wideScreenDescriptionTitle);
-        mWideScreenDescription = mRootView.requireViewById(R.id.car_ui_wideScreenDescription);
-        mExtractActionAutomotive =
-                mRootView.findViewById(R.id.car_ui_inputExtractActionAutomotive);
-        mContentAreaAutomotive = mRootView.requireViewById(R.id.car_ui_contentAreaAutomotive);
-        mRecyclerView = mRootView.requireViewById(R.id.car_ui_wideScreenSearchResultList);
-        mWideScreenErrorMessage = mRootView.requireViewById(R.id.car_ui_wideScreenErrorMessage);
-        mWideScreenExtractedTextIcon =
-                mRootView.findViewById(R.id.car_ui_wideScreenExtractedTextIcon);
-        mWideScreenErrorImage = mRootView.requireViewById(R.id.car_ui_wideScreenError);
-        mWideScreenClearData = mRootView.requireViewById(R.id.car_ui_wideScreenClearData);
-        mFullscreenArea = mRootView.requireViewById(R.id.car_ui_fullscreenArea);
-        mInputExtractEditTextContainer = mRootView.requireViewById(
-                R.id.car_ui_inputExtractEditTextContainer);
-        mWideScreenClearData.setOnClickListener(
-                v -> {
-                    // notify the app to clear the data.
-                    mInputConnection.performPrivateCommand(WIDE_SCREEN_CLEAR_DATA_ACTION, null);
-                });
-        mExtractViewHidden = false;
-
-        return mRootView;
-    }
-
-    /**
-     * Compute the interesting insets into your UI. When the content view is shown the default
-     * touchable insets are {@link InputMethodService.Insets#TOUCHABLE_INSETS_FRAME}. When content
-     * view is hidden then that area of the application is interactable by user.
-     *
-     * @param outInsets Fill in with the current UI insets.
-     */
-    public void onComputeInsets(@NonNull InputMethodService.Insets outInsets) {
-        if (!isWideScreenMode()) {
-            return;
-        }
-        Rect tempRect = new Rect();
-        int[] tempLocation = new int[2];
-        outInsets.contentTopInsets = outInsets.visibleTopInsets =
-                mInputMethodService.getWindow().getWindow().getDecorView().getHeight();
-        if (mImeRendersAllContent) {
-            outInsets.touchableRegion.setEmpty();
-            outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_FRAME;
-        } else {
-            mInputFrame.getLocationOnScreen(tempLocation);
-            tempRect.set(/* left= */0, /* top= */ 0,
-                    tempLocation[0] + mInputFrame.getWidth(),
-                    tempLocation[1] + mInputFrame.getHeight());
-            outInsets.touchableRegion.set(tempRect);
-            outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
-        }
-    }
-
-    /**
-     * Actions passed by the application must be "automotive_wide_screen" with the corresponding
-     * data
-     * that application wants to display. See the comments associated with each bundle key to know
-     * what view is rendered.
-     *
-     * <p> Each bundle key renders or updates/controls a particular view in the template. For
-     * example, if application rendered the description title and later also wanted to render an
-     * actual description with it then application should use both "add_desc_title_to_content_area"
-     * and "add_desc_to_content_area" to provide the data. Sending action with only
-     * "add_desc_to_content_area" bundle key will not add an extra view but will display only the
-     * description and not the title.
-     * <p>
-     * When the IME window is closed all the views are reset. For the default view visibility see
-     * {@link #resetAutomotiveWideScreenViews()}.
-     *
-     * @param action Name of the command to be performed.
-     * @param data   Any data to include with the command.
-     */
-    @RequiresApi(api = VERSION_CODES.R)
-    public void onAppPrivateCommand(String action, Bundle data) {
-        if (!isWideScreenMode()) {
-            return;
-        }
-        resetAutomotiveWideScreenViews();
-        if (data == null) {
-            return;
-        }
-        if (mAllowAppToHideContentArea || (mInputEditorInfo != null && isPackageAuthorized(
-                getEditorInfoPackageName()))) {
-            mImeRendersAllContent = data.getBoolean(REQUEST_RENDER_CONTENT_AREA, true);
-            if (!mImeRendersAllContent) {
-                mContentAreaAutomotive.setVisibility(View.GONE);
-            } else {
-                mContentAreaAutomotive.setVisibility(View.VISIBLE);
-            }
-        }
-
-        if (data.getParcelable(CONTENT_AREA_SURFACE_PACKAGE) != null
-                && Build.VERSION.SDK_INT >= VERSION_CODES.R) {
-            SurfacePackage surfacePackage = (SurfacePackage) data.getParcelable(
-                    CONTENT_AREA_SURFACE_PACKAGE);
-            mContentAreaSurfaceView.setChildSurfacePackage(surfacePackage);
-            mContentAreaSurfaceView.setVisibility(View.VISIBLE);
-            mContentAreaAutomotive.setVisibility(View.GONE);
-        }
-
-        String discTitle = data.getString(ADD_DESC_TITLE_TO_CONTENT_AREA);
-        if (!TextUtils.isEmpty(discTitle)) {
-            mWideScreenDescriptionTitle.setText(discTitle);
-            mWideScreenDescriptionTitle.setVisibility(View.VISIBLE);
-            mContentAreaAutomotive.setBackground(
-                    mContext.getDrawable(R.drawable.car_ui_ime_wide_screen_background));
-        }
-
-        String disc = data.getString(ADD_DESC_TO_CONTENT_AREA);
-        if (!TextUtils.isEmpty(disc)) {
-            mWideScreenDescription.setText(disc);
-            mWideScreenDescription.setVisibility(View.VISIBLE);
-            mContentAreaAutomotive.setBackground(
-                    mContext.getDrawable(R.drawable.car_ui_ime_wide_screen_background));
-        }
-
-        String errorMessage = data.getString(ADD_ERROR_DESC_TO_INPUT_AREA);
-        if (!TextUtils.isEmpty(errorMessage)) {
-            mWideScreenErrorMessage.setVisibility(View.VISIBLE);
-            mWideScreenClearData.setVisibility(View.GONE);
-            mWideScreenErrorImage.setVisibility(View.VISIBLE);
-            setExtractedEditTextBackground(
-                    R.drawable.car_ui_ime_wide_screen_input_area_tint_error_color);
-            mWideScreenErrorMessage.setText(errorMessage);
-            mContentAreaAutomotive.setBackground(
-                    mContext.getDrawable(R.drawable.car_ui_ime_wide_screen_background));
-        }
-
-        if (TextUtils.isEmpty(errorMessage)) {
-            mWideScreenErrorMessage.setVisibility(View.INVISIBLE);
-            mWideScreenErrorMessage.setText("");
-            mWideScreenClearData.setVisibility(View.VISIBLE);
-            mWideScreenErrorImage.setVisibility(View.GONE);
-            setExtractedEditTextBackground(
-                    R.drawable.car_ui_ime_wide_screen_input_area_tint_color);
-        }
-
-        int extractedTextIcon = data.getInt(WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID);
-        if (extractedTextIcon != 0) {
-            setWideScreenExtractedIcon(extractedTextIcon);
-        }
-
-        byte[] byteArray = data.getByteArray(WIDE_SCREEN_EXTRACTED_TEXT_ICON);
-        if (byteArray != null) {
-            Bitmap bitmap = Bitmap.CREATOR.createFromParcel(
-                    byteArrayToParcel(byteArray));
-            mWideScreenExtractedTextIcon.setImageDrawable(
-                    new BitmapDrawable(mContext.getResources(), bitmap));
-            mWideScreenExtractedTextIcon.setVisibility(View.VISIBLE);
-        }
-
-        if (WIDE_SCREEN_SEARCH_RESULTS.equals(action)) {
-            loadSearchItems();
-        }
-
-        if (mExtractActionAutomotive != null) {
-            mExtractActionAutomotive.setVisibility(View.VISIBLE);
-        }
-        if (mAutomotiveSearchItems != null) {
-            mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-            mRecyclerView.setVerticalScrollBarEnabled(true);
-            mRecyclerView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT);
-            mRecyclerView.setVisibility(View.VISIBLE);
-            mRecyclerView.setAdapter(new CarUiListItemAdapter(mAutomotiveSearchItems));
-            mContentAreaAutomotive.setBackground(
-                    mContext.getDrawable(R.drawable.car_ui_ime_wide_screen_background));
-            if (mExtractActionAutomotive != null) {
-                mExtractActionAutomotive.setVisibility(View.GONE);
-            }
-        }
-    }
-
-    private void loadSearchItems() {
-        if (mInputEditorInfo == null) {
-            Log.w(TAG, "Result can't be loaded, input InputEditorInfo not available ");
-            return;
-        }
-        Uri contentUrl = Uri.parse(SearchResultsProvider.getAuthority(
-                getPackageName(mInputEditorInfo)));
-        ContentResolver cr = mContext.getContentResolver();
-        try (Cursor c = cr.query(contentUrl, null, null, null, null)) {
-            mAutomotiveSearchItems = new ArrayList<>();
-            if (c != null && c.moveToFirst()) {
-                do {
-                    CarUiContentListItem searchItem = new CarUiContentListItem(
-                            CarUiContentListItem.Action.ICON);
-                    String itemId = c.getString(c.getColumnIndex(SearchResultsProvider.ITEM_ID));
-                    searchItem.setOnItemClickedListener(v -> onItemClicked(itemId));
-                    searchItem.setTitle(c.getString(
-                            c.getColumnIndex(SearchResultsProvider.TITLE)));
-                    searchItem.setBody(c.getString(
-                            c.getColumnIndex(SearchResultsProvider.SUBTITLE)));
-                    searchItem.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT);
-                    byte[] primaryBlob = c.getBlob(
-                            c.getColumnIndex(
-                                    SearchResultsProvider.PRIMARY_IMAGE_BLOB));
-                    if (primaryBlob != null) {
-                        Bitmap primaryBitmap = Bitmap.CREATOR.createFromParcel(
-                                byteArrayToParcel(primaryBlob));
-                        searchItem.setIcon(
-                                new BitmapDrawable(mContext.getResources(), primaryBitmap));
-                    }
-                    byte[] secondaryBlob = c.getBlob(
-                            c.getColumnIndex(
-                                    SearchResultsProvider.SECONDARY_IMAGE_BLOB));
-
-                    if (secondaryBlob != null) {
-                        Bitmap secondaryBitmap = Bitmap.CREATOR.createFromParcel(
-                                byteArrayToParcel(secondaryBlob));
-                        String secondaryItemId = c.getString(c.getColumnIndex(
-                                SearchResultsProvider.SECONDARY_IMAGE_ID));
-                        searchItem.setSupplementalIcon(
-                                new BitmapDrawable(mContext.getResources(), secondaryBitmap), v -> {
-                                    Bundle bundle = new Bundle();
-                                    bundle.putString(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST,
-                                            secondaryItemId);
-                                    mInputConnection.performPrivateCommand(WIDE_SCREEN_ACTION,
-                                            bundle);
-                                });
-                    }
-                    mAutomotiveSearchItems.add(searchItem);
-                } while (c.moveToNext());
-            }
-        }
-
-        mInputConnection.performPrivateCommand(WIDE_SCREEN_POST_LOAD_SEARCH_RESULTS_ACTION, null);
-    }
-
-    void onItemClicked(String itemId) {
-        Bundle bundle = new Bundle();
-        bundle.putString(SEARCH_RESULT_ITEM_ID_LIST, itemId);
-        mInputConnection.performPrivateCommand(WIDE_SCREEN_ACTION, bundle);
-    }
-
-    private static Parcel byteArrayToParcel(byte[] bytes) {
-        Parcel parcel = Parcel.obtain();
-        parcel.unmarshall(bytes, 0, bytes.length);
-        parcel.setDataPosition(0);
-        return parcel;
-    }
-
-    /**
-     * Evaluate if IME should launch in a fullscreen mode. In wide screen mode IME should always
-     * launch in a fullscreen mode so that {@link ExtractEditText} is inflated. Later the controller
-     * will detach the {@link ExtractEditText} from its original parent and inflate into the
-     * appropriate container in wide screen.
-     *
-     * @param isFullScreen value evaluated to be in fullscreen mode or not by the app.
-     */
-    public boolean onEvaluateFullscreenMode(boolean isFullScreen) {
-        return isWideScreenMode() || isFullScreen;
-    }
-
-    /**
-     * Initialize the view in the wide screen template based on the data provided by the app through
-     * {@link #onAppPrivateCommand(String, Bundle)}
-     */
-    @RequiresApi(api = VERSION_CODES.R)
-    public void onStartInputView(@NonNull EditorInfo editorInfo,
-                                 @Nullable InputConnection inputConnection,
-                                 @Nullable CharSequence textForImeAction) {
-        if (!isWideScreenMode()) {
-            return;
-        }
-        mInputEditorInfo = editorInfo;
-        mInputConnection = inputConnection;
-        View header = mRootView.requireViewById(R.id.car_ui_imeWideScreenInputArea);
-
-        header.setVisibility(View.VISIBLE);
-        if (mExtractViewHidden) {
-            mFullscreenArea.setVisibility(View.INVISIBLE);
-        } else {
-            mFullscreenArea.setVisibility(View.VISIBLE);
-        }
-
-        // This view is rendered by the framework when IME is in full screen mode. For more info
-        // see {@link #onEvaluateFullscreenMode}
-        mExtractEditText = getExtractEditText();
-        mExtractEditText.setPadding(
-                mContext.getResources().getDimensionPixelSize(
-                        R.dimen.car_ui_ime_wide_screen_input_edit_text_padding_left),
-                /* top= */0,
-                mContext.getResources().getDimensionPixelSize(
-                        R.dimen.car_ui_ime_wide_screen_input_edit_text_padding_right),
-                /* bottom= */0);
-        mExtractEditText.setTextSize(mContext.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_ime_wide_screen_input_edit_text_size));
-        mExtractEditText.setGravity(Gravity.START | Gravity.CENTER);
-
-        ViewGroup parent = (ViewGroup) mExtractEditText.getParent();
-        parent.removeViewInLayout(mExtractEditText);
-
-        FrameLayout.LayoutParams params =
-                new FrameLayout.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-
-        mInputExtractEditTextContainer.addView(mExtractEditText, params);
-
-        ImageView close = mRootView.findViewById(R.id.car_ui_closeKeyboard);
-        if (close != null) {
-            close.setOnClickListener(
-                    (v) -> {
-                        mInputMethodService.requestHideSelf(0);
-                    });
-        }
-
-        if (!mIsExtractIconProvidedByApp) {
-            setWideScreenExtractedIcon(/* iconResId= */0);
-        }
-
-        boolean hasAction = (mInputEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION)
-                != EditorInfo.IME_ACTION_NONE;
-        boolean hasInputType = mInputEditorInfo.inputType != InputType.TYPE_NULL;
-        boolean hasNoAccessoryAction =
-                (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_ACCESSORY_ACTION) == 0;
-
-        boolean hasLabel =
-                mInputEditorInfo.actionLabel != null || (hasAction && hasNoAccessoryAction
-                        && hasInputType);
-
-        if (hasLabel) {
-            intiExtractAction(textForImeAction);
-        }
-
-        if (mContentAreaSurfaceView.getVisibility() == View.GONE) {
-            sendSurfaceInfo();
-        }
-    }
-
-    @VisibleForTesting
-    ExtractEditText getExtractEditText() {
-        return mRootView.getRootView().requireViewById(
-                android.R.id.inputExtractEditText);
-    }
-
-    /**
-     * Sends the information for surface view to the application on which they can draw on. This
-     * information will ONLY be sent if OEM allows an application to hide the content area and let
-     * it draw its own content.
-     */
-    @RequiresApi(api = VERSION_CODES.R)
-    private void sendSurfaceInfo() {
-        if (!mAllowAppToHideContentArea && mContentAreaSurfaceView.getDisplay() == null
-                && !(mInputEditorInfo != null
-                && isPackageAuthorized(getEditorInfoPackageName()))) {
-            return;
-        }
-        // Dispatch the window visibility change for IME window as soon as its displayed.
-        mRootView.dispatchWindowVisibilityChanged(View.VISIBLE);
-        IBinder hostToken = null;
-        int displayId = mContentAreaSurfaceView.getDisplay() == null
-                ? 0 : mContentAreaSurfaceView.getDisplay().getDisplayId();
-        hostToken = mContentAreaSurfaceView.getHostToken();
-
-        Bundle bundle = new Bundle();
-        bundle.putBinder(CONTENT_AREA_SURFACE_HOST_TOKEN, hostToken);
-        bundle.putInt(CONTENT_AREA_SURFACE_DISPLAY_ID, displayId);
-        bundle.putInt(CONTENT_AREA_SURFACE_HEIGHT,
-                mContentAreaSurfaceView.getHeight() + getNavBarHeight());
-        bundle.putInt(CONTENT_AREA_SURFACE_WIDTH, mContentAreaSurfaceView.getWidth());
-
-        mInputConnection.performPrivateCommand(WIDE_SCREEN_ACTION, bundle);
-    }
-
-    @VisibleForTesting
-    boolean isPackageAuthorized(String packageName) {
-        String[] packages = mContext.getResources()
-                .getStringArray(R.array.car_ui_ime_wide_screen_allowed_package_list);
-
-        PackageInfo packageInfo = getPackageInfo(mContext, packageName);
-        // Checks if the application of the given context is installed in the system image. I.e.
-        // if it's a bundled app.
-        if (packageInfo != null && (packageInfo.applicationInfo.flags & (ApplicationInfo.FLAG_SYSTEM
-                | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
-            return true;
-        }
-
-        for (String pattern : packages) {
-            String regex = createRegexFromGlob(pattern);
-            if (packageName.matches(regex)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Return the package info for a particular package.
-     */
-    @Nullable
-    private static PackageInfo getPackageInfo(Context context,
-                                              String packageName) {
-        PackageManager packageManager = context.getPackageManager();
-        PackageInfo packageInfo = null;
-        try {
-            packageInfo = packageManager.getPackageInfo(
-                    packageName, /* flags= */ 0);
-        } catch (PackageManager.NameNotFoundException ex) {
-            Log.e(TAG, "package not found: " + packageName);
-        }
-        return packageInfo;
-    }
-
-    private static String createRegexFromGlob(String glob) {
-        Pattern reg = Pattern.compile(NOT_ASTERISK_OR_CAPTURED_ASTERISK);
-        Matcher m = reg.matcher(glob);
-        StringBuffer b = new StringBuffer();
-        while (m.find()) {
-            if (m.group(1) != null) {
-                m.appendReplacement(b, ".*");
-            } else {
-                m.appendReplacement(b, Matcher.quoteReplacement(m.group(0)));
-            }
-        }
-        m.appendTail(b);
-        return b.toString();
-    }
-
-    private int getNavBarHeight() {
-        Resources resources = mContext.getResources();
-        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
-        if (resourceId > 0) {
-            return resources.getDimensionPixelSize(resourceId);
-        }
-        return 0;
-    }
-
-    /**
-     * To support wide screen mode, IME should always call
-     * {@link InputMethodService#setExtractViewShown}
-     * with false and pass the flag to this method.
-     * <p>
-     * For example, within the IMS service call
-     * <pre>
-     *   @Override
-     *   public void setExtractViewShown(boolean shown) {
-     *     if (!carUiImeWideScreenController.isWideScreenMode()) {
-     *         super.setExtractViewShown(shown);
-     *         return;
-     *     }
-     *     super.setExtractViewShown(false);
-     *     mImeWideScreenController.setExtractViewShown(shown);
-     *   }
-     * </pre>
-     * <p>
-     * This is required as IMS checks for ExtractViewIsShown and if that is true then set the
-     * touchable insets to the entire screen rather than a region. If an app hides the content area
-     * in that case we want the user to be able to interact with the application.
-     */
-    public void setExtractViewShown(boolean shown) {
-        if (!isWideScreenMode()) {
-            return;
-        }
-        if (mExtractViewHidden == !shown) {
-            return;
-        }
-        mExtractViewHidden = !shown;
-        if (mExtractViewHidden) {
-            mFullscreenArea.setVisibility(View.INVISIBLE);
-        } else {
-            mFullscreenArea.setVisibility(View.VISIBLE);
-        }
-    }
-
-    private void intiExtractAction(CharSequence textForImeAction) {
-        if (mExtractActionAutomotive == null) {
-            return;
-        }
-        if (mInputEditorInfo.actionLabel != null) {
-            ((TextView) mExtractActionAutomotive).setText(mInputEditorInfo.actionLabel);
-        } else {
-            ((TextView) mExtractActionAutomotive).setText(textForImeAction);
-        }
-
-        // click listener for the action button shown in the content area.
-        mExtractActionAutomotive.setOnClickListener(v -> {
-            final EditorInfo editorInfo = mInputEditorInfo;
-            final InputConnection inputConnection = mInputConnection;
-            if (editorInfo == null || inputConnection == null) {
-                return;
-            }
-            if (editorInfo.actionId != 0) {
-                inputConnection.performEditorAction(editorInfo.actionId);
-            } else if ((editorInfo.imeOptions & EditorInfo.IME_MASK_ACTION)
-                    != EditorInfo.IME_ACTION_NONE) {
-                inputConnection.performEditorAction(
-                        editorInfo.imeOptions & EditorInfo.IME_MASK_ACTION);
-            }
-        });
-    }
-
-    private void setExtractedEditTextBackground(int drawableResId) {
-        mExtractEditText.setBackgroundTintList(mContext.getColorStateList(drawableResId));
-    }
-
-    @VisibleForTesting
-    void setContentAreaSurfaceView(SurfaceView surfaceView) {
-        mContentAreaSurfaceView = surfaceView;
-    }
-
-    @VisibleForTesting
-    String getPackageName(EditorInfo editorInfo) {
-        return editorInfo.packageName;
-    }
-
-    /**
-     * Sets the icon in the input area. If the icon resource Id is not provided by the application
-     * then application icon will be used instead.
-     *
-     * @param iconResId icon resource id for the image drawable to load.
-     */
-    private void setWideScreenExtractedIcon(@DrawableRes int iconResId) {
-        if (mInputEditorInfo == null || mWideScreenExtractedTextIcon == null) {
-            return;
-        }
-        try {
-            if (iconResId == 0) {
-                mWideScreenExtractedTextIcon.setImageDrawable(
-                        mContext.getPackageManager().getApplicationIcon(
-                                getEditorInfoPackageName()));
-            } else {
-                mIsExtractIconProvidedByApp = true;
-                mWideScreenExtractedTextIcon.setImageDrawable(
-                        mContext.createPackageContext(getEditorInfoPackageName(), 0).getDrawable(
-                                iconResId));
-            }
-            mWideScreenExtractedTextIcon.setVisibility(View.VISIBLE);
-        } catch (PackageManager.NameNotFoundException ex) {
-            Log.w(TAG, "setWideScreenExtractedIcon: package name not found ", ex);
-            mWideScreenExtractedTextIcon.setVisibility(View.GONE);
-        } catch (Resources.NotFoundException ex) {
-            Log.w(TAG, "setWideScreenExtractedIcon: resource not found with id " + iconResId, ex);
-            mWideScreenExtractedTextIcon.setVisibility(View.GONE);
-        }
-    }
-
-    @VisibleForTesting
-    String getEditorInfoPackageName() {
-        return mInputEditorInfo != null ? mInputEditorInfo.packageName : null;
-    }
-
-    /**
-     * Called when IME window closes. Reset all the views once that happens.
-     */
-    @RequiresApi(api = VERSION_CODES.R)
-    public void onFinishInputView() {
-        if (!isWideScreenMode()) {
-            return;
-        }
-        resetAutomotiveWideScreenViews();
-    }
-
-    @RequiresApi(api = VERSION_CODES.R)
-    private void resetAutomotiveWideScreenViews() {
-        mWideScreenDescriptionTitle.setVisibility(View.GONE);
-        mContentAreaSurfaceView.setVisibility(View.GONE);
-        mContentAreaSurfaceView.setChildSurfacePackage(null);
-        mWideScreenErrorMessage.setVisibility(View.GONE);
-        mRecyclerView.setVisibility(View.GONE);
-        mWideScreenDescription.setVisibility(View.GONE);
-        mFullscreenArea.setVisibility(View.VISIBLE);
-        if (mWideScreenExtractedTextIcon != null) {
-            mWideScreenExtractedTextIcon.setVisibility(View.VISIBLE);
-        }
-        mWideScreenClearData.setVisibility(View.VISIBLE);
-        mWideScreenErrorImage.setVisibility(View.GONE);
-        if (mExtractActionAutomotive != null) {
-            mExtractActionAutomotive.setVisibility(View.GONE);
-        }
-        mContentAreaAutomotive.setVisibility(View.VISIBLE);
-        mContentAreaAutomotive.setBackground(
-                mContext.getDrawable(R.drawable.car_ui_ime_wide_screen_no_content_background));
-        setExtractedEditTextBackground(R.drawable.car_ui_ime_wide_screen_input_area_tint_color);
-        mImeRendersAllContent = true;
-        mIsExtractIconProvidedByApp = false;
-        mExtractViewHidden = false;
-        mAutomotiveSearchItems = null;
-    }
-
-    /**
-     * Returns whether or not system is running in a wide screen mode.
-     */
-    public boolean isWideScreenMode() {
-        return CarUiUtils.getBooleanSystemProperty(mContext.getResources(),
-                R.string.car_ui_ime_wide_screen_system_property_name, false)
-                && Build.VERSION.SDK_INT >= VERSION_CODES.R;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiDropDownPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiDropDownPreference.java
deleted file mode 100644
index eacd1f3..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiDropDownPreference.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import androidx.annotation.Nullable;
-import androidx.preference.DropDownPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/**
- * This class extends the base {@link DropDownPreference} class. Adds the drawable icon to
- * the preference.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiDropDownPreference extends DropDownPreference
-        implements UxRestrictablePreference {
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted = false;
-
-    public CarUiDropDownPreference(Context context) {
-        super(context);
-    }
-
-    public CarUiDropDownPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiDropDownPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public CarUiDropDownPreference(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    /**
-     * Instead of displaying a drop-down that is not car optimized, have drop-down preferences
-     * mirror the behavior of list preferences.
-     */
-    @Override
-    protected void onClick() {
-        getPreferenceManager().showDialog(this);
-    }
-
-    @Override
-    public void onAttached() {
-        super.onAttached();
-
-        boolean showChevron = getContext().getResources().getBoolean(
-                R.bool.car_ui_preference_show_chevron);
-
-        if (!showChevron) {
-            return;
-        }
-
-        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, isUxRestricted());
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        if (restricted != mUxRestricted) {
-            mUxRestricted = restricted;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiEditTextPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiEditTextPreference.java
deleted file mode 100644
index 81ee09b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiEditTextPreference.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static com.android.car.ui.utils.CarUiUtils.getAttr;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.EditTextPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/**
- * This class extends the base {@link EditTextPreference} class. Adds the drawable icon to
- * the preference.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiEditTextPreference extends EditTextPreference
-        implements UxRestrictablePreference {
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted;
-    private boolean mShowChevron;
-
-    public CarUiEditTextPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(attrs, defStyleAttr, defStyleRes);
-    }
-
-    public CarUiEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public CarUiEditTextPreference(Context context, AttributeSet attrs) {
-        this(context, attrs, getAttr(context, R.attr.editTextPreferenceStyle,
-                android.R.attr.editTextPreferenceStyle));
-    }
-
-    public CarUiEditTextPreference(Context context) {
-        this(context, null);
-    }
-
-    private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        TypedArray a = getContext().obtainStyledAttributes(
-                attrs,
-                R.styleable.CarUiPreference,
-                defStyleAttr,
-                defStyleRes);
-
-        mShowChevron = a.getBoolean(R.styleable.CarUiPreference_showChevron, true);
-        mUxRestricted = a.getBoolean(R.styleable.CarUiPreference_car_ui_ux_restricted, false);
-
-        a.recycle();
-    }
-
-    protected void setTwoActionLayout() {
-        setLayoutResource(R.layout.car_ui_two_action_preference);
-    }
-
-    /**
-     * Returns the widget container if {@link #setTwoActionLayout) was called, otherwise null.
-     */
-    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
-    public View getWidgetActionContainer(PreferenceViewHolder holder) {
-        return CarUiUtils.findViewByRefId(holder.itemView, R.id.action_widget_container);
-    }
-
-    @Override
-    public void onAttached() {
-        super.onAttached();
-
-        boolean allowChevron = getContext().getResources().getBoolean(
-                R.bool.car_ui_preference_show_chevron);
-
-        if (!allowChevron || !mShowChevron) {
-            return;
-        }
-
-        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
-    }
-
-    public void setShowChevron(boolean showChevron) {
-        mShowChevron = showChevron;
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, isUxRestricted());
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        if (restricted != mUxRestricted) {
-            mUxRestricted = restricted;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiListPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiListPreference.java
deleted file mode 100644
index 385cbf2..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiListPreference.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-
-import androidx.annotation.Nullable;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/**
- * This class extends the base {@link ListPreference} class. Adds the drawable icon to
- * the preference.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiListPreference extends ListPreference implements UxRestrictablePreference {
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted = false;
-
-    public CarUiListPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(attrs, defStyleAttr, defStyleRes);
-    }
-
-    public CarUiListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, R.style.Preference_CarUi_Preference);
-    }
-
-    public CarUiListPreference(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.carUiPreferenceStyle);
-    }
-
-    public CarUiListPreference(Context context) {
-        this(context, null);
-    }
-
-    private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        TypedArray a = getContext().obtainStyledAttributes(
-                attrs,
-                R.styleable.CarUiPreference,
-                defStyleAttr,
-                defStyleRes);
-
-        mUxRestricted = a.getBoolean(R.styleable.CarUiPreference_car_ui_ux_restricted, false);
-        a.recycle();
-    }
-
-    @Override
-    public void onAttached() {
-        super.onAttached();
-
-        boolean showChevron = getContext().getResources().getBoolean(
-                R.bool.car_ui_preference_show_chevron);
-
-        if (!showChevron) {
-            return;
-        }
-
-        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, isUxRestricted());
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        if (restricted != mUxRestricted) {
-            mUxRestricted = restricted;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiMultiSelectListPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiMultiSelectListPreference.java
deleted file mode 100644
index 8649377..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiMultiSelectListPreference.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-
-import androidx.annotation.Nullable;
-import androidx.preference.MultiSelectListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/**
- * This class extends the base {@link CarUiMultiSelectListPreference} class. Adds the drawable icon
- * to the preference.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiMultiSelectListPreference extends MultiSelectListPreference
-        implements UxRestrictablePreference {
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted = false;
-
-    public CarUiMultiSelectListPreference(Context context) {
-        this(context, null);
-    }
-
-    public CarUiMultiSelectListPreference(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.carUiPreferenceStyle);
-    }
-
-    public CarUiMultiSelectListPreference(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, R.style.Preference_CarUi_Preference);
-    }
-
-    public CarUiMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(attrs, defStyleAttr, defStyleRes);
-    }
-
-    private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        TypedArray a = getContext().obtainStyledAttributes(
-                attrs,
-                R.styleable.CarUiPreference,
-                defStyleAttr,
-                defStyleRes);
-
-        mUxRestricted = a.getBoolean(R.styleable.CarUiPreference_car_ui_ux_restricted, false);
-        a.recycle();
-    }
-
-    /**
-     * This is to make getSelectedItems() visible from other classes in
-     * com.android.car.ui.preference.
-     */
-    @Override
-    protected boolean[] getSelectedItems() {
-        return super.getSelectedItems();
-    }
-
-    @Override
-    public void onAttached() {
-        super.onAttached();
-
-        boolean showChevron = getContext().getResources().getBoolean(
-                R.bool.car_ui_preference_show_chevron);
-
-        if (!showChevron) {
-            return;
-        }
-
-        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, isUxRestricted());
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        if (restricted != mUxRestricted) {
-            mUxRestricted = restricted;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiPreference.java
deleted file mode 100644
index 34abb54..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiPreference.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/**
- * This class extends the base {@link Preference} class. Adds the support to add a drawable icon to
- * the preference if there is one of fragment, intent or onPreferenceClickListener set.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiPreference extends Preference implements DisabledPreferenceCallback {
-    private boolean mShowChevron;
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted = false;
-
-    public CarUiPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(attrs, defStyleAttr, defStyleRes);
-    }
-
-    public CarUiPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, R.style.Preference_CarUi_Preference);
-    }
-
-    public CarUiPreference(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.carUiPreferenceStyle);
-    }
-
-    public CarUiPreference(Context context) {
-        this(context, null);
-    }
-
-    private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        TypedArray a = getContext().obtainStyledAttributes(
-                attrs,
-                R.styleable.CarUiPreference,
-                defStyleAttr,
-                defStyleRes);
-
-        mShowChevron = a.getBoolean(R.styleable.CarUiPreference_showChevron, true);
-        mUxRestricted = a.getBoolean(R.styleable.CarUiPreference_car_ui_ux_restricted, false);
-
-        a.recycle();
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, isUxRestricted());
-    }
-
-    @Override
-    public void onAttached() {
-        super.onAttached();
-
-        boolean allowChevron = getContext().getResources().getBoolean(
-                R.bool.car_ui_preference_show_chevron);
-
-        if (!allowChevron || !mShowChevron) {
-            return;
-        }
-
-        if (getOnPreferenceClickListener() != null || getIntent() != null
-                || getFragment() != null) {
-            setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
-        }
-    }
-
-    /**
-     * An exact copy of {@link androidx.preference.Preference#performClick(View)}
-     * This method was added here because super.performClick(View) is not open
-     * for app usage.
-     */
-    @SuppressWarnings("RestrictTo")
-    void performClickUnrestricted(View v) {
-        performClick();
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    public void setShowChevron(boolean showChevron) {
-        mShowChevron = showChevron;
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        mUxRestricted = restricted;
-        notifyChanged();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiRadioButtonPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiRadioButtonPreference.java
deleted file mode 100644
index 432967c..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiRadioButtonPreference.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.RadioButton;
-
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-import androidx.preference.TwoStatePreference;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/** A preference which shows a radio button at the start of the preference. */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiRadioButtonPreference extends TwoStatePreference
-        implements UxRestrictablePreference {
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted = false;
-
-    public CarUiRadioButtonPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    public CarUiRadioButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, /* defStyleRes= */ 0);
-    }
-
-    public CarUiRadioButtonPreference(Context context, AttributeSet attrs) {
-        // Reusing preferenceStyle since there is no separate style for TwoStatePreference or
-        // CarUiRadioButtonPreference.
-        this(context, attrs, CarUiUtils.getAttr(context, R.attr.preferenceStyle,
-                android.R.attr.preferenceStyle));
-    }
-
-    public CarUiRadioButtonPreference(Context context) {
-        this(context, /* attrs= */ null);
-    }
-
-    private void init() {
-        setLayoutResource(R.layout.car_ui_preference);
-        setWidgetLayoutResource(R.layout.car_ui_radio_button_preference_widget);
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        RadioButton radioButton = (RadioButton) CarUiUtils.findViewByRefId(holder.itemView,
-                R.id.radio_button);
-        radioButton.setChecked(isChecked());
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, mUxRestricted);
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        if (restricted != mUxRestricted) {
-            mUxRestricted = restricted;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiSeekBarDialogPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiSeekBarDialogPreference.java
deleted file mode 100644
index 74e7f2f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiSeekBarDialogPreference.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.preference.DialogPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/** A class implements some basic methods of a seekbar dialog preference. */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiSeekBarDialogPreference extends DialogPreference
-        implements DialogFragmentCallbacks, UxRestrictablePreference {
-
-    private int mSeekBarProgress;
-    private SeekBar mSeekBar;
-
-    private int mSeekBarTopTextViewVisibility;
-    private TextView mSeekBarTopTextView;
-    private String mSeekBarTopText;
-
-    private int mSeekBarLeftTextViewVisibility;
-    private TextView mSeekBarLeftTextView;
-    private String mSeekBarLeftText;
-
-    private int mSeekBarRightTextViewVisibility;
-    private TextView mSeekBarRightTextView;
-    private String mSeekBarRightText;
-
-    private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
-    private int mMaxProgress = 100;
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted = false;
-
-    public CarUiSeekBarDialogPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    public CarUiSeekBarDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CarUiSeekBarDialogPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CarUiSeekBarDialogPreference(Context context) {
-        super(context);
-        init();
-    }
-
-    private void init() {
-        setDialogLayoutResource(R.layout.car_ui_seekbar_dialog);
-        setPositiveButtonText(R.string.car_ui_dialog_preference_positive);
-        setNegativeButtonText(R.string.car_ui_dialog_preference_negative);
-    }
-
-    @Override
-    public void onAttached() {
-        super.onAttached();
-        mSeekBarProgress = getPersistedInt(0);
-    }
-
-    @Override
-    public void onBindDialogView(@NonNull View view) {
-        mSeekBar = CarUiUtils.findViewByRefId(view, R.id.seek_bar);
-        mSeekBarTopTextView = CarUiUtils.findViewByRefId(view, R.id.seek_bar_text_top);
-        mSeekBarLeftTextView = CarUiUtils.findViewByRefId(view, R.id.seek_bar_text_left);
-        mSeekBarRightTextView = CarUiUtils.findViewByRefId(view, R.id.seek_bar_text_right);
-
-        setProgress(mSeekBarProgress);
-
-        setSeekBarTopTextViewVisibility(mSeekBarTopTextViewVisibility);
-        setSeekBarTopTextViewText(mSeekBarTopText);
-
-        setSeekBarLeftTextViewVisibility(mSeekBarLeftTextViewVisibility);
-        setSeekBarLeftTextViewText(mSeekBarLeftText);
-
-        setSeekBarRightTextViewVisibility(mSeekBarRightTextViewVisibility);
-        setSeekBarRightTextViewText(mSeekBarRightText);
-
-        setMaxProgress(mMaxProgress);
-        setOnSeekBarChangeListener(mOnSeekBarChangeListener);
-    }
-
-    /**
-     * Get the progress bar's current level of progress. Return 0 when the progress bar is in
-     * indeterminate mode.
-     */
-    public int getProgress() {
-        if (mSeekBar != null) {
-            return mSeekBar.getProgress();
-        }
-        return mSeekBarProgress;
-    }
-
-    /**
-     * Sets the current progress to the specified value.
-     */
-    public void setProgress(int progress) {
-        if (mSeekBar != null) {
-            mSeekBar.setProgress(progress);
-        }
-        mSeekBarProgress = progress;
-    }
-
-    @Override
-    public void onDialogClosed(boolean positiveResult) {
-        if (positiveResult) {
-            mSeekBarProgress = mSeekBar.getProgress();
-            persistInt(mSeekBarProgress);
-            notifyChanged();
-        }
-
-        mSeekBarTopTextView = null;
-        mSeekBarRightTextView = null;
-        mSeekBarLeftTextView = null;
-        mSeekBar = null;
-    }
-
-    /**
-     * Sets the text view visibility on top of the seekbar.
-     */
-    public void setSeekBarTopTextViewVisibility(int visibility) {
-        if (mSeekBarTopTextView != null) {
-            mSeekBarTopTextView.setVisibility(visibility);
-        }
-        mSeekBarTopTextViewVisibility = visibility;
-    }
-
-    /**
-     * Gets the text on top of the seekbar.
-     */
-    @Nullable
-    public String getSeekBarTopTextViewText() {
-        if (mSeekBarTopTextView != null) {
-            return mSeekBarTopTextView.getText().toString();
-        }
-        return mSeekBarTopText;
-    }
-
-    /**
-     * Sets the text on top of the seekbar.
-     */
-    public void setSeekBarTopTextViewText(String text) {
-        if (mSeekBarTopTextView != null) {
-            mSeekBarTopTextView.setText(text);
-        }
-        mSeekBarTopText = text;
-    }
-
-    /**
-     * Sets the text view visibility on left of the seekbar.
-     */
-    public void setSeekBarLeftTextViewVisibility(int visibility) {
-        if (mSeekBarLeftTextView != null) {
-            mSeekBarLeftTextView.setVisibility(visibility);
-        }
-        mSeekBarLeftTextViewVisibility = visibility;
-    }
-
-    /**
-     * Gets the text on left of the seekbar.
-     */
-    @Nullable
-    public String getSeekBarLeftTextViewText() {
-        if (mSeekBarLeftTextView != null) {
-            return mSeekBarLeftTextView.getText().toString();
-        }
-        return mSeekBarLeftText;
-    }
-
-    /**
-     * Sets the text on Left of the seekbar.
-     */
-    public void setSeekBarLeftTextViewText(@Nullable String text) {
-        if (mSeekBarLeftTextView != null) {
-            mSeekBarLeftTextView.setText(text);
-        }
-        mSeekBarLeftText = text;
-    }
-
-
-    /**
-     * Sets the text view visibility on right of the seekbar.
-     */
-    public void setSeekBarRightTextViewVisibility(int visibility) {
-        if (mSeekBarRightTextView != null) {
-            mSeekBarRightTextView.setVisibility(visibility);
-        }
-        mSeekBarRightTextViewVisibility = visibility;
-    }
-
-    /**
-     * Gets the text on right of the seekbar.
-     */
-    @Nullable
-    public String getSeekBarRightTextViewText() {
-        if (mSeekBarRightTextView != null) {
-            return mSeekBarRightTextView.getText().toString();
-        }
-        return mSeekBarRightText;
-    }
-
-
-    /**
-     * Sets the text on right of the seekbar.
-     */
-    public void setSeekBarRightTextViewText(@Nullable String text) {
-        if (mSeekBarRightTextView != null) {
-            mSeekBarRightTextView.setText(text);
-        }
-        mSeekBarRightText = text;
-    }
-
-    /**
-     * Sets a listener to receive notifications of changes to the SeekBar's progress level. Also
-     * provides notifications of when the user starts and stops a touch gesture within the SeekBar.
-     *
-     * @param listener The seek bar notification listener
-     * @see SeekBar.OnSeekBarChangeListener
-     */
-    public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
-        if (mSeekBar != null) {
-            mSeekBar.setOnSeekBarChangeListener(listener);
-        }
-        mOnSeekBarChangeListener = listener;
-    }
-
-    /** Get the upper range of the progress bar */
-    public int getMaxProgress() {
-        if (mSeekBar != null) {
-            return mSeekBar.getMax();
-        }
-        return mMaxProgress;
-    }
-
-    /** Set the upper range of the progress bar */
-    public void setMaxProgress(int maxProgress) {
-        if (mSeekBar != null) {
-            mSeekBar.setMax(maxProgress);
-        }
-        mMaxProgress = maxProgress;
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, isUxRestricted());
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        if (restricted != mUxRestricted) {
-            mUxRestricted = restricted;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiSwitchPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiSwitchPreference.java
deleted file mode 100644
index f2f1839..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiSwitchPreference.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-import androidx.preference.SwitchPreference;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.function.Consumer;
-
-/**
- * This class is the same as the base {@link SwitchPreference} class, except it implements
- * {@link UxRestrictablePreference}
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiSwitchPreference extends SwitchPreference implements DisabledPreferenceCallback {
-
-    private Consumer<Preference> mRestrictedClickListener;
-    private boolean mUxRestricted = false;
-
-    public CarUiSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(attrs);
-    }
-
-    public CarUiSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(attrs);
-    }
-
-    public CarUiSwitchPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init(attrs);
-    }
-
-    public CarUiSwitchPreference(Context context) {
-        super(context);
-        init(null);
-    }
-
-    private void init(AttributeSet attrs) {
-        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CarUiPreference);
-        mUxRestricted = a.getBoolean(R.styleable.CarUiPreference_car_ui_ux_restricted, false);
-        a.recycle();
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        CarUiUtils.makeAllViewsUxRestricted(holder.itemView, isUxRestricted());
-    }
-
-    @Override
-    @SuppressWarnings("RestrictTo")
-    public void performClick() {
-        if ((isEnabled() || isSelectable()) && isUxRestricted()) {
-            if (mRestrictedClickListener != null) {
-                mRestrictedClickListener.accept(this);
-            }
-        } else {
-            super.performClick();
-        }
-    }
-
-    @Override
-    public void setUxRestricted(boolean restricted) {
-        if (mUxRestricted != restricted) {
-            mUxRestricted = restricted;
-            notifyChanged();
-        }
-    }
-
-    @Override
-    public boolean isUxRestricted() {
-        return mUxRestricted;
-    }
-
-    @Override
-    public void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener) {
-        mRestrictedClickListener = listener;
-    }
-
-    @Nullable
-    @Override
-    public Consumer<Preference> getOnClickWhileRestrictedListener() {
-        return mRestrictedClickListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionBasePreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionBasePreference.java
deleted file mode 100644
index 5151642..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionBasePreference.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-
-import androidx.annotation.CallSuper;
-import androidx.annotation.LayoutRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StyleableRes;
-
-import com.android.car.ui.R;
-
-/**
- * A base class for several types of preferences, that all have a main click action along
- * with a secondary action.
- */
-public abstract class CarUiTwoActionBasePreference extends CarUiPreference {
-
-    protected boolean mSecondaryActionEnabled = true;
-    protected boolean mSecondaryActionVisible = true;
-
-    public CarUiTwoActionBasePreference(Context context,
-            AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(attrs);
-    }
-
-    public CarUiTwoActionBasePreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(attrs);
-    }
-
-    public CarUiTwoActionBasePreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init(attrs);
-    }
-
-    public CarUiTwoActionBasePreference(Context context) {
-        super(context);
-        init(null);
-    }
-
-    @CallSuper
-    protected void init(@Nullable AttributeSet attrs) {
-        setShowChevron(false);
-
-        TypedArray a = getContext()
-                .obtainStyledAttributes(attrs, R.styleable.CarUiTwoActionBasePreference);
-        try {
-            disallowResourceIds(a,
-                    R.styleable.CarUiTwoActionBasePreference_layout,
-                    R.styleable.CarUiTwoActionBasePreference_android_layout,
-                    R.styleable.CarUiTwoActionBasePreference_widgetLayout,
-                    R.styleable.CarUiTwoActionBasePreference_android_widgetLayout);
-        } finally {
-            a.recycle();
-        }
-
-        a = getContext().obtainStyledAttributes(attrs,
-                R.styleable.CarUiTwoActionPreference);
-
-        try {
-            mSecondaryActionVisible = a.getBoolean(
-                    R.styleable.CarUiTwoActionPreference_actionShown, true);
-            mSecondaryActionEnabled = a.getBoolean(
-                    R.styleable.CarUiTwoActionPreference_actionEnabled, true);
-        } finally {
-            a.recycle();
-        }
-    }
-
-    /**
-     * Returns whether or not the secondary action is enabled.
-     */
-    public boolean isSecondaryActionEnabled() {
-        return mSecondaryActionEnabled && isEnabled();
-    }
-
-    /**
-     * Sets whether or not the secondary action is enabled. This is secondary to the overall
-     * {@link #setEnabled(boolean)} of the preference
-     */
-    public void setSecondaryActionEnabled(boolean enabled) {
-        mSecondaryActionEnabled = enabled;
-        notifyChanged();
-    }
-
-    /**
-     * Returns whether or not the secondary action is visible.
-     */
-    public boolean isSecondaryActionVisible() {
-        return mSecondaryActionVisible;
-    }
-
-    /**
-     * Sets whether or not the secondary action is visible.
-     */
-    public void setSecondaryActionVisible(boolean visible) {
-        mSecondaryActionVisible = visible;
-        notifyChanged();
-    }
-
-    /**
-     * Like {@link #onClick()}, but for the secondary action.
-     */
-    public void performSecondaryActionClick() {
-        if (mSecondaryActionEnabled && mSecondaryActionVisible) {
-            performSecondaryActionClickInternal();
-        }
-    }
-
-    protected abstract void performSecondaryActionClickInternal();
-
-    protected void setLayoutResourceInternal(@LayoutRes int layoutResId) {
-        super.setLayoutResource(layoutResId);
-    }
-
-    @Override
-    public void setLayoutResource(@LayoutRes int layoutResId) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setWidgetLayoutResource(@LayoutRes int widgetLayoutResId) {
-        throw new UnsupportedOperationException();
-    }
-
-    private static void disallowResourceIds(@NonNull TypedArray a, @StyleableRes int ...indices) {
-        for (int index : indices) {
-            if (a.hasValue(index)) {
-                throw new AssertionError("Setting this attribute is not allowed: "
-                        + a.getResources().getResourceName(index));
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionIconPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionIconPreference.java
deleted file mode 100644
index 1ed5d45..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionIconPreference.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-
-import java.util.function.Consumer;
-
-/**
- * A preference that has an icon button that can be pressed independently of pressing the main
- * body of the preference.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiTwoActionIconPreference extends CarUiTwoActionBasePreference {
-    @Nullable
-    protected Runnable mSecondaryActionOnClickListener;
-    @Nullable
-    private Drawable mSecondaryActionIcon;
-
-    public CarUiTwoActionIconPreference(Context context,
-            AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public CarUiTwoActionIconPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public CarUiTwoActionIconPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiTwoActionIconPreference(Context context) {
-        super(context);
-    }
-
-    @Override
-    protected void init(@Nullable AttributeSet attrs) {
-        super.init(attrs);
-
-        TypedArray a = getContext().obtainStyledAttributes(attrs,
-                R.styleable.CarUiTwoActionIconPreference);
-        try {
-            mSecondaryActionIcon = a.getDrawable(
-                    R.styleable.CarUiTwoActionIconPreference_secondaryActionIcon);
-        } finally {
-            a.recycle();
-        }
-
-        setLayoutResourceInternal(R.layout.car_ui_preference_two_action_icon);
-    }
-
-    @Override
-    protected void performSecondaryActionClickInternal() {
-        if (isSecondaryActionEnabled()) {
-            if (isUxRestricted()) {
-                Consumer<Preference> restrictedListener = getOnClickWhileRestrictedListener();
-                if (restrictedListener != null) {
-                    restrictedListener.accept(this);
-                }
-            } else if (mSecondaryActionOnClickListener != null) {
-                mSecondaryActionOnClickListener.run();
-            }
-        }
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        View firstActionContainer = requireViewByRefId(holder.itemView,
-                R.id.car_ui_first_action_container);
-        View secondActionContainer = requireViewByRefId(holder.itemView,
-                R.id.car_ui_second_action_container);
-        ViewGroup secondaryButton = requireViewByRefId(holder.itemView,
-                R.id.car_ui_secondary_action);
-        ImageView iconView = requireViewByRefId(holder.itemView,
-                R.id.car_ui_secondary_action_concrete);
-
-        holder.itemView.setFocusable(false);
-        holder.itemView.setClickable(false);
-        firstActionContainer.setOnClickListener(this::performClickUnrestricted);
-        firstActionContainer.setEnabled(isEnabled());
-        firstActionContainer.setFocusable(isEnabled());
-
-        secondActionContainer.setVisibility(mSecondaryActionVisible ? View.VISIBLE : View.GONE);
-        iconView.setImageDrawable(mSecondaryActionIcon);
-        iconView.setEnabled(isSecondaryActionEnabled());
-        secondaryButton.setEnabled(isSecondaryActionEnabled());
-        secondaryButton.setFocusable(isSecondaryActionEnabled());
-        secondaryButton.setOnClickListener(v -> performSecondaryActionClickInternal());
-    }
-
-    /**
-     * Sets the icon of the secondary action.
-     *
-     * The icon will be tinted to the primary text color, and resized to fit the space.
-     *
-     * @param drawable A {@link Drawable} to set as the icon.
-     */
-    public void setSecondaryActionIcon(@Nullable Drawable drawable) {
-        mSecondaryActionIcon = drawable;
-        notifyChanged();
-    }
-
-    /**
-     * Sets the icon of the secondary action.
-     *
-     * The icon will be tinted to the primary text color, and resized to fit the space.
-     *
-     * @param resid A drawable resource id to set as the icon.
-     */
-    public void setSecondaryActionIcon(@DrawableRes int resid) {
-        setSecondaryActionIcon(ContextCompat.getDrawable(getContext(), resid));
-    }
-
-    /**
-     * Sets the on-click listener of the secondary action button.
-     */
-    public void setOnSecondaryActionClickListener(@Nullable Runnable onClickListener) {
-        mSecondaryActionOnClickListener = onClickListener;
-        notifyChanged();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionPreference.java
deleted file mode 100644
index f5289f7..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionPreference.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2018 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.ui.preference;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-/**
- * A preference which can perform two actions. The secondary action is shown by default.
- * {@link #showAction(boolean)} may be used to manually set the visibility of the action.
- *
- * @deprecated This preference relies on the use of custom views. Use
- *             {@link CarUiTwoActionTextPreference}, {@link CarUiTwoActionSwitchPreference}, or
- *             {@link CarUiTwoActionIconPreference} instead.
- */
-@Deprecated
-public class CarUiTwoActionPreference extends CarUiPreference {
-
-    private boolean mIsActionShown;
-
-    public CarUiTwoActionPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init(attrs);
-    }
-
-    public CarUiTwoActionPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(attrs);
-    }
-
-    public CarUiTwoActionPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init(attrs);
-    }
-
-    public CarUiTwoActionPreference(Context context) {
-        super(context);
-        init(/* attrs= */ null);
-    }
-
-    /**
-     * Sets the custom two action preference layout and attributes.
-     * Check {@link #setLayoutResource} for layout requirements.
-     */
-    private void init(AttributeSet attrs) {
-        setLayoutResource(R.layout.car_ui_two_action_preference);
-        TypedArray preferenceAttributes = getContext().obtainStyledAttributes(attrs,
-                R.styleable.CarUiTwoActionPreference);
-        mIsActionShown = preferenceAttributes.getBoolean(
-                R.styleable.CarUiTwoActionPreference_actionShown, true);
-        setShowChevron(false);
-        preferenceAttributes.recycle();
-    }
-
-    /**
-     * Sets whether the secondary action is visible in the preference.
-     *
-     * @param isShown {@code true} if the secondary action should be shown.
-     */
-    public void showAction(boolean isShown) {
-        mIsActionShown = isShown;
-        notifyChanged();
-    }
-
-    /** Returns {@code true} if action is shown. */
-    public boolean isActionShown() {
-        return mIsActionShown;
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-        View containerWithoutWidget = CarUiUtils.findViewByRefId(holder.itemView,
-                R.id.car_ui_preference_container_without_widget);
-        View actionContainer = CarUiUtils.findViewByRefId(holder.itemView,
-                R.id.action_widget_container);
-        View widgetFrame = CarUiUtils.findViewByRefId(holder.itemView, android.R.id.widget_frame);
-        holder.itemView.setFocusable(!mIsActionShown);
-        containerWithoutWidget.setOnClickListener(
-                mIsActionShown ? this::performClickUnrestricted : null);
-        containerWithoutWidget.setClickable(mIsActionShown);
-        containerWithoutWidget.setFocusable(mIsActionShown);
-        actionContainer.setVisibility(mIsActionShown ? View.VISIBLE : View.GONE);
-        widgetFrame.setFocusable(mIsActionShown);
-        if (mIsActionShown) {
-            onBindWidgetFrame(widgetFrame);
-        }
-    }
-
-    /**
-     * Binds the created View for the second action.
-     *
-     * <p>This is a good place to set properties on any custom view.
-     *
-     * @param widgetFrame The widget frame which controls the 2nd action.
-     */
-    protected void onBindWidgetFrame(@NonNull View widgetFrame) {
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionSwitchPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionSwitchPreference.java
deleted file mode 100644
index 1ab02bb..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionSwitchPreference.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.Switch;
-
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-
-import java.util.function.Consumer;
-
-/**
- * A preference that has a switch that can be toggled independently of pressing the main
- * body of the preference.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiTwoActionSwitchPreference extends CarUiTwoActionBasePreference {
-    @Nullable
-    protected Consumer<Boolean> mSecondaryActionOnClickListener;
-    private boolean mSecondaryActionChecked;
-
-    public CarUiTwoActionSwitchPreference(Context context,
-            AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public CarUiTwoActionSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public CarUiTwoActionSwitchPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiTwoActionSwitchPreference(Context context) {
-        super(context);
-    }
-
-    @Override
-    protected void init(@Nullable AttributeSet attrs) {
-        super.init(attrs);
-
-        setLayoutResourceInternal(R.layout.car_ui_preference_two_action_switch);
-    }
-
-    @Override
-    protected void performSecondaryActionClickInternal() {
-        if (isSecondaryActionEnabled()) {
-            if (isUxRestricted()) {
-                Consumer<Preference> restrictedListener = getOnClickWhileRestrictedListener();
-                if (restrictedListener != null) {
-                    restrictedListener.accept(this);
-                }
-            } else {
-                mSecondaryActionChecked = !mSecondaryActionChecked;
-                notifyChanged();
-                if (mSecondaryActionOnClickListener != null) {
-                    mSecondaryActionOnClickListener.accept(mSecondaryActionChecked);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        View firstActionContainer = requireViewByRefId(holder.itemView,
-                R.id.car_ui_first_action_container);
-        View secondActionContainer = requireViewByRefId(holder.itemView,
-                R.id.car_ui_second_action_container);
-        View secondaryAction = requireViewByRefId(holder.itemView,
-                R.id.car_ui_secondary_action);
-        Switch s = requireViewByRefId(holder.itemView,
-                R.id.car_ui_secondary_action_concrete);
-
-        holder.itemView.setFocusable(false);
-        holder.itemView.setClickable(false);
-        firstActionContainer.setOnClickListener(this::performClickUnrestricted);
-        firstActionContainer.setEnabled(isEnabled() || isUxRestricted());
-        firstActionContainer.setFocusable(isEnabled() || isUxRestricted());
-
-        secondActionContainer.setVisibility(mSecondaryActionVisible ? View.VISIBLE : View.GONE);
-        s.setChecked(mSecondaryActionChecked);
-        s.setEnabled(isSecondaryActionEnabled());
-
-        secondaryAction.setOnClickListener(v -> performSecondaryActionClickInternal());
-        secondaryAction.setEnabled(isSecondaryActionEnabled() || isUxRestricted());
-        secondaryAction.setFocusable(isSecondaryActionEnabled() || isUxRestricted());
-    }
-
-    /**
-     * Sets the checked state of the switch in the secondary action space.
-     * @param checked Whether the switch should be checked or not.
-     */
-    public void setSecondaryActionChecked(boolean checked) {
-        mSecondaryActionChecked = checked;
-        notifyChanged();
-    }
-
-    /**
-     * Returns the checked state of the switch in the secondary action space.
-     * @return Whether the switch is checked or not.
-     */
-    public boolean isSecondaryActionChecked() {
-        return mSecondaryActionChecked;
-    }
-
-    /**
-     * Sets the on-click listener of the secondary action button.
-     *
-     * The listener is called with the current checked state of the switch.
-     */
-    public void setOnSecondaryActionClickListener(@Nullable Consumer<Boolean> onClickListener) {
-        mSecondaryActionOnClickListener = onClickListener;
-        notifyChanged();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionTextPreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionTextPreference.java
deleted file mode 100644
index a28baf2..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiTwoActionTextPreference.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.Button;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.car.ui.R;
-
-import java.util.function.Consumer;
-
-/**
- * A preference that has a text button that can be pressed independently of pressing the main
- * body of the preference.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class CarUiTwoActionTextPreference extends CarUiTwoActionBasePreference {
-
-    @Nullable
-    protected Runnable mSecondaryActionOnClickListener;
-    @Nullable
-    private CharSequence mSecondaryActionText;
-
-    public CarUiTwoActionTextPreference(Context context,
-            AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public CarUiTwoActionTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public CarUiTwoActionTextPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiTwoActionTextPreference(Context context) {
-        super(context);
-    }
-
-    @Override
-    protected void init(@Nullable AttributeSet attrs) {
-        super.init(attrs);
-
-        TypedArray a = getContext().obtainStyledAttributes(attrs,
-                R.styleable.CarUiTwoActionTextPreference);
-        int actionStyle = 0;
-        try {
-            actionStyle = a.getInteger(
-                    R.styleable.CarUiTwoActionTextPreference_secondaryActionStyle, 0);
-            mSecondaryActionText = a.getString(
-                    R.styleable.CarUiTwoActionTextPreference_secondaryActionText);
-        } finally {
-            a.recycle();
-        }
-
-        setLayoutResourceInternal(actionStyle == 0
-                ? R.layout.car_ui_preference_two_action_text
-                : R.layout.car_ui_preference_two_action_text_borderless);
-    }
-
-    @Override
-    protected void performSecondaryActionClickInternal() {
-        if (isSecondaryActionEnabled()) {
-            if (isUxRestricted()) {
-                Consumer<Preference> restrictedListener = getOnClickWhileRestrictedListener();
-                if (restrictedListener != null) {
-                    restrictedListener.accept(this);
-                }
-            } else if (mSecondaryActionOnClickListener != null) {
-                mSecondaryActionOnClickListener.run();
-            }
-        }
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        View firstActionContainer = requireViewByRefId(holder.itemView,
-                R.id.car_ui_first_action_container);
-        View secondActionContainer = requireViewByRefId(holder.itemView,
-                R.id.car_ui_second_action_container);
-        Button secondaryButton = requireViewByRefId(holder.itemView,
-                R.id.car_ui_secondary_action);
-
-        holder.itemView.setFocusable(false);
-        holder.itemView.setClickable(false);
-        firstActionContainer.setOnClickListener(this::performClickUnrestricted);
-        firstActionContainer.setEnabled(isEnabled());
-        firstActionContainer.setFocusable(isEnabled());
-
-        secondActionContainer.setVisibility(mSecondaryActionVisible ? View.VISIBLE : View.GONE);
-        secondaryButton.setText(mSecondaryActionText);
-        secondaryButton.setOnClickListener(v -> performSecondaryActionClickInternal());
-        secondaryButton.setEnabled(isSecondaryActionEnabled());
-        secondaryButton.setFocusable(isSecondaryActionEnabled());
-    }
-
-    @Nullable
-    public CharSequence getSecondaryActionText() {
-        return mSecondaryActionText;
-    }
-
-    /**
-     * Sets the title of the secondary action button.
-     *
-     * @param title The text to display on the secondary action.
-     */
-    public void setSecondaryActionText(@Nullable CharSequence title) {
-        mSecondaryActionText = title;
-        notifyChanged();
-    }
-
-    /**
-     * Sets the title of the secondary action button.
-     *
-     * @param resid A string resource of the text to display on the secondary action.
-     */
-    public void setSecondaryActionText(@StringRes int resid) {
-        setSecondaryActionText(getContext().getString(resid));
-    }
-
-    /**
-     * Sets the on-click listener of the secondary action button.
-     */
-    public void setOnSecondaryActionClickListener(@Nullable Runnable onClickListener) {
-        mSecondaryActionOnClickListener = onClickListener;
-        notifyChanged();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/DisabledPreferenceCallback.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/DisabledPreferenceCallback.java
deleted file mode 100644
index f6926be..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/DisabledPreferenceCallback.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-/**
- * Interface for preferences to handle clicks when its disabled.
- *
- * @deprecated use {@link UxRestrictablePreference} instead
- */
-@Deprecated
-public interface DisabledPreferenceCallback extends UxRestrictablePreference {
-
-    /**
-     * Sets the message to be displayed when the disabled preference is clicked.
-     *
-     * @deprecated Use {@link UxRestrictablePreference#setUxRestricted(boolean)} instead.
-     */
-    @Deprecated
-    default void setMessageToShowWhenDisabledPreferenceClicked(@NonNull String message) {
-        Log.w("carui",
-                "setMessageToShowWhenDisabledPreferenceClicked is deprecated, and does nothing!");
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/ListPreferenceFragment.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/ListPreferenceFragment.java
deleted file mode 100644
index b2407a2..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/ListPreferenceFragment.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static com.android.car.ui.preference.PreferenceDialogFragment.ARG_KEY;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.preference.DialogPreference;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.R;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.Toolbar;
-import com.android.car.ui.toolbar.ToolbarController;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A fragment that provides a layout with a list of options associated with a {@link
- * ListPreference}.
- */
-public class ListPreferenceFragment extends Fragment implements InsetsChangedListener {
-
-    private ListPreference mPreference;
-    private CarUiContentListItem mSelectedItem;
-    private int mSelectedIndex = -1;
-    private boolean mUseInstantPreferenceChangeCallback;
-
-    /**
-     * Returns a new instance of {@link ListPreferenceFragment} for the {@link ListPreference} with
-     * the given {@code key}.
-     */
-    @NonNull
-    static ListPreferenceFragment newInstance(String key) {
-        ListPreferenceFragment fragment = new ListPreferenceFragment();
-        Bundle b = new Bundle(/* capacity= */ 1);
-        b.putString(ARG_KEY, key);
-        fragment.setArguments(b);
-        return fragment;
-    }
-
-    @Nullable
-    @Override
-    public View onCreateView(
-            @NonNull LayoutInflater inflater, @Nullable ViewGroup container,
-            @Nullable Bundle savedInstanceState) {
-        return inflater.inflate(R.layout.car_ui_list_preference, container, false);
-    }
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        final CarUiRecyclerView carUiRecyclerView = CarUiUtils.requireViewByRefId(view, R.id.list);
-        mUseInstantPreferenceChangeCallback =
-                getResources().getBoolean(R.bool.car_ui_preference_list_instant_change_callback);
-        ToolbarController toolbar = null;
-        if (getTargetFragment() instanceof PreferenceFragment) {
-            toolbar = ((PreferenceFragment) getTargetFragment()).getPreferenceToolbar(this);
-        }
-
-        carUiRecyclerView.setClipToPadding(false);
-        mPreference = getListPreference();
-        if (toolbar != null) {
-            toolbar.setTitle(mPreference.getTitle());
-            toolbar.setSubtitle(null);
-            if (toolbar.isStateSet()) {
-                toolbar.setState(Toolbar.State.SUBPAGE);
-            } else {
-                toolbar.setNavButtonMode(NavButtonMode.BACK);
-            }
-            toolbar.setLogo(null);
-            toolbar.setMenuItems(null);
-            toolbar.setTabs(Collections.emptyList());
-        }
-
-        CharSequence[] entries = mPreference.getEntries();
-        CharSequence[] entryValues = mPreference.getEntryValues();
-
-        if (entries == null || entryValues == null) {
-            throw new IllegalStateException(
-                    "ListPreference requires an entries array and an entryValues array.");
-        }
-
-        if (entries.length != entryValues.length) {
-            throw new IllegalStateException(
-                    "ListPreference entries array length does not match entryValues array length.");
-        }
-
-        mSelectedIndex = mPreference.findIndexOfValue(mPreference.getValue());
-        List<CarUiListItem> listItems = new ArrayList<>();
-        CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);
-
-        for (int i = 0; i < entries.length; i++) {
-            String entry = entries[i].toString();
-            CarUiContentListItem item = new CarUiContentListItem(
-                    CarUiContentListItem.Action.RADIO_BUTTON);
-            item.setTitle(entry);
-
-            if (i == mSelectedIndex) {
-                item.setChecked(true);
-                mSelectedItem = item;
-            }
-
-            item.setOnCheckedChangeListener((listItem, isChecked) -> {
-                if (!isChecked) {
-                    // Previously selected item is unchecked now, no further processing is needed.
-                    return;
-                }
-
-                if (mSelectedItem != null) {
-                    mSelectedItem.setChecked(false);
-                    adapter.notifyItemChanged(listItems.indexOf(mSelectedItem));
-                }
-                mSelectedItem = listItem;
-                mSelectedIndex = listItems.indexOf(mSelectedItem);
-
-                if (mUseInstantPreferenceChangeCallback) {
-                    updatePreference();
-                }
-            });
-
-            listItems.add(item);
-        }
-
-        carUiRecyclerView.setAdapter(adapter);
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        if (getTargetFragment() instanceof PreferenceFragment) {
-            Insets insets = ((PreferenceFragment) getTargetFragment()).getPreferenceInsets(this);
-            if (insets != null) {
-                onCarUiInsetsChanged(insets);
-            }
-        }
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-
-        if (!mUseInstantPreferenceChangeCallback) {
-            updatePreference();
-        }
-    }
-
-    private void updatePreference() {
-        if (mSelectedIndex >= 0 && mPreference != null) {
-            String entryValue = mPreference.getEntryValues()[mSelectedIndex].toString();
-
-            if (mPreference.callChangeListener(entryValue)) {
-                mPreference.setValue(entryValue);
-            }
-        }
-    }
-
-    private ListPreference getListPreference() {
-        String key = requireArguments().getString(ARG_KEY);
-        DialogPreference.TargetFragment fragment =
-                (DialogPreference.TargetFragment) getTargetFragment();
-
-        if (key == null) {
-            throw new IllegalStateException(
-                    "ListPreference key not found in Fragment arguments");
-        }
-
-        if (fragment == null) {
-            throw new IllegalStateException(
-                    "Target fragment must be registered before displaying ListPreference "
-                            + "screen.");
-        }
-
-        Preference preference = fragment.findPreference(key);
-
-        if (!(preference instanceof ListPreference)) {
-            throw new IllegalStateException(
-                    "Cannot use ListPreferenceFragment with a preference that is not of type "
-                            + "ListPreference");
-        }
-
-        return (ListPreference) preference;
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        View view = requireView();
-        CarUiUtils.requireViewByRefId(view, R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        view.setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-        FocusArea focusArea = view.findViewById(R.id.car_ui_focus_area);
-        if (focusArea != null) {
-            focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-            focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java
deleted file mode 100644
index b876c23..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import static com.android.car.ui.preference.PreferenceDialogFragment.ARG_KEY;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.preference.DialogPreference;
-import androidx.preference.Preference;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.R;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.Toolbar;
-import com.android.car.ui.toolbar.ToolbarController;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A fragment that provides a layout with a list of options associated with a {@link
- * CarUiMultiSelectListPreference}.
- */
-public class MultiSelectListPreferenceFragment extends Fragment implements InsetsChangedListener {
-
-    private CarUiMultiSelectListPreference mPreference;
-    private Set<String> mNewValues;
-    private boolean mUseInstantPreferenceChangeCallback;
-
-    /**
-     * Returns a new instance of {@link MultiSelectListPreferenceFragment} for the {@link
-     * CarUiMultiSelectListPreference} with the given {@code key}.
-     */
-    @NonNull
-    static MultiSelectListPreferenceFragment newInstance(String key) {
-        MultiSelectListPreferenceFragment fragment = new MultiSelectListPreferenceFragment();
-        Bundle b = new Bundle(/* capacity= */ 1);
-        b.putString(ARG_KEY, key);
-        fragment.setArguments(b);
-        return fragment;
-    }
-
-    @Nullable
-    @Override
-    public View onCreateView(
-            @NonNull LayoutInflater inflater, @Nullable ViewGroup container,
-            @Nullable Bundle savedInstanceState) {
-        return inflater.inflate(R.layout.car_ui_list_preference, container, false);
-    }
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        final CarUiRecyclerView recyclerView = CarUiUtils.requireViewByRefId(view, R.id.list);
-        mUseInstantPreferenceChangeCallback =
-                getResources().getBoolean(R.bool.car_ui_preference_list_instant_change_callback);
-        ToolbarController toolbar = null;
-        if (getTargetFragment() instanceof PreferenceFragment) {
-            toolbar = ((PreferenceFragment) getTargetFragment()).getPreferenceToolbar(this);
-        }
-
-        mPreference = getPreference();
-
-        recyclerView.setClipToPadding(false);
-        if (toolbar != null) {
-            toolbar.setTitle(mPreference.getTitle());
-            toolbar.setSubtitle(null);
-            if (toolbar.isStateSet()) {
-                toolbar.setState(Toolbar.State.SUBPAGE);
-            } else {
-                toolbar.setNavButtonMode(NavButtonMode.BACK);
-            }
-            toolbar.setLogo(null);
-            toolbar.setMenuItems(null);
-            toolbar.setTabs(Collections.emptyList());
-        }
-
-        mNewValues = new HashSet<>(mPreference.getValues());
-        CharSequence[] entries = mPreference.getEntries();
-        CharSequence[] entryValues = mPreference.getEntryValues();
-
-        if (entries == null || entryValues == null) {
-            throw new IllegalStateException(
-                    "MultiSelectListPreference requires an entries array and an entryValues array"
-                            + ".");
-        }
-
-        if (entries.length != entryValues.length) {
-            throw new IllegalStateException(
-                    "MultiSelectListPreference entries array length does not match entryValues "
-                            + "array length.");
-        }
-
-        List<CarUiListItem> listItems = new ArrayList<>();
-        boolean[] selectedItems = mPreference.getSelectedItems();
-
-        for (int i = 0; i < entries.length; i++) {
-            String entry = entries[i].toString();
-            String entryValue = entryValues[i].toString();
-            CarUiContentListItem item = new CarUiContentListItem(
-                    CarUiContentListItem.Action.CHECK_BOX);
-            item.setTitle(entry);
-            item.setChecked(selectedItems[i]);
-            item.setOnCheckedChangeListener((listItem, isChecked) -> {
-                if (isChecked) {
-                    mNewValues.add(entryValue);
-                } else {
-                    mNewValues.remove(entryValue);
-                }
-
-                if (mUseInstantPreferenceChangeCallback) {
-                    updatePreference();
-                }
-            });
-
-            listItems.add(item);
-        }
-
-        CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);
-        recyclerView.setAdapter(adapter);
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        if (getTargetFragment() instanceof PreferenceFragment) {
-            Insets insets = ((PreferenceFragment) getTargetFragment()).getPreferenceInsets(this);
-            if (insets != null) {
-                onCarUiInsetsChanged(insets);
-            }
-        }
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        if (!mUseInstantPreferenceChangeCallback) {
-            updatePreference();
-        }
-    }
-
-    private void updatePreference() {
-        if (mPreference.callChangeListener(mNewValues)) {
-            mPreference.setValues(mNewValues);
-        }
-    }
-
-    private CarUiMultiSelectListPreference getPreference() {
-        if (getArguments() == null) {
-            throw new IllegalStateException("Preference arguments cannot be null");
-        }
-
-        String key = getArguments().getString(ARG_KEY);
-        DialogPreference.TargetFragment fragment =
-                (DialogPreference.TargetFragment) getTargetFragment();
-
-        if (key == null) {
-            throw new IllegalStateException(
-                    "MultiSelectListPreference key not found in Fragment arguments");
-        }
-
-        if (fragment == null) {
-            throw new IllegalStateException(
-                    "Target fragment must be registered before displaying "
-                            + "MultiSelectListPreference screen.");
-        }
-
-        Preference preference = fragment.findPreference(key);
-
-        if (!(preference instanceof CarUiMultiSelectListPreference)) {
-            throw new IllegalStateException(
-                    "Cannot use MultiSelectListPreferenceFragment with a preference that is "
-                            + "not of type CarUiMultiSelectListPreference");
-        }
-
-        return (CarUiMultiSelectListPreference) preference;
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        View view = requireView();
-        CarUiUtils.requireViewByRefId(view, R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        view.setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-        FocusArea focusArea = view.findViewById(R.id.car_ui_focus_area);
-        if (focusArea != null) {
-            focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-            focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/PreferenceFragment.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/PreferenceFragment.java
deleted file mode 100644
index 5fb8c5a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/PreferenceFragment.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.preference;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Log;
-import android.util.Pair;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.DialogFragment;
-import androidx.fragment.app.Fragment;
-import androidx.preference.DialogPreference;
-import androidx.preference.DropDownPreference;
-import androidx.preference.EditTextPreference;
-import androidx.preference.ListPreference;
-import androidx.preference.MultiSelectListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.PreferenceGroup;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-import androidx.preference.TwoStatePreference;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.R;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.toolbar.Toolbar;
-import com.android.car.ui.toolbar.ToolbarController;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A PreferenceFragmentCompat is the entry point to using the Preference library.
- *
- * <p>Using this fragment will replace regular Preferences with CarUi equivalents. Because of this,
- * certain properties that cannot be read out of Preferences will be lost upon calling
- * {@link #setPreferenceScreen(PreferenceScreen)}. These include the preference viewId,
- * defaultValue, and enabled state.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public abstract class PreferenceFragment extends PreferenceFragmentCompat implements
-        InsetsChangedListener {
-
-    private static final String TAG = "CarUiPreferenceFragment";
-    private static final String DIALOG_FRAGMENT_TAG =
-            "com.android.car.ui.PreferenceFragment.DIALOG";
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        ToolbarController toolbar = getPreferenceToolbar(this);
-        if (toolbar != null) {
-            setupToolbar(toolbar);
-        }
-    }
-
-    /**
-     * Sets up what the toolbar should display when on this PreferenceFragment.
-     *
-     * This can be overridden in subclasses to customize the toolbar. By default it puts a back
-     * button on the toolbar, and sets its title to the {@link PreferenceScreen PreferenceScreen's}
-     * title.
-     *
-     * @param toolbar The toolbar from {@link #getPreferenceToolbar(Fragment)}, where the Fragment
-     *                passed to getToolbar() is this fragment.
-     */
-    protected void setupToolbar(@NonNull ToolbarController toolbar) {
-        toolbar.setNavButtonMode(Toolbar.NavButtonMode.BACK);
-        PreferenceScreen preferenceScreen = getPreferenceScreen();
-        if (preferenceScreen != null) {
-            toolbar.setTitle(preferenceScreen.getTitle());
-        } else {
-            toolbar.setTitle(null);
-        }
-    }
-
-    /**
-     * Gets the toolbar for the given fragment. The fragment can be either this PreferenceFragment,
-     * or one of the fragments that are created from it such as {@link ListPreferenceFragment}.
-     *
-     * This can be overridden by subclasses to have the fragments use a different toolbar.
-     *
-     * @see #getPreferenceInsets(Fragment)
-     * @param fragment The fragment to get a toolbar for. Either this fragment, or one of the
-     *                 fragments that it launches.
-     */
-    @Nullable
-    protected ToolbarController getPreferenceToolbar(@NonNull Fragment fragment) {
-        return CarUi.getToolbar(getActivity());
-    }
-
-    /**
-     * Gets the {@link Insets} for the given fragment. The fragment can be either this
-     * PreferenceFragment, or one of the fragments that are created from it such as
-     * {@link ListPreferenceFragment}.
-     *
-     * This can be overridden by subclasses to have the fragments use different insets.
-     *
-     * @see #getPreferenceToolbar(Fragment)
-     * @param fragment The fragment to get insets for. Either this fragment, or one of the
-     *                 fragments that it launches.
-     */
-    @Nullable
-    protected Insets getPreferenceInsets(@NonNull Fragment fragment) {
-        return CarUi.getInsets(getActivity());
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        Insets insets = getPreferenceInsets(this);
-        if (insets != null) {
-            onCarUiInsetsChanged(insets);
-        }
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        View view = requireView();
-        FocusArea focusArea = CarUiUtils.requireViewByRefId(view, R.id.car_ui_focus_area);
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        CarUiUtils.requireViewByRefId(view, R.id.recycler_view)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        view.setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-
-    /**
-     * Called when a preference in the tree requests to display a dialog. Subclasses should override
-     * this method to display custom dialogs or to handle dialogs for custom preference classes.
-     *
-     * <p>Note: this is borrowed as-is from androidx.preference.PreferenceFragmentCompat with
-     * updates to launch Car UI library {@link DialogFragment} instead of the ones in the
-     * support library.
-     *
-     * @param preference The {@link Preference} object requesting the dialog
-     */
-    @Override
-    public void onDisplayPreferenceDialog(Preference preference) {
-
-        if (getActivity() instanceof OnPreferenceDisplayDialogCallback
-                && ((OnPreferenceDisplayDialogCallback) getActivity())
-                .onPreferenceDisplayDialog(this, preference)) {
-            return;
-        }
-
-        // check if dialog is already showing
-        if (requireFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
-            return;
-        }
-
-        final Fragment f;
-        if (preference instanceof EditTextPreference) {
-            f = EditTextPreferenceDialogFragment.newInstance(preference.getKey());
-        } else if (preference instanceof ListPreference) {
-            f = ListPreferenceFragment.newInstance(preference.getKey());
-        } else if (preference instanceof MultiSelectListPreference) {
-            f = MultiSelectListPreferenceFragment.newInstance(preference.getKey());
-        } else if (preference instanceof CarUiSeekBarDialogPreference) {
-            f = SeekbarPreferenceDialogFragment.newInstance(preference.getKey());
-        } else {
-            throw new IllegalArgumentException(
-                    "Cannot display dialog for an unknown Preference type: "
-                            + preference.getClass().getSimpleName()
-                            + ". Make sure to implement onPreferenceDisplayDialog() to handle "
-                            + "displaying a custom dialog for this Preference.");
-        }
-
-        f.setTargetFragment(this, 0);
-
-        if (f instanceof DialogFragment) {
-            ((DialogFragment) f).show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
-        } else {
-            if (getActivity() == null) {
-                throw new IllegalStateException(
-                        "Preference fragment is not attached to an Activity.");
-            }
-
-            if (getView() == null) {
-                throw new IllegalStateException(
-                        "Preference fragment must have a layout.");
-            }
-
-            Context context = getContext();
-            getActivity().getSupportFragmentManager().beginTransaction()
-                    .setCustomAnimations(
-                            CarUiUtils.getAttrResourceId(context,
-                                    android.R.attr.fragmentOpenEnterAnimation),
-                            CarUiUtils.getAttrResourceId(context,
-                                    android.R.attr.fragmentOpenExitAnimation),
-                            CarUiUtils.getAttrResourceId(context,
-                                    android.R.attr.fragmentCloseEnterAnimation),
-                            CarUiUtils.getAttrResourceId(context,
-                                    android.R.attr.fragmentCloseExitAnimation))
-                    .replace(((ViewGroup) getView().getParent()).getId(), f)
-                    .addToBackStack(null)
-                    .commit();
-        }
-    }
-
-    /**
-     * This override of setPreferenceScreen replaces preferences with their CarUi versions first.
-     */
-    @Override
-    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
-        // We do a search of the tree and every time we see a PreferenceGroup we remove
-        // all it's children, replace them with CarUi versions, and then re-add them
-
-        Map<Preference, String> dependencies = new HashMap<>();
-        List<Preference> children = new ArrayList<>();
-
-        // Stack of preferences to process
-        Deque<Preference> stack = new ArrayDeque<>();
-        stack.addFirst(preferenceScreen);
-
-        while (!stack.isEmpty()) {
-            Preference preference = stack.removeFirst();
-
-            if (preference instanceof PreferenceGroup) {
-                PreferenceGroup pg = (PreferenceGroup) preference;
-
-                children.clear();
-                for (int i = 0; i < pg.getPreferenceCount(); i++) {
-                    children.add(pg.getPreference(i));
-                }
-
-                pg.removeAll();
-
-                for (Preference child : children) {
-                    Preference replacement = getReplacementFor(child);
-
-                    dependencies.put(replacement, child.getDependency());
-                    pg.addPreference(replacement);
-                    stack.addFirst(replacement);
-                }
-            }
-        }
-
-        super.setPreferenceScreen(preferenceScreen);
-
-        // Set the dependencies after all the swapping has been done and they've been
-        // associated with this fragment, or we could potentially fail to find preferences
-        // or use the wrong preferenceManager
-        for (Map.Entry<Preference, String> entry : dependencies.entrySet()) {
-            entry.getKey().setDependency(entry.getValue());
-        }
-    }
-
-    // Mapping from regular preferences to CarUi preferences.
-    // Order is important, subclasses must come before their base classes
-    // Make sure all the following classes are added to proguard configuration.
-    private static final List<Pair<Class<? extends Preference>, Class<? extends Preference>>>
-            sPreferenceMapping = Arrays.asList(
-            new Pair<>(DropDownPreference.class, CarUiDropDownPreference.class),
-            new Pair<>(ListPreference.class, CarUiListPreference.class),
-            new Pair<>(MultiSelectListPreference.class, CarUiMultiSelectListPreference.class),
-            new Pair<>(EditTextPreference.class, CarUiEditTextPreference.class),
-            new Pair<>(SwitchPreference.class, CarUiSwitchPreference.class),
-            new Pair<>(Preference.class, CarUiPreference.class)
-    );
-
-    /**
-     * Gets the CarUi version of the passed in preference. If there is no suitable replacement, this
-     * method will return it's input.
-     *
-     * <p>When given a Preference that extends a replaceable preference, we log a warning instead
-     * of replacing it so that we don't remove any functionality.
-     */
-    private static Preference getReplacementFor(Preference preference) {
-        Class<? extends Preference> clazz = preference.getClass();
-
-        for (Pair<Class<? extends Preference>, Class<? extends Preference>> replacement
-                : sPreferenceMapping) {
-            Class<? extends Preference> source = replacement.first;
-            Class<? extends Preference> target = replacement.second;
-            if (source.isAssignableFrom(clazz)) {
-                if (clazz == source) {
-                    try {
-                        return copyPreference(preference, (Preference) target
-                                .getDeclaredConstructor(Context.class)
-                                .newInstance(preference.getContext()));
-                    } catch (ReflectiveOperationException e) {
-                        throw new RuntimeException(e);
-                    }
-                } else if (clazz == target || source == Preference.class) {
-                    // Don't warn about subclasses of Preference because there are many legitimate
-                    // uses for non-carui Preference subclasses, like Preference groups.
-                    return preference;
-                } else {
-                    Log.w(TAG, "Subclass of " + source.getSimpleName() + " was used, "
-                            + "preventing us from substituting it with " + target.getSimpleName());
-                    return preference;
-                }
-            }
-        }
-
-        return preference;
-    }
-
-    /**
-     * Copies all the properties of one preference to another.
-     *
-     * @return the {@code to} parameter
-     */
-    private static Preference copyPreference(Preference from, Preference to) {
-        // viewId and defaultValue don't have getters
-        // isEnabled() is not completely symmetrical with setEnabled(), so we can't use it.
-        to.setTitle(from.getTitle());
-        to.setOnPreferenceClickListener(from.getOnPreferenceClickListener());
-        to.setOnPreferenceChangeListener(from.getOnPreferenceChangeListener());
-        to.setIcon(from.getIcon());
-        to.setFragment(from.getFragment());
-        to.setIntent(from.getIntent());
-        to.setKey(from.getKey());
-        to.setOrder(from.getOrder());
-        to.setSelectable(from.isSelectable());
-        to.setPersistent(from.isPersistent());
-        to.setIconSpaceReserved(from.isIconSpaceReserved());
-        to.setWidgetLayoutResource(from.getWidgetLayoutResource());
-        to.setPreferenceDataStore(from.getPreferenceDataStore());
-        to.setShouldDisableView(from.getShouldDisableView());
-        to.setSingleLineTitle(from.isSingleLineTitle());
-        to.setVisible(from.isVisible());
-        to.setLayoutResource(from.getLayoutResource());
-        to.setCopyingEnabled(from.isCopyingEnabled());
-
-        if (from.getSummaryProvider() != null) {
-            to.setSummaryProvider(from.getSummaryProvider());
-        } else {
-            to.setSummary(from.getSummary());
-        }
-
-        if (from.peekExtras() != null) {
-            to.getExtras().putAll(from.peekExtras());
-        }
-
-        if (from instanceof DialogPreference) {
-            DialogPreference fromDialog = (DialogPreference) from;
-            DialogPreference toDialog = (DialogPreference) to;
-            toDialog.setDialogTitle(fromDialog.getDialogTitle());
-            toDialog.setDialogIcon(fromDialog.getDialogIcon());
-            toDialog.setDialogMessage(fromDialog.getDialogMessage());
-            toDialog.setDialogLayoutResource(fromDialog.getDialogLayoutResource());
-            toDialog.setNegativeButtonText(fromDialog.getNegativeButtonText());
-            toDialog.setPositiveButtonText(fromDialog.getPositiveButtonText());
-        }
-
-        // DropDownPreference extends ListPreference and doesn't add any extra api surface,
-        // so we don't need a case for it
-        if (from instanceof ListPreference) {
-            ListPreference fromList = (ListPreference) from;
-            ListPreference toList = (ListPreference) to;
-            toList.setEntries(fromList.getEntries());
-            toList.setEntryValues(fromList.getEntryValues());
-            toList.setValue(fromList.getValue());
-        } else if (from instanceof EditTextPreference) {
-            EditTextPreference fromText = (EditTextPreference) from;
-            EditTextPreference toText = (EditTextPreference) to;
-            toText.setText(fromText.getText());
-        } else if (from instanceof MultiSelectListPreference) {
-            MultiSelectListPreference fromMulti = (MultiSelectListPreference) from;
-            MultiSelectListPreference toMulti = (MultiSelectListPreference) to;
-            toMulti.setEntries(fromMulti.getEntries());
-            toMulti.setEntryValues(fromMulti.getEntryValues());
-            toMulti.setValues(fromMulti.getValues());
-        } else if (from instanceof TwoStatePreference) {
-            TwoStatePreference fromTwoState = (TwoStatePreference) from;
-            TwoStatePreference toTwoState = (TwoStatePreference) to;
-            toTwoState.setSummaryOn(fromTwoState.getSummaryOn());
-            toTwoState.setSummaryOff(fromTwoState.getSummaryOff());
-
-            if (from instanceof SwitchPreference) {
-                SwitchPreference fromSwitch = (SwitchPreference) from;
-                SwitchPreference toSwitch = (SwitchPreference) to;
-                toSwitch.setSwitchTextOn(fromSwitch.getSwitchTextOn());
-                toSwitch.setSwitchTextOff(fromSwitch.getSwitchTextOff());
-            }
-        }
-
-        // We don't need to add checks for things that we will never replace,
-        // like PreferenceGroup or CheckBoxPreference
-
-        return to;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/UxRestrictablePreference.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/UxRestrictablePreference.java
deleted file mode 100644
index a60782a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/UxRestrictablePreference.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.preference;
-
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-
-import java.util.function.Consumer;
-
-/**
- * An interface for preferences that can be ux restricted.
- *
- * A ux restricted preference will be displayed differently to indicate such, and will
- * display a toast message informing the user they cannot click it when they try to.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public interface UxRestrictablePreference {
-
-    /** Sets this preference as ux restricted or not */
-    void setUxRestricted(boolean restricted);
-
-    /** Returns if this preference is currently ux restricted */
-    boolean isUxRestricted();
-
-    /** Sets a listener to be called if the preference is clicked while it is ux restricted */
-    void setOnClickWhileRestrictedListener(@Nullable Consumer<Preference> listener);
-
-    /** Gets the listener to be called if the preference is clicked while it is ux restricted */
-    @Nullable
-    Consumer<Preference> getOnClickWhileRestrictedListener();
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiContentListItem.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiContentListItem.java
deleted file mode 100644
index 3eee3de..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiContentListItem.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.CarUiText;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Definition of list items that can be inserted into {@link CarUiListItemAdapter}.
- */
-public class CarUiContentListItem extends CarUiListItem {
-
-    /**
-     * Callback to be invoked when the checked state of a list item changed.
-     */
-    public interface OnCheckedChangeListener {
-        /**
-         * Called when the checked state of a list item has changed.
-         *
-         * @param item      whose checked state changed.
-         * @param isChecked new checked state of list item.
-         */
-        void onCheckedChanged(@NonNull CarUiContentListItem item, boolean isChecked);
-    }
-
-    /**
-     * Callback to be invoked when an item is clicked.
-     */
-    public interface OnClickListener {
-        /**
-         * Called when the item has been clicked.
-         *
-         * @param item whose checked state changed.
-         */
-        void onClick(@NonNull CarUiContentListItem item);
-    }
-
-    public enum IconType {
-        /**
-         * For an icon type of CONTENT, the primary icon is a larger than {@code STANDARD}.
-         */
-        CONTENT,
-        /**
-         * For an icon type of STANDARD, the primary icon is the standard size.
-         */
-        STANDARD,
-        /**
-         * For an icon type of AVATAR, the primary icon is masked to provide an icon with a modified
-         * shape.
-         */
-        AVATAR
-    }
-
-    /**
-     * Enum of secondary action types of a list item.
-     */
-    public enum Action {
-        /**
-         * For an action value of NONE, no action element is shown for a list item.
-         */
-        NONE,
-        /**
-         * For an action value of SWITCH, a switch is shown for the action element of the list
-         * item.
-         */
-        SWITCH,
-        /**
-         * For an action value of CHECK_BOX, a checkbox is shown for the action element of the list
-         * item.
-         */
-        CHECK_BOX,
-        /**
-         * For an action value of RADIO_BUTTON, a radio button is shown for the action element of
-         * the list item.
-         */
-        RADIO_BUTTON,
-        /**
-         * For an action value of ICON, an icon is shown for the action element of the list item.
-         */
-        ICON,
-        /**
-         * For an action value CHEVRON, a chevron is shown for the action element of the list item.
-         */
-        CHEVRON
-    }
-
-    @Nullable
-    private Drawable mIcon;
-    @Nullable
-    private Drawable mSupplementalIcon;
-    @Nullable
-    private CarUiText mTitle;
-    @Nullable
-    private List<CarUiText> mBody;
-    @NonNull
-    private final Action mAction;
-    @NonNull
-    private IconType mPrimaryIconType;
-    private boolean mIsActionDividerVisible;
-    private boolean mIsChecked;
-    private boolean mIsEnabled = true;
-    private boolean mIsActivated;
-    @Nullable
-    private OnClickListener mOnClickListener;
-    @Nullable
-    private OnCheckedChangeListener mOnCheckedChangeListener;
-    @Nullable
-    private OnClickListener mSupplementalIconOnClickListener;
-
-    public CarUiContentListItem(@NonNull Action action) {
-        mAction = action;
-        mPrimaryIconType = IconType.STANDARD;
-    }
-
-    /**
-     * Returns the title of the item.
-     */
-    @Nullable
-    public CarUiText getTitle() {
-        return mTitle;
-    }
-
-    /**
-     * Sets the title of the item.
-     *
-     * @param title text to display as title.
-     */
-    public void setTitle(@Nullable CharSequence title) {
-        mTitle = new CarUiText.Builder(title).build();
-    }
-
-    /**
-     * Sets the title of the item.
-     *
-     * @param text text to display as title
-     */
-    public void setTitle(@Nullable CarUiText text) {
-        mTitle = text;
-    }
-
-    /**
-     * Returns the body of the item.
-     */
-    @Nullable
-    public List<CarUiText> getBody() {
-        return mBody;
-    }
-
-    /**
-     * Sets the body of the item.
-     *
-     * @param body text to display as body text.
-     */
-    public void setBody(@Nullable CharSequence body) {
-        if (body == null) {
-            mBody = null;
-            return;
-        }
-
-        mBody = Collections.singletonList(new CarUiText.Builder(body).build());
-    }
-
-    /**
-     * Sets the body of the item.
-     *
-     * @param body text to display as body text.
-     */
-    public void setBody(@Nullable CarUiText body) {
-        if (body == null) {
-            mBody = null;
-            return;
-        }
-
-        mBody = Collections.singletonList(body);
-    }
-
-    /**
-     * Sets the body of the item.
-     *
-     * @param textList list of text to display as body text. Each {@link CarUiText} in the list will
-     *                 be rendered on a new line, separated by a line break.
-     */
-    public void setBody(@Nullable List<CarUiText> textList) {
-        mBody = textList;
-    }
-
-    /**
-     * Returns the icon of the item.
-     */
-    @Nullable
-    public Drawable getIcon() {
-        return mIcon;
-    }
-
-    /**
-     * Sets the icon of the item.
-     *
-     * @param icon the icon to display.
-     */
-    public void setIcon(@Nullable Drawable icon) {
-        mIcon = icon;
-    }
-
-    /**
-     * Returns the primary icon type for the item.
-     */
-    @NonNull
-    public IconType getPrimaryIconType() {
-        return mPrimaryIconType;
-    }
-
-    /**
-     * Sets the primary icon type for the item.
-     *
-     * @param icon the icon type for the item.
-     */
-    public void setPrimaryIconType(@NonNull IconType icon) {
-        mPrimaryIconType = icon;
-    }
-
-    /**
-     * Returns {@code true} if the item is activated.
-     */
-    public boolean isActivated() {
-        return mIsActivated;
-    }
-
-    /**
-     * Sets the activated state of the item.
-     *
-     * @param activated the activated state for the item.
-     */
-    public void setActivated(boolean activated) {
-        mIsActivated = activated;
-    }
-
-    /**
-     * Returns {@code true} if the item is enabled.
-     */
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    /**
-     * Sets the enabled state of the item.
-     *
-     * @param enabled the enabled state for the item.
-     */
-    public void setEnabled(boolean enabled) {
-        mIsEnabled = enabled;
-    }
-
-    /**
-     * Returns {@code true} if the item is checked. Will always return {@code false} when the action
-     * type for the item is {@code Action.NONE}.
-     */
-    public boolean isChecked() {
-        return mIsChecked;
-    }
-
-    /**
-     * Sets the checked state of the item.
-     *
-     * @param checked the checked state for the item.
-     */
-    public void setChecked(boolean checked) {
-        if (checked == mIsChecked) {
-            return;
-        }
-
-        // Checked state can only be set when action type is checkbox, radio button or switch.
-        if (mAction == Action.CHECK_BOX || mAction == Action.SWITCH
-                || mAction == Action.RADIO_BUTTON) {
-            mIsChecked = checked;
-
-            if (mOnCheckedChangeListener != null) {
-                mOnCheckedChangeListener.onCheckedChanged(this, mIsChecked);
-            }
-        }
-    }
-
-    /**
-     * Sets the visibility of the action divider.
-     *
-     * @param visible visibility of the action divider.
-     */
-    public void setActionDividerVisible(boolean visible) {
-        mIsActionDividerVisible = visible;
-    }
-
-    /**
-     * Returns {@code true} if the action divider is visible.
-     */
-    public boolean isActionDividerVisible() {
-        return mIsActionDividerVisible;
-    }
-
-    /**
-     * Returns the action type for the item.
-     */
-    @NonNull
-    public Action getAction() {
-        return mAction;
-    }
-
-    /**
-     * Returns the supplemental icon for the item.
-     */
-    @Nullable
-    public Drawable getSupplementalIcon() {
-        if (mAction != Action.ICON) {
-            return null;
-        }
-
-        return mSupplementalIcon;
-    }
-
-    /**
-     * Sets supplemental icon to be displayed in a list item.
-     *
-     * @param icon the Drawable to set as the icon, or null to clear the content.
-     */
-    public void setSupplementalIcon(@Nullable Drawable icon) {
-        setSupplementalIcon(icon, null);
-    }
-
-    /**
-     * Sets supplemental icon to be displayed in a list item.
-     *
-     * @param icon     the Drawable to set as the icon, or null to clear the content.
-     * @param listener the callback that is invoked when the icon is clicked.
-     */
-    public void setSupplementalIcon(@Nullable Drawable icon,
-            @Nullable OnClickListener listener) {
-        if (mAction != Action.ICON) {
-            throw new IllegalStateException(
-                    "Cannot set supplemental icon on list item that does not have an action of "
-                            + "type ICON");
-        }
-
-        mSupplementalIcon = icon;
-        mSupplementalIconOnClickListener = listener;
-    }
-
-    @Nullable
-    public OnClickListener getSupplementalIconOnClickListener() {
-        return mSupplementalIconOnClickListener;
-    }
-
-    /**
-     * Registers a callback to be invoked when the item is clicked.
-     *
-     * @param listener callback to be invoked when item is clicked.
-     */
-    public void setOnItemClickedListener(@Nullable OnClickListener listener) {
-        mOnClickListener = listener;
-    }
-
-    /**
-     * Returns the {@link OnClickListener} registered for this item.
-     */
-    @Nullable
-    public OnClickListener getOnClickListener() {
-        return mOnClickListener;
-    }
-
-    /**
-     * Registers a callback to be invoked when the checked state of list item changes.
-     *
-     * <p>Checked state changes can take place when the action type is {@code Action.SWITCH} or
-     * {@code Action.CHECK_BOX}.
-     *
-     * @param listener callback to be invoked when the checked state shown in the UI changes.
-     */
-    public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {
-        mOnCheckedChangeListener = listener;
-    }
-
-    /**
-     * Returns the {@link OnCheckedChangeListener} registered for this item.
-     */
-    @Nullable
-    public OnCheckedChangeListener getOnCheckedChangeListener() {
-        return mOnCheckedChangeListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiGridLayoutStyle.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiGridLayoutStyle.java
deleted file mode 100644
index e3caeda..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiGridLayoutStyle.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.GridLayoutManager.DefaultSpanSizeLookup;
-import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup;
-import androidx.recyclerview.widget.RecyclerView.LayoutManager;
-
-import com.android.car.ui.recyclerview.CarUiRecyclerView.CarUiRecyclerViewLayout;
-
-/**
- * CarUi proxy class for {@link GridLayoutManager}
- */
-public final class CarUiGridLayoutStyle implements CarUiLayoutStyle {
-
-    private int mSpanCount = 1;
-    @CarUiRecyclerViewLayout
-    private  int mLayoutType = CarUiRecyclerViewLayout.GRID;
-    @Orientation
-    private int mLayoutOrientation = VERTICAL;
-    private boolean mReverseLayout = false;
-    private int mSize = CarUiRecyclerView.SIZE_LARGE;
-    @Nullable
-    private SpanSizeLookup mSpanSizeLookup = new DefaultSpanSizeLookup();
-
-    /**
-     * @param layoutManager
-     * @return instance {@link CarUiLayoutStyle} using the passed {@link LayoutManager}
-     */
-    @Nullable
-    public static CarUiGridLayoutStyle from(@Nullable LayoutManager layoutManager) {
-        if (layoutManager == null) return null;
-        if (!(layoutManager instanceof GridLayoutManager)) {
-            throw new AssertionError("GridLayoutManager required.");
-        }
-
-        CarUiGridLayoutStyle layoutStyle = new CarUiGridLayoutStyle();
-        layoutStyle.setSpanCount(((GridLayoutManager) layoutManager).getSpanCount());
-        layoutStyle.setReverseLayout(((GridLayoutManager) layoutManager).getReverseLayout());
-        layoutStyle.setSpanSizeLookup(((GridLayoutManager) layoutManager).getSpanSizeLookup());
-        return layoutStyle;
-    }
-
-    /** Returns number of recyclerview spans */
-    public int getSpanCount() {
-        return mSpanCount;
-    }
-
-    /** sets number of recyclerview columns */
-    public void setSpanCount(int spanCount) {
-        if (spanCount <= 0) {
-            throw new AssertionError("Span count must be bigger than 0");
-        }
-        mSpanCount = spanCount;
-    }
-
-    /** Returns {@link CarUiRecyclerViewLayout} */
-    @CarUiRecyclerViewLayout
-    public int getLayoutType() {
-        return CarUiRecyclerViewLayout.GRID;
-    }
-
-    /** Returns layout direction {@link Orientation} */
-    @Orientation
-    public int getOrientation() {
-        return mLayoutOrientation;
-    }
-
-    /** sets layout direction {@link Orientation} */
-    public void setOrientation(@Orientation int orientation) {
-        mLayoutOrientation = orientation;
-    }
-
-    /** Returns true if layout is reversed */
-    public boolean getReverseLayout() {
-        return mReverseLayout;
-    }
-
-    /** sets if layout is reversed */
-    public void setReverseLayout(boolean reverseLayout) {
-        mReverseLayout = reverseLayout;
-    }
-
-    /** Returns a wrapper {@link androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup} */
-    @Nullable
-    public SpanSizeLookup getSpanSizeLookup() {
-        return mSpanSizeLookup;
-    }
-
-    /** Returns a wrapper {@link androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup} */
-    public void setSpanSizeLookup(@NonNull SpanSizeLookup spanSizeLookup) {
-        mSpanSizeLookup = spanSizeLookup;
-    }
-
-    /**
-     * @return CarUiRecyclerView size
-     */
-    public int getSize() {
-        return mSize;
-    }
-
-    /**
-     * @param size CarUiRecyclerView size
-     */
-    public void setSize(int size) {
-        mSize = size;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiLayoutStyle.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiLayoutStyle.java
deleted file mode 100644
index 60a38c9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiLayoutStyle.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import android.widget.LinearLayout;
-import androidx.annotation.IntDef;
-import androidx.recyclerview.widget.RecyclerView.LayoutManager;
-
-import com.android.car.ui.recyclerview.CarUiRecyclerView.CarUiRecyclerViewLayout;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * CarUi proxy class for {@link LayoutManager}
- */
-public interface CarUiLayoutStyle {
-
-    @IntDef({HORIZONTAL, VERTICAL})
-    @Retention(RetentionPolicy.SOURCE)
-    @interface Orientation {
-    }
-    int HORIZONTAL = LinearLayout.HORIZONTAL;
-    int VERTICAL = LinearLayout.VERTICAL;
-
-    /** Returns number of recyclerview spans */
-    int getSpanCount();
-
-    /** Returns {@link CarUiRecyclerViewLayout} */
-    @CarUiRecyclerViewLayout
-    int getLayoutType();
-
-    /** Returns layout direction {@link Orientation} */
-    @Orientation
-    int getOrientation();
-
-    /** Returns true if layout is reversed */
-    boolean getReverseLayout();
-
-    /** Returns CarUiRecyclerView size */
-    int getSize();
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiLinearLayoutStyle.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiLinearLayoutStyle.java
deleted file mode 100644
index 4d0d7a9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiLinearLayoutStyle.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView.LayoutManager;
-
-import com.android.car.ui.recyclerview.CarUiRecyclerView.CarUiRecyclerViewLayout;
-
-/**
- * CarUi proxy class for {@link LinearLayoutManager}
- */
-public final class CarUiLinearLayoutStyle implements CarUiLayoutStyle {
-
-    @CarUiRecyclerViewLayout
-    private  int mLayoutType = CarUiRecyclerViewLayout.LINEAR;
-    @Orientation
-    private int mLayoutOrientation = VERTICAL;
-    private boolean mReverseLayout = false;
-    private int mSize = CarUiRecyclerView.SIZE_LARGE;
-
-    /**
-     * @param layoutManager
-     * @return instance {@link CarUiLayoutStyle} using the passed {@link LayoutManager}
-     */
-    @Nullable
-    public static CarUiLinearLayoutStyle from(@Nullable LayoutManager layoutManager) {
-        if (layoutManager == null) return null;
-        if (!(layoutManager instanceof LinearLayoutManager)) {
-            throw new AssertionError("LinearLayoutManager required.");
-        }
-
-        CarUiLinearLayoutStyle layoutStyle = new CarUiLinearLayoutStyle();
-        layoutStyle.setOrientation(((LinearLayoutManager) layoutManager).getOrientation());
-        layoutStyle.setReverseLayout(((LinearLayoutManager) layoutManager).getReverseLayout());
-        return layoutStyle;
-    }
-
-    /** Returns number of recyclerview spans */
-    public int getSpanCount() {
-        return 1;
-    }
-
-    /** Returns {@link CarUiRecyclerViewLayout} */
-    @CarUiRecyclerViewLayout
-    public int getLayoutType() {
-        return CarUiRecyclerViewLayout.LINEAR;
-    }
-
-    /** Returns layout direction {@link Orientation} */
-    @Orientation
-    public int getOrientation() {
-        return mLayoutOrientation;
-    }
-
-    /** sets layout direction {@link Orientation} */
-    public void setOrientation(@Orientation int orientation) {
-        mLayoutOrientation = orientation;
-    }
-
-    /** Returns true if layout is reversed */
-    public boolean getReverseLayout() {
-        return mReverseLayout;
-    }
-
-    /** sets if layout is reversed */
-    public void setReverseLayout(boolean reverseLayout) {
-        mReverseLayout = reverseLayout;
-    }
-
-    /**
-     * @return CarUiRecyclerView size
-     */
-    public int getSize() {
-        return mSize;
-    }
-
-    /**
-     * @param size CarUiRecyclerView size
-     */
-    public void setSize(int size) {
-        mSize = size;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItemAdapter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItemAdapter.java
deleted file mode 100644
index 39926e1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItemAdapter.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.RadioButton;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-import com.android.car.ui.widget.CarUiTextView;
-
-import java.util.List;
-
-/**
- * Adapter for {@link CarUiRecyclerView} to display {@link CarUiContentListItem} and {@link
- * CarUiHeaderListItem}.
- *
- * <ul>
- * <li> Implements {@link CarUiRecyclerView.ItemCap} - defaults to unlimited item count.
- * </ul>
- */
-public class CarUiListItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
-        CarUiRecyclerView.ItemCap {
-
-    static final int VIEW_TYPE_LIST_ITEM = 1;
-    static final int VIEW_TYPE_LIST_HEADER = 2;
-
-    private final List<? extends CarUiListItem> mItems;
-    private final boolean mCompactLayout;
-    private int mMaxItems = CarUiRecyclerView.ItemCap.UNLIMITED;
-
-    public CarUiListItemAdapter(List<? extends CarUiListItem> items) {
-        this(items, false);
-    }
-
-    public CarUiListItemAdapter(List<? extends CarUiListItem> items, boolean useCompactLayout) {
-        this.mItems = items;
-        this.mCompactLayout = useCompactLayout;
-    }
-
-    @NonNull
-    @Override
-    public RecyclerView.ViewHolder onCreateViewHolder(
-            @NonNull ViewGroup parent, int viewType) {
-        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-
-        switch (viewType) {
-            case VIEW_TYPE_LIST_ITEM:
-                if (mCompactLayout) {
-                    return new ListItemViewHolder(
-                            inflater.inflate(R.layout.car_ui_list_item_compact, parent, false));
-                }
-                return new ListItemViewHolder(
-                        inflater.inflate(R.layout.car_ui_list_item, parent, false));
-            case VIEW_TYPE_LIST_HEADER:
-                return new HeaderViewHolder(
-                        inflater.inflate(R.layout.car_ui_header_list_item, parent, false));
-            default:
-                throw new IllegalStateException("Unknown item type.");
-        }
-    }
-
-    /**
-     * Returns the data set held by the adapter.
-     *
-     * <p>Any changes performed to this mutable list must be followed with an invocation of the
-     * appropriate notify method for the adapter.
-     */
-    @NonNull
-    public List<? extends CarUiListItem> getItems() {
-        return mItems;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        if (mItems.get(position) instanceof CarUiContentListItem) {
-            return VIEW_TYPE_LIST_ITEM;
-        } else if (mItems.get(position) instanceof CarUiHeaderListItem) {
-            return VIEW_TYPE_LIST_HEADER;
-        }
-
-        throw new IllegalStateException("Unknown view type.");
-    }
-
-    @Override
-    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
-        switch (holder.getItemViewType()) {
-            case VIEW_TYPE_LIST_ITEM:
-                if (!(holder instanceof ListItemViewHolder)) {
-                    throw new IllegalStateException("Incorrect view holder type for list item.");
-                }
-
-                CarUiListItem item = mItems.get(position);
-                if (!(item instanceof CarUiContentListItem)) {
-                    throw new IllegalStateException(
-                            "Expected item to be bound to viewHolder to be instance of "
-                                    + "CarUiContentListItem.");
-                }
-
-                ((ListItemViewHolder) holder).bind((CarUiContentListItem) item);
-                break;
-            case VIEW_TYPE_LIST_HEADER:
-                if (!(holder instanceof HeaderViewHolder)) {
-                    throw new IllegalStateException("Incorrect view holder type for list item.");
-                }
-
-                CarUiListItem header = mItems.get(position);
-                if (!(header instanceof CarUiHeaderListItem)) {
-                    throw new IllegalStateException(
-                            "Expected item to be bound to viewHolder to be instance of "
-                                    + "CarUiHeaderListItem.");
-                }
-
-                ((HeaderViewHolder) holder).bind((CarUiHeaderListItem) header);
-                break;
-            default:
-                throw new IllegalStateException("Unknown item view type.");
-        }
-    }
-
-    @Override
-    public int getItemCount() {
-        return mMaxItems == CarUiRecyclerView.ItemCap.UNLIMITED
-                ? mItems.size()
-                : Math.min(mItems.size(), mMaxItems);
-    }
-
-    @Override
-    public void setMaxItems(int maxItems) {
-        mMaxItems = maxItems;
-    }
-
-    /**
-     * Holds views of {@link CarUiContentListItem}.
-     */
-    static class ListItemViewHolder extends RecyclerView.ViewHolder {
-
-        final CarUiTextView mTitle;
-        final CarUiTextView mBody;
-        final ImageView mIcon;
-        final ImageView mContentIcon;
-        final ImageView mAvatarIcon;
-        final ViewGroup mIconContainer;
-        final ViewGroup mActionContainer;
-        final View mActionDivider;
-        final Switch mSwitch;
-        final CheckBox mCheckBox;
-        final RadioButton mRadioButton;
-        final ImageView mSupplementalIcon;
-        final View mTouchInterceptor;
-        final View mReducedTouchInterceptor;
-        final View mActionContainerTouchInterceptor;
-
-        ListItemViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mTitle = requireViewByRefId(itemView, R.id.car_ui_list_item_title);
-            mBody = requireViewByRefId(itemView, R.id.car_ui_list_item_body);
-            mIcon = requireViewByRefId(itemView, R.id.car_ui_list_item_icon);
-            mContentIcon = requireViewByRefId(itemView, R.id.car_ui_list_item_content_icon);
-            mAvatarIcon = requireViewByRefId(itemView, R.id.car_ui_list_item_avatar_icon);
-            mIconContainer = requireViewByRefId(itemView, R.id.car_ui_list_item_icon_container);
-            mActionContainer = requireViewByRefId(itemView, R.id.car_ui_list_item_action_container);
-            mActionDivider = requireViewByRefId(itemView, R.id.car_ui_list_item_action_divider);
-            mSwitch = requireViewByRefId(itemView, R.id.car_ui_list_item_switch_widget);
-            mCheckBox = requireViewByRefId(itemView, R.id.car_ui_list_item_checkbox_widget);
-            mRadioButton = requireViewByRefId(itemView, R.id.car_ui_list_item_radio_button_widget);
-            mSupplementalIcon = requireViewByRefId(itemView,
-                    R.id.car_ui_list_item_supplemental_icon);
-            mReducedTouchInterceptor = requireViewByRefId(itemView,
-                    R.id.car_ui_list_item_reduced_touch_interceptor);
-            mTouchInterceptor = requireViewByRefId(itemView,
-                    R.id.car_ui_list_item_touch_interceptor);
-            mActionContainerTouchInterceptor = requireViewByRefId(itemView,
-                    R.id.car_ui_list_item_action_container_touch_interceptor);
-        }
-
-        void bind(@NonNull CarUiContentListItem item) {
-            if (item.getTitle() != null) {
-                mTitle.setText(item.getTitle());
-                mTitle.setVisibility(View.VISIBLE);
-            } else {
-                mTitle.setVisibility(View.GONE);
-            }
-
-            if (item.getBody() != null) {
-                mBody.setText(item.getBody());
-                mBody.setVisibility(View.VISIBLE);
-            } else {
-                mBody.setVisibility(View.GONE);
-            }
-
-            mIcon.setVisibility(View.GONE);
-            mContentIcon.setVisibility(View.GONE);
-            mAvatarIcon.setVisibility(View.GONE);
-
-            Drawable icon = item.getIcon();
-            if (icon != null) {
-                mIconContainer.setVisibility(View.VISIBLE);
-
-                switch (item.getPrimaryIconType()) {
-                    case CONTENT:
-                        mContentIcon.setVisibility(View.VISIBLE);
-                        mContentIcon.setImageDrawable(icon);
-                        break;
-                    case STANDARD:
-                        mIcon.setVisibility(View.VISIBLE);
-                        mIcon.setImageDrawable(icon);
-                        break;
-                    case AVATAR:
-                        mAvatarIcon.setVisibility(View.VISIBLE);
-                        mAvatarIcon.setImageDrawable(icon);
-                        mAvatarIcon.setClipToOutline(true);
-                        break;
-                }
-            } else {
-                mIconContainer.setVisibility(View.GONE);
-            }
-
-            mActionDivider.setVisibility(
-                    item.isActionDividerVisible() ? View.VISIBLE : View.GONE);
-            mSwitch.setVisibility(View.GONE);
-            mCheckBox.setVisibility(View.GONE);
-            mRadioButton.setVisibility(View.GONE);
-            mSupplementalIcon.setVisibility(View.GONE);
-
-            CarUiContentListItem.OnClickListener itemOnClickListener = item.getOnClickListener();
-
-            switch (item.getAction()) {
-                case NONE:
-                    mActionContainer.setVisibility(View.GONE);
-
-                    // Display ripple effects across entire item when clicked by using full-sized
-                    // touch interceptor.
-                    mTouchInterceptor.setVisibility(View.VISIBLE);
-                    mTouchInterceptor.setOnClickListener(v -> {
-                        if (itemOnClickListener != null) {
-                            itemOnClickListener.onClick(item);
-                        }
-                    });
-                    mTouchInterceptor.setClickable(itemOnClickListener != null);
-                    mReducedTouchInterceptor.setVisibility(View.GONE);
-                    mActionContainerTouchInterceptor.setVisibility(View.GONE);
-                    break;
-                case SWITCH:
-                    bindCompoundButton(item, mSwitch, itemOnClickListener);
-                    break;
-                case CHECK_BOX:
-                    bindCompoundButton(item, mCheckBox, itemOnClickListener);
-                    break;
-                case RADIO_BUTTON:
-                    bindCompoundButton(item, mRadioButton, itemOnClickListener);
-                    break;
-                case CHEVRON:
-                    mSupplementalIcon.setVisibility(View.VISIBLE);
-                    mSupplementalIcon.setImageDrawable(itemView.getContext().getDrawable(
-                            R.drawable.car_ui_preference_icon_chevron));
-                    mActionContainer.setVisibility(View.VISIBLE);
-                    mTouchInterceptor.setVisibility(View.VISIBLE);
-                    mTouchInterceptor.setOnClickListener(v -> {
-                        if (itemOnClickListener != null) {
-                            itemOnClickListener.onClick(item);
-                        }
-                    });
-                    mTouchInterceptor.setClickable(itemOnClickListener != null);
-                    mReducedTouchInterceptor.setVisibility(View.GONE);
-                    mActionContainerTouchInterceptor.setVisibility(View.GONE);
-                    break;
-                case ICON:
-                    mSupplementalIcon.setVisibility(View.VISIBLE);
-                    mSupplementalIcon.setImageDrawable(item.getSupplementalIcon());
-
-                    mActionContainer.setVisibility(View.VISIBLE);
-
-                    // If the icon has a click listener, use a reduced touch interceptor to create
-                    // two distinct touch area; the action container and the remainder of the list
-                    // item. Each touch area will have its own ripple effect. If the icon has no
-                    // click listener, it shouldn't be clickable.
-                    if (item.getSupplementalIconOnClickListener() == null) {
-                        mTouchInterceptor.setVisibility(View.VISIBLE);
-                        mTouchInterceptor.setOnClickListener(v -> {
-                            if (itemOnClickListener != null) {
-                                itemOnClickListener.onClick(item);
-                            }
-                        });
-                        mTouchInterceptor.setClickable(itemOnClickListener != null);
-                        mReducedTouchInterceptor.setVisibility(View.GONE);
-                        mActionContainerTouchInterceptor.setVisibility(View.GONE);
-                    } else {
-                        mReducedTouchInterceptor.setVisibility(View.VISIBLE);
-                        mReducedTouchInterceptor.setOnClickListener(v -> {
-                            if (itemOnClickListener != null) {
-                                itemOnClickListener.onClick(item);
-                            }
-                        });
-                        mReducedTouchInterceptor.setClickable(itemOnClickListener != null);
-                        mActionContainerTouchInterceptor.setVisibility(View.VISIBLE);
-                        mActionContainerTouchInterceptor.setOnClickListener(
-                                (container) -> {
-                                    if (item.getSupplementalIconOnClickListener() != null) {
-                                        item.getSupplementalIconOnClickListener().onClick(item);
-                                    }
-                                });
-                        mActionContainerTouchInterceptor.setClickable(
-                                item.getSupplementalIconOnClickListener() != null);
-                        mTouchInterceptor.setVisibility(View.GONE);
-                    }
-                    break;
-                default:
-                    throw new IllegalStateException("Unknown secondary action type.");
-            }
-
-            itemView.setActivated(item.isActivated());
-            setEnabled(itemView, item.isEnabled());
-        }
-
-        void setEnabled(View view, boolean enabled) {
-            view.setEnabled(enabled);
-            if (view instanceof ViewGroup) {
-                ViewGroup group = (ViewGroup) view;
-
-                for (int i = 0; i < group.getChildCount(); i++) {
-                    setEnabled(group.getChildAt(i), enabled);
-                }
-            }
-        }
-
-        void bindCompoundButton(@NonNull CarUiContentListItem item,
-                @NonNull CompoundButton compoundButton,
-                @Nullable CarUiContentListItem.OnClickListener itemOnClickListener) {
-            compoundButton.setVisibility(View.VISIBLE);
-            compoundButton.setOnCheckedChangeListener(null);
-            compoundButton.setChecked(item.isChecked());
-            compoundButton.setOnCheckedChangeListener(
-                    (buttonView, isChecked) -> item.setChecked(isChecked));
-
-            // Clicks anywhere on the item should toggle the checkbox state. Use full touch
-            // interceptor.
-            mTouchInterceptor.setVisibility(View.VISIBLE);
-            mTouchInterceptor.setOnClickListener(v -> {
-                compoundButton.toggle();
-                if (itemOnClickListener != null) {
-                    itemOnClickListener.onClick(item);
-                }
-            });
-            // Compound button list items should always be clickable
-            mTouchInterceptor.setClickable(true);
-            mReducedTouchInterceptor.setVisibility(View.GONE);
-            mActionContainerTouchInterceptor.setVisibility(View.GONE);
-
-            mActionContainer.setVisibility(View.VISIBLE);
-            mActionContainer.setClickable(false);
-        }
-    }
-
-    /**
-     * Holds views of {@link CarUiHeaderListItem}.
-     */
-    static class HeaderViewHolder extends RecyclerView.ViewHolder {
-
-        private final TextView mTitle;
-        private final TextView mBody;
-
-        HeaderViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mTitle = requireViewByRefId(itemView, R.id.car_ui_list_item_title);
-            mBody = requireViewByRefId(itemView, R.id.car_ui_list_item_body);
-        }
-
-        private void bind(@NonNull CarUiHeaderListItem item) {
-            mTitle.setText(item.getTitle());
-
-            CharSequence body = item.getBody();
-            if (!TextUtils.isEmpty(body)) {
-                mBody.setText(body);
-            } else {
-                mBody.setVisibility(View.GONE);
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItemAdapterAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItemAdapterAdapterV1.java
deleted file mode 100644
index 82d0f6d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItemAdapterAdapterV1.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterDataObserverOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ViewHolderOEMV1;
-
-/**
- * Wrapper class that passes the data to car-ui via AdapterOEMV1 interface
- */
-public final class CarUiListItemAdapterAdapterV1 extends
-        RecyclerView.Adapter<CarUiListItemAdapterAdapterV1.ViewHolderWrapper> {
-
-    @NonNull
-    private AdapterOEMV1 mAdapter;
-
-    @NonNull
-    private final AdapterDataObserverOEMV1 mAdapterDataObserver = new AdapterDataObserverOEMV1() {
-        @Override
-        public void onChanged() {
-            CarUiListItemAdapterAdapterV1.super.notifyDataSetChanged();
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount) {
-            CarUiListItemAdapterAdapterV1.super.notifyItemRangeChanged(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount,
-                @Nullable Object payload) {
-            CarUiListItemAdapterAdapterV1.super.notifyItemRangeChanged(positionStart, itemCount,
-                    payload);
-        }
-
-        @Override
-        public void onItemRangeInserted(int positionStart, int itemCount) {
-            CarUiListItemAdapterAdapterV1.super.notifyItemRangeInserted(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemRangeRemoved(int positionStart, int itemCount) {
-            CarUiListItemAdapterAdapterV1.super.notifyItemRangeRemoved(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemMoved(int fromPosition, int toPosition) {
-            CarUiListItemAdapterAdapterV1.super.notifyItemMoved(fromPosition, toPosition);
-        }
-
-        @Override
-        public void onStateRestorationPolicyChanged() {
-            CarUiListItemAdapterAdapterV1.this.updateStateRestorationPolicy();
-        }
-    };
-
-    public CarUiListItemAdapterAdapterV1(@NonNull AdapterOEMV1 adapter) {
-        this.mAdapter = adapter;
-        CarUiListItemAdapterAdapterV1.super.setHasStableIds(adapter.hasStableIds());
-        updateStateRestorationPolicy();
-    }
-
-    private void updateStateRestorationPolicy() {
-        switch (mAdapter.getStateRestorationPolicyInt()) {
-            case 2:
-                CarUiListItemAdapterAdapterV1.super.setStateRestorationPolicy(
-                        RecyclerView.Adapter.StateRestorationPolicy.PREVENT);
-                break;
-            case 1:
-                CarUiListItemAdapterAdapterV1.super.setStateRestorationPolicy(
-                        RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);
-                break;
-            case 0:
-            default:
-                CarUiListItemAdapterAdapterV1.super.setStateRestorationPolicy(
-                        RecyclerView.Adapter.StateRestorationPolicy.ALLOW);
-        }
-    }
-
-    @Override
-    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
-        throw new IllegalStateException(
-                "OEM implementation of adapter can only be used with an OEM list view");
-    }
-
-    @Override
-    public int getItemCount() {
-        return mAdapter.getItemCount();
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return mAdapter.getItemId(position);
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mAdapter.getItemViewType(position);
-    }
-
-    @Override
-    public void onBindViewHolder(ViewHolderWrapper holder, int position) {
-        mAdapter.bindViewHolder(holder.getViewHolder(), position);
-    }
-
-    @Override
-    public ViewHolderWrapper onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
-        return new ViewHolderWrapper(mAdapter.createViewHolder(parent, viewType));
-    }
-
-    @Override
-    public boolean onFailedToRecycleView(ViewHolderWrapper holder) {
-        return mAdapter.onFailedToRecycleView(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewAttachedToWindow(ViewHolderWrapper holder) {
-        mAdapter.onViewAttachedToWindow(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewDetachedFromWindow(ViewHolderWrapper holder) {
-        mAdapter.onViewDetachedFromWindow(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewRecycled(ViewHolderWrapper holder) {
-        mAdapter.onViewRecycled(holder.getViewHolder());
-    }
-
-    @Override
-    public void registerAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) {
-        if (!super.hasObservers()) {
-            mAdapter.registerAdapterDataObserver(mAdapterDataObserver);
-        }
-        super.registerAdapterDataObserver(observer);
-    }
-
-    @Override
-    public void unregisterAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) {
-        super.unregisterAdapterDataObserver(observer);
-        if (!super.hasObservers()) {
-            mAdapter.unregisterAdapterDataObserver(mAdapterDataObserver);
-        }
-    }
-
-    /**
-     * Holds views for each element in the list.
-     */
-    public static class ViewHolderWrapper extends RecyclerView.ViewHolder {
-        @NonNull
-        private final ViewHolderOEMV1 mViewHolder;
-
-        ViewHolderWrapper(@NonNull ViewHolderOEMV1 viewHolder) {
-            super(viewHolder.getItemView());
-            mViewHolder = viewHolder;
-            setIsRecyclable(viewHolder.isRecyclable());
-        }
-
-        @NonNull
-        public ViewHolderOEMV1 getViewHolder() {
-            return mViewHolder;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRadioButtonListItemAdapter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRadioButtonListItemAdapter.java
deleted file mode 100644
index 2081db6..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRadioButtonListItemAdapter.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-
-import java.util.List;
-
-/**
- * Adapter for {@link CarUiRecyclerView} to display {@link CarUiRadioButtonListItem}. This adapter
- * allows for at most one item to be selected at a time.
- *
- * <ul>
- * <li> Implements {@link CarUiRecyclerView.ItemCap} - defaults to unlimited item count.
- * </ul>
- */
-public class CarUiRadioButtonListItemAdapter extends CarUiListItemAdapter {
-
-    private int mSelectedIndex = -1;
-
-    public CarUiRadioButtonListItemAdapter(List<CarUiRadioButtonListItem> items) {
-        super(items);
-        for (int i = 0; i < items.size(); i++) {
-            CarUiRadioButtonListItem item = items.get(i);
-            if (item.isChecked() && mSelectedIndex >= 0) {
-                throw new IllegalStateException(
-                        "At most one item in a CarUiRadioButtonListItemAdapter can be checked");
-            }
-
-            if (item.isChecked()) {
-                mSelectedIndex = i;
-            }
-        }
-    }
-
-    @NonNull
-    @Override
-    public RecyclerView.ViewHolder onCreateViewHolder(
-            @NonNull ViewGroup parent, int viewType) {
-        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-
-        if (viewType == VIEW_TYPE_LIST_ITEM) {
-            return new RadioButtonListItemViewHolder(
-                    inflater.inflate(R.layout.car_ui_list_item, parent, false));
-        }
-        return super.onCreateViewHolder(parent, viewType);
-    }
-
-    @Override
-    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
-        if (holder.getItemViewType() == VIEW_TYPE_LIST_ITEM) {
-            if (!(holder instanceof RadioButtonListItemViewHolder)) {
-                throw new IllegalStateException("Incorrect view holder type for list item.");
-            }
-
-            CarUiListItem item = getItems().get(position);
-            if (!(item instanceof CarUiRadioButtonListItem)) {
-                throw new IllegalStateException(
-                        "Expected item to be bound to viewHolder to be instance of "
-                                + "CarUiRadioButtonListItem.");
-            }
-
-            RadioButtonListItemViewHolder actualHolder = ((RadioButtonListItemViewHolder) holder);
-            actualHolder.bind((CarUiRadioButtonListItem) item);
-            actualHolder.setOnCheckedChangeListener(isChecked -> {
-                if (isChecked && mSelectedIndex >= 0) {
-                    CarUiRadioButtonListItem previousSelectedItem =
-                            (CarUiRadioButtonListItem) getItems().get(mSelectedIndex);
-                    previousSelectedItem.setChecked(false);
-                    notifyItemChanged(mSelectedIndex);
-                }
-
-                if (isChecked) {
-                    mSelectedIndex = position;
-                    CarUiRadioButtonListItem currentSelectedItem =
-                            (CarUiRadioButtonListItem) getItems().get(mSelectedIndex);
-                    currentSelectedItem.setChecked(true);
-                    notifyItemChanged(mSelectedIndex);
-                }
-            });
-
-        } else {
-            super.onBindViewHolder(holder, position);
-        }
-    }
-
-    /*
-     * @return the position of the currently selected item, -1 if no item is selected.
-     */
-    public int getSelectedItemPosition() {
-        return mSelectedIndex;
-    }
-
-    static class RadioButtonListItemViewHolder extends ListItemViewHolder {
-        /**
-         * Callback to be invoked when the checked state of a {@link RadioButtonListItemViewHolder}
-         * changed.
-         */
-        public interface OnCheckedChangeListener {
-            /**
-             * Called when the checked state of a {@link RadioButtonListItemViewHolder} has changed.
-             *
-             * @param isChecked new checked state of list item.
-             */
-            void onCheckedChanged(boolean isChecked);
-        }
-
-        @Nullable
-        private OnCheckedChangeListener mListener;
-
-        RadioButtonListItemViewHolder(@NonNull View itemView) {
-            super(itemView);
-        }
-
-        public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {
-            mListener = listener;
-        }
-
-        @Override
-        void bind(@NonNull CarUiContentListItem item) {
-            super.bind(item);
-            mRadioButton.setOnCheckedChangeListener(
-                    (buttonView, isChecked) -> {
-                        item.setChecked(isChecked);
-                        if (mListener != null) {
-                            mListener.onCheckedChanged(isChecked);
-                        }
-                    });
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerView.java
deleted file mode 100644
index e038d09..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerView.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-
-import java.lang.annotation.Retention;
-
-/**
- * A class to access the {@link CarUiRecyclerView} methods. The appearance and layout is
- * customizable by OEM.
- * <p>
- * This is the base class for CarUiRecyclerView implementation.
- */
-public abstract class CarUiRecyclerView extends RecyclerView {
-
-    /**
-     * Use this method to create an instance of CarUiRecyclerView at runtime.
-     */
-    public static CarUiRecyclerView create(Context context) {
-        return SharedLibraryFactorySingleton.get(context)
-                .createRecyclerView(context, null);
-    }
-
-    /**
-     * Use this method to create an instance of CarUiRecyclerView at runtime.
-     */
-    public static CarUiRecyclerView create(Context context, AttributeSet attributeSet) {
-        return SharedLibraryFactorySingleton.get(context)
-                .createRecyclerView(context, attributeSet);
-    }
-
-    /**
-     * Describes the expected relative size of the {@link CarUiRecyclerView}. The list may be
-     * rendered differently for each expected size.
-     */
-    @Retention(SOURCE)
-    @IntDef({SIZE_SMALL, SIZE_MEDIUM, SIZE_LARGE})
-    public @interface Size {}
-    public static final int SIZE_SMALL = 0;
-    public static final int SIZE_MEDIUM = 1;
-    public static final int SIZE_LARGE = 2;
-
-    /**
-     * The possible values for setScrollBarPosition. The default value is {@link
-     * CarUiRecyclerViewLayout#LINEAR}.
-     */
-    @IntDef({
-            CarUiRecyclerViewLayout.LINEAR,
-            CarUiRecyclerViewLayout.GRID,
-    })
-    @Retention(SOURCE)
-    public @interface CarUiRecyclerViewLayout {
-        /**
-         * Arranges items either horizontally in a single row or vertically in a single column. This
-         * is default.
-         */
-        int LINEAR = 0;
-
-        /**
-         * Arranges items in a Grid.
-         */
-        int GRID = 1;
-    }
-
-    /**
-     * Interface for a {@link RecyclerView.Adapter} to cap the number of items.
-     *
-     * <p>NOTE: it is still up to the adapter to use maxItems in {@link
-     * RecyclerView.Adapter#getItemCount()}.
-     *
-     * <p>the recommended way would be with:
-     *
-     * <pre>{@code
-     * {@literal@}Override
-     * public int getItemCount() {
-     *   return Math.min(super.getItemCount(), mMaxItems);
-     * }
-     * }</pre>
-     */
-    public interface ItemCap {
-
-        /**
-         * A value to pass to {@link #setMaxItems(int)} that indicates there should be no limit.
-         */
-        int UNLIMITED = -1;
-
-        /**
-         * Sets the maximum number of items available in the adapter. A value less than '0' means
-         * the list should not be capped.
-         */
-        void setMaxItems(int maxItems);
-    }
-
-    public CarUiRecyclerView(Context context) {
-        super(context);
-    }
-
-    public CarUiRecyclerView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    /**
-     * Return's the container which contains the scrollbar and this RecyclerView.
-     */
-    public abstract View getContainer();
-
-    /**
-     * Set the {@link LayoutManager} that this RecyclerView will use.
-     *
-     * <p>In contrast to other adapter-backed views such as {@link android.widget.ListView}
-     * or {@link android.widget.GridView}, RecyclerView allows client code to provide custom layout
-     * arrangements for child views. These arrangements are controlled by the {@link LayoutManager}.
-     * A LayoutManager must be provided for RecyclerView to function.</p>
-     *
-     * <p>Several default strategies are provided for common uses such as lists and grids.</p>
-     *
-     * @param layoutManager LayoutManager to use
-     * @deprecated to be implemented by OEM
-     */
-    @Deprecated
-    @Override
-    public void setLayoutManager(@Nullable LayoutManager layoutManager) {
-        super.setLayoutManager(layoutManager);
-    }
-
-    /**
-     * Return the {@link LayoutManager} currently responsible for
-     * layout policy for this RecyclerView.
-     *
-     * @return The currently bound LayoutManager
-     * @deprecated will return null for OEM implementation.
-     */
-    @Deprecated
-    @Nullable
-    @Override
-    public LayoutManager getLayoutManager() {
-        return super.getLayoutManager();
-    }
-
-    /**
-     * Add an {@link ItemDecoration} to this RecyclerView. Item decorations can affect both
-     * measurement and drawing of individual item views.
-     *
-     * <p>Item decorations are ordered. Decorations placed earlier in the list will
-     * be run/queried/drawn first for their effects on item views. Padding added to views will be
-     * nested; a padding added by an earlier decoration will mean further item decorations in the
-     * list will be asked to draw/pad within the previous decoration's given area.</p>
-     *
-     * @param decor Decoration to add
-     * @deprecated to be implemented by OEMs
-     */
-    @Deprecated
-    @Override
-    public void addItemDecoration(@NonNull ItemDecoration decor) {
-        super.addItemDecoration(decor);
-    }
-
-    /**
-     * Add an {@link ItemDecoration} to this RecyclerView. Item decorations can affect both
-     * measurement and drawing of individual item views.
-     *
-     * <p>Item decorations are ordered. Decorations placed earlier in the list will
-     * be run/queried/drawn first for their effects on item views. Padding added to views will be
-     * nested; a padding added by an earlier decoration will mean further item decorations in the
-     * list will be asked to draw/pad within the previous decoration's given area.</p>
-     *
-     * @param decor Decoration to add
-     * @param index Position in the decoration chain to insert this decoration at. If this value is
-     *              negative the decoration will be added at the end.
-     * @deprecated to be implemented by OEM
-     */
-    @Deprecated
-    @Override
-    public void addItemDecoration(@NonNull ItemDecoration decor, int index) {
-        super.addItemDecoration(decor, index);
-    }
-
-    /**
-     * Returns an {@link ItemDecoration} previously added to this RecyclerView.
-     *
-     * @param index The index position of the desired ItemDecoration.
-     * @return the ItemDecoration at index position
-     * @throws IndexOutOfBoundsException on invalid index
-     * @deprecated to be handled by OEM
-     */
-    @Deprecated
-    @Override
-    @NonNull
-    public ItemDecoration getItemDecorationAt(int index) {
-        return super.getItemDecorationAt(index);
-    }
-
-    /**
-     * Returns the number of {@link ItemDecoration} currently added to this RecyclerView.
-     *
-     * @return number of ItemDecorations currently added added to this RecyclerView.
-     * @deprecated to be handled by OEM
-     */
-    @Deprecated
-    @Override
-    public int getItemDecorationCount() {
-        return super.getItemDecorationCount();
-    }
-
-    /**
-     * Removes the {@link ItemDecoration} associated with the supplied index position.
-     *
-     * @param index The index position of the ItemDecoration to be removed.
-     * @deprecated to be handled by OEM
-     */
-    @Deprecated
-    @Override
-    public void removeItemDecorationAt(int index) {
-        super.removeItemDecorationAt(index);
-    }
-
-    /**
-     * Remove an {@link ItemDecoration} from this RecyclerView.
-     *
-     * <p>The given decoration will no longer impact the measurement and drawing of
-     * item views.</p>
-     *
-     * @param decor Decoration to remove
-     * @see #addItemDecoration(ItemDecoration)
-     * @deprecated to be handled by OEM
-     */
-    @Deprecated
-    @Override
-    public void removeItemDecoration(@NonNull ItemDecoration decor) {
-        super.removeItemDecoration(decor);
-    }
-
-    /**
-     * @deprecated this will return incorrect value when there is a oem implementation
-     */
-    @Override
-    @Deprecated
-    public int getChildCount() {
-        return super.getChildCount();
-    }
-
-    /**
-     * @deprecated this will return incorrect value when there is a oem implementation
-     */
-    @Deprecated
-    @Override
-    public View getChildAt(int index) {
-        return super.getChildAt(index);
-    }
-
-    /**
-     * Use this instead of setLayoutManager
-     * @param layoutStyle
-     */
-    public abstract void setLayoutStyle(CarUiLayoutStyle layoutStyle);
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerViewImpl.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerViewImpl.java
deleted file mode 100644
index 084a7d0..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerViewImpl.java
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-import static com.android.car.ui.utils.RotaryConstants.ROTARY_CONTAINER;
-import static com.android.car.ui.utils.RotaryConstants.ROTARY_HORIZONTALLY_SCROLLABLE;
-import static com.android.car.ui.utils.RotaryConstants.ROTARY_VERTICALLY_SCROLLABLE;
-import static com.android.car.ui.utils.ViewUtils.LazyLayoutView;
-import static com.android.car.ui.utils.ViewUtils.setRotaryScrollEnabled;
-
-import android.car.drivingstate.CarUxRestrictions;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.InputDevice;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewPropertyAnimator;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-import com.android.car.ui.recyclerview.decorations.grid.GridDividerItemDecoration;
-import com.android.car.ui.recyclerview.decorations.grid.GridOffsetItemDecoration;
-import com.android.car.ui.recyclerview.decorations.linear.LinearDividerItemDecoration;
-import com.android.car.ui.recyclerview.decorations.linear.LinearOffsetItemDecoration;
-import com.android.car.ui.recyclerview.decorations.linear.LinearOffsetItemDecoration.OffsetPosition;
-import com.android.car.ui.utils.CarUxRestrictionsUtil;
-
-import java.lang.reflect.Constructor;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * View that extends a {@link RecyclerView} and wraps itself into a {@link LinearLayout} which could
- * potentially include a scrollbar that has page up and down arrows. Interaction with this view is
- * similar to a {@code RecyclerView} as it takes the same adapter and the layout manager.
- */
-public final class CarUiRecyclerViewImpl extends CarUiRecyclerView implements LazyLayoutView {
-
-    private static final String TAG = "CarUiRecyclerView";
-
-    private final CarUxRestrictionsUtil.OnUxRestrictionsChangedListener mListener =
-            new UxRestrictionChangedListener();
-
-    @NonNull
-    private final CarUxRestrictionsUtil mCarUxRestrictionsUtil;
-    private boolean mScrollBarEnabled;
-    @Nullable
-    private String mScrollBarClass;
-    private int mScrollBarPaddingTop;
-    private int mScrollBarPaddingBottom;
-    @Nullable
-    private ScrollBar mScrollBar;
-
-    @Nullable
-    private GridOffsetItemDecoration mTopOffsetItemDecorationGrid;
-    @Nullable
-    private GridOffsetItemDecoration mBottomOffsetItemDecorationGrid;
-    @Nullable
-    private RecyclerView.ItemDecoration mTopOffsetItemDecorationLinear;
-    @Nullable
-    private RecyclerView.ItemDecoration mBottomOffsetItemDecorationLinear;
-    @Nullable
-    private GridDividerItemDecoration mDividerItemDecorationGrid;
-    @Nullable
-    private RecyclerView.ItemDecoration mDividerItemDecorationLinear;
-    private int mNumOfColumns;
-    private boolean mInstallingExtScrollBar = false;
-    private int mContainerVisibility = View.VISIBLE;
-    @Nullable
-    private Rect mContainerPadding;
-    @Nullable
-    private Rect mContainerPaddingRelative;
-    @Nullable
-    private ViewGroup mContainer;
-    @Size
-    private int mSize;
-
-    // Set to true when when styled attributes are read and initialized.
-    private boolean mIsInitialized;
-    private boolean mEnableDividers;
-
-    private boolean mHasScrolled = false;
-
-    @NonNull
-    private final Set<Runnable> mOnLayoutCompletedListeners = new HashSet<>();
-
-    private OnScrollListener mOnScrollListener = new OnScrollListener() {
-        @Override
-        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
-            if (dx > 0 || dy > 0) {
-                mHasScrolled = true;
-                removeOnScrollListener(this);
-            }
-        }
-    };
-
-    public CarUiRecyclerViewImpl(@NonNull Context context) {
-        this(context, null);
-    }
-
-    public CarUiRecyclerViewImpl(@NonNull Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, R.attr.carUiRecyclerViewStyle);
-    }
-
-    public CarUiRecyclerViewImpl(@NonNull Context context, @Nullable AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
-        mCarUxRestrictionsUtil = CarUxRestrictionsUtil.getInstance(context);
-        init(context, attrs, defStyle);
-    }
-
-    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
-        setClipToPadding(false);
-        TypedArray a = context.obtainStyledAttributes(
-                attrs,
-                R.styleable.CarUiRecyclerView,
-                defStyleAttr,
-                R.style.Widget_CarUi_CarUiRecyclerView);
-        initRotaryScroll(a);
-
-        mScrollBarEnabled = context.getResources().getBoolean(R.bool.car_ui_scrollbar_enable);
-
-        mScrollBarPaddingTop = context.getResources()
-                .getDimensionPixelSize(R.dimen.car_ui_scrollbar_padding_top);
-        mScrollBarPaddingBottom = context.getResources()
-                .getDimensionPixelSize(R.dimen.car_ui_scrollbar_padding_bottom);
-
-        @CarUiRecyclerViewLayout int carUiRecyclerViewLayout =
-                a.getInt(R.styleable.CarUiRecyclerView_layoutStyle, CarUiRecyclerViewLayout.LINEAR);
-        mNumOfColumns = a.getInt(R.styleable.CarUiRecyclerView_numOfColumns, /* defValue= */ 2);
-        mEnableDividers =
-                a.getBoolean(R.styleable.CarUiRecyclerView_enableDivider, /* defValue= */ false);
-
-        mDividerItemDecorationLinear = new LinearDividerItemDecoration(
-                context.getDrawable(R.drawable.car_ui_recyclerview_divider));
-
-        mDividerItemDecorationGrid =
-                new GridDividerItemDecoration(
-                        context.getDrawable(R.drawable.car_ui_divider),
-                        context.getDrawable(R.drawable.car_ui_divider),
-                        mNumOfColumns);
-
-        mTopOffsetItemDecorationLinear =
-                new LinearOffsetItemDecoration(0, OffsetPosition.START);
-        mBottomOffsetItemDecorationLinear =
-                new LinearOffsetItemDecoration(0, OffsetPosition.END);
-        mTopOffsetItemDecorationGrid =
-                new GridOffsetItemDecoration(0, mNumOfColumns,
-                        OffsetPosition.START);
-        mBottomOffsetItemDecorationGrid =
-                new GridOffsetItemDecoration(0, mNumOfColumns,
-                        OffsetPosition.END);
-
-        mIsInitialized = true;
-
-        // Check if a layout manager has already been set via XML
-        boolean isLayoutMangerSet = getLayoutManager() != null;
-        if (!isLayoutMangerSet && carUiRecyclerViewLayout
-                == CarUiRecyclerView.CarUiRecyclerViewLayout.LINEAR) {
-            setLayoutManager(new LinearLayoutManager(getContext()) {
-                @Override
-                public void onLayoutCompleted(RecyclerView.State state) {
-                    super.onLayoutCompleted(state);
-                    // Iterate through a copied set instead of the original set because the original
-                    // set might be modified during iteration.
-                    Set<Runnable> onLayoutCompletedListeners =
-                        new HashSet<>(mOnLayoutCompletedListeners);
-                    for (Runnable runnable : onLayoutCompletedListeners) {
-                        runnable.run();
-                    }
-                }
-            });
-        } else if (!isLayoutMangerSet && carUiRecyclerViewLayout
-                == CarUiRecyclerView.CarUiRecyclerViewLayout.GRID) {
-            setLayoutManager(new GridLayoutManager(getContext(), mNumOfColumns) {
-                @Override
-                public void onLayoutCompleted(RecyclerView.State state) {
-                    super.onLayoutCompleted(state);
-                    // Iterate through a copied set instead of the original set because the original
-                    // set might be modified during iteration.
-                    Set<Runnable> onLayoutCompletedListeners =
-                        new HashSet<>(mOnLayoutCompletedListeners);
-                    for (Runnable runnable : onLayoutCompletedListeners) {
-                        runnable.run();
-                    }
-                }
-            });
-        }
-        addOnScrollListener(mOnScrollListener);
-
-        mSize = a.getInt(R.styleable.CarUiRecyclerView_carUiSize, SIZE_LARGE);
-
-        a.recycle();
-
-        if (!mScrollBarEnabled) {
-            return;
-        }
-
-        mContainer = new FrameLayout(getContext());
-
-        setVerticalScrollBarEnabled(false);
-        setHorizontalScrollBarEnabled(false);
-
-        mScrollBarClass = context.getResources().getString(R.string.car_ui_scrollbar_component);
-    }
-
-    @Override
-    public void setLayoutManager(@Nullable LayoutManager layoutManager) {
-        // Cannot setup item decorations before stylized attributes have been read.
-        if (mIsInitialized) {
-            addItemDecorations(layoutManager);
-        }
-        super.setLayoutManager(layoutManager);
-    }
-
-    @Override
-    public void setLayoutStyle(CarUiLayoutStyle layoutStyle) {
-        LayoutManager layoutManager;
-        if (layoutStyle.getLayoutType() == CarUiRecyclerViewLayout.LINEAR) {
-            layoutManager = new LinearLayoutManager(getContext(),
-                    layoutStyle.getOrientation(),
-                    layoutStyle.getReverseLayout()) {
-                @Override
-                public void onLayoutCompleted(RecyclerView.State state) {
-                    super.onLayoutCompleted(state);
-                    // Iterate through a copied set instead of the original set because the original
-                    // set might be modified during iteration.
-                    Set<Runnable> onLayoutCompletedListeners =
-                        new HashSet<>(mOnLayoutCompletedListeners);
-                    for (Runnable runnable : onLayoutCompletedListeners) {
-                        runnable.run();
-                    }
-                }
-            };
-        } else {
-            layoutManager = new GridLayoutManager(getContext(),
-                    layoutStyle.getSpanCount(),
-                    layoutStyle.getOrientation(),
-                    layoutStyle.getReverseLayout()) {
-                @Override
-                public void onLayoutCompleted(RecyclerView.State state) {
-                    super.onLayoutCompleted(state);
-                    // Iterate through a copied set instead of the original set because the original
-                    // set might be modified during iteration.
-                    Set<Runnable> onLayoutCompletedListeners =
-                        new HashSet<>(mOnLayoutCompletedListeners);
-                    for (Runnable runnable : onLayoutCompletedListeners) {
-                        runnable.run();
-                    }
-                }
-            };
-            // TODO(b/190444037): revisit usage of LayoutStyles and their casting
-            if (layoutStyle instanceof CarUiGridLayoutStyle) {
-                ((GridLayoutManager) layoutManager).setSpanSizeLookup(
-                        ((CarUiGridLayoutStyle) layoutStyle).getSpanSizeLookup());
-            }
-        }
-        setLayoutManager(layoutManager);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * Note that this method will never return true if this view has no items in it's adapter. This
-     * is fine since an RecyclerView with empty items is not able to restore focus inside it.
-     */
-    @Override
-    public boolean isLayoutCompleted() {
-        RecyclerView.Adapter adapter = getAdapter();
-        return adapter != null && adapter.getItemCount() > 0 && !isComputingLayout();
-    }
-
-    @Override
-    public void addOnLayoutCompleteListener(@Nullable Runnable runnable) {
-        if (runnable != null) {
-            mOnLayoutCompletedListeners.add(runnable);
-        }
-    }
-
-    @Override
-    public void removeOnLayoutCompleteListener(@Nullable Runnable runnable) {
-        if (runnable != null) {
-            mOnLayoutCompletedListeners.remove(runnable);
-        }
-    }
-
-    @Override
-    public View getContainer() {
-        return mContainer;
-    }
-
-    // This method should not be invoked before item decorations are initialized by the #init()
-    // method.
-    private void addItemDecorations(LayoutManager layoutManager) {
-        // remove existing Item decorations.
-        removeItemDecoration(Objects.requireNonNull(mDividerItemDecorationGrid));
-        removeItemDecoration(Objects.requireNonNull(mTopOffsetItemDecorationGrid));
-        removeItemDecoration(Objects.requireNonNull(mBottomOffsetItemDecorationGrid));
-        removeItemDecoration(Objects.requireNonNull(mDividerItemDecorationLinear));
-        removeItemDecoration(Objects.requireNonNull(mTopOffsetItemDecorationLinear));
-        removeItemDecoration(Objects.requireNonNull(mBottomOffsetItemDecorationLinear));
-
-        if (layoutManager instanceof GridLayoutManager) {
-            if (mEnableDividers) {
-                addItemDecoration(Objects.requireNonNull(mDividerItemDecorationGrid));
-            }
-            addItemDecoration(Objects.requireNonNull(mTopOffsetItemDecorationGrid));
-            addItemDecoration(Objects.requireNonNull(mBottomOffsetItemDecorationGrid));
-            setNumOfColumns(((GridLayoutManager) layoutManager).getSpanCount());
-        } else {
-            if (mEnableDividers) {
-                addItemDecoration(Objects.requireNonNull(mDividerItemDecorationLinear));
-            }
-            addItemDecoration(Objects.requireNonNull(mTopOffsetItemDecorationLinear));
-            addItemDecoration(Objects.requireNonNull(mBottomOffsetItemDecorationLinear));
-        }
-    }
-
-    /**
-     * If this view's {@code rotaryScrollEnabled} attribute is set to true, sets the content
-     * description so that the {@code RotaryService} will treat it as a scrollable container and
-     * initializes this view accordingly.
-     */
-    private void initRotaryScroll(@Nullable TypedArray styledAttributes) {
-        boolean rotaryScrollEnabled = styledAttributes != null && styledAttributes.getBoolean(
-                R.styleable.CarUiRecyclerView_rotaryScrollEnabled, /* defValue=*/ false);
-        if (rotaryScrollEnabled) {
-            int orientation = styledAttributes
-                    .getInt(R.styleable.CarUiRecyclerView_android_orientation,
-                            LinearLayout.VERTICAL);
-            setRotaryScrollEnabled(
-                    this, /* isVertical= */ orientation == LinearLayout.VERTICAL);
-        } else {
-            CharSequence contentDescription = getContentDescription();
-            rotaryScrollEnabled = contentDescription != null
-                    && (ROTARY_HORIZONTALLY_SCROLLABLE.contentEquals(contentDescription)
-                    || ROTARY_VERTICALLY_SCROLLABLE.contentEquals(contentDescription));
-        }
-
-        // If rotary scrolling is enabled, set a generic motion event listener to convert
-        // SOURCE_ROTARY_ENCODER scroll events into SOURCE_MOUSE scroll events that RecyclerView
-        // knows how to handle.
-        setOnGenericMotionListener(rotaryScrollEnabled ? (v, event) -> {
-            if (event.getAction() == MotionEvent.ACTION_SCROLL) {
-                if (event.getSource() == InputDevice.SOURCE_ROTARY_ENCODER) {
-                    MotionEvent mouseEvent = MotionEvent.obtain(event);
-                    mouseEvent.setSource(InputDevice.SOURCE_MOUSE);
-                    CarUiRecyclerViewImpl.super.onGenericMotionEvent(mouseEvent);
-                    return true;
-                }
-            }
-            return false;
-        } : null);
-
-        // If rotary scrolling is enabled, mark this view as focusable. This view will be focused
-        // when no focusable elements are visible.
-        setFocusable(rotaryScrollEnabled);
-
-        // Focus this view before descendants so that the RotaryService can focus this view when it
-        // wants to.
-        setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
-
-        // Disable the default focus highlight. No highlight should appear when this view is
-        // focused.
-        setDefaultFocusHighlightEnabled(false);
-
-        // If rotary scrolling is enabled, set a focus change listener to highlight the scrollbar
-        // thumb when this recycler view is focused, i.e. when no focusable descendant is visible.
-        setOnFocusChangeListener(rotaryScrollEnabled ? (v, hasFocus) -> {
-            if (mScrollBar != null) mScrollBar.setHighlightThumb(hasFocus);
-        } : null);
-
-        // This view is a rotary container if it's not a scrollable container.
-        if (!rotaryScrollEnabled) {
-            super.setContentDescription(ROTARY_CONTAINER);
-        }
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        super.onRestoreInstanceState(state);
-
-        // If we're restoring an existing RecyclerView, consider
-        // it as having already scrolled some.
-        mHasScrolled = true;
-    }
-
-    @Override
-    public void requestLayout() {
-        super.requestLayout();
-        if (mScrollBar != null) {
-            mScrollBar.requestLayout();
-        }
-    }
-
-    /**
-     * Sets the number of columns in which grid needs to be divided.
-     */
-    private void setNumOfColumns(int numberOfColumns) {
-        mNumOfColumns = numberOfColumns;
-        if (mTopOffsetItemDecorationGrid != null) {
-            mTopOffsetItemDecorationGrid.setNumOfColumns(mNumOfColumns);
-        }
-        if (mDividerItemDecorationGrid != null) {
-            mDividerItemDecorationGrid.setNumOfColumns(mNumOfColumns);
-        }
-    }
-
-    /**
-     * Changes the visibility of the entire container. If the container is not present i.e scrollbar
-     * is not visible then the visibility or Recyclerview is changed.
-     */
-    @Override
-    public void setVisibility(int visibility) {
-        super.setVisibility(visibility);
-        mContainerVisibility = visibility;
-        if (mContainer != null) {
-            mContainer.setVisibility(visibility);
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mCarUxRestrictionsUtil.register(mListener);
-        if (mInstallingExtScrollBar || !mScrollBarEnabled) {
-            return;
-        }
-        // When CarUiRV is detached from the current parent and attached to the container with
-        // the scrollBar, onAttachedToWindow() will get called immediately when attaching the
-        // CarUiRV to the container. This flag will help us keep track of this state and avoid
-        // recursion. We also want to reset the state of this flag as soon as the container is
-        // successfully attached to the CarUiRV's original parent.
-        mInstallingExtScrollBar = true;
-        installExternalScrollBar();
-        mInstallingExtScrollBar = false;
-    }
-
-    /**
-     * This method will detach the current recycler view from its parent and attach it to the
-     * container which is a LinearLayout. Later the entire container is attached to the parent where
-     * the recycler view was set with the same layout params.
-     */
-    private void installExternalScrollBar() {
-        if (mContainer.getParent() != null) {
-            // We've already installed the parent container.
-            // onAttachToWindow() can be called multiple times, but on the second time
-            // we will crash if we try to add mContainer as a child of a view again while
-            // it already has a parent.
-            return;
-        }
-
-        mContainer.removeAllViews();
-        LayoutInflater inflater = LayoutInflater.from(getContext());
-
-        switch (mSize) {
-            case SIZE_SMALL:
-                // Small layout is rendered without scrollbar
-                return;
-            case SIZE_MEDIUM:
-                inflater.inflate(R.layout.car_ui_recycler_view_medium, mContainer, true);
-                break;
-            case SIZE_LARGE:
-            default:
-                inflater.inflate(R.layout.car_ui_recycler_view, mContainer, true);
-        }
-
-        mContainer.setVisibility(mContainerVisibility);
-
-        if (mContainerPadding != null) {
-            mContainer.setPadding(mContainerPadding.left, mContainerPadding.top,
-                    mContainerPadding.right, mContainerPadding.bottom);
-        } else if (mContainerPaddingRelative != null) {
-            mContainer.setPaddingRelative(mContainerPaddingRelative.left,
-                    mContainerPaddingRelative.top, mContainerPaddingRelative.right,
-                    mContainerPaddingRelative.bottom);
-        } else {
-            mContainer.setPadding(getPaddingLeft(), /* top= */ 0,
-                    getPaddingRight(), /* bottom= */ 0);
-            setPadding(/* left= */ 0, getPaddingTop(),
-                    /* right= */ 0, getPaddingBottom());
-        }
-
-        mContainer.setLayoutParams(getLayoutParams());
-        ViewGroup parent = (ViewGroup) getParent();
-        int index = parent.indexOfChild(this);
-        parent.removeViewInLayout(this);
-
-        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-        ((CarUiRecyclerViewContainer) requireViewByRefId(mContainer, R.id.car_ui_recycler_view))
-                .addRecyclerView(this, params);
-        parent.addView(mContainer, index);
-
-        createScrollBarFromConfig(requireViewByRefId(mContainer, R.id.car_ui_scroll_bar));
-    }
-
-    private void createScrollBarFromConfig(@NonNull View scrollView) {
-        Class<?> cls;
-        try {
-            cls = !TextUtils.isEmpty(mScrollBarClass)
-                    ? getContext().getClassLoader().loadClass(mScrollBarClass)
-                    : DefaultScrollBar.class;
-        } catch (ReflectiveOperationException e) {
-            throw new IllegalArgumentException("Error loading scroll bar component: "
-                    + mScrollBarClass, e);
-        }
-        try {
-            Constructor<?> cnst = cls.getDeclaredConstructor();
-            cnst.setAccessible(true);
-            mScrollBar = (ScrollBar) cnst.newInstance();
-        } catch (ReflectiveOperationException e) {
-            throw new IllegalArgumentException("Error creating scroll bar component: "
-                    + mScrollBarClass, e);
-        }
-
-        mScrollBar.initialize(this, scrollView);
-
-        setScrollBarPadding(mScrollBarPaddingTop, mScrollBarPaddingBottom);
-    }
-
-    @Override
-    public void setAlpha(float value) {
-        if (mScrollBarEnabled) {
-            mContainer.setAlpha(value);
-        } else {
-            super.setAlpha(value);
-        }
-    }
-
-    @Override
-    public ViewPropertyAnimator animate() {
-        return mScrollBarEnabled ? mContainer.animate() : super.animate();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mCarUxRestrictionsUtil.unregister(mListener);
-    }
-
-    @Override
-    public int getPaddingLeft() {
-        if (mContainerPadding != null) {
-            return mContainerPadding.left;
-        }
-
-        return super.getPaddingLeft();
-    }
-
-    @Override
-    public int getPaddingRight() {
-        if (mContainerPadding != null) {
-            return mContainerPadding.right;
-        }
-
-        return super.getPaddingRight();
-    }
-
-    @Override
-    public void setPadding(int left, int top, int right, int bottom) {
-        mContainerPaddingRelative = null;
-        if (mScrollBarEnabled) {
-            boolean isAtStart = (mScrollBar != null && mScrollBar.isAtStart());
-            super.setPadding(0, top, 0, bottom);
-            if (!mHasScrolled || isAtStart) {
-                // If we haven't scrolled, and thus are still at the top of the screen,
-                // we should stay scrolled to the top after applying padding. Without this
-                // scroll, the padding will start scrolled offscreen. We need the padding
-                // to be onscreen to shift the content into a good visible range.
-                scrollToPosition(0);
-            }
-            mContainerPadding = new Rect(left, 0, right, 0);
-            if (mContainer != null) {
-                mContainer.setPadding(left, 0, right, 0);
-            }
-            setScrollBarPadding(mScrollBarPaddingTop, mScrollBarPaddingBottom);
-        } else {
-            super.setPadding(left, top, right, bottom);
-        }
-    }
-
-    @Override
-    public void setPaddingRelative(int start, int top, int end, int bottom) {
-        mContainerPadding = null;
-        if (mScrollBarEnabled) {
-            super.setPaddingRelative(0, top, 0, bottom);
-            if (!mHasScrolled) {
-                // If we haven't scrolled, and thus are still at the top of the screen,
-                // we should stay scrolled to the top after applying padding. Without this
-                // scroll, the padding will start scrolled offscreen. We need the padding
-                // to be onscreen to shift the content into a good visible range.
-                scrollToPosition(0);
-            }
-            mContainerPaddingRelative = new Rect(start, 0, end, 0);
-            if (mContainer != null) {
-                mContainer.setPaddingRelative(start, 0, end, 0);
-            }
-            setScrollBarPadding(mScrollBarPaddingTop, mScrollBarPaddingBottom);
-        } else {
-            super.setPaddingRelative(start, top, end, bottom);
-        }
-    }
-
-    /**
-     * Sets the scrollbar's padding top and bottom. This padding is applied in addition to the
-     * padding of the RecyclerView.
-     */
-    private void setScrollBarPadding(int paddingTop, int paddingBottom) {
-        if (mScrollBarEnabled) {
-            mScrollBarPaddingTop = paddingTop;
-            mScrollBarPaddingBottom = paddingBottom;
-
-            if (mScrollBar != null) {
-                mScrollBar.setPadding(paddingTop + getPaddingTop(),
-                        paddingBottom + getPaddingBottom());
-            }
-        }
-    }
-
-    @Override
-    public void setContentDescription(CharSequence contentDescription) {
-        super.setContentDescription(contentDescription);
-        initRotaryScroll(/* styledAttributes= */ null);
-    }
-
-    @Override
-    public void setAdapter(@Nullable Adapter adapter) {
-        if (mScrollBar != null) {
-            // Make sure this is called before super so that scrollbar can get a reference to
-            // the adapter using RecyclerView#getAdapter()
-            mScrollBar.adapterChanged(adapter);
-        }
-        super.setAdapter(adapter);
-    }
-
-    private class UxRestrictionChangedListener implements
-            CarUxRestrictionsUtil.OnUxRestrictionsChangedListener {
-
-        @Override
-        public void onRestrictionsChanged(@NonNull CarUxRestrictions carUxRestrictions) {
-            Adapter<?> adapter = getAdapter();
-            // If the adapter does not implement ItemCap, then the max items on it cannot be
-            // updated.
-            if (!(adapter instanceof CarUiRecyclerView.ItemCap)) {
-                return;
-            }
-
-            int maxItems = CarUiRecyclerView.ItemCap.UNLIMITED;
-            if ((carUxRestrictions.getActiveRestrictions()
-                    & CarUxRestrictions.UX_RESTRICTIONS_LIMIT_CONTENT)
-                    != 0) {
-                maxItems = carUxRestrictions.getMaxCumulativeContentItems();
-            }
-
-            int originalCount = adapter.getItemCount();
-            ((CarUiRecyclerView.ItemCap) adapter).setMaxItems(maxItems);
-            int newCount = adapter.getItemCount();
-
-            if (newCount == originalCount) {
-                return;
-            }
-
-            if (newCount < originalCount) {
-                adapter.notifyItemRangeRemoved(newCount, originalCount - newCount);
-            } else {
-                adapter.notifyItemRangeInserted(originalCount, newCount - originalCount);
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiSnapHelper.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiSnapHelper.java
deleted file mode 100644
index 3ed3247..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiSnapHelper.java
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearSnapHelper;
-import androidx.recyclerview.widget.OrientationHelper;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.LayoutManager;
-
-import java.util.Objects;
-
-/**
- * Inspired by {@link androidx.car.widget.PagedSnapHelper}
- *
- * <p>Extension of a {@link LinearSnapHelper} that will snap to the start of the target child view
- * to the start of the attached {@link RecyclerView}. The start of the view is defined as the top if
- * the RecyclerView is scrolling vertically; it is defined as the left (or right if RTL) if the
- * RecyclerView is scrolling horizontally.
- */
-/* package */ class CarUiSnapHelper extends LinearSnapHelper {
-    /**
-     * The percentage of a View that needs to be completely visible for it to be a viable snap
-     * target.
-     */
-    private static final float VIEW_VISIBLE_THRESHOLD = 0.5f;
-
-    /**
-     * When a View is longer than containing RecyclerView, the percentage of the end of this View
-     * that needs to be completely visible to prevent the rest of views to be a viable snap target.
-     *
-     * <p>In other words, if a longer-than-screen View takes more than threshold screen space on its
-     * end, do not snap to any View.
-     */
-    private static final float LONG_ITEM_END_VISIBLE_THRESHOLD = 0.3f;
-
-    private final Context mContext;
-    @Nullable
-    private RecyclerView mRecyclerView;
-
-    public CarUiSnapHelper(Context context) {
-        mContext = context;
-    }
-
-    // Orientation helpers are lazily created per LayoutManager.
-    @Nullable
-    private OrientationHelper mVerticalHelper;
-    @Nullable
-    private OrientationHelper mHorizontalHelper;
-
-    @Override
-    public int[] calculateDistanceToFinalSnap(
-            @NonNull LayoutManager layoutManager, @NonNull View targetView) {
-        int[] out = new int[2];
-
-        // Don't snap when not in touch mode, i.e. when using rotary.
-        if (!mRecyclerView.isInTouchMode()) {
-            return out;
-        }
-
-        if (layoutManager.canScrollHorizontally()) {
-            out[0] = distanceToTopMargin(targetView, getHorizontalHelper(layoutManager));
-        }
-
-        if (layoutManager.canScrollVertically()) {
-            out[1] = distanceToTopMargin(targetView, getVerticalHelper(layoutManager));
-        }
-
-        return out;
-    }
-
-    /**
-     * Finds the view to snap to. The view to snap to is the child of the LayoutManager that is
-     * closest to the start of the RecyclerView. The "start" depends on if the LayoutManager
-     * is scrolling horizontally or vertically. If it is horizontally scrolling, then the
-     * start is the view on the left (right if RTL). Otherwise, it is the top-most view.
-     *
-     * @param layoutManager The current {@link LayoutManager} for the attached RecyclerView.
-     * @return The View closest to the start of the RecyclerView. Returns {@code null}when:
-     * <ul>
-     *     <li>there is no item; or
-     *     <li>no visible item can fully fit in the containing RecyclerView; or
-     *     <li>an item longer than containing RecyclerView is about to scroll out.
-     * </ul>
-     */
-    @Override
-    @Nullable
-    public View findSnapView(LayoutManager layoutManager) {
-        int childCount = layoutManager.getChildCount();
-        if (childCount == 0) {
-            return null;
-        }
-
-        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
-
-        // If there's only one child, then that will be the snap target.
-        if (childCount == 1) {
-            View firstChild = layoutManager.getChildAt(0);
-            return isValidSnapView(firstChild, orientationHelper) ? firstChild : null;
-        }
-
-        if (mRecyclerView == null) {
-            return null;
-        }
-
-        // If the top child view is longer than the RecyclerView (long item), and it's not yet
-        // scrolled out - meaning the screen it takes up is more than threshold,
-        // do not snap to any view.
-        // This way avoids next View snapping to top "pushes" out the end of a long item.
-        View firstChild = mRecyclerView.getChildAt(0);
-        if (firstChild.getHeight() > mRecyclerView.getHeight()
-                // Long item start is scrolled past screen;
-                && orientationHelper.getDecoratedStart(firstChild) < 0
-                // and it takes up more than threshold screen size.
-                && orientationHelper.getDecoratedEnd(firstChild) > (
-                mRecyclerView.getHeight() * LONG_ITEM_END_VISIBLE_THRESHOLD)) {
-            return null;
-        }
-
-        @NonNull View lastVisibleChild = Objects.requireNonNull(
-                layoutManager.getChildAt(childCount - 1));
-
-        // Check if the last child visible is the last item in the list.
-        boolean lastItemVisible =
-                layoutManager.getPosition(lastVisibleChild) == layoutManager.getItemCount() - 1;
-
-        // If it is, then check how much of that view is visible.
-        float lastItemPercentageVisible = lastItemVisible
-                ? getPercentageVisible(lastVisibleChild, orientationHelper) : 0;
-
-        View closestChild = null;
-        int closestDistanceToStart = Integer.MAX_VALUE;
-        float closestPercentageVisible = 0.f;
-
-        // Iterate to find the child closest to the top and more than half way visible.
-        for (int i = 0; i < childCount; i++) {
-            View child = layoutManager.getChildAt(i);
-            int startOffset = orientationHelper.getDecoratedStart(child);
-
-            if (Math.abs(startOffset) < closestDistanceToStart) {
-                float percentageVisible = getPercentageVisible(child, orientationHelper);
-
-                if (percentageVisible > VIEW_VISIBLE_THRESHOLD
-                        && percentageVisible > closestPercentageVisible) {
-                    closestDistanceToStart = startOffset;
-                    closestChild = child;
-                    closestPercentageVisible = percentageVisible;
-                }
-            }
-        }
-
-        View childToReturn = closestChild;
-
-        // If closestChild is null, then that means we were unable to find a closest child that
-        // is over the VIEW_VISIBLE_THRESHOLD. This could happen if the views are larger than
-        // the given area. In this case, consider returning the lastVisibleChild so that the screen
-        // scrolls. Also, check if the last item should be displayed anyway if it is mostly visible.
-        if ((childToReturn == null
-                || (lastItemVisible && lastItemPercentageVisible > closestPercentageVisible))) {
-            childToReturn = lastVisibleChild;
-        }
-
-        // Return null if the childToReturn is not valid. This allows the user to scroll freely
-        // with no snapping. This can allow them to see the entire view.
-        return isValidSnapView(childToReturn, orientationHelper) ? childToReturn : null;
-    }
-
-    private static int distanceToTopMargin(@NonNull View targetView, OrientationHelper helper) {
-        final int childTop = helper.getDecoratedStart(targetView);
-        final int containerTop = helper.getStartAfterPadding();
-        return childTop - containerTop;
-    }
-
-    /**
-     * Returns whether or not the given View is a valid snapping view. A view is considered valid
-     * for snapping if it can fit entirely within the height of the RecyclerView it is contained
-     * within.
-     *
-     * <p>If the view is larger than the RecyclerView, then it might not want to be snapped to
-     * to allow the user to scroll and see the rest of the View.
-     *
-     * @param view   The view to determine the snapping potential.
-     * @param helper The {@link OrientationHelper} associated with the current RecyclerView.
-     * @return {@code true} if the given view is a valid snapping view; {@code false} otherwise.
-     */
-    private static boolean isValidSnapView(View view, OrientationHelper helper) {
-        return helper.getDecoratedMeasurement(view) <= helper.getTotalSpace();
-    }
-
-    /**
-     * Returns the percentage of the given view that is visible, relative to its containing
-     * RecyclerView.
-     *
-     * @param view   The View to get the percentage visible of.
-     * @param helper An {@link OrientationHelper} to aid with calculation.
-     * @return A float indicating the percentage of the given view that is visible.
-     */
-    static float getPercentageVisible(View view, OrientationHelper helper) {
-        int start = helper.getStartAfterPadding();
-        int end = helper.getEndAfterPadding();
-
-        int viewStart = helper.getDecoratedStart(view);
-        int viewEnd = helper.getDecoratedEnd(view);
-
-        if (viewStart >= start && viewEnd <= end) {
-            // The view is within the bounds of the RecyclerView, so it's fully visible.
-            return 1.f;
-        } else if (viewEnd <= start) {
-            // The view is above the visible area of the RecyclerView.
-            return 0;
-        } else if (viewStart >= end) {
-            // The view is below the visible area of the RecyclerView.
-            return 0;
-        } else if (viewStart <= start && viewEnd >= end) {
-            // The view is larger than the height of the RecyclerView.
-            return ((float) end - start) / helper.getDecoratedMeasurement(view);
-        } else if (viewStart < start) {
-            // The view is above the start of the RecyclerView.
-            return ((float) viewEnd - start) / helper.getDecoratedMeasurement(view);
-        } else {
-            // The view is below the end of the RecyclerView.
-            return ((float) end - viewStart) / helper.getDecoratedMeasurement(view);
-        }
-    }
-
-    @Override
-    public void attachToRecyclerView(@Nullable RecyclerView recyclerView) {
-        super.attachToRecyclerView(recyclerView);
-        mRecyclerView = recyclerView;
-    }
-
-    /**
-     * Returns a scroller specific to this {@code PagedSnapHelper}. This scroller is used for all
-     * smooth scrolling operations, including flings.
-     *
-     * @param layoutManager The {@link LayoutManager} associated with the attached
-     *                      {@link RecyclerView}.
-     * @return a {@link RecyclerView.SmoothScroller} which will handle the scrolling.
-     */
-    @Override
-    protected RecyclerView.SmoothScroller createScroller(@NonNull LayoutManager layoutManager) {
-        return new CarUiSmoothScroller(mContext);
-    }
-
-    /**
-     * Calculate the estimated scroll distance in each direction given velocities on both axes.
-     * This method will clamp the maximum scroll distance so that a single fling will never scroll
-     * more than one page.
-     *
-     * @param velocityX Fling velocity on the horizontal axis.
-     * @param velocityY Fling velocity on the vertical axis.
-     * @return An array holding the calculated distances in x and y directions respectively.
-     */
-    @Override
-    public int[] calculateScrollDistance(int velocityX, int velocityY) {
-        int[] outDist = super.calculateScrollDistance(velocityX, velocityY);
-
-        if (mRecyclerView == null) {
-            return outDist;
-        }
-
-        LayoutManager layoutManager = mRecyclerView.getLayoutManager();
-        if (layoutManager == null || layoutManager.getChildCount() == 0) {
-            return outDist;
-        }
-
-        int lastChildPosition = isAtEnd(layoutManager) ? 0 : layoutManager.getChildCount() - 1;
-
-        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
-        @NonNull View lastChild = Objects.requireNonNull(
-                layoutManager.getChildAt(lastChildPosition));
-        float percentageVisible = getPercentageVisible(lastChild, orientationHelper);
-
-        int maxDistance = layoutManager.getHeight();
-        if (percentageVisible > 0.f) {
-            // The max and min distance is the total height of the RecyclerView minus the height of
-            // the last child. This ensures that each scroll will never scroll more than a single
-            // page on the RecyclerView. That is, the max scroll will make the last child the
-            // first child and vice versa when scrolling the opposite way.
-            maxDistance -= layoutManager.getDecoratedMeasuredHeight(lastChild);
-        }
-
-        int minDistance = -maxDistance;
-
-        outDist[0] = clamp(outDist[0], minDistance, maxDistance);
-        outDist[1] = clamp(outDist[1], minDistance, maxDistance);
-
-        return outDist;
-    }
-
-    /**
-     * Estimates a position to which CarUiSnapHelper will try to snap to for a requested scroll
-     * distance.
-     *
-     * @param helper         The {@link OrientationHelper} that is created from the LayoutManager.
-     * @param scrollDistance The intended scroll distance.
-     *
-     * @return The diff between the target snap position and the current position.
-     */
-    public int estimateNextPositionDiffForScrollDistance(OrientationHelper helper,
-            int scrollDistance) {
-        float distancePerChild = computeDistancePerChild(helper.getLayoutManager(), helper);
-        if (distancePerChild <= 0) {
-            return 0;
-        }
-        return Math.round(scrollDistance / distancePerChild);
-    }
-
-    /**
-     * This method is taken verbatim from the [androidx] {@link LinearSnapHelper} private method
-     * implementation.
-     *
-     * Computes an average pixel value to pass a single child.
-     * <p>
-     * Returns a negative value if it cannot be calculated.
-     *
-     * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
-     *                      {@link RecyclerView}.
-     * @param helper        The relevant {@link OrientationHelper} for the attached
-     *                      {@link RecyclerView.LayoutManager}.
-     *
-     * @return A float value that is the average number of pixels needed to scroll by one view in
-     * the relevant direction.
-     */
-    private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager,
-            OrientationHelper helper) {
-        View minPosView = null;
-        View maxPosView = null;
-        int minPos = Integer.MAX_VALUE;
-        int maxPos = Integer.MIN_VALUE;
-        int childCount = layoutManager.getChildCount();
-        if (childCount == 0) {
-            return 1;
-        }
-
-        for (int i = 0; i < childCount; i++) {
-            View child = layoutManager.getChildAt(i);
-            final int pos = layoutManager.getPosition(child);
-            if (pos == RecyclerView.NO_POSITION) {
-                continue;
-            }
-            if (pos < minPos) {
-                minPos = pos;
-                minPosView = child;
-            }
-            if (pos > maxPos) {
-                maxPos = pos;
-                maxPosView = child;
-            }
-        }
-        if (minPosView == null || maxPosView == null) {
-            return 1;
-        }
-        int start = Math.min(helper.getDecoratedStart(minPosView),
-                helper.getDecoratedStart(maxPosView));
-        int end = Math.max(helper.getDecoratedEnd(minPosView),
-                helper.getDecoratedEnd(maxPosView));
-        int distance = end - start;
-        if (distance == 0) {
-            return 0;
-        }
-        return 1f * distance / ((maxPos - minPos) + 1);
-    }
-
-    /**
-     * Returns {@code true} if the RecyclerView is completely displaying the first item.
-     */
-    public boolean isAtStart(@Nullable LayoutManager layoutManager) {
-        if (layoutManager == null || layoutManager.getChildCount() == 0) {
-            return true;
-        }
-
-        @NonNull View firstChild = Objects.requireNonNull(layoutManager.getChildAt(0));
-        OrientationHelper orientationHelper =
-                layoutManager.canScrollVertically() ? getVerticalHelper(layoutManager)
-                        : getHorizontalHelper(layoutManager);
-
-        // Check that the first child is completely visible and is the first item in the list.
-        return orientationHelper.getDecoratedStart(firstChild)
-                >= orientationHelper.getStartAfterPadding() && layoutManager.getPosition(firstChild)
-                == 0;
-    }
-
-    /**
-     * Returns {@code true} if the RecyclerView is completely displaying the last item.
-     */
-    public boolean isAtEnd(@Nullable LayoutManager layoutManager) {
-        if (layoutManager == null || layoutManager.getChildCount() == 0) {
-            return true;
-        }
-
-        int childCount = layoutManager.getChildCount();
-        OrientationHelper orientationHelper =
-                layoutManager.canScrollVertically() ? getVerticalHelper(layoutManager)
-                        : getHorizontalHelper(layoutManager);
-
-        @NonNull View lastVisibleChild = Objects.requireNonNull(
-                layoutManager.getChildAt(childCount - 1));
-
-        // The list has reached the bottom if the last child that is visible is the last item
-        // in the list and it's fully shown.
-        return layoutManager.getPosition(lastVisibleChild) == (layoutManager.getItemCount() - 1)
-                && layoutManager.getDecoratedBottom(lastVisibleChild)
-                <= orientationHelper.getEndAfterPadding();
-    }
-
-    /**
-     * Returns an {@link OrientationHelper} that corresponds to the current scroll direction of the
-     * given {@link LayoutManager}.
-     */
-    @NonNull
-    private OrientationHelper getOrientationHelper(@NonNull LayoutManager layoutManager) {
-        return layoutManager.canScrollVertically()
-                ? getVerticalHelper(layoutManager)
-                : getHorizontalHelper(layoutManager);
-    }
-
-    @NonNull
-    private OrientationHelper getVerticalHelper(@NonNull LayoutManager layoutManager) {
-        if (mVerticalHelper == null || mVerticalHelper.getLayoutManager() != layoutManager) {
-            mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
-        }
-        return mVerticalHelper;
-    }
-
-    @NonNull
-    private OrientationHelper getHorizontalHelper(@NonNull LayoutManager layoutManager) {
-        if (mHorizontalHelper == null || mHorizontalHelper.getLayoutManager() != layoutManager) {
-            mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
-        }
-        return mHorizontalHelper;
-    }
-
-    /**
-     * Ensures that the given value falls between the range given by the min and max values. This
-     * method does not check that the min value is greater than or equal to the max value. If the
-     * parameters are not well-formed, this method's behavior is undefined.
-     *
-     * @param value The value to clamp.
-     * @param min   The minimum value the given value can be.
-     * @param max   The maximum value the given value can be.
-     * @return A number that falls between {@code min} or {@code max} or one of those values if the
-     * given value is less than or greater than {@code min} and {@code max} respectively.
-     */
-    private static int clamp(int value, int min, int max) {
-        return Math.max(min, Math.min(max, value));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ContentLimiting.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ContentLimiting.java
deleted file mode 100644
index 29fb159..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ContentLimiting.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import androidx.annotation.IdRes;
-import androidx.annotation.StringRes;
-
-/**
- * An interface for {@link androidx.recyclerview.widget.RecyclerView.Adapter} objects whose
- * content can be limited to a provided maximum number of items.
- */
-public interface ContentLimiting {
-
-    /**
-     * A value that indicates there should be no limit.
-     */
-    int UNLIMITED = -1;
-
-    /**
-     * Sets the maximum number of items available in the adapter. Use {@link #UNLIMITED} if
-     * the list should not be capped.
-     */
-    void setMaxItems(int maxItems);
-
-    /**
-     * Sets the message to show in the UI when the list content length is capped.
-     */
-    void setScrollingLimitedMessageResId(@StringRes int resId);
-
-    /**
-     * Returns the resource ID of a string resource that can uniquely identify the list
-     * displayed via this adapter in the UI for the purposes of mapping UXR restriction
-     * customizations to it.
-     */
-    @IdRes
-    int getConfigurationId();
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ContentLimitingAdapter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ContentLimitingAdapter.java
deleted file mode 100644
index 1a97b97..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ContentLimitingAdapter.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.util.Log;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.StringRes;
-import androidx.recyclerview.widget.RecyclerView;
-
-/**
- * A {@link RecyclerView.Adapter} that can limit its content based on a given length limit which
- * can change at run-time.
- *
- * @param <T> type of the {@link RecyclerView.ViewHolder} objects used by base classes.
- */
-public abstract class ContentLimitingAdapter<T extends RecyclerView.ViewHolder>
-        extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ContentLimiting {
-    private static final String TAG = "ContentLimitingAdapter";
-
-    private static final int SCROLLING_LIMITED_MESSAGE_VIEW_TYPE = Integer.MAX_VALUE;
-
-    private Integer mScrollingLimitedMessageResId;
-    private RangeFilter mRangeFilter = new PassThroughFilter();
-    private RecyclerView mRecyclerView;
-    private boolean mIsLimiting = false;
-
-    /**
-     * Returns the viewType value to use for the scrolling limited message views.
-     *
-     * Override this method to provide your own alternative value if {@link Integer#MAX_VALUE} is
-     * a viewType value already in-use by your adapter.
-     */
-    public int getScrollingLimitedMessageViewType() {
-        return SCROLLING_LIMITED_MESSAGE_VIEW_TYPE;
-    }
-
-    @Override
-    @NonNull
-    public final RecyclerView.ViewHolder onCreateViewHolder(
-            @NonNull ViewGroup parent, int viewType) {
-        if (viewType == getScrollingLimitedMessageViewType()) {
-            return ScrollingLimitedViewHolder.create(parent);
-        }
-
-        return onCreateViewHolderImpl(parent, viewType);
-    }
-
-    /** See {@link RangeFilter#indexToPosition}. */
-    protected int indexToPosition(int index) {
-        return mRangeFilter.indexToPosition(index);
-    }
-
-    /** See {@link RangeFilter#positionToIndex}. */
-    protected int positionToIndex(int position) {
-        return mRangeFilter.positionToIndex(position);
-    }
-
-    /**
-     * Returns a {@link androidx.recyclerview.widget.RecyclerView.ViewHolder} of type {@code T}.
-     *
-     * <p>It is delegated to by {@link #onCreateViewHolder(ViewGroup, int)} to handle any
-     * {@code viewType}s other than the one corresponding to the "scrolling is limited" message.
-     */
-    protected abstract T onCreateViewHolderImpl(
-            @NonNull ViewGroup parent, int viewType);
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public final void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
-        if (holder instanceof ScrollingLimitedViewHolder) {
-            ScrollingLimitedViewHolder vh = (ScrollingLimitedViewHolder) holder;
-            vh.bind(mScrollingLimitedMessageResId);
-        } else {
-            int index = mRangeFilter.positionToIndex(position);
-            if (index != RangeFilterImpl.INVALID_INDEX) {
-                int size = getUnrestrictedItemCount();
-                if (0 <= index && index < size) {
-                    onBindViewHolderImpl((T) holder, index);
-                } else {
-                    Log.e(TAG, "onBindViewHolder pos: " + position + " gave index: "
-                            + index + " out of bounds size: " + size
-                            + " " + mRangeFilter.toString());
-                }
-            } else {
-                Log.e(TAG, "onBindViewHolder invalid position " + position
-                        + " " + mRangeFilter.toString());
-            }
-        }
-    }
-
-    /**
-     * Binds {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}s of type {@code T}.
-     *
-     * <p>It is delegated to by {@link #onBindViewHolder(RecyclerView.ViewHolder, int)} to handle
-     * holders that are not of type {@link ScrollingLimitedViewHolder}.
-     */
-    protected abstract void onBindViewHolderImpl(T holder, int position);
-
-    @Override
-    public final int getItemViewType(int position) {
-        if (mRangeFilter.positionToIndex(position) == RangeFilterImpl.INVALID_INDEX) {
-            return getScrollingLimitedMessageViewType();
-        } else {
-            return getItemViewTypeImpl(mRangeFilter.positionToIndex(position));
-        }
-    }
-
-    /**
-     * Returns the view type of the item at {@code position}.
-     *
-     * <p>Defaults to the implementation in {@link RecyclerView.Adapter#getItemViewType(int)}.
-     *
-     * <p>It is delegated to by {@link #getItemViewType(int)} for all positions other than the
-     * {@link #getScrollingLimitedMessagePosition()}.
-     */
-    protected int getItemViewTypeImpl(int position) {
-        return super.getItemViewType(position);
-    }
-
-    /**
-     * Returns the position where the "scrolling is limited" message should be placed.
-     *
-     * <p>The default implementation is to put this item at the very end of the limited list.
-     * Subclasses can override to choose a different position to suit their needs.
-     *
-     * @deprecated limiting message offset is not supported any more.
-     */
-    @Deprecated
-    protected int getScrollingLimitedMessagePosition() {
-        return getItemCount() - 1;
-    }
-
-    @Override
-    public final int getItemCount() {
-        if (mIsLimiting) {
-            return mRangeFilter.getFilteredCount();
-        } else {
-            return getUnrestrictedItemCount();
-        }
-    }
-
-    /**
-     * Returns the number of items in the unrestricted list being displayed via this adapter.
-     */
-    protected abstract int getUnrestrictedItemCount();
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public final void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
-        super.onViewRecycled(holder);
-
-        if (!(holder instanceof ScrollingLimitedViewHolder)) {
-            onViewRecycledImpl((T) holder);
-        }
-    }
-
-    /**
-     * Recycles {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}s of type {@code T}.
-     *
-     * <p>It is delegated to by {@link #onViewRecycled(RecyclerView.ViewHolder)} to handle
-     * holders that are not of type {@link ScrollingLimitedViewHolder}.
-     */
-    @SuppressWarnings("unused")
-    protected void onViewRecycledImpl(@NonNull T holder) {
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public final boolean onFailedToRecycleView(@NonNull RecyclerView.ViewHolder holder) {
-        if (!(holder instanceof ScrollingLimitedViewHolder)) {
-            return onFailedToRecycleViewImpl((T) holder);
-        }
-        return super.onFailedToRecycleView(holder);
-    }
-
-    /**
-     * Handles failed recycle attempts for
-     * {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}s of type {@code T}.
-     *
-     * <p>It is delegated to by {@link #onFailedToRecycleView(RecyclerView.ViewHolder)} for holders
-     * that are not of type {@link ScrollingLimitedViewHolder}.
-     */
-    protected boolean onFailedToRecycleViewImpl(@NonNull T holder) {
-        return super.onFailedToRecycleView(holder);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public final void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
-        super.onViewAttachedToWindow(holder);
-        if (!(holder instanceof ScrollingLimitedViewHolder)) {
-            onViewAttachedToWindowImpl((T) holder);
-        }
-    }
-
-    /**
-     * Handles attaching {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}s of type
-     * {@code T} to the application window.
-     *
-     * <p>It is delegated to by {@link #onViewAttachedToWindow(RecyclerView.ViewHolder)} for
-     * holders that are not of type {@link ScrollingLimitedViewHolder}.
-     */
-    @SuppressWarnings("unused")
-    protected void onViewAttachedToWindowImpl(@NonNull T holder) {
-    }
-
-    @Override
-    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
-        mRecyclerView = recyclerView;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public final void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
-        super.onViewDetachedFromWindow(holder);
-        if (!(holder instanceof ScrollingLimitedViewHolder)) {
-            onViewDetachedFromWindowImpl((T) holder);
-        }
-    }
-
-    /**
-     * Handles detaching {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}s of type
-     * {@code T} from the application window.
-     *
-     * <p>It is delegated to by {@link #onViewDetachedFromWindow(RecyclerView.ViewHolder)} for
-     * holders that are not of type {@link ScrollingLimitedViewHolder}.
-     */
-    @SuppressWarnings("unused")
-    protected void onViewDetachedFromWindowImpl(@NonNull T holder) {
-    }
-
-    @Override
-    public void setMaxItems(int maxItems) {
-        if (maxItems >= 0) {
-            if (mRangeFilter != null && mIsLimiting) {
-                Log.w(TAG, "A new filter range received before parked");
-                // remove the original filter first.
-                mRangeFilter.removeFilter();
-            }
-            mIsLimiting = true;
-            mRangeFilter = new RangeFilterImpl(this, maxItems);
-            mRangeFilter.recompute(getUnrestrictedItemCount(), computeAnchorIndexWhenRestricting());
-            mRangeFilter.applyFilter();
-            autoScrollWhenRestricted();
-        } else {
-            mRangeFilter.removeFilter();
-
-            mIsLimiting = false;
-            mRangeFilter = new PassThroughFilter();
-            mRangeFilter.recompute(getUnrestrictedItemCount(), 0);
-        }
-    }
-
-    /**
-     * Returns the position in the truncated list to scroll to when the list is limited.
-     *
-     * Returns -1 to disable the scrolling.
-     */
-    protected int getScrollToPositionWhenRestricted() {
-        return -1;
-    }
-
-    private void autoScrollWhenRestricted() {
-        int scrollToPosition = getScrollToPositionWhenRestricted();
-        if (scrollToPosition >= 0 && mRecyclerView != null) {
-            RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager();
-            if (layoutManager != null) {
-                layoutManager.scrollToPosition(scrollToPosition);
-            }
-        }
-    }
-
-    /**
-     * Computes the anchor point index in the original list when limiting starts.
-     * Returns position 0 by default.
-     *
-     * Override this function to return a different anchor point to control the position of the
-     * limiting window.
-     */
-    protected int computeAnchorIndexWhenRestricting() {
-        return 0;
-    }
-
-    /**
-     * Updates the changes from underlying data along with a new anchor.
-     */
-    public void updateUnderlyingDataChanged(int unrestrictedCount, int newAnchorIndex) {
-        mRangeFilter.recompute(unrestrictedCount, newAnchorIndex);
-    }
-
-    /**
-     * Changes the index where the limiting range surrounds. Items that are added and removed will
-     * be notified.
-     */
-    public void notifyLimitingAnchorChanged(int newPivotIndex) {
-        mRangeFilter.notifyPivotIndexChanged(newPivotIndex);
-    }
-
-    @Override
-    public void setScrollingLimitedMessageResId(@StringRes int resId) {
-        if (mScrollingLimitedMessageResId == null || mScrollingLimitedMessageResId != resId) {
-            mScrollingLimitedMessageResId = resId;
-            mRangeFilter.invalidateMessagePositions();
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DefaultScrollBar.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DefaultScrollBar.java
deleted file mode 100644
index 698f8ae..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DefaultScrollBar.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.Interpolator;
-
-import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.OrientationHelper;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.LayoutManager;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-/**
- * The default scroll bar widget for the {@link CarUiRecyclerView}.
- *
- * <p>Inspired by {@link androidx.car.widget.PagedListView}. Most pagination and scrolling logic
- * has been ported from the PLV with minor updates.
- */
-class DefaultScrollBar implements ScrollBar {
-
-
-    private float mButtonDisabledAlpha;
-    private CarUiSnapHelper mSnapHelper;
-
-    private View mScrollView;
-    private View mScrollTrack;
-    private View mScrollThumb;
-    private View mUpButton;
-    private View mDownButton;
-    private int mScrollbarThumbMinHeight;
-
-    private RecyclerView mRecyclerView;
-
-    private final Interpolator mPaginationInterpolator = new AccelerateDecelerateInterpolator();
-
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-
-    private OrientationHelper mOrientationHelper;
-
-    private OnContinuousScrollListener mPageUpOnContinuousScrollListener;
-    private OnContinuousScrollListener mPageDownOnContinuousScrollListener;
-
-    @Override
-    public void initialize(RecyclerView rv, View scrollView) {
-        mRecyclerView = rv;
-
-        mScrollView = scrollView;
-
-        Resources res = rv.getContext().getResources();
-
-        mButtonDisabledAlpha = CarUiUtils.getFloat(res, R.dimen.car_ui_button_disabled_alpha);
-        mScrollbarThumbMinHeight = (int) rv.getContext().getResources()
-                .getDimension(R.dimen.car_ui_scrollbar_min_thumb_height);
-
-        mUpButton = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_page_up);
-        View.OnClickListener paginateUpButtonOnClickListener = v -> pageUp();
-        mUpButton.setOnClickListener(paginateUpButtonOnClickListener);
-        mPageUpOnContinuousScrollListener = new OnContinuousScrollListener(rv.getContext(),
-                paginateUpButtonOnClickListener);
-        mUpButton.setOnTouchListener(mPageUpOnContinuousScrollListener);
-
-        mDownButton = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_page_down);
-        View.OnClickListener paginateDownButtonOnClickListener = v -> pageDown();
-        mDownButton.setOnClickListener(paginateDownButtonOnClickListener);
-        mPageDownOnContinuousScrollListener = new OnContinuousScrollListener(rv.getContext(),
-                paginateDownButtonOnClickListener);
-        mDownButton.setOnTouchListener(mPageDownOnContinuousScrollListener);
-
-        mScrollTrack = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_track);
-        mScrollThumb = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_thumb);
-
-        mSnapHelper = new CarUiSnapHelper(rv.getContext());
-        getRecyclerView().setOnFlingListener(null);
-        mSnapHelper.attachToRecyclerView(getRecyclerView());
-
-        // enables fast scrolling.
-        FastScroller fastScroller = new FastScroller(mRecyclerView, mScrollTrack, mScrollView);
-        fastScroller.enable();
-
-        getRecyclerView().addOnScrollListener(mRecyclerViewOnScrollListener);
-
-        mScrollView.setVisibility(View.INVISIBLE);
-        mScrollView.addOnLayoutChangeListener(
-                (View v,
-                        int left,
-                        int top,
-                        int right,
-                        int bottom,
-                        int oldLeft,
-                        int oldTop,
-                        int oldRight,
-                        int oldBottom) -> mHandler.post(this::updatePaginationButtons));
-    }
-
-    public RecyclerView getRecyclerView() {
-        return mRecyclerView;
-    }
-
-    @Override
-    public void requestLayout() {
-        mScrollView.requestLayout();
-    }
-
-    @Override
-    public void setPadding(int paddingStart, int paddingEnd) {
-        mScrollView.setPadding(mScrollView.getPaddingLeft(), paddingStart,
-                mScrollView.getPaddingRight(), paddingEnd);
-    }
-
-    @Override
-    public void adapterChanged(@Nullable RecyclerView.Adapter adapter) {
-        try {
-            if (mRecyclerView.getAdapter() != null) {
-                mRecyclerView.getAdapter().unregisterAdapterDataObserver(mAdapterChangeObserver);
-            }
-            if (adapter != null) {
-                adapter.registerAdapterDataObserver(mAdapterChangeObserver);
-            }
-        } catch (IllegalStateException e) {
-            // adapter is already registered. and we're trying to register again.
-            // or adapter was not registered and we're trying to unregister again.
-            // ignore.
-        }
-    }
-
-    /**
-     * Sets whether or not the up button on the scroll bar is clickable.
-     *
-     * @param enabled {@code true} if the up button is enabled.
-     */
-    private void setUpEnabled(boolean enabled) {
-        // If the button is held down the button is disabled, the MotionEvent.ACTION_UP event on
-        // button release will not be sent to cancel pending scrolls. Manually cancel any pending
-        // scroll.
-        if (!enabled) {
-            mPageUpOnContinuousScrollListener.cancelPendingScroll();
-        }
-
-        mUpButton.setEnabled(enabled);
-        mUpButton.setAlpha(enabled ? 1f : mButtonDisabledAlpha);
-    }
-
-    /**
-     * Sets whether or not the down button on the scroll bar is clickable.
-     *
-     * @param enabled {@code true} if the down button is enabled.
-     */
-    private void setDownEnabled(boolean enabled) {
-        // If the button is held down the button is disabled, the MotionEvent.ACTION_UP event on
-        // button release will not be sent to cancel pending scrolls. Manually cancel any pending
-        // scroll.
-        if (!enabled) {
-            mPageDownOnContinuousScrollListener.cancelPendingScroll();
-        }
-
-        mDownButton.setEnabled(enabled);
-        mDownButton.setAlpha(enabled ? 1f : mButtonDisabledAlpha);
-    }
-
-    /**
-     * Returns whether or not the down button on the scroll bar is clickable.
-     *
-     * @return {@code true} if the down button is enabled. {@code false} otherwise.
-     */
-    private boolean isDownEnabled() {
-        return mDownButton.isEnabled();
-    }
-
-    /**
-     * Sets the range, offset and extent of the scroll bar. The range represents the size of a
-     * container for the scrollbar thumb; offset is the distance from the start of the container to
-     * where the thumb should be; and finally, extent is the size of the thumb.
-     *
-     * <p>These values can be expressed in arbitrary units, so long as they share the same units.
-     * The values should also be positive.
-     *
-     * @param range  The range of the scrollbar's thumb
-     * @param offset The offset of the scrollbar's thumb
-     * @param extent The extent of the scrollbar's thumb
-     */
-    private void setParameters(
-            @IntRange(from = 0) int range,
-            @IntRange(from = 0) int offset,
-            @IntRange(from = 0) int extent) {
-        // Not laid out yet, so values cannot be calculated.
-        if (!mScrollView.isLaidOut()) {
-            return;
-        }
-
-        // If the scroll bars aren't visible, then no need to update.
-        if (mScrollView.getVisibility() != View.VISIBLE || range == 0) {
-            return;
-        }
-
-        int thumbLength = calculateScrollThumbLength(range, extent);
-        int thumbOffset = calculateScrollThumbOffset(range, offset, thumbLength);
-
-        // Sets the size of the thumb and request a redraw if needed.
-        ViewGroup.LayoutParams lp = mScrollThumb.getLayoutParams();
-
-        if (lp.height != thumbLength || thumbLength < mScrollThumb.getHeight()) {
-            lp.height = thumbLength;
-            mScrollThumb.requestLayout();
-        }
-
-        moveY(mScrollThumb, thumbOffset);
-    }
-
-    /**
-     * Calculates and returns how big the scroll bar thumb should be based on the given range and
-     * extent.
-     *
-     * @param range  The total amount of space the scroll bar is allowed to roam over.
-     * @param extent The amount of space that the scroll bar takes up relative to the range.
-     * @return The height of the scroll bar thumb in pixels.
-     */
-    private int calculateScrollThumbLength(int range, int extent) {
-        // Scale the length by the available space that the thumb can fill.
-        return max(Math.round(((float) extent / range) * mScrollTrack.getHeight()),
-                min(mScrollbarThumbMinHeight, mScrollTrack.getHeight()));
-    }
-
-    /**
-     * Calculates and returns how much the scroll thumb should be offset from the top of where it
-     * has been laid out.
-     *
-     * @param range       The total amount of space the scroll bar is allowed to roam over.
-     * @param offset      The amount the scroll bar should be offset, expressed in the same units as
-     *                    the given range.
-     * @param thumbLength The current length of the thumb in pixels.
-     * @return The amount the thumb should be offset in pixels.
-     */
-    private int calculateScrollThumbOffset(int range, int offset, int thumbLength) {
-        // Ensure that if the user has reached the bottom of the list, then the scroll bar is
-        // aligned to the bottom as well. Otherwise, scale the offset appropriately.
-        // This offset will be a value relative to the parent of this scrollbar, so start by where
-        // the top of scrollbar track is.
-        return mScrollTrack.getTop()
-                + (isDownEnabled()
-                ? Math.round(((float) offset / range) * (mScrollTrack.getHeight() - thumbLength))
-                : mScrollTrack.getHeight() - thumbLength);
-    }
-
-    /**
-     * Moves the given view to the specified 'y' position.
-     */
-    private void moveY(final View view, float newPosition) {
-        view.animate()
-                .y(newPosition)
-                .setDuration(/* duration= */ 0)
-                .setInterpolator(mPaginationInterpolator)
-                .start();
-    }
-
-    private final RecyclerView.OnScrollListener mRecyclerViewOnScrollListener =
-            new RecyclerView.OnScrollListener() {
-                @Override
-                public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
-                    updatePaginationButtons();
-                    cacheChildrenHeight(recyclerView.getLayoutManager());
-                }
-            };
-    private final SparseArray<Integer> mChildHeightByAdapterPosition = new SparseArray();
-
-    private final RecyclerView.AdapterDataObserver mAdapterChangeObserver =
-            new RecyclerView.AdapterDataObserver() {
-                @Override
-                public void onChanged() {
-                    clearCachedHeights();
-                }
-                @Override
-                public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
-                    clearCachedHeights();
-                }
-                @Override
-                public void onItemRangeChanged(int positionStart, int itemCount) {
-                    clearCachedHeights();
-                }
-                @Override
-                public void onItemRangeInserted(int positionStart, int itemCount) {
-                    clearCachedHeights();
-                }
-                @Override
-                public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-                    clearCachedHeights();
-                }
-                @Override
-                public void onItemRangeRemoved(int positionStart, int itemCount) {
-                    clearCachedHeights();
-                }
-            };
-
-    private void clearCachedHeights() {
-        mChildHeightByAdapterPosition.clear();
-        cacheChildrenHeight(getLayoutManager());
-    }
-
-    private void cacheChildrenHeight(@Nullable RecyclerView.LayoutManager layoutManager) {
-        if (layoutManager == null) {
-            return;
-        }
-        for (int i = 0; i < layoutManager.getChildCount(); i++) {
-            View child = layoutManager.getChildAt(i);
-            int childPosition = layoutManager.getPosition(child);
-            if (mChildHeightByAdapterPosition.indexOfKey(childPosition) < 0) {
-                mChildHeightByAdapterPosition.put(childPosition, child.getHeight());
-            }
-        }
-    }
-
-    private int estimateNextPositionScrollUp(int currentPos, int scrollDistance,
-            OrientationHelper orientationHelper) {
-        int nextPos = 0;
-        int distance = 0;
-        for (int i = currentPos - 1; i >= 0; i--) {
-            if (mChildHeightByAdapterPosition.indexOfKey(i) < 0) {
-                // Use the average height estimate when there is not enough data
-                nextPos = mSnapHelper.estimateNextPositionDiffForScrollDistance(
-                        orientationHelper, -scrollDistance);
-                break;
-            }
-            if ((distance + mChildHeightByAdapterPosition.get(i)) > Math.abs(scrollDistance)) {
-                nextPos = i - currentPos + 1;
-                break;
-            }
-            distance += mChildHeightByAdapterPosition.get(i);
-        }
-        return nextPos;
-    }
-
-    private OrientationHelper getOrientationHelper(RecyclerView.LayoutManager layoutManager) {
-        if (mOrientationHelper == null || mOrientationHelper.getLayoutManager() != layoutManager) {
-            // CarUiRecyclerView is assumed to be a list that always vertically scrolls.
-            mOrientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
-        }
-        return mOrientationHelper;
-    }
-
-    /**
-     * Scrolls the contents of the RecyclerView up a page. A page is defined as the height of the
-     * {@code CarUiRecyclerView}.
-     *
-     * <p>The resulting first item in the list will be snapped to so that it is completely visible.
-     * If this is not possible due to the first item being taller than the containing {@code
-     * CarUiRecyclerView}, then the snapping will not occur.
-     */
-    void pageUp() {
-        int currentOffset = computeVerticalScrollOffset();
-        RecyclerView.LayoutManager layoutManager = getLayoutManager();
-        if (layoutManager == null || layoutManager.getChildCount() == 0 || currentOffset == 0) {
-            return;
-        }
-
-        // Use OrientationHelper to calculate scroll distance in order to match snapping behavior.
-        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
-        int scrollDistance = orientationHelper.getTotalSpace();
-
-        View currentPosView = getFirstMostVisibleChild(orientationHelper);
-        int currentPos = currentPosView != null ? getLayoutManager().getPosition(
-                currentPosView) : 0;
-        int nextPos = estimateNextPositionScrollUp(currentPos,
-                scrollDistance - Math.max(0, orientationHelper.getStartAfterPadding()
-                        - orientationHelper.getDecoratedStart(currentPosView)), orientationHelper);
-        if (nextPos == 0) {
-            // Distance should always be positive. Negate its value to scroll up.
-            smoothScrollBy(0, -scrollDistance);
-        } else {
-            smoothScrollToPosition(Math.max(0, currentPos + nextPos));
-        }
-    }
-
-    private View getFirstMostVisibleChild(OrientationHelper helper) {
-        float mostVisiblePercent = 0;
-        View mostVisibleView = null;
-
-        for (int i = 0; i < getLayoutManager().getChildCount(); i++) {
-            View child = getLayoutManager().getChildAt(i);
-            float visiblePercentage = CarUiSnapHelper.getPercentageVisible(child, helper);
-            if (visiblePercentage == 1f) {
-                mostVisibleView = child;
-                break;
-            } else if (visiblePercentage > mostVisiblePercent) {
-                mostVisiblePercent = visiblePercentage;
-                mostVisibleView = child;
-            }
-        }
-
-        return mostVisibleView;
-    }
-
-    /**
-     * Scrolls the contents of the RecyclerView down a page. A page is defined as the height of the
-     * {@code CarUiRecyclerView}.
-     *
-     * <p>This method will attempt to bring the last item in the list as the first item. If the
-     * current first item in the list is taller than the {@code CarUiRecyclerView}, then it will be
-     * scrolled the length of a page, but not snapped to.
-     */
-    void pageDown() {
-        RecyclerView.LayoutManager layoutManager = getLayoutManager();
-        if (layoutManager == null || layoutManager.getChildCount() == 0) {
-            return;
-        }
-
-        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
-        int screenSize = orientationHelper.getTotalSpace();
-        int scrollDistance = screenSize;
-
-        View currentPosView = getFirstMostVisibleChild(orientationHelper);
-
-        // If current view is partially visible and bottom of the view is below visible area of
-        // the recyclerview either scroll down one page (screenSize) or enough to align the bottom
-        // of the view with the bottom of the recyclerview. Note that this will not cause a snap,
-        // because the current view is already snapped to the top or it wouldn't be the most
-        // visible view.
-        if (layoutManager.isViewPartiallyVisible(currentPosView,
-                /* completelyVisible= */ false, /* acceptEndPointInclusion= */ false)
-                        && orientationHelper.getDecoratedEnd(currentPosView)
-                                > orientationHelper.getEndAfterPadding()) {
-            scrollDistance = Math.min(screenSize,
-                    orientationHelper.getDecoratedEnd(currentPosView)
-                            - orientationHelper.getEndAfterPadding());
-        }
-
-        // Iterate over the childview (bottom to top) and stop when we find the first
-        // view that we can snap to and the scroll size is less than max scroll size (screenSize)
-        for (int i = layoutManager.getChildCount() - 1; i >= 0; i--) {
-            View child = layoutManager.getChildAt(i);
-
-            // Ignore the child if it's above the currentview, as scrolldown will only move down.
-            // Note that in case of gridview, child will not be the same as the currentview.
-            if (orientationHelper.getDecoratedStart(child)
-                    <= orientationHelper.getDecoratedStart(currentPosView)) {
-                break;
-            }
-
-            // Ignore the child if the scroll distance is bigger than the max scroll size
-            if (orientationHelper.getDecoratedStart(child)
-                    - orientationHelper.getStartAfterPadding() <= screenSize) {
-                // If the child is already fully visible we can scroll even further.
-                if (orientationHelper.getDecoratedEnd(child)
-                        <= orientationHelper.getEndAfterPadding()) {
-                    scrollDistance = orientationHelper.getDecoratedEnd(child)
-                            - orientationHelper.getStartAfterPadding();
-                } else {
-                    scrollDistance = orientationHelper.getDecoratedStart(child)
-                            - orientationHelper.getStartAfterPadding();
-                }
-                break;
-            }
-        }
-
-        smoothScrollBy(0, scrollDistance);
-    }
-
-    /**
-     * Determines if scrollbar should be visible or not and shows/hides it accordingly. If this is
-     * being called as a result of adapter changes, it should be called after the new layout has
-     * been calculated because the method of determining scrollbar visibility uses the current
-     * layout. If this is called after an adapter change but before the new layout, the visibility
-     * determination may not be correct.
-     */
-    private void updatePaginationButtons() {
-        RecyclerView.LayoutManager layoutManager = getLayoutManager();
-
-        if (layoutManager == null) {
-            mScrollView.setVisibility(View.INVISIBLE);
-            return;
-        }
-
-        boolean isAtStart = isAtStart();
-        boolean isAtEnd = isAtEnd();
-
-        // enable/disable the button before the view is shown. So there is no flicker.
-        setUpEnabled(!isAtStart);
-        setDownEnabled(!isAtEnd);
-
-        if ((isAtStart && isAtEnd) || layoutManager.getItemCount() == 0) {
-            mScrollView.setVisibility(View.INVISIBLE);
-        } else {
-            OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
-            int screenSize = orientationHelper.getTotalSpace();
-            int touchTargetSize = (int) getRecyclerView().getContext().getResources()
-                    .getDimension(R.dimen.car_ui_touch_target_size);
-            ViewGroup.MarginLayoutParams upButtonLayoutParam =
-                    (ViewGroup.MarginLayoutParams) mUpButton.getLayoutParams();
-            int upButtonMargin = upButtonLayoutParam.topMargin
-                    + upButtonLayoutParam.bottomMargin;
-            ViewGroup.MarginLayoutParams downButtonLayoutParam =
-                    (ViewGroup.MarginLayoutParams) mDownButton.getLayoutParams();
-            int downButtonMargin = downButtonLayoutParam.topMargin
-                    + downButtonLayoutParam.bottomMargin;
-            int margin = upButtonMargin + downButtonMargin;
-            if (screenSize < 2 * touchTargetSize + margin) {
-                mScrollView.setVisibility(View.INVISIBLE);
-            } else {
-                ViewGroup.MarginLayoutParams trackLayoutParam =
-                        (ViewGroup.MarginLayoutParams) mScrollTrack.getLayoutParams();
-                int trackMargin = trackLayoutParam.topMargin
-                        + trackLayoutParam.bottomMargin;
-                margin += trackMargin;
-                // touchTargetSize (for up button) + touchTargetSize (for down button)
-                // + max(touchTargetSize, mScrollbarThumbMinHeight)
-                // + margin (all margins added together)
-                if (screenSize < 2 * touchTargetSize
-                        + max(touchTargetSize, mScrollbarThumbMinHeight) + margin) {
-                    mScrollTrack.setVisibility(View.INVISIBLE);
-                    mScrollThumb.setVisibility(View.INVISIBLE);
-                } else {
-                    mScrollTrack.setVisibility(View.VISIBLE);
-                    mScrollThumb.setVisibility(View.VISIBLE);
-                }
-                mScrollView.setVisibility(View.VISIBLE);
-            }
-        }
-
-        if (layoutManager.canScrollVertically()) {
-            setParameters(
-                    computeVerticalScrollRange(),
-                    computeVerticalScrollOffset(),
-                    computeVerticalScrollExtent());
-        } else {
-            setParameters(
-                    computeHorizontalScrollRange(),
-                    computeHorizontalScrollOffset(),
-                    computeHorizontalScrollExtent());
-        }
-
-        mScrollView.invalidate();
-    }
-
-    /**
-     * Returns {@code true} if the RecyclerView is completely displaying the first item.
-     */
-    @Override
-    public boolean isAtStart() {
-        return mSnapHelper.isAtStart(getLayoutManager());
-    }
-
-    @Override
-    public void setHighlightThumb(boolean highlight) {
-        mScrollThumb.setActivated(highlight);
-    }
-
-    /**
-     * Returns {@code true} if the RecyclerView is completely displaying the last item.
-     */
-    boolean isAtEnd() {
-        return mSnapHelper.isAtEnd(getLayoutManager());
-    }
-
-    @VisibleForTesting
-    LayoutManager getLayoutManager() {
-        return getRecyclerView().getLayoutManager();
-    }
-
-    @VisibleForTesting
-    void smoothScrollToPosition(int max) {
-        getRecyclerView().smoothScrollToPosition(max);
-    }
-
-    @VisibleForTesting
-    void smoothScrollBy(int dx, int dy) {
-        getRecyclerView().smoothScrollBy(dx, dy);
-    }
-
-    @VisibleForTesting
-    int computeVerticalScrollRange() {
-        return getRecyclerView().computeVerticalScrollRange();
-    }
-
-    @VisibleForTesting
-    int computeVerticalScrollOffset() {
-        return getRecyclerView().computeVerticalScrollOffset();
-    }
-
-    @VisibleForTesting
-    int computeVerticalScrollExtent() {
-        return getRecyclerView().computeVerticalScrollExtent();
-    }
-
-    @VisibleForTesting
-    int computeHorizontalScrollRange() {
-        return getRecyclerView().computeHorizontalScrollRange();
-    }
-
-    @VisibleForTesting
-    int computeHorizontalScrollOffset() {
-        return getRecyclerView().computeHorizontalScrollOffset();
-    }
-
-    @VisibleForTesting
-    int computeHorizontalScrollExtent() {
-        return getRecyclerView().computeHorizontalScrollExtent();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapter.java
deleted file mode 100644
index 62d9feb..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapter.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.view.ViewGroup;
-
-import androidx.annotation.IdRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-/**
- * A delegating implementation of {@link ContentLimiting} interface.
- *
- * <p>This class will provide content limiting capability to any {@link RecyclerView.Adapter} that
- * is wrapped in it.
- *
- * @param <T> type of the {@link RecyclerView.ViewHolder} objects used by the delegate.
- */
-public class DelegatingContentLimitingAdapter<T extends RecyclerView.ViewHolder>
-        extends ContentLimitingAdapter<T> {
-    private static final int SCROLLING_LIMITED_MESSAGE_VIEW_TYPE = Integer.MAX_VALUE;
-    private static final int SCROLLING_LIMITED_MESSAGE_DEFAULT_POSITION_OFFSET = -1;
-
-    private final RecyclerView.Adapter<T> mDelegate;
-    private final int mScrollingLimitedMessageViewType;
-    private final int mScrollingLimitedMessagePositionOffset;
-    @IdRes
-    private final int mConfigId;
-    @NonNull
-    private final Observer mAdapterDataObserver;
-
-    /**
-     * Provides the abilities to delegate {@link ContentLimitingAdapter} callback functions.
-     */
-    public interface ContentLimiting {
-        /**
-         * @see ContentLimitingAdapter#getScrollToPositionWhenRestricted()
-         */
-        int getScrollToPositionWhenRestricted();
-
-        /**
-         * @see ContentLimitingAdapter#computeAnchorIndexWhenRestricting()
-         */
-        int computeAnchorIndexWhenRestricting();
-    }
-
-    /**
-     * Constructs a {@link DelegatingContentLimitingAdapter} that uses {@link Integer#MAX_VALUE}
-     * for the scrolling limited message viewType and positions it at the very bottom of the list
-     * being content limited.
-     *
-     * <p>Use {@link #DelegatingContentLimitingAdapter(RecyclerView.Adapter, int, int, int)} if you
-     * need to customize any of the two default values above.
-     *
-     * @param delegate - the {@link RecyclerView.Adapter} whose content needs to be limited.
-     * @param configId - an Id Resource that can be used to identify said adapter.
-     */
-    public DelegatingContentLimitingAdapter(
-            RecyclerView.Adapter<T> delegate,
-            @IdRes int configId) {
-        this(delegate,
-                configId,
-                SCROLLING_LIMITED_MESSAGE_VIEW_TYPE,
-                SCROLLING_LIMITED_MESSAGE_DEFAULT_POSITION_OFFSET);
-    }
-
-    /**
-     * Constructs a {@link DelegatingContentLimitingAdapter}.
-     *
-     * @param delegate - the {@link RecyclerView.Adapter} whose content needs to be limited.
-     * @param configId - an Id Resource that can be used to identify said adapter.
-     * @param viewType - viewType value for the scrolling limited message
-     * @param offset   - offset of the position of the scrolling limited message. Negative values
-     *                 will be treated as a "bottom offset", i.e. they represent the value to
-     *                 subtract from {@link #getItemCount()} to get to the actual position of the
-     *                 message. For example, by default the offset is -1, meaning the position of
-     *                 the scrolling limited message will be getItemCount() - 1, which in a list
-     *                 indexed at 0 means the very last item. Positive values will be treated as
-     *                 "top offset", so an offset of 0 will put the scrolling limited message at the
-     *                 very top of the list.
-     * @deprecated offset is not supported in the {@link ContentLimitingAdapter} any more.
-     */
-    @Deprecated
-    public DelegatingContentLimitingAdapter(RecyclerView.Adapter<T> delegate,
-            @IdRes int configId,
-            int viewType,
-            int offset) {
-        mDelegate = delegate;
-        mConfigId = configId;
-        mScrollingLimitedMessageViewType = viewType;
-        mScrollingLimitedMessagePositionOffset = offset;
-        mAdapterDataObserver = new Observer();
-    }
-
-    @Override
-    public void registerAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) {
-        if (!hasObservers()) {
-            mDelegate.registerAdapterDataObserver(mAdapterDataObserver);
-        }
-        super.registerAdapterDataObserver(observer);
-    }
-
-    @Override
-    public void unregisterAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) {
-        super.unregisterAdapterDataObserver(observer);
-
-        if (!hasObservers()) {
-            mDelegate.unregisterAdapterDataObserver(mAdapterDataObserver);
-        }
-    }
-
-    private class Observer extends RecyclerView.AdapterDataObserver {
-
-        @Override
-        public void onChanged() {
-            DelegatingContentLimitingAdapter.this.notifyDataSetChanged();
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount) {
-            DelegatingContentLimitingAdapter.this
-                    .notifyItemRangeChanged(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
-            DelegatingContentLimitingAdapter.this
-                    .notifyItemRangeChanged(positionStart, itemCount, payload);
-        }
-
-        @Override
-        public void onItemRangeInserted(int positionStart, int itemCount) {
-            DelegatingContentLimitingAdapter.this
-                    .notifyItemRangeInserted(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemRangeRemoved(int positionStart, int itemCount) {
-            DelegatingContentLimitingAdapter.this
-                    .notifyItemRangeRemoved(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-            DelegatingContentLimitingAdapter.this.notifyDataSetChanged();
-        }
-    }
-
-    @Override
-    @NonNull
-    public T onCreateViewHolderImpl(@NonNull ViewGroup parent, int viewType) {
-        return mDelegate.onCreateViewHolder(parent, viewType);
-    }
-
-    @Override
-    public void onBindViewHolderImpl(T holder, int position) {
-        mDelegate.onBindViewHolder(holder, position);
-    }
-
-    @Override
-    public int getItemViewTypeImpl(int position) {
-        return mDelegate.getItemViewType(position);
-    }
-
-    @Override
-    protected void onViewRecycledImpl(@NonNull T holder) {
-        mDelegate.onViewRecycled(holder);
-    }
-
-    @Override
-    protected boolean onFailedToRecycleViewImpl(@NonNull T holder) {
-        return mDelegate.onFailedToRecycleView(holder);
-    }
-
-    @Override
-    protected void onViewAttachedToWindowImpl(@NonNull T holder) {
-        mDelegate.onViewAttachedToWindow(holder);
-    }
-
-    @Override
-    protected void onViewDetachedFromWindowImpl(@NonNull T holder) {
-        mDelegate.onViewDetachedFromWindow(holder);
-    }
-
-    @Override
-    public void setHasStableIds(boolean hasStableIds) {
-        mDelegate.setHasStableIds(hasStableIds);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return mDelegate.getItemId(position);
-    }
-
-    @Override
-    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
-        super.onAttachedToRecyclerView(recyclerView);
-        mDelegate.onAttachedToRecyclerView(recyclerView);
-    }
-
-    @Override
-    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
-        super.onDetachedFromRecyclerView(recyclerView);
-        mDelegate.onDetachedFromRecyclerView(recyclerView);
-    }
-
-    @Override
-    protected int computeAnchorIndexWhenRestricting() {
-        if (mDelegate instanceof DelegatingContentLimitingAdapter.ContentLimiting) {
-            return ((DelegatingContentLimitingAdapter.ContentLimiting) mDelegate)
-                    .computeAnchorIndexWhenRestricting();
-        } else {
-            return 0;
-        }
-    }
-
-    @Override
-    protected int getScrollToPositionWhenRestricted() {
-        if (mDelegate instanceof DelegatingContentLimitingAdapter.ContentLimiting) {
-            return ((DelegatingContentLimitingAdapter.ContentLimiting) mDelegate)
-                    .getScrollToPositionWhenRestricted();
-        } else {
-            return -1;
-        }
-    }
-
-    @Override
-    public int getUnrestrictedItemCount() {
-        return mDelegate.getItemCount();
-    }
-
-    @Override
-    @IdRes
-    public int getConfigurationId() {
-        return mConfigId;
-    }
-
-    @Override
-    public int getScrollingLimitedMessageViewType() {
-        return mScrollingLimitedMessageViewType;
-    }
-
-    @Override
-    protected int getScrollingLimitedMessagePosition() {
-        if (mScrollingLimitedMessagePositionOffset < 0) {
-            // For negative values, treat them as a bottom offset.
-            return getItemCount() + mScrollingLimitedMessagePositionOffset;
-        } else {
-            // For positive values, treat them like a top offset.
-            return mScrollingLimitedMessagePositionOffset;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/FastScroller.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/FastScroller.java
deleted file mode 100644
index 0a60090..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/FastScroller.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-
-/**
- * Class responsible for fast scrolling. This class offers two functionalities.
- * <ul>
- *     <li>User can hold the thumb and drag.</li>
- *     <li>User can click anywhere on the track and thumb will scroll to that position.</li>
- * </ul>
- */
-class FastScroller implements View.OnTouchListener {
-
-    private float mTouchDownY = -1;
-
-    @NonNull
-    private final View mScrollTrackView;
-    @NonNull
-    private final View mScrollThumb;
-    @NonNull
-    private final RecyclerView mRecyclerView;
-    private final int mClickActionThreshold;
-
-    FastScroller(@NonNull RecyclerView recyclerView, @NonNull View scrollTrackView,
-            @NonNull View scrollView) {
-        mRecyclerView = recyclerView;
-        mScrollTrackView = scrollTrackView;
-        mScrollThumb = requireViewByRefId(scrollView, R.id.car_ui_scrollbar_thumb);
-        mClickActionThreshold = ViewConfiguration.get(
-                recyclerView.getContext()).getScaledTouchSlop();
-    }
-
-    void enable() {
-        mScrollTrackView.setOnTouchListener(this);
-    }
-
-    @Override
-    public boolean onTouch(View v, MotionEvent me) {
-        switch (me.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mTouchDownY = me.getY();
-                break;
-            case MotionEvent.ACTION_MOVE:
-                float thumbBottom = mScrollThumb.getY() + mScrollThumb.getHeight();
-                // check if the move coordinates are within the bounds of the thumb. i.e user is
-                // holding and dragging the thumb.
-                if (!(me.getY() + mScrollTrackView.getY() < thumbBottom
-                        && me.getY() + mScrollTrackView.getY() > mScrollThumb.getY())) {
-                    // don't do anything if touch is detected outside the thumb
-                    return true;
-                }
-                // calculate where the center of the thumb is on the screen.
-                float thumbCenter = mScrollThumb.getY() + mScrollThumb.getHeight() / 2.0f;
-                // me.getY() returns the coordinates relative to the view. For example, if we
-                // click the top left of the scroll track the coordinates will be 0,0. Hence, we
-                // need to add the relative coordinates to the actual coordinates computed by the
-                // thumb center and add them to get the final Y coordinate. "(me.getY() -
-                // mTouchDownY)" calculates the distance that is moved from the previous touch
-                // event.
-                verticalScrollTo(thumbCenter + (me.getY() - mTouchDownY));
-                mTouchDownY = me.getY();
-                break;
-            case MotionEvent.ACTION_UP:
-            default:
-                if (isClick(mTouchDownY, me.getY())) {
-                    verticalScrollTo(me.getY() + mScrollTrackView.getY());
-                }
-                mTouchDownY = -1;
-        }
-        return true;
-    }
-
-    /**
-     * Checks if the start and end points are within the threshold to be considered as a click.
-     */
-    private boolean isClick(float startY, float endY) {
-        return Math.abs(startY - endY) < mClickActionThreshold;
-    }
-
-    private void verticalScrollTo(float y) {
-        int scrollingBy = calculateScrollDistance(y);
-        if (scrollingBy != 0) {
-            mRecyclerView.scrollBy(0, scrollingBy);
-        }
-    }
-
-    private int calculateScrollDistance(float newDragPos) {
-        final int[] scrollbarRange = getVerticalRange();
-        int scrollbarLength = scrollbarRange[1] - scrollbarRange[0];
-
-        float thumbCenter = mScrollThumb.getY() + mScrollThumb.getHeight() / 2.0f;
-
-        if (scrollbarLength == 0) {
-            return 0;
-        }
-        // percentage of data to be scrolled.
-        float percentage = ((newDragPos - thumbCenter) / (float) scrollbarLength);
-        int totalPossibleOffset =
-                mRecyclerView.computeVerticalScrollRange() - mRecyclerView.getHeight();
-        return (int) (percentage * totalPossibleOffset);
-    }
-
-    /**
-     * Gets the (min, max) vertical positions of the vertical scroll bar. The range starts from the
-     * center of thumb when thumb is top aligned to center of the thumb when thumb is bottom
-     * aligned.
-     */
-    private int[] getVerticalRange() {
-        int[] verticalRange = new int[2];
-        verticalRange[0] = (int) mScrollTrackView.getY() + mScrollThumb.getHeight() / 2;
-        verticalRange[1] = (int) mScrollTrackView.getY() + mScrollTrackView.getHeight()
-                - mScrollThumb.getHeight() / 2;
-        return verticalRange;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/OnContinuousScrollListener.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/OnContinuousScrollListener.java
deleted file mode 100644
index 5b5d616..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/OnContinuousScrollListener.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnTouchListener;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.ui.R;
-
-/**
- * A class, that can be used as a TouchListener on any view (e.g. a Button). It periodically calls
- * the provided clickListener. The first callback is fired after the initial Delay, and subsequent
- * ones after the defined interval.
- */
-public class OnContinuousScrollListener implements OnTouchListener {
-
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-    private final int mInitialDelay;
-    private final int mRepeatInterval;
-    private final OnClickListener mOnClickListener;
-    private View mTouchedView;
-    private boolean mIsLongPressed;
-
-    /**
-     * Notifies listener and self schedules to be re-run at next callback interval.
-     */
-    private final Runnable mPeriodicRunnable = new Runnable() {
-        @Override
-        public void run() {
-            if (mTouchedView.isEnabled()) {
-                mHandler.postDelayed(this, mRepeatInterval);
-                mOnClickListener.onClick(mTouchedView);
-                mIsLongPressed = true;
-            } else {
-                mIsLongPressed = false;
-            }
-        }
-    };
-
-    /**
-     * @param clickListener The OnClickListener, that will be called periodically
-     */
-    public OnContinuousScrollListener(@NonNull Context context,
-            @NonNull OnClickListener clickListener) {
-        this.mInitialDelay = context.getResources().getInteger(
-                R.integer.car_ui_scrollbar_longpress_initial_delay);
-        this.mRepeatInterval = context.getResources().getInteger(
-                R.integer.car_ui_scrollbar_longpress_repeat_interval);
-
-        if (mInitialDelay < 0 || mRepeatInterval < 0) {
-            throw new IllegalArgumentException("negative intervals are not allowed");
-        }
-        this.mOnClickListener = clickListener;
-    }
-
-    /**
-     * Cancel pending scroll operations. Any scroll operations that were scheduled to possibly be
-     * performed, as part of a continuous scroll, will be cancelled.
-     */
-    public void cancelPendingScroll() {
-        mHandler.removeCallbacks(mPeriodicRunnable);
-        mIsLongPressed = false;
-    }
-
-    @Override
-    public boolean onTouch(View view, MotionEvent motionEvent) {
-        mTouchedView = view;
-        switch (motionEvent.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mHandler.removeCallbacks(mPeriodicRunnable);
-                mHandler.postDelayed(mPeriodicRunnable, mInitialDelay);
-                mTouchedView.setPressed(true);
-                return true;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                if (!mIsLongPressed) {
-                    mOnClickListener.onClick(view);
-                }
-                mHandler.removeCallbacks(mPeriodicRunnable);
-                mTouchedView.setPressed(false);
-                mIsLongPressed = false;
-                return true;
-        }
-        return false;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/PassThroughFilter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/PassThroughFilter.java
deleted file mode 100644
index 4a02a94..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/PassThroughFilter.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-/**
- * A trivial implementation that doesn't do any filtering (simplifies the filter's code).
- */
-public class PassThroughFilter implements RangeFilter {
-    private int mCount;
-
-    @Override
-    public void recompute(int newCount, int pivotIndex) {
-        mCount = newCount;
-    }
-
-    @Override
-    public void notifyPivotIndexChanged(int pivotIndex) {
-    }
-
-    @Override
-    public int getFilteredCount() {
-        return mCount;
-    }
-
-    @Override
-    public int indexToPosition(int index) {
-        return index;
-    }
-
-    @Override
-    public int positionToIndex(int position) {
-        return position;
-    }
-
-    @Override
-    public void invalidateMessagePositions() {
-    }
-
-    @Override
-    public void applyFilter() {
-    }
-
-    @Override
-    public void removeFilter() {
-    }
-};
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RangeFilter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RangeFilter.java
deleted file mode 100644
index c9ea953..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RangeFilter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-/**
- * Interface for helper objects that hide elements from lists that are too long. The limiting
- * happens around a pivot element that can be anywhere in the list. Elements near that pivot will
- * be visible, while elements at the head and / or tail of the list will be replaced by a message
- * telling the user about the truncation.
- */
-public interface RangeFilter {
-
-    int INVALID_INDEX = -1;
-    int INVALID_POSITION = -1;
-
-    /**
-     * Computes new restrictions when the list (and optionally) the pivot have changed.
-     * The implementation doesn't send any notification.
-     */
-    void recompute(int newCount, int pivotIndex);
-
-    /**
-     * Computes new restrictions when only the pivot has changed.
-     * The implementation must send notification changes (ideally incremental ones).
-     */
-    void notifyPivotIndexChanged(int pivotIndex);
-
-    /** Returns the number of elements in the resulting list, including the message(s). */
-    int getFilteredCount();
-
-    /**
-     * Converts an index in the unfiltered data set to a RV position in the filtered UI in the
-     * 0 .. {@link #getFilteredCount} range which includes the limits message(s).
-     * Returns INVALID_POSITION if that element has been filtered out.
-     */
-    int indexToPosition(int index);
-
-    /**
-     * Converts a RV position in the filtered UI to an index in the unfiltered data set.
-     * Returns INVALID_INDEX if a message is shown at that position.
-     */
-    int positionToIndex(int position);
-
-    /** Send notification changes for the restriction message(s) if there are any. */
-    void invalidateMessagePositions();
-
-    /**
-     * Called when the filter will be applied. If needed, notifies the adapter with data
-     * removal signal.
-     */
-    void applyFilter();
-
-    /**
-     * Called when the filter will be removed. If needed, notifies the adapter with data
-     * inserted signal.
-     */
-    void removeFilter();
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RangeFilterImpl.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RangeFilterImpl.java
deleted file mode 100644
index 8f39514..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RangeFilterImpl.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.RecyclerView;
-
-/**
- * An implementation of {@link RangeFilter} interface.
- */
-public class RangeFilterImpl implements RangeFilter {
-
-    private static final String TAG = "RangeFilterImpl";
-
-    private final RecyclerView.Adapter<?> mAdapter;
-    private final int mMaxItems;
-    private final int mMaxItemsFirstHalf;
-    private final int mMaxItemsSecondHalf;
-
-    private int mUnlimitedCount;
-    @VisibleForTesting
-    int mPivotIndex;
-    private final ListRange mRange = new ListRange();
-
-    /**
-     * Constructor
-     * @param adapter the adapter to notify of changes in {@link #notifyPivotIndexChanged(int)}.
-     * @param maxItems the maximum number of items to show.
-     */
-    public RangeFilterImpl(RecyclerView.Adapter<?> adapter, int maxItems) {
-        mAdapter = adapter;
-        if (maxItems <= 0) {
-            mMaxItemsFirstHalf = 0;
-            mMaxItemsSecondHalf = 0;
-            mMaxItems = 0;
-        } else {
-            mMaxItemsFirstHalf = maxItems / 2;
-            mMaxItemsSecondHalf = maxItems - mMaxItemsFirstHalf;
-            mMaxItems = maxItems;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "RangeFilterImpl{"
-                + "mMaxItemsFirstHalf=" + mMaxItemsFirstHalf
-                + "mMaxItemsSecondHalf=" + mMaxItemsSecondHalf
-                + ", mUnlimitedCount=" + mUnlimitedCount
-                + ", mPivotIndex=" + mPivotIndex
-                + ", mRange=" + mRange.toString()
-                + '}';
-    }
-
-    @Override
-    public int getFilteredCount() {
-        return mRange.mLimitedCount;
-    }
-
-    @Override
-    public void invalidateMessagePositions() {
-        if (mRange.mClampedHead > 0) {
-            mAdapter.notifyItemChanged(0);
-        }
-        if (mRange.mClampedTail > 0) {
-            mAdapter.notifyItemChanged(getFilteredCount() - 1);
-        }
-    }
-
-    @Override
-    public void applyFilter() {
-        if (mRange.isTailClamped()) {
-            mAdapter.notifyItemInserted(mUnlimitedCount);
-            mAdapter.notifyItemRangeRemoved(mRange.mEndIndex, mUnlimitedCount - mRange.mEndIndex);
-        }
-        if (mRange.isHeadClamped()) {
-            mAdapter.notifyItemRangeRemoved(0, mRange.mStartIndex);
-            mAdapter.notifyItemInserted(0);
-        }
-    }
-
-    @Override
-    public void removeFilter() {
-        if (mRange.isTailClamped()) {
-            // Remove the message
-            mAdapter.notifyItemRemoved(mRange.mLimitedCount - 1);
-            // Add the tail items that were dropped
-            mAdapter.notifyItemRangeInserted(mRange.mLimitedCount - 1,
-                    mUnlimitedCount - mRange.mEndIndex);
-        }
-        if (mRange.isHeadClamped()) {
-            // Add the head items that were dropped
-            mAdapter.notifyItemRangeInserted(1, mRange.mStartIndex);
-            // Remove the message
-            mAdapter.notifyItemRemoved(0);
-        }
-    }
-
-    @Override
-    public void recompute(int newCount, int pivotIndex) {
-        if (pivotIndex < 0 || newCount <= pivotIndex) {
-            Log.e(TAG, "Invalid pivotIndex: " + pivotIndex + " newCount: " + newCount);
-            pivotIndex = 0;
-        }
-        mUnlimitedCount = newCount;
-        mPivotIndex = pivotIndex;
-
-        mRange.mClampedHead = 0;
-        mRange.mClampedTail = 0;
-
-        if (mUnlimitedCount <= mMaxItems) {
-            // Under the cap case.
-            mRange.mStartIndex = 0;
-            mRange.mEndIndex = mUnlimitedCount;
-            mRange.mLimitedCount = mUnlimitedCount;
-        } else if (mMaxItems <= 0) {
-            // Zero cap case.
-            mRange.mStartIndex = 0;
-            mRange.mEndIndex = 0;
-            mRange.mLimitedCount = 1; // One limit message
-            mRange.mClampedTail = 1;
-        } else if (mPivotIndex <= mMaxItemsFirstHalf) {
-            // No need to clamp the head case
-            // For example: P = 2, M/2 = 2 => exactly two items before the pivot.
-            // Tail has to be clamped or we'd be in the "under the cap" case.
-            mRange.mStartIndex = 0;
-            mRange.mEndIndex = mMaxItems;
-            mRange.mLimitedCount = mMaxItems + 1; // One limit message at the end
-            mRange.mClampedTail = 1;
-        } else if ((mUnlimitedCount - 1 - mPivotIndex) <= mMaxItemsSecondHalf) {
-            // No need to clamp the tail case
-            // For example: C = 5, P = 2 => exactly 2 items after the pivot (count is exclusive).
-            // Head has to be clamped or we'd be in the "under the cap" case.
-            mRange.mEndIndex = mUnlimitedCount;
-            mRange.mStartIndex = mRange.mEndIndex - mMaxItems;
-            mRange.mLimitedCount = mMaxItems + 1; // One limit message at the start
-            mRange.mClampedHead = 1;
-        } else {
-            // Both head and tail need clamping
-            mRange.mStartIndex = mPivotIndex - mMaxItemsFirstHalf;
-            mRange.mEndIndex = mPivotIndex + mMaxItemsSecondHalf;
-            mRange.mLimitedCount = mMaxItems + 2; // One limit message at each end.
-            mRange.mClampedHead = 1;
-            mRange.mClampedTail = 1;
-        }
-    }
-
-    @Override
-    public void notifyPivotIndexChanged(int pivotIndex) {
-        // TODO: Implement this function.
-    }
-
-    @Override
-    public int indexToPosition(int index) {
-        if ((mRange.mStartIndex <= index) && (index < mRange.mEndIndex)) {
-            return mRange.indexToPosition(index);
-        } else {
-            return INVALID_POSITION;
-        }
-    }
-
-    @Override
-    public int positionToIndex(int position) {
-        return mRange.positionToIndex(position);
-    }
-
-    @VisibleForTesting
-    ListRange getRange() {
-        return mRange;
-    }
-
-    /** Represents a portion of the unfiltered list. */
-    static class ListRange {
-        public static final int INVALID_INDEX = -1;
-
-        @VisibleForTesting
-        /* In original data, inclusive. */
-                int mStartIndex;
-        @VisibleForTesting
-        /* In original data, exclusive. */
-                int mEndIndex;
-
-        @VisibleForTesting
-        /* 1 when clamped, otherwise 0. */
-                int mClampedHead;
-        @VisibleForTesting
-        /* 1 when clamped, otherwise 0. */
-                int mClampedTail;
-
-        @VisibleForTesting
-        /* The count of the resulting elements, including the truncation message(s). */
-                int mLimitedCount;
-
-        /**
-         * Deep copy from a ListRange.
-         */
-        public void copyFrom(ListRange range) {
-            mStartIndex = range.mStartIndex;
-            mEndIndex = range.mEndIndex;
-            mClampedHead = range.mClampedHead;
-            mClampedTail = range.mClampedTail;
-            mLimitedCount = range.mLimitedCount;
-        }
-
-        @Override
-        public String toString() {
-            return "ListRange{"
-                    + "mStartIndex=" + mStartIndex
-                    + ", mEndIndex=" + mEndIndex
-                    + ", mClampedHead=" + mClampedHead
-                    + ", mClampedTail=" + mClampedTail
-                    + ", mLimitedCount=" + mLimitedCount
-                    + '}';
-        }
-
-        /**
-         * Converts an index in the unrestricted list to the position in the restricted one.
-         *
-         * Unchecked index needed by {@link #notifyPivotIndexChanged(int)}.
-         */
-        public int indexToPosition(int index) {
-            return index - mStartIndex + mClampedHead;
-        }
-
-        /** Converts the position in the restricted list to an index in the unrestricted one.*/
-        public int positionToIndex(int position) {
-            int index = position - mClampedHead + mStartIndex;
-            if ((index < mStartIndex) || (mEndIndex <= index)) {
-                return INVALID_INDEX;
-            } else {
-                return index;
-            }
-        }
-
-        public boolean isHeadClamped() {
-            return mClampedHead == 1;
-        }
-
-        public boolean isTailClamped() {
-            return mClampedTail == 1;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RecyclerViewAdapterAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RecyclerViewAdapterAdapterV1.java
deleted file mode 100644
index f4a3292..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RecyclerViewAdapterAdapterV1.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.Adapter;
-import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterDataObserverOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ViewHolderOEMV1;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * AdapterV1 class for delegating calls to AdapterOEMV1
- */
-public final class RecyclerViewAdapterAdapterV1
-        implements AdapterOEMV1<RecyclerViewAdapterAdapterV1.ViewHolderAdapterV1> {
-
-    @Nullable
-    private RecyclerView mRecyclerView;
-
-    @NonNull
-    private final Adapter mAdapter;
-
-    @NonNull
-    private List<AdapterDataObserverOEMV1> mAdapterDataObservers = new ArrayList<>();
-
-    private AdapterDataObserver mAdapterDataObserver = new AdapterDataObserver() {
-        @Override
-        public void onChanged() {
-            for (AdapterDataObserverOEMV1 observer: mAdapterDataObservers) {
-                observer.onChanged();
-            }
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount) {
-            for (AdapterDataObserverOEMV1 observer: mAdapterDataObservers) {
-                observer.onItemRangeChanged(positionStart, itemCount);
-            }
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount,
-                @Nullable Object payload) {
-            for (AdapterDataObserverOEMV1 observer: mAdapterDataObservers) {
-                observer.onItemRangeChanged(positionStart, itemCount, payload);
-            }
-        }
-
-        @Override
-        public void onItemRangeInserted(int positionStart, int itemCount) {
-            for (AdapterDataObserverOEMV1 observer: mAdapterDataObservers) {
-                observer.onItemRangeInserted(positionStart, itemCount);
-            }
-        }
-
-        @Override
-        public void onItemRangeRemoved(int positionStart, int itemCount) {
-            for (AdapterDataObserverOEMV1 observer: mAdapterDataObservers) {
-                observer.onItemRangeRemoved(positionStart, itemCount);
-            }
-        }
-
-        @Override
-        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-            for (AdapterDataObserverOEMV1 observer: mAdapterDataObservers) {
-                for (int i = 0; i < itemCount; i++) {
-                    observer.onItemMoved(fromPosition + i, toPosition + i);
-                }
-            }
-        }
-
-        @Override
-        public void onStateRestorationPolicyChanged() {
-            for (AdapterDataObserverOEMV1 observer: mAdapterDataObservers) {
-                observer.onStateRestorationPolicyChanged();
-            }
-        }
-    };
-
-    public RecyclerViewAdapterAdapterV1(@NonNull RecyclerView.Adapter adapter) {
-        mAdapter = adapter;
-    }
-
-    @NonNull
-    public RecyclerView.Adapter getAdapter() {
-        return mAdapter;
-    }
-
-    @Override
-    public int getItemCount() {
-        return mAdapter.getItemCount();
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return mAdapter.getItemId(position);
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mAdapter.getItemViewType(position);
-    }
-
-    @Override
-    public int getStateRestorationPolicyInt() {
-        switch (mAdapter.getStateRestorationPolicy()) {
-            case PREVENT:
-                return AdapterOEMV1.PREVENT;
-            case PREVENT_WHEN_EMPTY:
-                return AdapterOEMV1.PREVENT_WHEN_EMPTY;
-            case ALLOW:
-            default:
-                return AdapterOEMV1.ALLOW;
-        }
-    }
-
-    @Override
-    public void onAttachedToRecyclerView(RecyclerViewOEMV1 recyclerView) {
-        if (mRecyclerView != null) {
-            mAdapter.onAttachedToRecyclerView(mRecyclerView);
-            mAdapter.registerAdapterDataObserver(mAdapterDataObserver);
-        }
-    }
-
-    @Override
-    public void bindViewHolder(ViewHolderAdapterV1 holder, int position) {
-        mAdapter.bindViewHolder(holder.getViewHolder(), position);
-    }
-
-    @Override
-    public ViewHolderAdapterV1 createViewHolder(ViewGroup parent, int viewType) {
-        return new ViewHolderAdapterV1(mAdapter.createViewHolder(parent, viewType));
-    }
-
-    @Override
-    public void onDetachedFromRecyclerView(RecyclerViewOEMV1 recyclerView) {
-        if (mRecyclerView != null) {
-            mAdapter.unregisterAdapterDataObserver(mAdapterDataObserver);
-            mAdapter.onDetachedFromRecyclerView(mRecyclerView);
-        }
-    }
-
-    @Override
-    public boolean onFailedToRecycleView(ViewHolderAdapterV1 holder) {
-        return mAdapter.onFailedToRecycleView(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewAttachedToWindow(ViewHolderAdapterV1 holder) {
-        mAdapter.onViewAttachedToWindow(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewDetachedFromWindow(ViewHolderAdapterV1 holder) {
-        mAdapter.onViewDetachedFromWindow(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewRecycled(ViewHolderAdapterV1 holder) {
-        mAdapter.onViewRecycled(holder.getViewHolder());
-    }
-
-    @Override
-    public void registerAdapterDataObserver(AdapterDataObserverOEMV1 observer) {
-        if (observer == null) {
-            return;
-        }
-        mAdapterDataObservers.add(observer);
-    }
-
-    @Override
-    public void unregisterAdapterDataObserver(AdapterDataObserverOEMV1 observer) {
-        if (observer == null) {
-            return;
-        }
-        mAdapterDataObservers.remove(observer);
-    }
-
-    @Override
-    public boolean hasStableIds() {
-        return mAdapter.hasStableIds();
-    }
-
-    @Override
-    public void setRecyclerView(@Nullable View recyclerview) {
-        mRecyclerView = (RecyclerView) recyclerview;
-    }
-
-    static class ViewHolderAdapterV1 implements ViewHolderOEMV1 {
-
-        private RecyclerView.ViewHolder mViewHolder;
-
-        ViewHolderAdapterV1(@NonNull RecyclerView.ViewHolder viewHolder) {
-            mViewHolder = viewHolder;
-        }
-
-        @NonNull
-        public ViewHolder getViewHolder() {
-            return mViewHolder;
-        }
-
-        @Override
-        public boolean isRecyclable() {
-            return mViewHolder.isRecyclable();
-        }
-
-        @Override
-        public View getItemView() {
-            return mViewHolder.itemView;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RecyclerViewAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RecyclerViewAdapterV1.java
deleted file mode 100644
index dc32278..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/RecyclerViewAdapterV1.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.LayoutStyleOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.OnScrollListenerOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.SpanSizeLookupOEMV1;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * AdapterV1 class for making oem implementation available for UI
- *
- * For CarUi internal usage only.
- */
-public final class RecyclerViewAdapterV1 extends CarUiRecyclerView
-        implements OnScrollListenerOEMV1 {
-
-    @Nullable
-    private RecyclerViewOEMV1 mOEMRecyclerView;
-    @Nullable
-    private AdapterOEMV1 mOEMAdapter;
-
-    private List<OnScrollListener> mScrollListeners = new ArrayList<>();
-
-    public RecyclerViewAdapterV1(@NonNull Context context) {
-        this(context, null);
-    }
-
-    public RecyclerViewAdapterV1(@NonNull Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, R.attr.carUiRecyclerViewStyle);
-    }
-
-    public RecyclerViewAdapterV1(@NonNull Context context, @Nullable AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    /**
-     * Called to pass the oem recyclerview implementation.
-     * @param oemRecyclerView
-     */
-    public void setRecyclerViewOEMV1(@NonNull RecyclerViewOEMV1 oemRecyclerView) {
-        mOEMRecyclerView = oemRecyclerView;
-
-        mOEMRecyclerView.addOnScrollListener(this);
-        super.setLayoutManager(new LinearLayoutManager(getContext()));
-        View oemRV = oemRecyclerView.getView();
-        ViewGroup.LayoutParams params = new MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT);
-        oemRV.setLayoutParams(params);
-        RecyclerView.Adapter adapter = new CustomAdapter(oemRV);
-        super.setAdapter(adapter);
-    }
-
-    @Override
-    public void setLayoutManager(@Nullable LayoutManager layoutManager) {
-        if (layoutManager instanceof LinearLayoutManager) {
-            setLayoutStyle(CarUiLinearLayoutStyle.from(layoutManager));
-        } else {
-            setLayoutStyle(CarUiGridLayoutStyle.from(layoutManager));
-        }
-    }
-
-    @Override
-    public View getContainer() {
-        return mOEMRecyclerView.getContainer();
-    }
-
-    @Override
-    public void setAdapter(RecyclerView.Adapter adapter) {
-        if (mOEMAdapter != null) {
-            mOEMAdapter.setRecyclerView(null);
-        }
-
-        if (adapter == null) {
-            mOEMRecyclerView.setAdapter(null);
-        } else {
-            mOEMAdapter = new RecyclerViewAdapterAdapterV1(adapter);
-            mOEMRecyclerView.setAdapter(mOEMAdapter);
-            mOEMAdapter.setRecyclerView(this);
-        }
-    }
-
-    @Override
-    public void addOnScrollListener(@NonNull RecyclerView.OnScrollListener listener) {
-        mScrollListeners.add(listener);
-    }
-
-    @Override
-    public void removeOnScrollListener(@NonNull RecyclerView.OnScrollListener listener) {
-        if (mScrollListeners != null) {
-            mScrollListeners.remove(listener);
-        }
-    }
-
-    @Override
-    public void clearOnScrollListeners() {
-        if (mScrollListeners != null) {
-            mScrollListeners.clear();
-        }
-        mOEMRecyclerView.clearOnScrollListeners();
-    }
-
-    @Override
-    public void onScrollStateChanged(@NonNull RecyclerViewOEMV1 recyclerView, int newState) {
-        if (mScrollListeners != null) {
-            for (RecyclerView.OnScrollListener listener: mScrollListeners) {
-                listener.onScrollStateChanged(this, newState);
-            }
-        }
-    }
-
-    @Override
-    public void onScrolled(@NonNull RecyclerViewOEMV1 recyclerView, int dx, int dy) {
-        if (mScrollListeners != null) {
-            for (RecyclerView.OnScrollListener listener: mScrollListeners) {
-                listener.onScrolled(this, dx, dy);
-            }
-        }
-    }
-
-    @Override
-    public void scrollToPosition(int position) {
-        mOEMRecyclerView.scrollToPosition(position);
-    }
-
-    @Override
-    public void smoothScrollBy(int dx, int dy) {
-        mOEMRecyclerView.smoothScrollBy(dx, dy);
-    }
-
-    @Override
-    public void smoothScrollToPosition(int position) {
-        mOEMRecyclerView.smoothScrollToPosition(position);
-    }
-
-    @Override
-    public ViewHolder findViewHolderForAdapterPosition(int position) {
-        // TODO
-        return null;
-    }
-
-    @Override
-    public void setHasFixedSize(boolean hasFixedSize) {
-        mOEMRecyclerView.setHasFixedSize(hasFixedSize);
-    }
-
-    @Override
-    public boolean hasFixedSize() {
-        return mOEMRecyclerView.hasFixedSize();
-    }
-
-    private static class CustomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
-
-        @NonNull
-        private View mView;
-
-        CustomAdapter(@NonNull View view) {
-            mView = view;
-        }
-
-        @Override
-        public int getItemCount() {
-            return 1;
-        }
-
-        @NonNull
-        @Override
-        public RecyclerView.ViewHolder onCreateViewHolder(
-                @NonNull ViewGroup parent, int viewType) {
-            return new CustomViewHolder(mView);
-        }
-
-        @Override
-        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
-        }
-
-        static class CustomViewHolder extends RecyclerView.ViewHolder {
-            CustomViewHolder(@NonNull View itemView) {
-                super(itemView);
-            }
-        }
-    }
-
-    /**
-     * @deprecated LayoutManager will be implemented by OEMs,
-     * use other available APIs to get the required data
-     * @return null
-     */
-    @Nullable
-    @Override
-    @Deprecated
-    public LayoutManager getLayoutManager() {
-        return null;
-    }
-
-    @Override
-    public void setLayoutStyle(@Nullable CarUiLayoutStyle layoutStyle) {
-        if (layoutStyle == null) mOEMRecyclerView.setLayoutStyle(null);
-
-        final LayoutStyleOEMV1 oemLayoutStyle = new LayoutStyleOEMV1() {
-            @Override
-            public int getSpanCount() {
-                return layoutStyle.getSpanCount();
-            }
-
-            @Override
-            public int getLayoutType() {
-                return layoutStyle.getLayoutType();
-            }
-
-            @Override
-            public int getOrientation() {
-                return layoutStyle.getOrientation();
-            }
-
-            @Override
-            public boolean getReverseLayout() {
-                return layoutStyle.getReverseLayout();
-            }
-
-            @Override
-            public SpanSizeLookupOEMV1 getSpanSizeLookup() {
-                if (layoutStyle instanceof CarUiLinearLayoutStyle) return null;
-                return ((CarUiGridLayoutStyle) layoutStyle).getSpanSizeLookup() == null ? null
-                        : position -> ((CarUiGridLayoutStyle) layoutStyle)
-                                .getSpanSizeLookup().getSpanSize(position);
-            }
-        };
-        mOEMRecyclerView.setLayoutStyle(oemLayoutStyle);
-    }
-
-    @Override
-    public void setPadding(int left, int top, int right, int bottom) {
-        mOEMRecyclerView.setPadding(left, top, right, bottom);
-    }
-
-    @Override
-    public void setPaddingRelative(int start, int top, int end, int bottom) {
-        mOEMRecyclerView.setPaddingRelative(start, top, end, bottom);
-    }
-
-    @Override
-    public void setClipToPadding(boolean clipToPadding) {
-        mOEMRecyclerView.setClipToPadding(clipToPadding);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ScrollBar.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ScrollBar.java
deleted file mode 100644
index 05863d0..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ScrollBar.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview;
-
-import android.view.View;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-/**
- * An abstract class that defines required contract for a custom scroll bar for the {@link
- * CarUiRecyclerView}. All custom scroll bar must inherit from this class.
- */
-public interface ScrollBar {
-    /**
-     * The concrete class should implement this method to initialize configuration of a scrollbar
-     * view.
-     */
-    void initialize(RecyclerView recyclerView, View scrollView);
-
-    /**
-     * Requests layout of the scrollbar. Should be called when there's been a change that will
-     * affect the size of the scrollbar view.
-     */
-    void requestLayout();
-
-    /** Sets the padding of the scrollbar, relative to the padding of the RecyclerView. */
-    void setPadding(int paddingStart, int paddingEnd);
-
-    /**
-     * Called when recyclerview's setAdapter is called.
-     */
-    void adapterChanged(RecyclerView.Adapter adapter);
-
-    /**
-     * Returns {@code true} if the RecyclerView is completely displaying the first item.
-     */
-    boolean isAtStart();
-
-    /** Highlights or unhighlight the scrollbar's thumb. */
-    void setHighlightThumb(boolean highlight);
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ScrollingLimitedViewHolder.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ScrollingLimitedViewHolder.java
deleted file mode 100644
index 63b8692..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/ScrollingLimitedViewHolder.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.recyclerview;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-/**
- * {@link RecyclerView.ViewHolder} for the last item in a scrolling limited list.
- */
-public final class ScrollingLimitedViewHolder extends RecyclerView.ViewHolder {
-
-    private final TextView mMessage;
-
-    /**
-     * Return an instance of {@link ScrollingLimitedViewHolder} with an already inflated root view.
-     * @param parent - the parent {@link ViewGroup} to use during inflation of the root view.
-     */
-    public static ScrollingLimitedViewHolder create(@NonNull ViewGroup parent) {
-        View rootView = LayoutInflater.from(parent.getContext())
-                .inflate(R.layout.car_ui_list_limiting_message, parent, false);
-        return new ScrollingLimitedViewHolder(rootView);
-    }
-
-    ScrollingLimitedViewHolder(@NonNull View itemView) {
-        super(itemView);
-        mMessage = CarUiUtils.requireViewByRefId(itemView, R.id.car_ui_list_limiting_message);
-    }
-
-    /**
-     * Update the content of this {@link ScrollingLimitedViewHolder} object using the provided
-     * message String resource id.
-     * @param messageId
-     */
-    public void bind(@StringRes @Nullable Integer messageId) {
-        int resId = (messageId != null) ? messageId : R.string.car_ui_scrolling_limited_message;
-        mMessage.setText(mMessage.getContext().getString(resId));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/grid/GridDividerItemDecoration.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/grid/GridDividerItemDecoration.java
deleted file mode 100644
index 5eb090a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/grid/GridDividerItemDecoration.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview.decorations.grid;
-
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-
-import java.util.Objects;
-
-/** Adds interior dividers to a RecyclerView with a GridLayoutManager. */
-public class GridDividerItemDecoration extends RecyclerView.ItemDecoration {
-
-    private final Drawable mHorizontalDivider;
-    private final Drawable mVerticalDivider;
-    private int mNumColumns;
-
-    /**
-     * Sole constructor. Takes in {@link Drawable} objects to be used as horizontal and vertical
-     * dividers.
-     *
-     * @param horizontalDivider A divider {@code Drawable} to be drawn on the rows of the grid of
-     *                          the
-     *                          RecyclerView
-     * @param verticalDivider   A divider {@code Drawable} to be drawn on the columns of the grid of
-     *                          the
-     *                          RecyclerView
-     * @param numColumns        The number of columns in the grid of the RecyclerView
-     */
-    public GridDividerItemDecoration(
-            Drawable horizontalDivider, Drawable verticalDivider, int numColumns) {
-        this.mHorizontalDivider = horizontalDivider;
-        this.mVerticalDivider = verticalDivider;
-        this.mNumColumns = numColumns;
-    }
-
-    /**
-     * Draws horizontal and/or vertical dividers onto the parent RecyclerView.
-     *
-     * @param canvas The {@link Canvas} onto which dividers will be drawn
-     * @param parent The RecyclerView onto which dividers are being added
-     * @param state  The current RecyclerView.State of the RecyclerView
-     */
-    @Override
-    public void onDrawOver(@NonNull Canvas canvas, @NonNull RecyclerView parent,
-            @NonNull RecyclerView.State state) {
-        drawVerticalDividers(canvas, parent);
-        drawHorizontalDividers(canvas, parent);
-    }
-
-    /**
-     * Determines the size and location of offsets between items in the parent RecyclerView.
-     *
-     * @param outRect The {@link Rect} of offsets to be added around the child view
-     * @param view    The child view to be decorated with an offset
-     * @param parent  The RecyclerView onto which dividers are being added
-     * @param state   The current RecyclerView.State of the RecyclerView
-     */
-    @Override
-    public void getItemOffsets(
-            Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
-            @NonNull RecyclerView.State state) {
-        outRect.set(
-                0, 0, mHorizontalDivider.getIntrinsicWidth(),
-                mHorizontalDivider.getIntrinsicHeight());
-    }
-
-    /**
-     * Adds horizontal dividers to a RecyclerView with a GridLayoutManager or its subclass.
-     *
-     * @param canvas The {@link Canvas} onto which dividers will be drawn
-     * @param parent The RecyclerView onto which dividers are being added
-     */
-    private void drawHorizontalDividers(Canvas canvas, RecyclerView parent) {
-        RecyclerView.LayoutManager layoutManager = Objects.requireNonNull(
-                parent.getLayoutManager());
-        int childCount = layoutManager.getChildCount();
-        int rowCount = childCount / mNumColumns;
-        int lastRowChildCount = childCount % mNumColumns;
-        int lastColumn = Math.min(childCount, mNumColumns);
-
-        for (int i = 1; i < lastColumn; i++) {
-            int lastRowChildIndex;
-            if (i < lastRowChildCount) {
-                lastRowChildIndex = i + (rowCount * mNumColumns);
-            } else {
-                lastRowChildIndex = i + ((rowCount - 1) * mNumColumns);
-            }
-
-
-            View firstRowChild = layoutManager.getChildAt(i);
-            View lastRowChild = layoutManager.getChildAt(lastRowChildIndex);
-
-            int dividerTop =
-                    firstRowChild.getTop() + (int) parent.getContext().getResources().getDimension(
-                            R.dimen.car_ui_recyclerview_divider_top_margin);
-            int dividerRight = firstRowChild.getLeft();
-            int dividerLeft = dividerRight - mHorizontalDivider.getIntrinsicWidth();
-            int dividerBottom = lastRowChild.getBottom()
-                    - (int) parent.getContext().getResources().getDimension(
-                    R.dimen.car_ui_recyclerview_divider_bottom_margin);
-
-            mHorizontalDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
-            mHorizontalDivider.draw(canvas);
-        }
-    }
-
-    public void setNumOfColumns(int numberOfColumns) {
-        mNumColumns = numberOfColumns;
-    }
-
-    /**
-     * Adds vertical dividers to a RecyclerView with a GridLayoutManager or its subclass.
-     *
-     * @param canvas The {@link Canvas} onto which dividers will be drawn
-     * @param parent The RecyclerView onto which dividers are being added
-     */
-    private void drawVerticalDividers(Canvas canvas, RecyclerView parent) {
-        RecyclerView.LayoutManager layoutManager = Objects.requireNonNull(
-                parent.getLayoutManager());
-        double childCount = layoutManager.getChildCount();
-        double rowCount = Math.ceil(childCount / mNumColumns);
-        int rightmostChildIndex;
-        for (int i = 1; i <= rowCount; i++) {
-            // we don't want the divider on top of first row.
-            if (i == 1) {
-                continue;
-            }
-            if (i == rowCount) {
-                rightmostChildIndex = ((i - 1) * mNumColumns) - 1;
-            } else {
-                rightmostChildIndex = (i * mNumColumns) - 1;
-            }
-
-            View leftmostChild = layoutManager.getChildAt(mNumColumns * (i - 1));
-            View rightmostChild = layoutManager.getChildAt(rightmostChildIndex);
-
-            // draws on top of each row.
-            int dividerLeft =
-                    leftmostChild.getLeft() + (int) parent.getContext().getResources().getDimension(
-                            R.dimen.car_ui_recyclerview_divider_start_margin);
-            int dividerBottom = leftmostChild.getTop();
-            int dividerTop = dividerBottom - mVerticalDivider.getIntrinsicHeight();
-            int dividerRight = rightmostChild.getRight()
-                    - (int) parent.getContext().getResources().getDimension(
-                    R.dimen.car_ui_recyclerview_divider_end_margin);
-
-            mVerticalDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
-            mVerticalDivider.draw(canvas);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/linear/LinearDividerItemDecoration.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/linear/LinearDividerItemDecoration.java
deleted file mode 100644
index 3ab24aa..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/linear/LinearDividerItemDecoration.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview.decorations.linear;
-
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-
-import java.util.Objects;
-
-/** Adds interior dividers to a RecyclerView with a LinearLayoutManager or its subclass. */
-public class LinearDividerItemDecoration extends RecyclerView.ItemDecoration {
-
-    private final Drawable mDivider;
-    private int mOrientation;
-
-    /**
-     * Sole constructor. Takes in a {@link Drawable} to be used as the interior
-     * car_ui_recyclerview_divider.
-     *
-     * @param divider A car_ui_recyclerview_divider {@code Drawable} to be drawn on the
-     *                RecyclerView
-     */
-    public LinearDividerItemDecoration(Drawable divider) {
-        this.mDivider = divider;
-    }
-
-    /**
-     * Draws horizontal or vertical dividers onto the parent RecyclerView.
-     *
-     * @param canvas The {@link Canvas} onto which dividers will be drawn
-     * @param parent The RecyclerView onto which dividers are being added
-     * @param state  The current RecyclerView.State of the RecyclerView
-     */
-    @Override
-    public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent,
-            @NonNull RecyclerView.State state) {
-        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
-            drawHorizontalDividers(canvas, parent);
-        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
-            drawVerticalDividers(canvas, parent);
-        }
-    }
-
-    /**
-     * Determines the size and location of offsets between items in the parent RecyclerView.
-     *
-     * @param outRect The {@link Rect} of offsets to be added around the child view
-     * @param view    The child view to be decorated with an offset
-     * @param parent  The RecyclerView onto which dividers are being added
-     * @param state   The current RecyclerView.State of the RecyclerView
-     */
-    @Override
-    public void getItemOffsets(
-            @NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
-            @NonNull RecyclerView.State state) {
-        super.getItemOffsets(outRect, view, parent, state);
-
-        if (parent.getChildAdapterPosition(view) == 0) {
-            return;
-        }
-
-        mOrientation = ((LinearLayoutManager) Objects.requireNonNull(
-                parent.getLayoutManager())).getOrientation();
-        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
-            outRect.left = mDivider.getIntrinsicWidth();
-        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
-            outRect.top = mDivider.getIntrinsicHeight();
-        }
-    }
-
-    /**
-     * Adds dividers to a RecyclerView with a LinearLayoutManager or its subclass oriented
-     * horizontally.
-     *
-     * @param canvas The {@link Canvas} onto which horizontal dividers will be drawn
-     * @param parent The RecyclerView onto which horizontal dividers are being added
-     */
-    private void drawHorizontalDividers(Canvas canvas, RecyclerView parent) {
-        int parentTop =
-                parent.getPaddingTop() + (int) parent.getContext().getResources().getDimension(
-                        R.dimen.car_ui_recyclerview_divider_top_margin);
-        int parentBottom = parent.getHeight() - parent.getPaddingBottom()
-                - (int) parent.getContext().getResources().getDimension(
-                R.dimen.car_ui_recyclerview_divider_bottom_margin);
-
-        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
-        int childCount = layoutManager.getChildCount();
-        for (int i = 0; i < childCount - 1; i++) {
-            View child = layoutManager.getChildAt(i);
-
-            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
-
-            int parentLeft = child.getRight() + params.rightMargin;
-            int parentRight = parentLeft + mDivider.getIntrinsicWidth();
-
-            mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
-            mDivider.draw(canvas);
-        }
-    }
-
-    /**
-     * Adds dividers to a RecyclerView with a LinearLayoutManager or its subclass oriented
-     * vertically.
-     *
-     * @param canvas The {@link Canvas} onto which vertical dividers will be drawn
-     * @param parent The RecyclerView onto which vertical dividers are being added
-     */
-    private void drawVerticalDividers(Canvas canvas, RecyclerView parent) {
-        int parentLeft =
-                parent.getPaddingLeft() + (int) parent.getContext().getResources().getDimension(
-                        R.dimen.car_ui_recyclerview_divider_start_margin);
-        int parentRight = parent.getWidth() - parent.getPaddingRight()
-                - (int) parent.getContext().getResources().getDimension(
-                R.dimen.car_ui_recyclerview_divider_end_margin);
-
-        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
-        int childCount = layoutManager.getChildCount();
-        for (int i = 0; i < childCount - 1; i++) {
-            View child = layoutManager.getChildAt(i);
-
-            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
-
-            int parentTop = child.getBottom() + params.bottomMargin;
-            int parentBottom = parentTop + mDivider.getIntrinsicHeight();
-
-            mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
-            mDivider.draw(canvas);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/linear/LinearOffsetItemDecoration.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/linear/LinearOffsetItemDecoration.java
deleted file mode 100644
index 62d361e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/linear/LinearOffsetItemDecoration.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.recyclerview.decorations.linear;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import java.lang.annotation.Retention;
-import java.util.Objects;
-
-/**
- * Adds an offset to the start of a RecyclerView using a LinearLayoutManager or its subclass.
- *
- * <p>If the RecyclerView.LayoutManager is oriented vertically, the offset will be added to the top
- * of the RecyclerView. If the LayoutManager is oriented horizontally, the offset will be added to
- * the left of the RecyclerView.
- */
-public class LinearOffsetItemDecoration extends RecyclerView.ItemDecoration {
-
-    private int mOffsetPx;
-    private Drawable mOffsetDrawable;
-    private int mOrientation;
-    @OffsetPosition
-    private int mOffsetPosition;
-
-    /** The possible values for setScrollbarPosition. */
-    @IntDef({
-            OffsetPosition.START,
-            OffsetPosition.END,
-    })
-    @Retention(SOURCE)
-    public @interface OffsetPosition {
-        /** Position the offset to the start of the screen. */
-        int START = 0;
-
-        /** Position offset to the end of the screen. */
-        int END = 1;
-    }
-
-    /**
-     * Constructor that takes in the size of the offset to be added to the start of the
-     * RecyclerView.
-     *
-     * @param offsetPx       The size of the offset to be added to the start of the RecyclerView in
-     *                       pixels
-     * @param offsetPosition Position where offset needs to be applied.
-     */
-    public LinearOffsetItemDecoration(int offsetPx, int offsetPosition) {
-        this.mOffsetPx = offsetPx;
-        this.mOffsetPosition = offsetPosition;
-    }
-
-    /**
-     * Constructor that takes in a {@link Drawable} to be drawn at the start of the RecyclerView.
-     *
-     * @param offsetDrawable The {@code Drawable} to be added to the start of the RecyclerView
-     */
-    public LinearOffsetItemDecoration(Drawable offsetDrawable) {
-        this.mOffsetDrawable = offsetDrawable;
-    }
-
-    /**
-     * Determines the size and location of the offset to be added to the start of the RecyclerView.
-     *
-     * @param outRect The {@link Rect} of offsets to be added around the child view
-     * @param view    The child view to be decorated with an offset
-     * @param parent  The RecyclerView onto which dividers are being added
-     * @param state   The current RecyclerView.State of the RecyclerView
-     */
-    @Override
-    public void getItemOffsets(
-            @NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
-            @NonNull RecyclerView.State state) {
-        super.getItemOffsets(outRect, view, parent, state);
-
-        if (mOffsetPosition == OffsetPosition.START && parent.getChildAdapterPosition(view) > 0) {
-            return;
-        }
-
-        int itemCount = state.getItemCount();
-        if (mOffsetPosition == OffsetPosition.END
-                && parent.getChildAdapterPosition(view) != itemCount - 1) {
-            return;
-        }
-
-        mOrientation = ((LinearLayoutManager) Objects.requireNonNull(
-                parent.getLayoutManager())).getOrientation();
-        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
-            if (mOffsetPx > 0) {
-                if (mOffsetPosition == OffsetPosition.START) {
-                    outRect.left = mOffsetPx;
-                } else {
-                    outRect.right = mOffsetPx;
-                }
-            } else if (mOffsetDrawable != null) {
-                if (mOffsetPosition == OffsetPosition.START) {
-                    outRect.left = mOffsetDrawable.getIntrinsicWidth();
-                } else {
-                    outRect.right = mOffsetDrawable.getIntrinsicWidth();
-                }
-            }
-        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
-            if (mOffsetPx > 0) {
-                if (mOffsetPosition == OffsetPosition.START) {
-                    outRect.top = mOffsetPx;
-                } else {
-                    outRect.bottom = mOffsetPx;
-                }
-            } else if (mOffsetDrawable != null) {
-                if (mOffsetPosition == OffsetPosition.START) {
-                    outRect.top = mOffsetDrawable.getIntrinsicHeight();
-                } else {
-                    outRect.bottom = mOffsetDrawable.getIntrinsicHeight();
-                }
-            }
-        }
-    }
-
-    /**
-     * Draws horizontal or vertical offset onto the start of the parent RecyclerView.
-     *
-     * @param c      The {@link Canvas} onto which an offset will be drawn
-     * @param parent The RecyclerView onto which an offset is being added
-     * @param state  The current RecyclerView.State of the RecyclerView
-     */
-    @Override
-    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent,
-            @NonNull RecyclerView.State state) {
-        super.onDraw(c, parent, state);
-        if (mOffsetDrawable == null) {
-            return;
-        }
-
-        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
-            drawOffsetHorizontal(c, parent);
-        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
-            drawOffsetVertical(c, parent);
-        }
-    }
-
-    private void drawOffsetHorizontal(Canvas canvas, RecyclerView parent) {
-        int parentTop = parent.getPaddingTop();
-        int parentBottom = parent.getHeight() - parent.getPaddingBottom();
-        int parentLeft;
-        int offsetDrawableRight;
-
-        if (mOffsetPosition == OffsetPosition.START) {
-            parentLeft = parent.getPaddingLeft();
-        } else {
-            RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
-            View lastChild = layoutManager.getChildAt(layoutManager.getChildCount() - 1);
-            RecyclerView.LayoutParams lastChildLayoutParams =
-                    (RecyclerView.LayoutParams) lastChild.getLayoutParams();
-            parentLeft = lastChild.getRight() + lastChildLayoutParams.rightMargin;
-        }
-        offsetDrawableRight = parentLeft + mOffsetDrawable.getIntrinsicWidth();
-
-        mOffsetDrawable.setBounds(parentLeft, parentTop, offsetDrawableRight, parentBottom);
-        mOffsetDrawable.draw(canvas);
-    }
-
-    private void drawOffsetVertical(Canvas canvas, RecyclerView parent) {
-        int parentLeft = parent.getPaddingLeft();
-        int parentRight = parent.getWidth() - parent.getPaddingRight();
-
-        int parentTop;
-        int offsetDrawableBottom;
-
-        if (mOffsetPosition == OffsetPosition.START) {
-            parentTop = parent.getPaddingTop();
-        } else {
-            RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
-            View lastChild = layoutManager.getChildAt(layoutManager.getChildCount() - 1);
-            RecyclerView.LayoutParams lastChildLayoutParams =
-                    (RecyclerView.LayoutParams) lastChild.getLayoutParams();
-            parentTop = lastChild.getBottom() + lastChildLayoutParams.bottomMargin;
-        }
-        offsetDrawableBottom = parentTop + mOffsetDrawable.getIntrinsicHeight();
-
-        mOffsetDrawable.setBounds(parentLeft, parentTop, parentRight, offsetDrawableBottom);
-        mOffsetDrawable.draw(canvas);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/AdapterClassLoader.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/AdapterClassLoader.java
deleted file mode 100644
index 7995c42..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/AdapterClassLoader.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import dalvik.system.PathClassLoader;
-
-import java.util.regex.Pattern;
-
-/**
- * This is a {@link PathClassLoader} that you can pass an additional classloaders to the
- * constructor. That will be searched after the classes in this classloader have been searched,
- * but before the parent classloader is searched. The first classloader in the list of
- * classloaders is set as the parent classloader.
- *
- * Much of the code is copied from {@link dalvik.system.DelegateLastClassLoader}. However,
- * note that resource loading is not implemented the same way just because we didn't need it.
- */
-class AdapterClassLoader extends PathClassLoader {
-
-    @Nullable
-    private final ClassLoader mSharedLibraryClassLoader;
-
-    private static final Pattern PATTERN = Pattern.compile(
-            "^com\\.android\\.car\\.ui\\..*AdapterV[0-9]+(\\$.*)?$"
-            + "|Lambda"
-            + "|^" + Pattern.quote(OemApiUtil.class.getName()) + "$");
-
-    private static final Pattern SHARED_LIBRARY_PATTERN =
-            Pattern.compile("^com\\.android\\.car\\.ui\\.sharedlibrary\\."
-                    + "(oemapis\\..*|SharedLibraryVersionProviderImpl)$");
-
-    /**
-     * Equivalent to calling {@link #AdapterClassLoader(String, String, ClassLoader, ClassLoader)}
-     * with {@code librarySearchPath = null, delegateResourceLoading = true}.
-     */
-    AdapterClassLoader(String dexPath, @Nullable ClassLoader parent,
-            @Nullable ClassLoader additionalClassloader) {
-        this(dexPath, null, parent, additionalClassloader);
-    }
-
-    /**
-     * Equivalent to calling
-     * {@link #AdapterClassLoader(String, String, ClassLoader, ClassLoader, boolean)}
-     * with {@code delegateResourceLoading = true}.
-     */
-    AdapterClassLoader(String dexPath, String librarySearchPath, @Nullable ClassLoader parent,
-            @Nullable ClassLoader additionalClassloader) {
-        this(dexPath, librarySearchPath, parent, additionalClassloader, true);
-    }
-
-    /**
-     * See {@link dalvik.system.DelegateLastClassLoader#DelegateLastClassLoader
-     * (String, String, List<ClassLoader>, boolean)}.
-     */
-    AdapterClassLoader(@NonNull String dexPath, @Nullable String librarySearchPath,
-            @Nullable ClassLoader parent, @Nullable ClassLoader additionalClassloader,
-                boolean delegateResourceLoading) {
-        super(dexPath, librarySearchPath, parent);
-        mSharedLibraryClassLoader = additionalClassloader;
-    }
-
-    /**
-     * A copy from {@link dalvik.system.DelegateLastClassLoader}, but uses both {@code parent}
-     * and {@code additionalClassLoader} from the constructor as parent classloaders.
-     *
-     * If AdapterClassLoader are loaded, loading them
-     * from this classloader will be skipped and instead they'll be loaded from the parent
-     * classloader, so that they are not duplicated.
-     */
-    @Override
-    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        // First, check whether the class has already been loaded. Return it if that's the case.
-        Class<?> cl = findLoadedClass(name);
-        if (cl != null) {
-            return cl;
-        }
-
-        // Next, check whether the class in question is present in the boot classpath.
-        try {
-            return Object.class.getClassLoader().loadClass(name);
-        } catch (ClassNotFoundException ignored) {
-            // It's fine, just continue
-        }
-
-        ClassNotFoundException fromSuper = null;
-
-        // Only load adapter classes and certain util classes in this classloader.
-        if (name != null && PATTERN.matcher(name).find()) {
-            // Next, check whether the class in question is present in the dexPath that this
-            // classloader operates on, or its shared libraries.
-            try {
-                return findClass(name);
-            } catch (ClassNotFoundException ex) {
-                fromSuper = ex;
-            }
-        }
-
-        // Loading OEM-APIs
-        // Next, check any additional classloaders.
-        if (mSharedLibraryClassLoader != null && SHARED_LIBRARY_PATTERN.matcher(name).matches()) {
-            try {
-                return mSharedLibraryClassLoader.loadClass(name);
-            } catch (ClassNotFoundException ignored) {
-                // It's fine, just continue
-            }
-        }
-
-        // Finally, check whether the class in question is present in the parent classloader.
-        try {
-            return getParent().loadClass(name);
-        } catch (ClassNotFoundException cnfe) {
-            // The exception we're catching here is the CNFE thrown by the parent of this
-            // classloader. However, we would like to throw a CNFE that provides details about
-            // the class path / list of dex files associated with *this* classloader, so we choose
-            // to throw the exception thrown from that lookup.
-            if (fromSuper == null) {
-                throw cnfe;
-            }
-            throw fromSuper;
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/OemApiUtil.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/OemApiUtil.java
deleted file mode 100644
index a9c48c3..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/OemApiUtil.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.android.car.ui.sharedlibrary.oemapis.SharedLibraryFactoryOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.SharedLibraryVersionProviderOEMV1;
-
-/**
- * Helper class for accessing oem-apis without reflection.
- *
- * Because this class creates adapters, and adapters implement OEM APIs, this class cannot
- * be created with the app's classloader. You must use {@link AdapterClassLoader} to load it
- * so that both the app and shared library's classes can be loaded from this class.
- */
-final class OemApiUtil {
-
-    private static final String TAG = "carui";
-
-    /**
-     * Given a shared library's context, return it's implementation of {@link SharedLibraryFactory}.
-     *
-     * This is done by asking the shared library's {@link SharedLibraryVersionProvider} for a
-     * factory object, and checking if it's instanceof each version of
-     * {@link SharedLibraryFactoryOEMV1}, casting to the correct one when found.
-     *
-     * @param sharedLibraryContext The shared library's context. This context will return
-     *                             the shared library's classloader from
-     *                             {@link Context#getClassLoader()}.
-     * @param appPackageName The package name of the application. This is passed to the shared
-     *                       library so that it can provide unique customizations per-app.
-     * @return A {@link SharedLibraryFactory}
-     */
-    static SharedLibraryFactory getSharedLibraryFactory(
-            Context sharedLibraryContext, String appPackageName) {
-
-        Object oemVersionProvider = null;
-        try {
-            oemVersionProvider = Class
-                    .forName("com.android.car.ui.sharedlibrary.SharedLibraryVersionProviderImpl")
-                    .getDeclaredConstructor()
-                    .newInstance();
-        } catch (ClassNotFoundException e) {
-            Log.i(TAG, "SharedLibraryVersionProviderImpl not found.", e);
-        } catch (ReflectiveOperationException e) {
-            Log.e(TAG, "SharedLibraryVersionProviderImpl could not be instantiated!", e);
-        }
-
-        // Add new version providers in an if-else chain here, in descending version order so
-        // that higher versions are preferred.
-        SharedLibraryVersionProvider versionProvider = null;
-        if (oemVersionProvider instanceof SharedLibraryVersionProviderOEMV1) {
-            versionProvider = new SharedLibraryVersionProviderAdapterV1(
-                    (SharedLibraryVersionProviderOEMV1) oemVersionProvider);
-        } else {
-            Log.e(TAG, "SharedLibraryVersionProviderImpl was not instanceof any known "
-                    + "versions of SharedLibraryVersionProviderOEMV#.");
-        }
-
-        SharedLibraryFactory oemSharedLibraryFactory = null;
-        if (versionProvider != null) {
-            Object factory = versionProvider.getSharedLibraryFactory(
-                    1, sharedLibraryContext, appPackageName);
-            if (factory instanceof SharedLibraryFactoryOEMV1) {
-                oemSharedLibraryFactory = new SharedLibraryFactoryAdapterV1(
-                        (SharedLibraryFactoryOEMV1) factory, sharedLibraryContext);
-            } else {
-                Log.e(TAG, "SharedLibraryVersionProvider found, but did not provide a"
-                        + " factory implementing any known interfaces!");
-            }
-        }
-
-        return oemSharedLibraryFactory;
-    }
-
-    private OemApiUtil() {}
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryConfigProvider.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryConfigProvider.java
deleted file mode 100644
index 239be64..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryConfigProvider.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import java.util.Set;
-
-/**
- * This interface can be implemented on an app's {@link android.app.Application} class
- * in order to provide additional options to consider when loading the shared library.
- */
-public interface SharedLibraryConfigProvider {
-
-    /**
-     * Returns a set of {@link SharedLibrarySpecifier SharedLibrarySpecifiers}. If a shared library
-     * is in this set, it will not be loaded. The fallback implementation in the static version of
-     * car-ui-lib will be used instead.
-     */
-    Set<SharedLibrarySpecifier> getSharedLibraryDenyList();
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactory.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactory.java
deleted file mode 100644
index 8010341..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactory.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.appstyledview.AppStyledViewController;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.ToolbarController;
-import com.android.car.ui.widget.CarUiTextView;
-
-import java.util.List;
-
-/**
- * This interface contains methods to create customizable carui components.
- */
-public interface SharedLibraryFactory {
-
-    /**
-     * Creates the base layout, and optionally the toolbar.
-     *
-     * @param contentView           The view to install the base layout around.
-     * @param insetsChangedListener A method to call when the insets change.
-     * @param toolbarEnabled        Whether or not to add a toolbar to the base layout.
-     * @param fullscreen            A hint specifying whether this view we're installing around
-     *                              takes up the whole screen or not. Used to know if putting
-     *                              decorations around the edges is appropriate.
-     * @return A {@link ToolbarController} or null if {@code toolbarEnabled} was false.
-     */
-    @Nullable
-    ToolbarController installBaseLayoutAround(
-            View contentView,
-            InsetsChangedListener insetsChangedListener,
-            boolean toolbarEnabled,
-            boolean fullscreen);
-
-    /**
-     * Creates a {@link CarUiTextView}.
-     *
-     * @param context The visual context to create views with.
-     * @return A {@link CarUiTextView}
-     */
-    @NonNull
-    CarUiTextView createTextView(Context context, AttributeSet attrs);
-
-    /**
-     * Creates a app styled view.
-     *
-     * @return the view used for app styled view.
-     */
-    AppStyledViewController createAppStyledView(Context activityContext);
-
-    /**
-     * Creates an instance of CarUiRecyclerView
-     *
-     * @param context The visual context to create views with.
-     * @param attrs   An object containing initial attributes for the button.
-     */
-    CarUiRecyclerView createRecyclerView(Context context, AttributeSet attrs);
-
-    /**
-     * Creates an instance of list item adapter
-     */
-    RecyclerView.Adapter<? extends RecyclerView.ViewHolder> createListItemAdapter(
-            List<? extends CarUiListItem> items);
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactoryAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactoryAdapterV1.java
deleted file mode 100644
index 730d2d8..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactoryAdapterV1.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.text.SpannableString;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.CarUiText;
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.FocusAreaAdapterV1;
-import com.android.car.ui.FocusParkingView;
-import com.android.car.ui.FocusParkingViewAdapterV1;
-import com.android.car.ui.R;
-import com.android.car.ui.appstyledview.AppStyledViewController;
-import com.android.car.ui.appstyledview.AppStyledViewControllerAdapterV1;
-import com.android.car.ui.appstyledview.AppStyledViewControllerImpl;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiHeaderListItem;
-import com.android.car.ui.recyclerview.CarUiLayoutStyle;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapterAdapterV1;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.recyclerview.CarUiRecyclerView.CarUiRecyclerViewLayout;
-import com.android.car.ui.recyclerview.RecyclerViewAdapterV1;
-import com.android.car.ui.sharedlibrary.oemapis.InsetsOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.SharedLibraryFactoryOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.appstyledview.AppStyledViewControllerOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ContentListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.HeaderListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.LayoutStyleOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewAttributesOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.SpanSizeLookupOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ViewHolderOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1;
-import com.android.car.ui.toolbar.ToolbarController;
-import com.android.car.ui.toolbar.ToolbarControllerAdapterV1;
-import com.android.car.ui.utils.CarUiUtils;
-import com.android.car.ui.widget.CarUiTextView;
-
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * This class is an wrapper around {@link SharedLibraryFactoryOEMV1} that implements {@link
- * SharedLibraryFactory}, to provide a version-agnostic way of interfacing with the OEM's
- * SharedLibraryFactory.
- */
-public final class SharedLibraryFactoryAdapterV1 implements SharedLibraryFactory {
-    SharedLibraryFactoryOEMV1 mOem;
-    SharedLibraryFactoryStub mFactoryStub;
-
-    public SharedLibraryFactoryAdapterV1(SharedLibraryFactoryOEMV1 oem, Context sharedLibContext) {
-        mOem = oem;
-        mFactoryStub = new SharedLibraryFactoryStub(sharedLibContext);
-
-        mOem.setRotaryFactories(
-                c -> new FocusParkingViewAdapterV1(new FocusParkingView(c)),
-                c -> new FocusAreaAdapterV1(new FocusArea(c)));
-    }
-
-    @Override
-    @Nullable
-    public ToolbarController installBaseLayoutAround(
-            View contentView,
-            InsetsChangedListener insetsChangedListener,
-            boolean toolbarEnabled,
-            boolean fullscreen) {
-
-        if (!mOem.customizesBaseLayout()) {
-            return mFactoryStub.installBaseLayoutAround(contentView,
-                    insetsChangedListener, toolbarEnabled, fullscreen);
-        }
-
-        ToolbarControllerOEMV1 toolbar = mOem.installBaseLayoutAround(contentView,
-                insets -> insetsChangedListener.onCarUiInsetsChanged(adaptInsets(insets)),
-                toolbarEnabled, fullscreen);
-
-        return toolbar != null
-                ? new ToolbarControllerAdapterV1(contentView.getContext(), toolbar)
-                : null;
-    }
-
-    @NonNull
-    @Override
-    public CarUiTextView createTextView(Context context, AttributeSet attrs) {
-        return mFactoryStub.createTextView(context, attrs);
-    }
-
-
-    @Override
-    public AppStyledViewController createAppStyledView(Context activityContext) {
-        AppStyledViewControllerOEMV1 appStyledViewControllerOEMV1 = mOem.createAppStyledView();
-        return appStyledViewControllerOEMV1 == null ? new AppStyledViewControllerImpl(
-                activityContext) : new AppStyledViewControllerAdapterV1(
-                appStyledViewControllerOEMV1);
-    }
-
-    private Insets adaptInsets(InsetsOEMV1 insetsOEM) {
-        return new Insets(insetsOEM.getLeft(), insetsOEM.getTop(),
-                insetsOEM.getRight(), insetsOEM.getBottom());
-    }
-
-    @Override
-    public CarUiRecyclerView createRecyclerView(@NonNull Context context,
-            @Nullable AttributeSet attrs) {
-        RecyclerViewAttributesOEMV1 oemAttrs = from(context, attrs);
-        RecyclerViewOEMV1 oemRecyclerView = mOem.createRecyclerView(context, oemAttrs);
-        if (oemRecyclerView != null) {
-            RecyclerViewAdapterV1 rv = new RecyclerViewAdapterV1(context, attrs);
-            rv.setRecyclerViewOEMV1(oemRecyclerView);
-            return rv;
-        } else {
-            return mFactoryStub.createRecyclerView(context, attrs);
-        }
-    }
-
-    @Override
-    public RecyclerView.Adapter<? extends RecyclerView.ViewHolder> createListItemAdapter(
-            List<? extends CarUiListItem> items) {
-        List<ListItemOEMV1> oemItems = CarUiUtils.convertList(items,
-                SharedLibraryFactoryAdapterV1::toOemListItem);
-
-        AdapterOEMV1<? extends ViewHolderOEMV1> oemAdapter = mOem.createListItemAdapter(oemItems);
-        return oemAdapter != null ? new CarUiListItemAdapterAdapterV1(oemAdapter)
-                : mFactoryStub.createListItemAdapter(items);
-    }
-
-    private static RecyclerViewAttributesOEMV1 from(Context context, AttributeSet attrs) {
-        RecyclerViewAttributesOEMV1 oemAttrs = null;
-        if (attrs != null) {
-            TypedArray a = context.obtainStyledAttributes(
-                    attrs,
-                    R.styleable.CarUiRecyclerView,
-                    0,
-                    R.style.Widget_CarUi_CarUiRecyclerView);
-            final int carUiRecyclerViewLayout = a.getInt(
-                    R.styleable.CarUiRecyclerView_layoutStyle,
-                    CarUiRecyclerViewLayout.LINEAR);
-            final int spanCount = a.getInt(
-                    R.styleable.CarUiRecyclerView_numOfColumns, /* defValue= */ 1);
-            final boolean rotaryScrollEnabled = a.getBoolean(
-                    R.styleable.CarUiRecyclerView_rotaryScrollEnabled,
-                    /* defValue=*/ false);
-            final int orientation = a.getInt(
-                    R.styleable.CarUiRecyclerView_android_orientation,
-                    CarUiLayoutStyle.VERTICAL);
-            final boolean reversed = a.getBoolean(
-                    R.styleable.CarUiRecyclerView_reverseLayout, false);
-            final int size = a.getInt(R.styleable.CarUiRecyclerView_carUiSize,
-                    CarUiRecyclerView.SIZE_LARGE);
-            a.recycle();
-
-            final LayoutStyleOEMV1 layoutStyle = new LayoutStyleOEMV1() {
-                @Override
-                public int getSpanCount() {
-                    return spanCount;
-                }
-
-                @Override
-                public int getLayoutType() {
-                    switch (carUiRecyclerViewLayout) {
-                        case CarUiRecyclerViewLayout.GRID:
-                            return LayoutStyleOEMV1.LAYOUT_TYPE_GRID;
-                        case CarUiRecyclerViewLayout.LINEAR:
-                        default:
-                            return LayoutStyleOEMV1.LAYOUT_TYPE_LINEAR;
-                    }
-                }
-
-                @Override
-                public int getOrientation() {
-                    switch (orientation) {
-                        case CarUiLayoutStyle.HORIZONTAL:
-                            return LayoutStyleOEMV1.ORIENTATION_HORIZONTAL;
-                        case CarUiLayoutStyle.VERTICAL:
-                        default:
-                            return LayoutStyleOEMV1.ORIENTATION_VERTICAL;
-                    }
-                }
-
-                @Override
-                public boolean getReverseLayout() {
-                    return reversed;
-                }
-
-                @Override
-                public SpanSizeLookupOEMV1 getSpanSizeLookup() {
-                    // This can be set via setLayoutStyle API later.
-                    return null;
-                }
-            };
-
-            oemAttrs = new RecyclerViewAttributesOEMV1() {
-                @Override
-                public boolean isRotaryScrollEnabled() {
-                    return rotaryScrollEnabled;
-                }
-
-                @Override
-                public int getSize() {
-                    switch (size) {
-                        case CarUiRecyclerView.SIZE_SMALL:
-                            return RecyclerViewAttributesOEMV1.SIZE_SMALL;
-                        case CarUiRecyclerView.SIZE_MEDIUM:
-                            return RecyclerViewAttributesOEMV1.SIZE_MEDIUM;
-                        case CarUiRecyclerView.SIZE_LARGE:
-                        default:
-                            return RecyclerViewAttributesOEMV1.SIZE_LARGE;
-                    }
-                }
-
-                @Override
-                public LayoutStyleOEMV1 getLayoutStyle() {
-                    return layoutStyle;
-                }
-            };
-        }
-        return oemAttrs;
-    }
-
-    private static ListItemOEMV1 toOemListItem(CarUiListItem item) {
-        if (item instanceof CarUiHeaderListItem) {
-            CarUiHeaderListItem header = (CarUiHeaderListItem) item;
-            return new HeaderListItemOEMV1.Builder(new SpannableString(header.getTitle()))
-                    .setBody(new SpannableString(header.getBody()))
-                    .build();
-        } else if (item instanceof CarUiContentListItem) {
-            CarUiContentListItem contentItem = (CarUiContentListItem) item;
-
-            ContentListItemOEMV1.Builder builder = new ContentListItemOEMV1.Builder(
-                    toOemListItemAction(contentItem.getAction()));
-
-            if (contentItem.getTitle() != null) {
-                builder.setTitle(
-                        new SpannableString(contentItem.getTitle().getPreferredText()));
-            }
-
-            if (contentItem.getBody() != null) {
-                builder.setBody(new SpannableString(
-                        CarUiText.combineMultiLine(contentItem.getBody())));
-            }
-
-            builder.setIcon(contentItem.getIcon(),
-                    toOemListItemIconType(contentItem.getPrimaryIconType()));
-
-            if (contentItem.getAction() == CarUiContentListItem.Action.ICON) {
-                Consumer<ContentListItemOEMV1> listener =
-                        contentItem.getSupplementalIconOnClickListener() != null
-                                ? oemItem ->
-                                contentItem.getSupplementalIconOnClickListener().onClick(
-                                        contentItem) : null;
-                builder.setSupplementalIcon(contentItem.getSupplementalIcon(), listener);
-            }
-
-            if (contentItem.getOnClickListener() != null) {
-                Consumer<ContentListItemOEMV1> listener =
-                        contentItem.getOnClickListener() != null
-                                ? oemItem ->
-                                contentItem.getOnClickListener().onClick(contentItem) : null;
-                builder.setOnItemClickedListener(listener);
-            }
-
-            builder.setOnCheckedChangeListener(
-                    oemItem -> contentItem.setChecked(oemItem.isChecked()))
-                    .setActionDividerVisible(contentItem.isActionDividerVisible())
-                    .setEnabled(contentItem.isEnabled())
-                    .setChecked(contentItem.isChecked())
-                    .setActivated(contentItem.isActivated());
-            return builder.build();
-        } else {
-            throw new IllegalStateException("Unexpected list item type");
-        }
-    }
-
-    private static ContentListItemOEMV1.Action toOemListItemAction(
-            CarUiContentListItem.Action action) {
-        switch (action) {
-            case NONE:
-                return ContentListItemOEMV1.Action.NONE;
-            case SWITCH:
-                return ContentListItemOEMV1.Action.SWITCH;
-            case CHECK_BOX:
-                return ContentListItemOEMV1.Action.CHECK_BOX;
-            case RADIO_BUTTON:
-                return ContentListItemOEMV1.Action.RADIO_BUTTON;
-            case ICON:
-                return ContentListItemOEMV1.Action.ICON;
-            case CHEVRON:
-                return ContentListItemOEMV1.Action.CHEVRON;
-            default:
-                throw new IllegalStateException("Unexpected list item action type");
-        }
-    }
-
-    private static ContentListItemOEMV1.IconType toOemListItemIconType(
-            CarUiContentListItem.IconType iconType) {
-        switch (iconType) {
-            case CONTENT:
-                return ContentListItemOEMV1.IconType.CONTENT;
-            case STANDARD:
-                return ContentListItemOEMV1.IconType.STANDARD;
-            case AVATAR:
-                return ContentListItemOEMV1.IconType.AVATAR;
-            default:
-                throw new IllegalStateException("Unexpected list item icon type");
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactorySingleton.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactorySingleton.java
deleted file mode 100644
index a59b187..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactorySingleton.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import static java.util.Objects.requireNonNull;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Process;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This is a singleton that contains a {@link SharedLibraryFactory}. That SharedLibraryFactory
- * is used to create UI components that we want to be customizable by the OEM.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class SharedLibraryFactorySingleton {
-
-    private static final String TAG = "carui";
-    private static SharedLibraryFactory sInstance;
-
-    /*
-     ********************************************
-     *               WARNING                    *
-     ********************************************
-     * The OEM APIs as they appear on this      *
-     * branch of android are not finalized!     *
-     * If a shared library is built using them, *
-     * it will cause apps to crash!             *
-     *                                          *
-     * Please only use a shared library with    *
-     * a later version of car-ui-lib.           *
-     ********************************************
-     */
-    private static boolean sSharedLibEnabled = false;
-
-    /**
-     * Get the {@link SharedLibraryFactory}.
-     *
-     * If this is the first time the method is being called, it will initialize it using reflection
-     * to check for the existence of a shared library, and resolving the appropriate version
-     * of the shared library to use.
-     */
-    public static SharedLibraryFactory get(Context context) {
-        if (sInstance != null) {
-            return sInstance;
-        }
-
-        context = context.getApplicationContext();
-
-        if (!sSharedLibEnabled) {
-            sInstance = new SharedLibraryFactoryStub(context);
-            return sInstance;
-        }
-
-        String sharedLibPackageName = CarUiUtils.getSystemProperty(context.getResources(),
-                R.string.car_ui_shared_library_package_system_property_name);
-
-        if (TextUtils.isEmpty(sharedLibPackageName)) {
-            sInstance = new SharedLibraryFactoryStub(context);
-            return sInstance;
-        }
-
-        PackageInfo sharedLibPackageInfo;
-        try {
-            sharedLibPackageInfo = context.getPackageManager()
-                    .getPackageInfo(sharedLibPackageName, 0);
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "Could not load CarUi shared library, package "
-                    + sharedLibPackageName + " was not found.");
-            sInstance = new SharedLibraryFactoryStub(context);
-            return sInstance;
-        }
-
-        Context applicationContext = context.getApplicationContext();
-        if (applicationContext instanceof SharedLibraryConfigProvider) {
-            Set<SharedLibrarySpecifier> deniedPackages =
-                    ((SharedLibraryConfigProvider) applicationContext).getSharedLibraryDenyList();
-            if (deniedPackages != null && deniedPackages.stream()
-                    .anyMatch(specs -> specs.matches(sharedLibPackageInfo))) {
-                Log.i(TAG, "Package " + context.getPackageName()
-                        + " denied loading shared library " + sharedLibPackageName);
-                sInstance = new SharedLibraryFactoryStub(context);
-                return sInstance;
-            }
-        }
-
-        Context sharedLibraryContext;
-        try {
-            sharedLibraryContext = context.createPackageContext(
-                    sharedLibPackageName,
-                    Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "Could not load CarUi shared library, package "
-                    + sharedLibPackageName + " was not found.");
-            sInstance = new SharedLibraryFactoryStub(context);
-            return sInstance;
-        }
-
-        AdapterClassLoader adapterClassLoader =
-                instantiateClassLoader(context.getApplicationInfo(),
-                        requireNonNull(SharedLibraryFactorySingleton.class.getClassLoader()),
-                        sharedLibraryContext.getClassLoader());
-
-        try {
-            Class<?> oemApiUtilClass = adapterClassLoader
-                    .loadClass("com.android.car.ui.sharedlibrarysupport.OemApiUtil");
-            Method getSharedLibraryFactoryMethod = oemApiUtilClass.getDeclaredMethod(
-                    "getSharedLibraryFactory", Context.class, String.class);
-            getSharedLibraryFactoryMethod.setAccessible(true);
-            sInstance = (SharedLibraryFactory) getSharedLibraryFactoryMethod
-                    .invoke(null, sharedLibraryContext, context.getPackageName());
-        } catch (ReflectiveOperationException e) {
-            Log.e(TAG, "Could not load CarUi shared library", e);
-            sInstance = new SharedLibraryFactoryStub(context);
-            return sInstance;
-        }
-
-        if (sInstance == null) {
-            Log.e(TAG, "Could not load CarUi shared library");
-            sInstance = new SharedLibraryFactoryStub(context);
-            return sInstance;
-        }
-
-        Log.i(TAG, "Loaded shared library " + sharedLibPackageName
-                + " version " + sharedLibPackageInfo.getLongVersionCode()
-                + " for package " + context.getPackageName());
-
-        return sInstance;
-    }
-
-    /**
-     * This method globally enables/disables the shared library. It only applies upon the next
-     * call to {@link #get}, components that have already been created won't switch between
-     * the shared/static library implementations.
-     * <p>
-     * This method is @VisibleForTesting so that unit tests can run both with and without
-     * the shared library. Since it's tricky to use correctly, real apps shouldn't use it.
-     * Instead, apps should use {@link SharedLibraryConfigProvider} to control if their
-     * shared library is disabled.
-     */
-    @VisibleForTesting
-    public static void setSharedLibEnabled(boolean sharedLibEnabled) {
-        sSharedLibEnabled = sharedLibEnabled;
-        // Cause the next call to get() to reinitialize the shared library
-        sInstance = null;
-    }
-
-    private SharedLibraryFactorySingleton() {}
-
-    @NonNull
-    private static AdapterClassLoader instantiateClassLoader(@NonNull ApplicationInfo appInfo,
-            @NonNull ClassLoader parent, @NonNull ClassLoader sharedlibraryClassLoader) {
-        // All this apk loading code is copied from another Google app
-        List<String> libraryPaths = new ArrayList<>(3);
-        if (appInfo.nativeLibraryDir != null) {
-            libraryPaths.add(appInfo.nativeLibraryDir);
-        }
-        if ((appInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) == 0) {
-            for (String abi : getSupportedAbisForCurrentRuntime()) {
-                libraryPaths.add(appInfo.sourceDir + "!/lib/" + abi);
-            }
-        }
-
-        String flatLibraryPaths = (libraryPaths.size() == 0
-                ? null : TextUtils.join(File.pathSeparator, libraryPaths));
-
-        String apkPaths = appInfo.sourceDir;
-        if (appInfo.sharedLibraryFiles != null && appInfo.sharedLibraryFiles.length > 0) {
-            // Unless you pass PackageManager.GET_SHARED_LIBRARY_FILES this will always be null
-            // HOWEVER, if you running on a device with F5 active, the module's dex files are
-            // always listed in ApplicationInfo.sharedLibraryFiles and should be included in
-            // the classpath.
-            apkPaths +=
-                    File.pathSeparator + TextUtils.join(File.pathSeparator,
-                            appInfo.sharedLibraryFiles);
-        }
-
-        return new AdapterClassLoader(apkPaths, flatLibraryPaths, parent, sharedlibraryClassLoader);
-    }
-
-    private static List<String> getSupportedAbisForCurrentRuntime() {
-        List<String> abis = new ArrayList<>();
-        if (Process.is64Bit()) {
-            Collections.addAll(abis, Build.SUPPORTED_64_BIT_ABIS);
-        } else {
-            Collections.addAll(abis, Build.SUPPORTED_32_BIT_ABIS);
-        }
-        return abis;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactoryStub.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactoryStub.java
deleted file mode 100644
index 3bb69b6..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryFactoryStub.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import androidx.annotation.LayoutRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-
-import com.android.car.ui.R;
-import com.android.car.ui.appstyledview.AppStyledViewController;
-import com.android.car.ui.appstyledview.AppStyledViewControllerImpl;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.recyclerview.CarUiRecyclerViewImpl;
-import com.android.car.ui.toolbar.ToolbarController;
-import com.android.car.ui.toolbar.ToolbarControllerImpl;
-import com.android.car.ui.widget.CarUiTextView;
-import com.android.car.ui.widget.CarUiTextViewImpl;
-
-import java.util.List;
-
-/**
- * This is the stub implementation of {@link SharedLibraryFactory}, used when there is no shared
- * library installed on the system. It delegates to the static library implementation of the
- * necessary components.
- * <p>
- * Do not use from client apps, for car-ui-lib internal use only.
- */
-//TODO(b/179092760) Find a way to prevent apps from using this
-public final class SharedLibraryFactoryStub implements SharedLibraryFactory {
-
-    private final Context mContext;
-
-    public SharedLibraryFactoryStub(Context context) {
-        mContext = context;
-    }
-
-    @Nullable
-    @Override
-    public ToolbarController installBaseLayoutAround(View contentView,
-            InsetsChangedListener insetsChangedListener,
-            boolean toolbarEnabled,
-            boolean fullscreen) {
-        boolean legacyToolbar = Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q;
-        @LayoutRes final int baseLayoutRes;
-
-        if (toolbarEnabled) {
-            if (legacyToolbar) {
-                boolean twoRow = contentView.getResources()
-                        .getBoolean(R.bool.car_ui_toolbar_tabs_on_second_row);
-                baseLayoutRes = twoRow
-                        ? R.layout.car_ui_base_layout_toolbar_legacy_two_row
-                        : R.layout.car_ui_base_layout_toolbar_legacy;
-            } else {
-                baseLayoutRes = R.layout.car_ui_base_layout_toolbar;
-            }
-        } else {
-            baseLayoutRes = R.layout.car_ui_base_layout;
-        }
-
-        View baseLayout = LayoutInflater.from(contentView.getContext())
-                .inflate(baseLayoutRes, null, false);
-
-        // Replace the app's content view with a base layout
-        ViewGroup contentViewParent = (ViewGroup) contentView.getParent();
-        int contentIndex = contentViewParent.indexOfChild(contentView);
-        contentViewParent.removeView(contentView);
-        contentViewParent.addView(baseLayout, contentIndex, contentView.getLayoutParams());
-
-        // Add the app's content view to the baseLayout's content view container
-        FrameLayout contentViewContainer = requireViewByRefId(baseLayout,
-                R.id.car_ui_base_layout_content_container);
-        contentViewContainer.addView(contentView, new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-
-        ToolbarController toolbarController = null;
-        if (toolbarEnabled) {
-            if (legacyToolbar) {
-                toolbarController = new ToolbarControllerImpl(
-                        requireViewByRefId(baseLayout, R.id.car_ui_toolbar));
-            } else {
-                toolbarController = new ToolbarControllerImpl(baseLayout);
-            }
-        }
-
-        InsetsUpdater insetsUpdater = new InsetsUpdater(baseLayout, contentView);
-        insetsUpdater.replaceInsetsChangedListenerWith(insetsChangedListener);
-
-        return toolbarController;
-    }
-
-    @NonNull
-    @Override
-    public CarUiTextView createTextView(Context context, AttributeSet attrs) {
-        return new CarUiTextViewImpl(context, attrs);
-    }
-
-    @Override
-    public AppStyledViewController createAppStyledView(Context activityContext) {
-        return new AppStyledViewControllerImpl(activityContext);
-    }
-
-    /**
-     * InsetsUpdater waits for layout changes, and when there is one, calculates the appropriate
-     * insets into the content view.
-     *
-     * <p>It then calls {@link InsetsChangedListener#onCarUiInsetsChanged(Insets)} on the
-     * {@link Activity} and any {@link Fragment Fragments} the Activity might have. If none of the
-     * Activity/Fragments implement {@link InsetsChangedListener}, it will set padding on the
-     * content view equal to the insets.
-     */
-    public static final class InsetsUpdater {
-        // These tags mark views that should overlay the content view in the base layout.
-        // OEMs should add them to views in their base layout, ie: android:tag="car_ui_left_inset"
-        // Apps will then be able to draw under these views, but will be encouraged to not put
-        // any user-interactable content there.
-        private static final String LEFT_INSET_TAG = "car_ui_left_inset";
-        private static final String RIGHT_INSET_TAG = "car_ui_right_inset";
-        private static final String TOP_INSET_TAG = "car_ui_top_inset";
-        private static final String BOTTOM_INSET_TAG = "car_ui_bottom_inset";
-
-        private final View mContentView;
-        private final View mContentViewContainer; // Equivalent to mContentView except in Media
-        private final View mLeftInsetView;
-        private final View mRightInsetView;
-        private final View mTopInsetView;
-        private final View mBottomInsetView;
-        private InsetsChangedListener mInsetsChangedListenerDelegate;
-
-        @NonNull
-        private Insets mInsets = new Insets();
-
-        /**
-         * Constructs an InsetsUpdater that calculates and dispatches insets to an {@link
-         * Activity}.
-         *
-         * @param baseLayout  The root view of the base layout
-         * @param contentView The android.R.id.content View
-         */
-        InsetsUpdater(
-                @NonNull View baseLayout,
-                @NonNull View contentView) {
-            mContentView = contentView;
-            mContentViewContainer = requireViewByRefId(baseLayout,
-                    R.id.car_ui_base_layout_content_container);
-
-            mLeftInsetView = baseLayout.findViewWithTag(LEFT_INSET_TAG);
-            mRightInsetView = baseLayout.findViewWithTag(RIGHT_INSET_TAG);
-            mTopInsetView = baseLayout.findViewWithTag(TOP_INSET_TAG);
-            mBottomInsetView = baseLayout.findViewWithTag(BOTTOM_INSET_TAG);
-
-            final View.OnLayoutChangeListener layoutChangeListener =
-                    (View v, int left, int top, int right, int bottom,
-                            int oldLeft, int oldTop, int oldRight, int oldBottom) -> {
-                        if (left != oldLeft || top != oldTop
-                                || right != oldRight || bottom != oldBottom) {
-                            recalcInsets();
-                        }
-                    };
-
-            if (mLeftInsetView != null) {
-                mLeftInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            if (mRightInsetView != null) {
-                mRightInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            if (mTopInsetView != null) {
-                mTopInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            if (mBottomInsetView != null) {
-                mBottomInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            contentView.addOnLayoutChangeListener(layoutChangeListener);
-            mContentViewContainer.addOnLayoutChangeListener(layoutChangeListener);
-        }
-
-        public void replaceInsetsChangedListenerWith(InsetsChangedListener listener) {
-            mInsetsChangedListenerDelegate = listener;
-        }
-
-        /**
-         * Recalculate the amount of insets we need, and then dispatch them.
-         */
-        private void recalcInsets() {
-
-            // Calculate how much each inset view overlays the content view
-
-            // These initial values are for Media Center's implementation of base layouts.
-            // They should evaluate to 0 in all other apps, because the content view and content
-            // view container have the same size and position there.
-            int top = Math.max(0,
-                    getTopOfView(mContentViewContainer) - getTopOfView(mContentView));
-            int left = Math.max(0,
-                    getLeftOfView(mContentViewContainer) - getLeftOfView(mContentView));
-            int right = Math.max(0,
-                    getRightOfView(mContentView) - getRightOfView(mContentViewContainer));
-            int bottom = Math.max(0,
-                    getBottomOfView(mContentView) - getBottomOfView(mContentViewContainer));
-            if (mTopInsetView != null) {
-                top += Math.max(0,
-                        getBottomOfView(mTopInsetView) - getTopOfView(mContentViewContainer));
-            }
-            if (mBottomInsetView != null) {
-                bottom += Math.max(0,
-                        getBottomOfView(mContentViewContainer) - getTopOfView(mBottomInsetView));
-            }
-            if (mLeftInsetView != null) {
-                left += Math.max(0,
-                        getRightOfView(mLeftInsetView) - getLeftOfView(mContentViewContainer));
-            }
-            if (mRightInsetView != null) {
-                right += Math.max(0,
-                        getRightOfView(mContentViewContainer) - getLeftOfView(mRightInsetView));
-            }
-            Insets insets = new Insets(left, top, right, bottom);
-
-            if (!insets.equals(mInsets)) {
-                mInsets = insets;
-                dispatchNewInsets(insets);
-            }
-        }
-
-        /**
-         * Dispatch the new {@link Insets} to the {@link InsetsChangedListener} IIF there is one,
-         * otherwise dispatch the new {@link Insets} to the {@link Activity} and all of its {@link
-         * Fragment Fragments}. If none of those implement {@link InsetsChangedListener}, we will
-         * set the value of the insets as padding on the content view.
-         *
-         * @param insets The newly-changed insets.
-         */
-        /* package */ void dispatchNewInsets(Insets insets) {
-            mInsets = insets;
-
-
-            if (mInsetsChangedListenerDelegate != null) {
-                mInsetsChangedListenerDelegate.onCarUiInsetsChanged(insets);
-            } else {
-                mContentView.setPadding(insets.getLeft(), insets.getTop(),
-                        insets.getRight(), insets.getBottom());
-            }
-        }
-
-        private static int getLeftOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[0];
-        }
-
-        private static int getRightOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[0] + v.getWidth();
-        }
-
-        private static int getTopOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[1];
-        }
-
-        private static int getBottomOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[1] + v.getHeight();
-        }
-    }
-
-    @Override
-    public CarUiRecyclerView createRecyclerView(Context context, AttributeSet attrs) {
-        return new CarUiRecyclerViewImpl(context, attrs);
-    }
-
-    @Override
-    public CarUiListItemAdapter createListItemAdapter(List<? extends CarUiListItem> items) {
-        return new CarUiListItemAdapter(items);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibrarySpecifier.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibrarySpecifier.java
deleted file mode 100644
index 5dc7bec..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibrarySpecifier.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import android.content.pm.PackageInfo;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * This is a data class that represents a particular shared library. It can be used
- * via {@link SharedLibraryConfigProvider} to deny loading certain shared libraries.
- *
- * Create a new instance of this class using {@link #builder()}.
- */
-public final class SharedLibrarySpecifier {
-
-    @Nullable
-    private final String mPackageName;
-    @Nullable
-    private final Long mMaxVersion;
-
-    private SharedLibrarySpecifier(Builder builder) {
-        mPackageName = builder.mPackageName;
-        mMaxVersion = builder.mMaxVersion;
-    }
-
-    /** Creates a {@link Builder} */
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /* package */ boolean matches(@NonNull PackageInfo packageInfo) {
-        boolean nameMatches = mPackageName == null
-                || mPackageName.equals(packageInfo.packageName);
-        boolean versionMatches = mMaxVersion == null
-                || mMaxVersion >= packageInfo.getLongVersionCode();
-        return nameMatches && versionMatches;
-    }
-
-    /** A builder class for {@link SharedLibrarySpecifier} */
-    public static class Builder {
-        @Nullable
-        private String mPackageName;
-        @Nullable
-        private Long mMaxVersion;
-
-        private Builder() {}
-
-        /**
-         * Sets the package name to match. If it is unset, any package name will be matched.
-         *
-         * @return This builder, for chaining calls.
-         */
-        public Builder setPackageName(String packageName) {
-            mPackageName = packageName;
-            return this;
-        }
-
-        /**
-         * Sets the maximum version to match. This is the {@code android:versionCode} integer
-         * in the shared library's {@code <manifest>} tag. If it is unset, any version will
-         * be matched.
-         *
-         * @return This builder, for chaining calls.
-         */
-        public Builder setMaxVersion(long maxVersion) {
-            mMaxVersion = maxVersion;
-            return this;
-        }
-
-        /** Builds the {@link SharedLibrarySpecifier} */
-        public SharedLibrarySpecifier build() {
-            return new SharedLibrarySpecifier(this);
-        }
-    };
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryVersionProvider.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryVersionProvider.java
deleted file mode 100644
index daf2bda..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryVersionProvider.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import android.content.Context;
-
-/**
- * An interface for objects that support providing a list a supported versions of
- * {@link SharedLibraryFactory} to the app. See
- * {@link #getSharedLibraryFactory(int, Context, String)}} for more information.
- *
- * Do not use from client apps, for car-ui-lib internal use only.
- */
-//TODO(b/179092760) Find a way to prevent apps from using this
-public interface SharedLibraryVersionProvider {
-    /**
-     * Returns an object that implements {@link SharedLibraryFactory} or a later version.
-     *
-     * OEMs should aim to return the highest version of the factory possible that is <=
-     * {@code maxVersion}. If the shared library is not able to provide that version,
-     * it may return null, in which case car-ui-lib will fall back to it's static,
-     * uncustomized implementation.
-     *
-     * The shared library may also choose to return different SharedLibraryFactories based on
-     * certain conditions, like what type of device this is, or what app it's being used in.
-     * (The app can be discovered via {@link android.app.Application#getProcessName()}
-     *
-     * @param maxVersion The maximum version of {@link SharedLibraryFactory} supported by the
-     *                   app.
-     * @param context The shared library's context. It uses the shared library's classloader,
-     *                so layout inflaters created from it can use views defined in the shared lib.
-     * @param packageName The package name of the app creating the shared library. Can be used
-     *                    to provide per-app customizations.
-     *
-     * @return An object implementing {@link SharedLibraryFactory} for a version <=
-     *         {@code maxVersion}.
-     */
-    Object getSharedLibraryFactory(int maxVersion, Context context, String packageName);
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryVersionProviderAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryVersionProviderAdapterV1.java
deleted file mode 100644
index ca14aea..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/sharedlibrarysupport/SharedLibraryVersionProviderAdapterV1.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrarysupport;
-
-import android.content.Context;
-
-import com.android.car.ui.sharedlibrary.oemapis.SharedLibraryVersionProviderOEMV1;
-
-/**
- * This class is an wrapper around {@link SharedLibraryVersionProviderOEMV1} that implements
- * {@link SharedLibraryVersionProvider}, to provide a version-agnostic way of interfacing with
- * the OEM's SharedLibraryFactoryVersionProvider.
- */
-final class SharedLibraryVersionProviderAdapterV1 implements SharedLibraryVersionProvider {
-
-    private SharedLibraryVersionProviderOEMV1 mOemProvider;
-
-    SharedLibraryVersionProviderAdapterV1(
-            SharedLibraryVersionProviderOEMV1 oemVersionProvider) {
-        mOemProvider = oemVersionProvider;
-    }
-
-    @Override
-    public Object getSharedLibraryFactory(int maxVersion, Context context, String packageName) {
-        return mOemProvider.getSharedLibraryFactory(maxVersion, context, packageName);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java
deleted file mode 100644
index 8a66906..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.widget.EditText;
-
-import androidx.annotation.Nullable;
-
-import java.util.function.BiConsumer;
-
-/**
- * Edit text supporting the callbacks from the IMS. This will be useful in widescreen IME mode to
- * allow car-ui-lib to receive responses (like onClick events) from the IMS
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-class CarUiEditText extends EditText {
-
-    @Nullable
-    private BiConsumer<String, Bundle> mOnAppPrivateCommandListener = null;
-
-    // These need to be public for the layout inflater to inflate them, but
-    // checkstyle complains about a public constructor on a package-private class
-    //CHECKSTYLE:OFF Generated code
-    public CarUiEditText(Context context) {
-        super(context);
-    }
-
-    public CarUiEditText(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiEditText(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public CarUiEditText(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-    //CHECKSTYLE:ON Generated code
-
-    @Override
-    public boolean onPrivateIMECommand(String action, Bundle data) {
-        if (mOnAppPrivateCommandListener != null) {
-            mOnAppPrivateCommandListener.accept(action, data);
-        }
-        return false;
-    }
-
-    /**
-     * Sets a listener to be called when {@link #onPrivateIMECommand(String, Bundle)} is called.
-     */
-    public void setOnPrivateImeCommandListener(BiConsumer<String, Bundle> listener) {
-        mOnAppPrivateCommandListener = listener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/DeprecatedTabWrapper.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/DeprecatedTabWrapper.java
deleted file mode 100644
index f452c4e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/DeprecatedTabWrapper.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.function.Consumer;
-
-/**
- * Do not use, this class is only public so that it can be accessed from a different classloader.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class DeprecatedTabWrapper {
-    private final TabLayout.Tab mTab;
-    private final Consumer<Tab> mOnSelectedListener;
-    private String mTitle = "";
-    private Drawable mIcon = null;
-
-    public DeprecatedTabWrapper(
-            @NonNull Context context,
-            @NonNull TabLayout.Tab tab,
-            @Nullable Runnable updateListener,
-            @Nullable Consumer<Tab> onSelectedListener) {
-        mTab = tab;
-        mOnSelectedListener = onSelectedListener;
-
-        TextViewListener textViewListener = new TextViewListener(context);
-        textViewListener.setTextListener(str -> {
-            mTitle = str == null ? "" : str.toString();
-            if (updateListener != null) {
-                updateListener.run();
-            }
-        });
-        ImageViewListener imageViewListener = new ImageViewListener(context);
-        imageViewListener.setImageDrawableListener(icon -> {
-            mIcon = icon;
-            if (updateListener != null) {
-                updateListener.run();
-            }
-        });
-
-        tab.bindIcon(imageViewListener);
-        tab.bindText(textViewListener);
-    }
-
-    /**
-     * Gets the underlying {@link TabLayout.Tab}
-     */
-    public TabLayout.Tab getDeprecatedTab() {
-        return mTab;
-    }
-
-    /**
-     * Converts the underlying {@link TabLayout.Tab} into a {@link Tab} and returns it.
-     */
-    public Tab getModernTab() {
-        return Tab.builder()
-                .setText(mTitle)
-                .setIcon(mIcon)
-                .setSelectedListener(mOnSelectedListener)
-                .build();
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ImageViewListener.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ImageViewListener.java
deleted file mode 100644
index 106b612..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ImageViewListener.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.widget.ImageView;
-
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class ImageViewListener extends ImageView {
-
-    private Consumer<Drawable> mImageDrawableListener;
-
-    public ImageViewListener(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void setImageDrawable(Drawable drawable) {
-        super.setImageDrawable(drawable);
-
-        if (mImageDrawableListener != null) {
-            mImageDrawableListener.accept(drawable);
-        }
-    }
-
-    public void setImageDrawableListener(Consumer<Drawable> imageDrawableListener) {
-        mImageDrawableListener = imageDrawableListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItem.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItem.java
deleted file mode 100644
index 0414d26..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItem.java
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import android.car.drivingstate.CarUxRestrictions;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUxRestrictionsUtil;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Represents a button to display in the {@link Toolbar}.
- *
- * <p>There are currently 3 types of buttons: icon, text, and switch. Using
- * {@link Builder#setCheckable()} will ensure that you get a switch, after that
- * {@link Builder#setIcon(int)} will ensure an icon, and anything left just requires
- * {@link Builder#setTitle(int)}.
- *
- * <p>Each MenuItem has a {@link DisplayBehavior} that controls if it appears on the {@link Toolbar}
- * itself, or it's overflow menu.
- *
- * <p>If you require a search or settings button, you should use
- * {@link Builder#setToSearch()} or
- * {@link Builder#setToSettings()}.
- *
- * <p>Some properties can be changed after the creating a MenuItem, but others require being set
- * with a {@link Builder}.
- */
-public class MenuItem {
-
-    private final Context mContext;
-    private final boolean mIsCheckable;
-    private final boolean mIsActivatable;
-    private final boolean mIsSearch;
-    private final boolean mShowIconAndTitle;
-    private final boolean mIsTinted;
-    private final boolean mIsPrimary;
-    @CarUxRestrictions.CarUxRestrictionsInfo
-
-    private int mId;
-    private CarUxRestrictions mCurrentRestrictions;
-    // This is a WeakReference to allow the Toolbar (and by extension, the whole screen
-    // the toolbar is on) to be garbage-collected if the MenuItem is held past the
-    // lifecycle of the toolbar.
-    private WeakReference<Listener> mListener = new WeakReference<>(null);
-    private CharSequence mTitle;
-    private Drawable mIcon;
-    private OnClickListener mOnClickListener;
-    private final DisplayBehavior mDisplayBehavior;
-    private int mUxRestrictions;
-    private boolean mIsEnabled;
-    private boolean mIsChecked;
-    private boolean mIsVisible;
-    private boolean mIsActivated;
-
-    @SuppressWarnings("FieldCanBeLocal") // Used with weak references
-    private final CarUxRestrictionsUtil.OnUxRestrictionsChangedListener mUxRestrictionsListener =
-            uxRestrictions -> {
-                boolean wasRestricted = isRestricted();
-                mCurrentRestrictions = uxRestrictions;
-
-                if (isRestricted() != wasRestricted) {
-                    update();
-                }
-            };
-
-    private MenuItem(Builder builder) {
-        mContext = builder.mContext;
-        mId = builder.mId;
-        mIsCheckable = builder.mIsCheckable;
-        mIsActivatable = builder.mIsActivatable;
-        mTitle = builder.mTitle;
-        mIcon = builder.mIcon;
-        mOnClickListener = builder.mOnClickListener;
-        mDisplayBehavior = builder.mDisplayBehavior;
-        mIsEnabled = builder.mIsEnabled;
-        mIsChecked = builder.mIsChecked;
-        mIsVisible = builder.mIsVisible;
-        mIsActivated = builder.mIsActivated;
-        mIsSearch = builder.mIsSearch;
-        mShowIconAndTitle = builder.mShowIconAndTitle;
-        mIsTinted = builder.mIsTinted;
-        mIsPrimary = builder.mIsPrimary;
-        mUxRestrictions = builder.mUxRestrictions;
-
-        CarUxRestrictionsUtil.getInstance(mContext).register(mUxRestrictionsListener);
-    }
-
-    private void update() {
-        Listener listener = mListener.get();
-        if (listener != null) {
-            listener.onMenuItemChanged(this);
-        }
-    }
-
-    /** Sets the id, which is purely for the client to distinguish MenuItems with.  */
-    public void setId(int id) {
-        mId = id;
-        update();
-    }
-
-    /** Gets the id, which is purely for the client to distinguish MenuItems with. */
-    public int getId() {
-        return mId;
-    }
-
-    /** Returns whether the MenuItem is enabled */
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    /** Sets whether the MenuItem is enabled */
-    public void setEnabled(boolean enabled) {
-        mIsEnabled = enabled;
-
-        update();
-    }
-
-    /** Returns whether the MenuItem is checkable. If it is, it will be displayed as a switch. */
-    public boolean isCheckable() {
-        return mIsCheckable;
-    }
-
-    /**
-     * Returns whether the MenuItem is currently checked. Only valid if {@link #isCheckable()}
-     * is true.
-     */
-    public boolean isChecked() {
-        return mIsChecked;
-    }
-
-    /**
-     * Sets whether or not the MenuItem is checked.
-     * @throws IllegalStateException When {@link #isCheckable()} is false.
-     */
-    public void setChecked(boolean checked) {
-        if (!isCheckable()) {
-            throw new IllegalStateException("Cannot call setChecked() on a non-checkable MenuItem");
-        }
-
-        mIsChecked = checked;
-
-        update();
-    }
-
-    public boolean isTinted() {
-        return mIsTinted;
-    }
-
-    /** Returns whether or not the MenuItem is visible */
-    public boolean isVisible() {
-        return mIsVisible;
-    }
-
-    /** Sets whether or not the MenuItem is visible */
-    public void setVisible(boolean visible) {
-        mIsVisible = visible;
-
-        update();
-    }
-
-    /**
-     * Returns whether the MenuItem is activatable. If it is, it's every click will toggle
-     * the MenuItem's View to appear activated or not.
-     */
-    public boolean isActivatable() {
-        return mIsActivatable;
-    }
-
-    /** Returns whether or not this view is selected. Toggles after every click */
-    public boolean isActivated() {
-        return mIsActivated;
-    }
-
-    /** Sets the MenuItem as activated and updates it's View to the activated state */
-    public void setActivated(boolean activated) {
-        if (!isActivatable()) {
-            throw new IllegalStateException(
-                    "Cannot call setActivated() on a non-activatable MenuItem");
-        }
-
-        mIsActivated = activated;
-
-        update();
-    }
-
-    /** Gets the title of this MenuItem. */
-    public CharSequence getTitle() {
-        return mTitle;
-    }
-
-    /** Sets the title of this MenuItem. */
-    public void setTitle(CharSequence title) {
-        mTitle = title;
-
-        update();
-    }
-
-    /** Sets the title of this MenuItem to a string resource. */
-    public void setTitle(int resId) {
-        setTitle(mContext.getString(resId));
-    }
-
-    /** Sets the UxRestrictions of this MenuItem. */
-    public void setUxRestrictions(@CarUxRestrictions.CarUxRestrictionsInfo int uxRestrictions) {
-        if (mUxRestrictions != uxRestrictions) {
-            mUxRestrictions = uxRestrictions;
-            update();
-        }
-    }
-
-    @CarUxRestrictions.CarUxRestrictionsInfo
-    public int getUxRestrictions() {
-        return mUxRestrictions;
-    }
-
-    /** Gets the current {@link OnClickListener} */
-    public OnClickListener getOnClickListener() {
-        return mOnClickListener;
-    }
-
-    public boolean isShowingIconAndTitle() {
-        return mShowIconAndTitle;
-    }
-
-    /** Sets the {@link OnClickListener} */
-    public void setOnClickListener(OnClickListener listener) {
-        mOnClickListener = listener;
-
-        update();
-    }
-
-    public boolean isRestricted() {
-        return CarUxRestrictionsUtil.isRestricted(mUxRestrictions, mCurrentRestrictions);
-    }
-
-    /** Calls the {@link OnClickListener}. */
-    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-    public void performClick() {
-        if (!isEnabled() || !isVisible()) {
-            return;
-        }
-
-        if (isRestricted()) {
-            Toast.makeText(mContext,
-                    R.string.car_ui_restricted_while_driving, Toast.LENGTH_LONG).show();
-            return;
-        }
-
-        if (isActivatable()) {
-            setActivated(!isActivated());
-        }
-
-        if (isCheckable()) {
-            setChecked(!isChecked());
-        }
-
-        if (mOnClickListener != null) {
-            mOnClickListener.onClick(this);
-        }
-    }
-
-    /** Gets the current {@link DisplayBehavior} */
-    public DisplayBehavior getDisplayBehavior() {
-        return mDisplayBehavior;
-    }
-
-    /** Gets the current Icon */
-    public Drawable getIcon() {
-        return mIcon;
-    }
-
-    /** Sets the Icon of this MenuItem. */
-    public void setIcon(Drawable icon) {
-        mIcon = icon;
-
-        update();
-    }
-
-    /** Sets the Icon of this MenuItem to a drawable resource. */
-    public void setIcon(int resId) {
-        setIcon(resId == 0
-                ? null
-                : mContext.getDrawable(resId));
-    }
-
-    /**
-     * Returns if this MenuItem is a primary MenuItem, which means it should be visually
-     * distinct to indicate that.
-     */
-    public boolean isPrimary() {
-        return mIsPrimary;
-    }
-
-    /** Returns if this is the search MenuItem, which is not shown while searching */
-    public boolean isSearch() {
-        return mIsSearch;
-    }
-
-    /** Builder class */
-    public static final class Builder {
-        private final Context mContext;
-
-        private String mSearchTitle;
-        private String mSettingsTitle;
-        private Drawable mSearchIcon;
-        private Drawable mSettingsIcon;
-
-        private int mId = View.NO_ID;
-        private CharSequence mTitle;
-        private Drawable mIcon;
-        private OnClickListener mOnClickListener;
-        private DisplayBehavior mDisplayBehavior = DisplayBehavior.ALWAYS;
-        private boolean mIsTinted = true;
-        private boolean mShowIconAndTitle = false;
-        private boolean mIsEnabled = true;
-        private boolean mIsCheckable = false;
-        private boolean mIsChecked = false;
-        private boolean mIsVisible = true;
-        private boolean mIsActivatable = false;
-        private boolean mIsActivated = false;
-        private boolean mIsSearch = false;
-        private boolean mIsSettings = false;
-        private boolean mIsPrimary = false;
-        @CarUxRestrictions.CarUxRestrictionsInfo
-        private int mUxRestrictions = CarUxRestrictions.UX_RESTRICTIONS_BASELINE;
-
-        public Builder(Context c) {
-            // Must use getApplicationContext to avoid leaking activities when the MenuItem
-            // is held onto for longer than the Activity's lifecycle
-            mContext = c.getApplicationContext();
-        }
-
-        /** Builds a {@link MenuItem} from the current state of the Builder */
-        public MenuItem build() {
-            if (mIsActivatable && (mShowIconAndTitle || mIcon == null)) {
-                throw new IllegalStateException("Only simple icons can be activatable");
-            }
-            if (mIsCheckable && (mShowIconAndTitle || mIsActivatable)) {
-                throw new IllegalStateException("Unsupported options for a checkable MenuItem");
-            }
-            if (mIsSearch && mIsSettings) {
-                throw new IllegalStateException("Can't have both a search and settings MenuItem");
-            }
-            if (mIsActivatable && mDisplayBehavior == DisplayBehavior.NEVER) {
-                throw new IllegalStateException("Activatable MenuItems not supported as Overflow");
-            }
-
-            if (mIsSearch && (!mSearchTitle.contentEquals(mTitle)
-                    || !mSearchIcon.equals(mIcon)
-                    || mIsCheckable
-                    || mIsActivatable
-                    || !mIsTinted
-                    || mShowIconAndTitle
-                    || mDisplayBehavior != DisplayBehavior.ALWAYS)) {
-                throw new IllegalStateException("Invalid search MenuItem");
-            }
-
-            if (mIsSettings && (!mSettingsTitle.contentEquals(mTitle)
-                    || !mSettingsIcon.equals(mIcon)
-                    || mIsCheckable
-                    || mIsActivatable
-                    || !mIsTinted
-                    || mShowIconAndTitle
-                    || mDisplayBehavior != DisplayBehavior.ALWAYS)) {
-                throw new IllegalStateException("Invalid settings MenuItem");
-            }
-
-            return new MenuItem(this);
-        }
-
-        /** Sets the id, which is purely for the client to distinguish MenuItems with. */
-        public Builder setId(int id) {
-            mId = id;
-            return this;
-        }
-
-        /** Sets the title to a string resource id */
-        public Builder setTitle(int resId) {
-            setTitle(mContext.getString(resId));
-            return this;
-        }
-
-        /** Sets the title */
-        public Builder setTitle(CharSequence title) {
-            mTitle = title;
-            return this;
-        }
-
-        /**
-         * Sets the icon to a drawable resource id.
-         *
-         * <p>The icon's color and size will be changed to match the other MenuItems.
-         */
-        public Builder setIcon(int resId) {
-            mIcon = resId == 0
-                    ? null
-                    : mContext.getDrawable(resId);
-            return this;
-        }
-
-        /**
-         * Sets the icon to a drawable.
-         *
-         * <p>The icon's color and size will be changed to match the other MenuItems.
-         */
-        public Builder setIcon(Drawable icon) {
-            mIcon = icon;
-            return this;
-        }
-
-        /**
-         * Sets whether to tint the icon, true by default.
-         *
-         * <p>Try not to use this, it should only be used if the MenuItem is displaying some
-         * kind of logo or avatar and should be colored.
-         */
-        public Builder setTinted(boolean tinted) {
-            mIsTinted = tinted;
-            return this;
-        }
-
-        /** Sets whether the MenuItem is visible or not. Default true. */
-        public Builder setVisible(boolean visible) {
-            mIsVisible = visible;
-            return this;
-        }
-
-        /**
-         * Makes the MenuItem activatable, which means it will toggle it's visual state after
-         * every click.
-         */
-        public Builder setActivatable() {
-            mIsActivatable = true;
-            return this;
-        }
-
-        /**
-         * Sets whether or not the MenuItem is selected. If it is,
-         * {@link View#setSelected(boolean)} will be called on its View.
-         */
-        public Builder setActivated(boolean activated) {
-            setActivatable();
-            mIsActivated = activated;
-            return this;
-        }
-
-        /** Sets the {@link OnClickListener} */
-        public Builder setOnClickListener(OnClickListener listener) {
-            mOnClickListener = listener;
-            return this;
-        }
-
-        /**
-         * Used to show both the icon and title when displayed on the toolbar. If this
-         * is false, only the icon while be displayed when the MenuItem is in the toolbar
-         * and only the title will be displayed when the MenuItem is in the overflow menu.
-         *
-         * <p>Defaults to false.
-         */
-        public Builder setShowIconAndTitle(boolean showIconAndTitle) {
-            mShowIconAndTitle = showIconAndTitle;
-            return this;
-        }
-
-        /**
-         * Sets the {@link DisplayBehavior}.
-         *
-         * <p>If the DisplayBehavior is {@link DisplayBehavior#NEVER}, the MenuItem must not be
-         * {@link #setCheckable() checkable}.
-         */
-        public Builder setDisplayBehavior(DisplayBehavior behavior) {
-            mDisplayBehavior = behavior;
-            return this;
-        }
-
-        /** Sets whether the MenuItem is enabled or not. Default true. */
-        public Builder setEnabled(boolean enabled) {
-            mIsEnabled = enabled;
-            return this;
-        }
-
-        /**
-         * Makes the MenuItem checkable, meaning it will be displayed as a
-         * switch.
-         *
-         * <p>The MenuItem is not checkable by default.
-         */
-        public Builder setCheckable() {
-            mIsCheckable = true;
-            return this;
-        }
-
-        /**
-         * Sets whether the MenuItem is checked or not. This will imply {@link #setCheckable()}.
-         */
-        public Builder setChecked(boolean checked) {
-            setCheckable();
-            mIsChecked = checked;
-            return this;
-        }
-
-        /**
-         * Sets whether the MenuItem is primary. This is just a visual change.
-         */
-        public Builder setPrimary(boolean primary) {
-            mIsPrimary = primary;
-            return this;
-        }
-
-        /**
-         * Sets under what {@link android.car.drivingstate.CarUxRestrictions.CarUxRestrictionsInfo}
-         * the MenuItem should be restricted.
-         */
-        public Builder setUxRestrictions(
-                @CarUxRestrictions.CarUxRestrictionsInfo int restrictions) {
-            mUxRestrictions = restrictions;
-            return this;
-        }
-
-        /**
-         * Creates a search MenuItem.
-         *
-         * <p>The advantage of using this over creating your own is getting an OEM-styled search
-         * icon, and this button will always disappear while searching, even when the
-         * {@link Toolbar Toolbar's} showMenuItemsWhileSearching is true.
-         *
-         * <p>If using this, you should only change the id, visibility, or onClickListener.
-         */
-        public Builder setToSearch() {
-            mSearchTitle = mContext.getString(R.string.car_ui_toolbar_menu_item_search_title);
-            mSearchIcon = mContext.getDrawable(R.drawable.car_ui_icon_search);
-            mIsSearch = true;
-            setTitle(mSearchTitle);
-            setIcon(mSearchIcon);
-            return this;
-        }
-
-        /**
-         * Creates a settings MenuItem.
-         *
-         * <p>The advantage of this over creating your own is getting an OEM-styled settings icon,
-         * and that the MenuItem will be restricted based on
-         * {@link CarUxRestrictions#UX_RESTRICTIONS_NO_SETUP}
-         *
-         * <p>If using this, you should only change the id, visibility, or onClickListener.
-         */
-        public Builder setToSettings() {
-            mSettingsTitle = mContext.getString(R.string.car_ui_toolbar_menu_item_settings_title);
-            mSettingsIcon = mContext.getDrawable(R.drawable.car_ui_icon_settings);
-            mIsSettings = true;
-            setTitle(mSettingsTitle);
-            setIcon(mSettingsIcon);
-            setUxRestrictions(CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP);
-            return this;
-        }
-
-        /** @deprecated Use {@link #setToSearch()} instead. */
-        @Deprecated
-        public static MenuItem createSearch(Context c, OnClickListener listener) {
-            return MenuItem.builder(c)
-                    .setToSearch()
-                    .setOnClickListener(listener)
-                    .build();
-        }
-
-        /** @deprecated Use {@link #setToSettings()} instead. */
-        @Deprecated
-        public static MenuItem createSettings(Context c, OnClickListener listener) {
-            return MenuItem.builder(c)
-                    .setToSettings()
-                    .setOnClickListener(listener)
-                    .build();
-        }
-    }
-
-    /** Get a new {@link Builder}. */
-    public static Builder builder(Context context) {
-        return new Builder(context);
-    }
-
-    /**
-     * OnClickListener for a MenuItem.
-     */
-    public interface OnClickListener {
-        /** Called when the MenuItem is clicked */
-        void onClick(MenuItem item);
-    }
-
-    /**
-     * DisplayBehavior controls how the MenuItem is presented in the Toolbar
-     */
-    public enum DisplayBehavior {
-        /** Always show the MenuItem on the toolbar instead of the overflow menu */
-        ALWAYS,
-        /** Never show the MenuItem in the toolbar, always put it in the overflow menu */
-        NEVER
-    }
-
-    /**
-     * Listener for {@link Toolbar} to update when this MenuItem changes.
-     *
-     * Do not use from client apps, for car-ui-lib internal use only.
-     */
-    //TODO(b/179092760) Find a way to prevent apps from using this
-    public interface Listener {
-        /** Called when the MenuItem is changed. For use only by {@link Toolbar} */
-        void onMenuItemChanged(MenuItem item);
-    }
-
-    /**
-     * Sets a listener for changes to this MenuItem. Note that the MenuItem will only hold
-     * weak references to the Listener, so that the listener is not held if the MenuItem
-     * outlives the toolbar.
-     *
-     * Do not use from client apps, for car-ui-lib internal use only.
-     */
-    //TODO(b/179092760) Find a way to prevent apps from using this
-    public void setListener(@Nullable Listener listener) {
-        mListener = new WeakReference<>(listener);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemAdapterV1.java
deleted file mode 100644
index f134c25..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemAdapterV1.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import static com.android.car.ui.utils.CarUiUtils.charSequenceToString;
-
-import android.graphics.drawable.Drawable;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.MenuItemOEMV1;
-
-import java.util.function.Consumer;
-
-/**
- * Adapts a {@link com.android.car.ui.toolbar.MenuItem} into a
- * {@link com.android.car.ui.sharedlibrary.oemapis.toolbar.MenuItemOEMV1}
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class MenuItemAdapterV1 implements MenuItemOEMV1 {
-
-    private final MenuItem mClientMenuItem;
-    private Consumer<MenuItemOEMV1> mUpdateListener;
-
-    // This needs to be a member variable because it's only held with a weak listener
-    // elsewhere.
-    private final MenuItem.Listener mClientListener = menuItem -> {
-        if (mUpdateListener != null) {
-            mUpdateListener.accept(this);
-        }
-    };
-
-    public MenuItemAdapterV1(MenuItem item) {
-        mClientMenuItem = item;
-        item.setListener(mClientListener);
-    }
-
-    @Override
-    public void setUpdateListener(Consumer<MenuItemOEMV1> listener) {
-        mUpdateListener = listener;
-    }
-
-    @Override
-    public void performClick() {
-        mClientMenuItem.performClick();
-    }
-
-    @Override
-    public int getId() {
-        return mClientMenuItem.getId();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mClientMenuItem.isEnabled();
-    }
-
-    @Override
-    public boolean isCheckable() {
-        return mClientMenuItem.isCheckable();
-    }
-
-    @Override
-    public boolean isChecked() {
-        return mClientMenuItem.isChecked();
-    }
-
-    @Override
-    public boolean isTinted() {
-        return mClientMenuItem.isTinted();
-    }
-
-    @Override
-    public boolean isVisible() {
-        return mClientMenuItem.isVisible();
-    }
-
-    @Override
-    public boolean isActivatable() {
-        return mClientMenuItem.isActivatable();
-    }
-
-    @Override
-    public boolean isActivated() {
-        return mClientMenuItem.isActivated();
-    }
-
-    @Override
-    public String getTitle() {
-        return charSequenceToString(mClientMenuItem.getTitle());
-    }
-
-    @Override
-    public boolean isRestricted() {
-        return mClientMenuItem.isRestricted();
-    }
-
-    @Override
-    public boolean isShowingIconAndTitle() {
-        return mClientMenuItem.isShowingIconAndTitle();
-    }
-
-    @Override
-    public boolean isClickable() {
-        return mClientMenuItem.getOnClickListener() != null
-                || isCheckable()
-                || isActivatable();
-    }
-
-    @Override
-    public int getDisplayBehavior() {
-        MenuItem.DisplayBehavior displayBehavior = mClientMenuItem.getDisplayBehavior();
-        if (displayBehavior == MenuItem.DisplayBehavior.NEVER) {
-            return MenuItemOEMV1.DISPLAY_BEHAVIOR_NEVER;
-        } else {
-            return MenuItemOEMV1.DISPLAY_BEHAVIOR_ALWAYS;
-        }
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mClientMenuItem.getIcon();
-    }
-
-    @Override
-    public boolean isPrimary() {
-        return mClientMenuItem.isPrimary();
-    }
-
-    public boolean isSearch() {
-        return mClientMenuItem.isSearch();
-    }
-
-    /** Delegates to {@link MenuItem#setVisible(boolean)} */
-    public void setVisible(boolean visible) {
-        mClientMenuItem.setVisible(visible);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemRenderer.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemRenderer.java
deleted file mode 100644
index a757ea6..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemRenderer.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.text.TextUtils;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.annotation.LayoutRes;
-import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
-
-import com.android.car.ui.R;
-import com.android.car.ui.uxr.DrawableStateView;
-
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-class MenuItemRenderer implements MenuItem.Listener {
-
-    private static final int[] RESTRICTED_STATE = new int[] {R.attr.state_ux_restricted};
-
-    private final int mMenuItemIconSize;
-
-    private boolean mToolbarIsSearching;
-
-    private final MenuItem mMenuItem;
-    private final ViewGroup mParentView;
-    private View mView;
-    private View mIconContainer;
-    private ImageView mIconView;
-    private Switch mSwitch;
-    private TextView mTextView;
-    private TextView mTextWithIconView;
-    private boolean mIndividualClickListeners;
-
-    MenuItemRenderer(MenuItem item, ViewGroup parentView) {
-        mMenuItem = item;
-        mParentView = parentView;
-        mMenuItem.setListener(this);
-
-        mMenuItemIconSize = parentView.getContext().getResources()
-                .getDimensionPixelSize(R.dimen.car_ui_toolbar_menu_item_icon_size);
-    }
-
-    void setToolbarIsSearching(boolean searching) {
-        if (searching != mToolbarIsSearching) {
-            mToolbarIsSearching = searching;
-
-            if (mMenuItem.isSearch()) {
-                updateView();
-            }
-        }
-    }
-
-    @Override
-    public void onMenuItemChanged(MenuItem changedItem) {
-        updateView();
-    }
-
-    void createView(Consumer<View> callback) {
-        AsyncLayoutInflater inflater = new AsyncLayoutInflater(mParentView.getContext());
-        @LayoutRes int layout = mMenuItem.isPrimary()
-                ? R.layout.car_ui_toolbar_menu_item_primary
-                : R.layout.car_ui_toolbar_menu_item;
-        inflater.inflate(layout, mParentView, (View view, int resid,
-                ViewGroup parent) -> {
-            mView = view;
-
-            mIconContainer =
-                    requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_icon_container);
-            mIconView = requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_icon);
-            mSwitch = requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_switch);
-            mTextView = requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_text);
-            mTextWithIconView =
-                    requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_text_with_icon);
-            mIndividualClickListeners = mView.getContext().getResources()
-                    .getBoolean(R.bool.car_ui_toolbar_menuitem_individual_click_listeners);
-
-            updateView();
-            callback.accept(mView);
-        });
-    }
-
-    private void updateView() {
-        if (mView == null) {
-            return;
-        }
-
-        mView.setId(mMenuItem.getId());
-
-        boolean hasIcon = mMenuItem.getIcon() != null;
-        boolean hasText = !TextUtils.isEmpty(mMenuItem.getTitle());
-        boolean textAndIcon = mMenuItem.isShowingIconAndTitle();
-        boolean checkable = mMenuItem.isCheckable();
-
-        if (!mMenuItem.isVisible()
-                || (mMenuItem.isSearch() && mToolbarIsSearching)
-                || (!checkable && !hasIcon && !hasText)) {
-            mView.setVisibility(View.GONE);
-            return;
-        }
-        mView.setVisibility(View.VISIBLE);
-        mView.setContentDescription(mMenuItem.getTitle());
-
-        View clickTarget;
-        if (checkable) {
-            mSwitch.setChecked(mMenuItem.isChecked());
-            clickTarget = mSwitch;
-        } else if (hasText && hasIcon && textAndIcon) {
-            mMenuItem.getIcon().setBounds(0, 0, mMenuItemIconSize, mMenuItemIconSize);
-            mTextWithIconView.setCompoundDrawables(mMenuItem.getIcon(), null, null, null);
-            mTextWithIconView.setText(mMenuItem.getTitle());
-            clickTarget = mTextWithIconView;
-        } else if (hasIcon) {
-            mIconView.setImageDrawable(mMenuItem.getIcon());
-            clickTarget = mIconContainer;
-        } else { // hasText will be true
-            mTextView.setText(mMenuItem.getTitle());
-            clickTarget = mTextView;
-        }
-
-        mIconContainer.setVisibility(clickTarget == mIconContainer ? View.VISIBLE : View.GONE);
-        mTextView.setVisibility(clickTarget == mTextView ? View.VISIBLE : View.GONE);
-        mTextWithIconView.setVisibility(clickTarget == mTextWithIconView
-                ? View.VISIBLE : View.GONE);
-        mSwitch.setVisibility(clickTarget == mSwitch ? View.VISIBLE : View.GONE);
-
-        if (!mIndividualClickListeners) {
-            clickTarget = mView;
-        }
-
-        if (!mMenuItem.isTinted() && hasIcon) {
-            mMenuItem.getIcon().setTintList(null);
-        }
-
-        recursiveSetEnabledAndDrawableState(mView);
-        mView.setActivated(mMenuItem.isActivated());
-
-        if (mMenuItem.getOnClickListener() != null
-                || mMenuItem.isCheckable()
-                || mMenuItem.isActivatable()) {
-            clickTarget.setOnClickListener(v -> mMenuItem.performClick());
-        } else if (clickTarget == mView) {
-            mView.setOnClickListener(null);
-            mView.setClickable(false);
-        }
-    }
-
-    private void recursiveSetEnabledAndDrawableState(View view) {
-        view.setEnabled(mMenuItem.isEnabled());
-
-        int[] drawableState = mMenuItem.isRestricted() ? RESTRICTED_STATE : null;
-        if (view instanceof ImageView) {
-            ((ImageView) view).setImageState(drawableState, true);
-        } else if (view instanceof DrawableStateView) {
-            ((DrawableStateView) view).setExtraDrawableState(drawableState, null);
-        }
-
-        if (view instanceof ViewGroup) {
-            ViewGroup viewGroup = ((ViewGroup) view);
-            for (int i = 0; i < viewGroup.getChildCount(); i++) {
-                recursiveSetEnabledAndDrawableState(viewGroup.getChildAt(i));
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemXmlParserUtil.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemXmlParserUtil.java
deleted file mode 100644
index 604152b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/MenuItemXmlParserUtil.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Xml;
-import android.view.View;
-
-import androidx.annotation.XmlRes;
-
-import com.android.car.ui.R;
-import com.android.car.ui.utils.CarUiUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A class for reading {@link MenuItem MenuItems} from xml files.
- *
- * Apps don't need to use this, as there also exists a {@link ToolbarController#setMenuItems(int)}
- * function that will include the same functionality.
- */
-public class MenuItemXmlParserUtil {
-
-    private MenuItemXmlParserUtil() {}
-
-    /**
-     * Reads a list of {@link MenuItem MenuItems} from the provided xml file.
-     *
-     * Apps don't need to use this, as there also exists a
-     * {@link ToolbarController#setMenuItems(int)} function that will include the same
-     * functionality.
-     */
-    public static List<MenuItem> readMenuItemList(Context c, @XmlRes int resId) {
-        if (resId == 0) {
-            return new ArrayList<>();
-        }
-
-        try (XmlResourceParser parser = c.getResources().getXml(resId)) {
-            AttributeSet attrs = Xml.asAttributeSet(parser);
-            List<MenuItem> menuItems = new ArrayList<>();
-
-            parser.next();
-            parser.next();
-            parser.require(XmlPullParser.START_TAG, null, "MenuItems");
-            while (parser.next() != XmlPullParser.END_TAG) {
-                menuItems.add(readMenuItem(c, parser, attrs));
-            }
-
-            return menuItems;
-        } catch (XmlPullParserException | IOException e) {
-            throw new RuntimeException("Unable to parse Menu Items", e);
-        }
-    }
-
-    private static MenuItem readMenuItem(Context c, XmlResourceParser parser, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
-
-        parser.require(XmlPullParser.START_TAG, null, "MenuItem");
-
-        TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.CarUiToolbarMenuItem);
-        try {
-            int id = a.getResourceId(R.styleable.CarUiToolbarMenuItem_id, View.NO_ID);
-            String title = a.getString(R.styleable.CarUiToolbarMenuItem_title);
-            Drawable icon = a.getDrawable(R.styleable.CarUiToolbarMenuItem_icon);
-            boolean isSearch = a.getBoolean(R.styleable.CarUiToolbarMenuItem_search, false);
-            boolean isSettings = a.getBoolean(R.styleable.CarUiToolbarMenuItem_settings, false);
-            boolean tinted = a.getBoolean(R.styleable.CarUiToolbarMenuItem_tinted, true);
-            boolean visible = a.getBoolean(R.styleable.CarUiToolbarMenuItem_visible, true);
-            boolean showIconAndTitle = a.getBoolean(
-                    R.styleable.CarUiToolbarMenuItem_showIconAndTitle, false);
-            boolean checkable = a.getBoolean(R.styleable.CarUiToolbarMenuItem_checkable, false);
-            boolean checked = a.getBoolean(R.styleable.CarUiToolbarMenuItem_checked, false);
-            boolean checkedExists = a.hasValue(R.styleable.CarUiToolbarMenuItem_checked);
-            boolean activatable = a.getBoolean(R.styleable.CarUiToolbarMenuItem_activatable, false);
-            boolean activated = a.getBoolean(R.styleable.CarUiToolbarMenuItem_activated, false);
-            boolean activatedExists = a.hasValue(R.styleable.CarUiToolbarMenuItem_activated);
-            int displayBehaviorInt = a.getInt(R.styleable.CarUiToolbarMenuItem_displayBehavior, 0);
-            int uxRestrictions = a.getInt(R.styleable.CarUiToolbarMenuItem_uxRestrictions, 0);
-            String onClickMethod = a.getString(R.styleable.CarUiToolbarMenuItem_onClick);
-            MenuItem.OnClickListener onClickListener = null;
-
-            if (onClickMethod != null) {
-                Activity activity = CarUiUtils.getActivity(c);
-                if (activity == null) {
-                    throw new RuntimeException("Couldn't find an activity for the MenuItem");
-                }
-
-                try {
-                    Method m = activity.getClass().getMethod(onClickMethod, MenuItem.class);
-                    onClickListener = i -> {
-                        try {
-                            m.invoke(activity, i);
-                        } catch (InvocationTargetException | IllegalAccessException e) {
-                            throw new RuntimeException("Couldn't call the MenuItem's listener", e);
-                        }
-                    };
-                } catch (NoSuchMethodException e) {
-                    throw new RuntimeException("OnClick method "
-                            + onClickMethod + "(MenuItem) not found in your activity", e);
-                }
-            }
-
-            MenuItem.DisplayBehavior displayBehavior = displayBehaviorInt == 0
-                    ? MenuItem.DisplayBehavior.ALWAYS
-                    : MenuItem.DisplayBehavior.NEVER;
-
-            parser.next();
-            parser.require(XmlPullParser.END_TAG, null, "MenuItem");
-
-            MenuItem.Builder builder = MenuItem.builder(c)
-                    .setId(id)
-                    .setTitle(title)
-                    .setIcon(icon)
-                    .setOnClickListener(onClickListener)
-                    .setUxRestrictions(uxRestrictions)
-                    .setTinted(tinted)
-                    .setVisible(visible)
-                    .setShowIconAndTitle(showIconAndTitle)
-                    .setDisplayBehavior(displayBehavior);
-
-            if (isSearch) {
-                builder.setToSearch();
-            }
-
-            if (isSettings) {
-                builder.setToSettings();
-            }
-
-            if (checkable || checkedExists) {
-                builder.setChecked(checked);
-            }
-
-            if (activatable || activatedExists) {
-                builder.setActivated(activated);
-            }
-
-            return builder.build();
-        } finally {
-            a.recycle();
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/NavButtonMode.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/NavButtonMode.java
deleted file mode 100644
index 16bbe69..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/NavButtonMode.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-/**
- * An enum representing the nav button in the toolbar. The nav button can also be thought of
- * as the back button. Besides {@link #DISABLED}, all of these modes are purely aesthetic and don't
- * affect the functionality of the nav button at all.
- */
-public enum NavButtonMode {
-    /** A back button */
-    BACK,
-    /** A close button */
-    CLOSE,
-    /** A down button, used to indicate that the page will animate down when navigating away */
-    DOWN,
-    /** Don't show the nav button */
-    DISABLED,
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ProgressBarControllerAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ProgressBarControllerAdapterV1.java
deleted file mode 100644
index b03bb73..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ProgressBarControllerAdapterV1.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ProgressBarControllerOEMV1;
-
-class ProgressBarControllerAdapterV1 implements ProgressBarController {
-
-    @Nullable
-    private final ProgressBarControllerOEMV1 mOemProgressbar;
-    private boolean mVisible = false;
-    private boolean mIndeterminate = true;
-    private int mMax = 100;
-    private int mMin = 0;
-    private int mProgress = 0;
-
-    ProgressBarControllerAdapterV1(@Nullable ProgressBarControllerOEMV1 oemProgressbar) {
-        mOemProgressbar = oemProgressbar;
-    }
-
-    @Override
-    public void setVisible(boolean visible) {
-        if (mOemProgressbar != null) {
-            mOemProgressbar.setVisible(visible);
-        }
-        mVisible = visible;
-    }
-
-    @Override
-    public boolean isVisible() {
-        return mVisible;
-    }
-
-    @Override
-    public void setIndeterminate(boolean indeterminate) {
-        if (mOemProgressbar != null) {
-            mOemProgressbar.setIndeterminate(indeterminate);
-        }
-        mIndeterminate = indeterminate;
-    }
-
-    @Override
-    public boolean isIndeterminate() {
-        return mIndeterminate;
-    }
-
-    @Override
-    public void setMax(int max) {
-        if (mOemProgressbar != null) {
-            mOemProgressbar.setMax(max);
-        }
-        mMax = max;
-    }
-
-    @Override
-    public int getMax() {
-        return mMax;
-    }
-
-    @Override
-    public void setMin(int min) {
-        if (mOemProgressbar != null) {
-            mOemProgressbar.setMin(min);
-        }
-        mMin = min;
-    }
-
-    @Override
-    public int getMin() {
-        return mMin;
-    }
-
-    @Override
-    public void setProgress(int progress) {
-        if (mOemProgressbar != null) {
-            mOemProgressbar.setProgress(progress);
-        }
-        mProgress = progress;
-    }
-
-    @Override
-    public int getProgress() {
-        return mProgress;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchCapabilities.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchCapabilities.java
deleted file mode 100644
index 79449a3..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchCapabilities.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-/**
- * Class defining the capabilities of search
- */
-public final class SearchCapabilities {
-
-    private final boolean mCanShowSearchResultsView;
-    private final boolean mCanShowSearchResultItems;
-
-    /**
-     * Returns true if the toolbar can display search result items. One example of this is when the
-     * system is configured to display search items in the IME instead of in the app.
-     */
-    public boolean canShowSearchResultItems() {
-        return mCanShowSearchResultItems;
-    }
-
-    /**
-     * Returns true if the app is allowed to set search results view.
-     */
-    public boolean canShowSearchResultsView() {
-        return mCanShowSearchResultsView;
-    }
-
-    private SearchCapabilities(SearchCapabilitiesBuilder builder) {
-        mCanShowSearchResultsView = builder.mCanShowSearchResultsView;
-        mCanShowSearchResultItems = builder.mCanShowSearchResultItems;
-    }
-
-    /**
-     * Creates the instance of {@link SearchCapabilities.SearchCapabilitiesBuilder}
-     */
-    public static SearchCapabilities.SearchCapabilitiesBuilder builder() {
-        return new SearchCapabilities.SearchCapabilitiesBuilder();
-    }
-
-    /**
-     * Builder for {@link SearchCapabilities}
-     */
-    public static final class SearchCapabilitiesBuilder {
-
-        private boolean mCanShowSearchResultsView;
-        private boolean mCanShowSearchResultItems;
-
-        private SearchCapabilitiesBuilder() {
-
-        }
-
-        /**
-         * Sets if IME can display the search results item or not.
-         */
-        public SearchCapabilitiesBuilder setCanShowSearchResultItems(
-                boolean canShowSearchResultItems) {
-            mCanShowSearchResultItems = canShowSearchResultItems;
-            return this;
-        }
-
-        /**
-         * Sets if IME can display the search results view or not.
-         */
-        public SearchCapabilitiesBuilder setCanShowSearchResultsView(
-                boolean canShowSearchResultsView) {
-            mCanShowSearchResultsView = canShowSearchResultsView;
-            return this;
-        }
-
-        /** Builds a {@link SearchCapabilities} from the current state of the Builder */
-        public SearchCapabilities build() {
-            return new SearchCapabilities(this);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchConfig.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchConfig.java
deleted file mode 100644
index 917b397..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchConfig.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
-import com.android.car.ui.recyclerview.CarUiListItem;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Class used to provide data for IME widescreen search results.
- */
-public final class SearchConfig {
-
-    @Nullable
-    private final View mSearchResultsView;
-    @Nullable
-    private final Drawable mSearchResultsInputViewIcon;
-    @Nullable
-    private final List<? extends CarUiImeSearchListItem> mSearchResultItems;
-
-    /**
-     * Returns the view set by {@link SearchConfigBuilder#setSearchResultsView(View)}
-     */
-    @Nullable
-    public View getSearchResultsView() {
-        return mSearchResultsView;
-    }
-
-    /**
-     * Returns the icon set by {@link SearchConfigBuilder#setSearchResultsInputViewIcon} )}
-     */
-    @Nullable
-    public Drawable getSearchResultsInputViewIcon() {
-        return mSearchResultsInputViewIcon;
-    }
-
-    /**
-     * Returns the search results set by {@link SearchConfigBuilder#setSearchResultItems(List)}
-     */
-    @Nullable
-    public List<? extends CarUiImeSearchListItem> getSearchResultItems() {
-        return mSearchResultItems;
-    }
-
-    private SearchConfig(SearchConfigBuilder builder) {
-        mSearchResultItems = builder.mSearchResultItems;
-        mSearchResultsInputViewIcon = builder.mSearchResultsInputViewIcon;
-        mSearchResultsView = builder.mSearchResultsView;
-    }
-
-    /**
-     * Creates the instance of {@link SearchConfigBuilder}
-     */
-    public static SearchConfigBuilder builder() {
-        return new SearchConfigBuilder();
-    }
-
-    /**
-     * Builder for {@link SearchConfig}
-     */
-    public static final class SearchConfigBuilder {
-
-        @Nullable
-        private View mSearchResultsView;
-        @Nullable
-        private Drawable mSearchResultsInputViewIcon;
-        @Nullable
-        private List<? extends CarUiImeSearchListItem> mSearchResultItems;
-
-        private SearchConfigBuilder() {
-
-        }
-
-        /**
-         * Set the icon to be displayed within the input field of IME window.
-         */
-        public SearchConfigBuilder setSearchResultsInputViewIcon(@Nullable Drawable drawable) {
-            mSearchResultsInputViewIcon = drawable;
-            return this;
-        }
-
-        /**
-         * Sets list of search item {@link CarUiListItem} to be displayed in the IMS
-         * template. This method should be called when system is running in a wide screen mode. Apps
-         * can check that by using
-         * {@link com.android.car.ui.toolbar.ToolbarController##canShowSearchResultItems()}
-         * Else, this method will throw an {@link IllegalStateException}
-         */
-        public SearchConfigBuilder setSearchResultItems(
-                @Nullable List<? extends CarUiImeSearchListItem> searchItems) {
-            if (searchItems == null || searchItems.size() == 0) {
-                mSearchResultItems = null;
-            } else {
-                mSearchResultItems = Collections.unmodifiableList(new ArrayList<>(searchItems));
-            }
-            return this;
-        }
-
-        /**
-         * Add a view within a container that will animate with the wide screen IME to display
-         * search
-         * results.
-         *
-         * <p>Note: Apps can only call this method if the package name is allowed via OEM to render
-         * their view.  To check if the application have the permission to do so or not first call
-         * {@link com.android.car.ui.toolbar.ToolbarController#canShowSearchResultsView()}.
-         * If the app is not allowed this method will throw an {@link IllegalStateException}
-         *
-         * @param view to be added in the container.
-         */
-        public SearchConfigBuilder setSearchResultsView(@Nullable View view) {
-            mSearchResultsView = view;
-            return this;
-        }
-
-        /** Builds a {@link SearchConfig} from the current state of the Builder */
-        public SearchConfig build() {
-            if (mSearchResultsView != null && mSearchResultItems != null) {
-                throw new RuntimeException(
-                        "Both searchResultItems and searchResultsView can't be set at the same "
-                                + "time");
-            }
-            return new SearchConfig(this);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchMode.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchMode.java
deleted file mode 100644
index a56cbb3..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchMode.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-/**
- * An enum describing the possible search states a toolbar could be in.
- * See {@link ToolbarController}.
- */
-public enum SearchMode {
-    /** Don't show a search bar */
-    DISABLED,
-    /** Show a search bar */
-    SEARCH,
-    /**
-     * Show a search bar, but don't include any visual indication it's for searching.
-     * It could just be for editing text.
-     */
-    EDIT,
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchView.java
deleted file mode 100644
index 5f6a72b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchView.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.ImageView;
-
-import androidx.annotation.NonNull;
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-import com.android.car.ui.R;
-
-import java.util.Collections;
-import java.util.Set;
-import java.util.function.Consumer;
-
-/**
- * A search view used by {@link Toolbar}.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class SearchView extends ConstraintLayout {
-
-    private final InputMethodManager mInputMethodManager;
-    private final SearchWidescreenController mSearchWidescreenController;
-    private final ImageView mIcon;
-    private final EditText mSearchText;
-    private final View mCloseIcon;
-    private final int mStartPaddingWithoutIcon;
-    private final int mStartPadding;
-    private final int mEndPadding;
-
-    private Set<Consumer<String>> mSearchListeners = Collections.emptySet();
-    private Set<Runnable> mSearchCompletedListeners =
-            Collections.emptySet();
-    private Set<Toolbar.OnSearchListener> mDeprecatedSearchListeners = Collections.emptySet();
-    private Set<Toolbar.OnSearchCompletedListener> mDeprecatedSearchCompletedListeners =
-            Collections.emptySet();
-    private final TextWatcher mTextWatcher = new TextWatcher() {
-        @Override
-        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-        }
-
-        @Override
-        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-        }
-
-        @Override
-        public void afterTextChanged(Editable editable) {
-            onSearch(editable.toString());
-        }
-    };
-
-    private boolean mIsPlainText = false;
-
-    public SearchView(Context context) {
-        this(context, null);
-    }
-
-    public SearchView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public SearchView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        mInputMethodManager = getContext().getSystemService(InputMethodManager.class);
-
-        LayoutInflater inflater = LayoutInflater.from(context);
-        inflater.inflate(R.layout.car_ui_toolbar_search_view, this, true);
-
-        mSearchText = requireViewByRefId(this, R.id.car_ui_toolbar_search_bar);
-        mIcon = requireViewByRefId(this, R.id.car_ui_toolbar_search_icon);
-        mCloseIcon = requireViewByRefId(this, R.id.car_ui_toolbar_search_close);
-
-        mCloseIcon.setOnClickListener(view -> {
-            if (view.isFocused()) {
-                mSearchText.requestFocus();
-                mInputMethodManager.showSoftInput(mSearchText, 0);
-            }
-            mSearchText.getText().clear();
-        });
-        mCloseIcon.setVisibility(View.GONE);
-
-        mStartPaddingWithoutIcon = mSearchText.getPaddingStart();
-        mStartPadding = context.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_toolbar_search_search_icon_container_width);
-        mEndPadding = context.getResources().getDimensionPixelSize(
-                R.dimen.car_ui_toolbar_search_close_icon_container_width);
-
-        mSearchText.setSaveEnabled(false);
-        mSearchText.setPaddingRelative(mStartPadding, 0, mEndPadding, 0);
-
-        mSearchText.setOnClickListener((view) -> mInputMethodManager.showSoftInput(view, 0));
-
-        mSearchText.setOnFocusChangeListener(
-                (view, hasFocus) -> {
-                    if (!hasFocus) {
-                        mInputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
-                    }
-                });
-
-        mSearchText.addTextChangedListener(mTextWatcher);
-
-        mSearchText.setOnEditorActionListener((v, actionId, event) -> {
-            if (actionId == EditorInfo.IME_ACTION_DONE
-                    || actionId == EditorInfo.IME_ACTION_SEARCH) {
-                notifyQuerySubmit();
-            } else if (isEnter(event)) {
-                if (event.getAction() == KeyEvent.ACTION_UP) {
-                    // Note that we want to trigger search only on ACTION_UP, but want to return
-                    // true for all actions for the relevant key event.
-                    notifyQuerySubmit();
-                }
-                return true;
-            }
-            return false;
-        });
-
-        mSearchWidescreenController = new SearchWidescreenController(context);
-        mSearchWidescreenController.setTextView(mSearchText);
-        if (mSearchText instanceof CarUiEditText) {
-            ((CarUiEditText) mSearchText).setOnPrivateImeCommandListener(
-                    mSearchWidescreenController.getOnPrivateImeCommandListener());
-        }
-    }
-
-    private boolean isEnter(KeyEvent event) {
-        boolean result = false;
-        if (event != null) {
-            int keyCode = event.getKeyCode();
-            result = keyCode == KeyEvent.KEYCODE_ENTER
-                    || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER
-                    || keyCode == KeyEvent.KEYCODE_SEARCH;
-        }
-        return result;
-    }
-
-    private void notifyQuerySubmit() {
-        mSearchText.clearFocus();
-        for (Runnable listener : mSearchCompletedListeners) {
-            listener.run();
-        }
-        for (Toolbar.OnSearchCompletedListener listener : mDeprecatedSearchCompletedListeners) {
-            listener.onSearchCompleted();
-        }
-    }
-
-    private boolean mWasShown = false;
-
-    @Override
-    public void onVisibilityChanged(@NonNull View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-
-        boolean isShown = isShown();
-        if (isShown && !mWasShown) {
-            boolean hasQuery = mSearchText.getText().length() > 0;
-            mCloseIcon.setVisibility(hasQuery ? View.VISIBLE : View.GONE);
-            mSearchText.requestFocus();
-            mInputMethodManager.showSoftInput(mSearchText, 0);
-        }
-        mWasShown = isShown;
-    }
-
-    /**
-     * Sets the {@link SearchConfig} full of data to show in the IME.
-     *
-     * @see SearchWidescreenController#setSearchConfig(SearchConfig)
-     */
-    public void setSearchConfig(SearchConfig config) {
-        mSearchWidescreenController.setSearchConfig(config);
-    }
-
-    /**
-     * Sets a listener for the search text changing.
-     */
-    public void setSearchListeners(
-            Set<Toolbar.OnSearchListener> deprecatedListeners,
-            Set<Consumer<String>> listeners) {
-        mSearchListeners = listeners;
-        mDeprecatedSearchListeners = deprecatedListeners;
-    }
-
-    /**
-     * Sets a listener for the user completing their search, for example by clicking the
-     * enter/search button on the keyboard.
-     */
-    public void setSearchCompletedListeners(
-            Set<Toolbar.OnSearchCompletedListener> deprecatedListeners,
-            Set<Runnable> listeners) {
-        mSearchCompletedListeners = listeners;
-        mDeprecatedSearchCompletedListeners = deprecatedListeners;
-    }
-
-    /**
-     * Sets the search hint
-     *
-     * @param hint A CharSequence of the search hint.
-     */
-    public void setHint(CharSequence hint) {
-        mSearchText.setHint(hint);
-    }
-
-    /**
-     * Sets a custom icon to display in the search box.
-     */
-    public void setIcon(Drawable d) {
-        if (d == null) {
-            mIcon.setImageResource(R.drawable.car_ui_icon_search);
-        } else {
-            mIcon.setImageDrawable(d);
-        }
-    }
-
-    /**
-     * Sets whether or not the search bar should look like a regular text box instead of a search
-     * box.
-     */
-    public void setPlainText(boolean plainText) {
-        if (plainText != mIsPlainText) {
-            if (plainText) {
-                mSearchText.setPaddingRelative(mStartPaddingWithoutIcon, 0, mEndPadding, 0);
-                mSearchText.setImeOptions(EditorInfo.IME_ACTION_DONE);
-                mIcon.setVisibility(View.GONE);
-            } else {
-                mSearchText.setPaddingRelative(mStartPadding, 0, mEndPadding, 0);
-                mSearchText.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
-                mIcon.setVisibility(View.VISIBLE);
-            }
-            mIsPlainText = plainText;
-
-            // Needed to detect changes to imeOptions
-            mInputMethodManager.restartInput(mSearchText);
-        }
-    }
-
-    private void onSearch(String query) {
-        mCloseIcon.setVisibility(TextUtils.isEmpty(query) ? View.GONE : View.VISIBLE);
-
-        for (Consumer<String> listener : mSearchListeners) {
-            listener.accept(query);
-        }
-        for (Toolbar.OnSearchListener listener : mDeprecatedSearchListeners) {
-            listener.onSearch(query);
-        }
-    }
-
-    /**
-     * Sets the text being searched.
-     */
-    public void setSearchQuery(String query) {
-        mSearchText.setText(query);
-        mSearchText.setSelection(mSearchText.getText().length());
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchWidescreenController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchWidescreenController.java
deleted file mode 100644
index 23afd77..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/SearchWidescreenController.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static android.view.WindowInsets.Type.ime;
-
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_DISPLAY_ID;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_HEIGHT;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_HOST_TOKEN;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_PACKAGE;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_WIDTH;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_ITEM_ID_LIST;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_ACTION;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_CLEAR_DATA_ACTION;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_POST_LOAD_SEARCH_RESULTS_ACTION;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_SEARCH_RESULTS;
-import static com.android.car.ui.utils.CarUiUtils.getBooleanSystemProperty;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.hardware.display.DisplayManager;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Parcel;
-import android.view.Display;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.CarUiText;
-import com.android.car.ui.R;
-import com.android.car.ui.core.SearchResultsProvider;
-import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-
-import java.util.List;
-import java.util.function.BiConsumer;
-
-/**
- * Internal class to car-ui-lib, do not use from outside.
- * <p>
- * Handles converting a {@link SearchConfig} into the appropriate commands to send to the widescreen
- * IME.
- * <p>
- * You must call {@link #setTextView} and {@link #getOnPrivateImeCommandListener} after creating
- * this object to finish initializing it, but they don't have to be called immediately. The
- * SearchWidescreenController will still accept calls to {@link #setSearchConfig} even before
- * the TextView has been set, it will just wait for the TextView before doing anything.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class SearchWidescreenController {
-
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-    private final Context mContext;
-    private final InputMethodManager mInputMethodManager;
-    @Nullable
-    private TextView mTextView;
-    private SurfaceControlViewHost mSurfaceControlViewHost;
-    private int mSurfaceHeight;
-    private int mSurfaceWidth;
-    private boolean mIsImeWidescreenViewSet = false;
-    private ViewGroup mOriginalParent;
-    private ViewGroup.LayoutParams mLayoutParams;
-
-    @NonNull
-    private SearchConfig mSearchConfig = SearchConfig.builder().build();
-
-    public SearchWidescreenController(@NonNull Context context) {
-        mContext = context;
-        mInputMethodManager = context.getSystemService(InputMethodManager.class);
-    }
-
-    /**
-     * Sets the text view that will be used to send the IME commands. This can be called at
-     * any time after the creation of this SearchWidescreenController, the controller will
-     * do nothing until the text view is set.
-     */
-    public void setTextView(@Nullable TextView textView) {
-        if (mTextView != null) {
-            throw new IllegalStateException("TextView already set");
-        }
-        mTextView = textView;
-        initializeWindowInsetsListener();
-    }
-
-    /**
-     * Sets the {@link SearchConfig} of data to display in the IME widescreen.
-     */
-    public void setSearchConfig(@Nullable SearchConfig searchConfig) {
-        if (searchConfig == null) {
-            searchConfig = SearchConfig.builder().build();
-        }
-        mSearchConfig = searchConfig;
-    }
-
-    @Nullable
-    private View getSearchResultsView() {
-        View view = mSearchConfig.getSearchResultsView();
-        if (view instanceof CarUiRecyclerView) {
-            return ((CarUiRecyclerView) view).getContainer();
-        }
-        return view;
-    }
-
-    private void initializeWindowInsetsListener() {
-        View.OnApplyWindowInsetsListener onApplyWindowInsetsListener = (v, insets) -> {
-            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
-                // We should never get here because we don't register the listener pre-R anyways.
-                throw new IllegalStateException("Cannot check if the ime is visible pre R");
-            }
-            if (mTextView == null) {
-                return v.onApplyWindowInsets(insets);
-            }
-
-            if (insets.isVisible(ime())) {
-                FrameLayout wideScreenImeContentAreaViewContainer;
-                View contentView = getSearchResultsView();
-                if (!mIsImeWidescreenViewSet && contentView != null) {
-                    // When the IME opens after the setSearchConfig()
-                    // call, setup a container and attach the view to the IME surface.
-                    // The container is necessary because the content view needs to be removed
-                    // and added back into the app when the IME closes, and views cannot be
-                    // detatched from a SurfaceControlViewHost. We save the content view's old
-                    // LayoutParams and parent for when it's reattached to the app.
-                    mLayoutParams = contentView.getLayoutParams();
-                    mOriginalParent = (ViewGroup) contentView.getParent();
-                    if (mOriginalParent != null) {
-                        mOriginalParent.removeView(contentView);
-                    }
-
-                    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
-                            ViewGroup.LayoutParams.MATCH_PARENT,
-                            ViewGroup.LayoutParams.MATCH_PARENT);
-                    // This is different from getSearchResultsView() because getSearchResultsView()
-                    // will turn CarUiRecyclerViews into their containing views. But here
-                    // we want to actually know if it is a CarUiRecyclerView
-                    View originalView = mSearchConfig.getSearchResultsView();
-                    if (originalView instanceof CarUiRecyclerView) {
-                        // We need to use a negative layout margin to have the list take the full
-                        // content area.
-                        params.topMargin = -originalView.getPaddingTop();
-                        params.bottomMargin = -originalView.getPaddingBottom();
-                        params.leftMargin = -originalView.getPaddingLeft();
-                        params.rightMargin = -originalView.getPaddingRight();
-                    }
-                    wideScreenImeContentAreaViewContainer = new FrameLayout(mContext);
-                    wideScreenImeContentAreaViewContainer.addView(contentView, params);
-                } else {
-                    wideScreenImeContentAreaViewContainer = null;
-                }
-
-                displaySearchWideScreen();
-                mHandler.post(() -> {
-                    if (mSurfaceControlViewHost != null
-                            && wideScreenImeContentAreaViewContainer != null
-                            && mSurfaceControlViewHost.getView() == null) {
-                        // set the container with app's view into the Surface view.
-                        mIsImeWidescreenViewSet = true;
-                        mSurfaceControlViewHost.setView(
-                                wideScreenImeContentAreaViewContainer, mSurfaceWidth,
-                                mSurfaceHeight);
-                    }
-                });
-            } else {
-                removeView();
-                mIsImeWidescreenViewSet = false;
-            }
-            return v.onApplyWindowInsets(insets);
-        };
-
-        // We need to add the window insets changed listener to the root view.
-        // The text view may not be part of the view hierarchy yet, so in that case
-        // add a listener for when it's attached to the window and then set the window insets
-        // listener.
-        // The listener has code that requires R, so only register it if the system is on R.
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && mTextView != null) {
-            if (mTextView.isAttachedToWindow()) {
-                mTextView.getRootView().setOnApplyWindowInsetsListener(onApplyWindowInsetsListener);
-            } else {
-                mTextView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
-                    @Override
-                    public void onViewAttachedToWindow(View v) {
-                        mTextView.getRootView().setOnApplyWindowInsetsListener(
-                                onApplyWindowInsetsListener);
-                        mTextView.removeOnAttachStateChangeListener(this);
-                    }
-
-                    @Override
-                    public void onViewDetachedFromWindow(View v) {
-                    }
-                });
-            }
-        }
-    }
-
-    private void displaySearchWideScreen() {
-        Uri contentUri = SearchResultsProvider.getSearchResultsTableUri(mContext);
-        // clear the table.
-        mContext.getContentResolver().delete(contentUri, null, null);
-
-        // If the app requested showing a view and we support it, we will show that instead
-        // of the templatized list items.
-        if (getSearchResultsView() != null && getSearchCapabilities().canShowSearchResultsView()) {
-            return;
-        }
-
-        List<? extends CarUiImeSearchListItem> searchItems = mSearchConfig.getSearchResultItems();
-        if (searchItems == null) {
-            mInputMethodManager.sendAppPrivateCommand(mTextView, WIDE_SCREEN_ACTION, null);
-            return;
-        }
-
-        for (int id = 0; id < searchItems.size(); id++) {
-            CarUiImeSearchListItem item = searchItems.get(id);
-            ContentValues values = new ContentValues();
-            values.put(SearchResultsProvider.ITEM_ID, id);
-            values.put(SearchResultsProvider.SECONDARY_IMAGE_ID, id);
-            BitmapDrawable icon = (BitmapDrawable) item.getIcon();
-            values.put(SearchResultsProvider.PRIMARY_IMAGE_BLOB,
-                    icon != null ? bitmapToByteArray(icon.getBitmap()) : null);
-            BitmapDrawable supplementalIcon = (BitmapDrawable) item.getSupplementalIcon();
-            values.put(SearchResultsProvider.SECONDARY_IMAGE_BLOB,
-                    supplementalIcon != null ? bitmapToByteArray(supplementalIcon.getBitmap())
-                            : null);
-            values.put(SearchResultsProvider.TITLE,
-                    item.getTitle() != null ? item.getTitle().getPreferredText().toString() : null);
-            values.put(SearchResultsProvider.SUBTITLE,
-                    item.getBody() != null ? CarUiText.combineMultiLine(item.getBody()).toString()
-                            : null);
-            mContext.getContentResolver().insert(contentUri, values);
-        }
-        mInputMethodManager.sendAppPrivateCommand(mTextView, WIDE_SCREEN_SEARCH_RESULTS,
-                new Bundle());
-    }
-
-    /**
-     * Remove the app's view from the container and attach it back to its original parent.
-     */
-    private void removeView() {
-        View contentView = getSearchResultsView();
-        if (mOriginalParent != null && contentView != null) {
-            mHandler.post(() -> {
-                ViewGroup parent = (ViewGroup) contentView.getParent();
-                if (parent != null) {
-                    parent.removeView(contentView);
-                }
-                mOriginalParent.addView(contentView, mLayoutParams);
-                mOriginalParent.requestLayout();
-                mOriginalParent = null;
-                mLayoutParams = null;
-            });
-        }
-    }
-
-    private void onItemClicked(String itemId) {
-        List<? extends CarUiImeSearchListItem> items = mSearchConfig.getSearchResultItems();
-        CarUiImeSearchListItem item = items == null
-                ? null
-                : items.get(Integer.parseInt(itemId));
-        if (item != null) {
-            CarUiContentListItem.OnClickListener listener = item.getOnClickListener();
-            if (listener != null) {
-                listener.onClick(item);
-            }
-        }
-    }
-
-    private void onSecondaryImageClicked(String secondaryImageId) {
-        List<? extends CarUiImeSearchListItem> items = mSearchConfig.getSearchResultItems();
-        CarUiImeSearchListItem item = items == null
-                ? null
-                : items.get(Integer.parseInt(secondaryImageId));
-        if (item != null) {
-            CarUiContentListItem.OnClickListener listener =
-                    item.getSupplementalIconOnClickListener();
-            if (listener != null) {
-                listener.onClick(item);
-            }
-        }
-    }
-
-    private void onSurfaceInfo(int displayId, IBinder binder, int width, int height) {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
-            // Other code like getSearchCapabilities().canShowSearchResultsView() returning false
-            // should prevent us from getting here.
-            throw new IllegalStateException("Views in the widescreen ime aren't supported pre R");
-        }
-
-        DisplayManager dm = mContext.getSystemService(DisplayManager.class);
-
-        Display display = dm.getDisplay(displayId);
-
-        mSurfaceControlViewHost = new SurfaceControlViewHost(mContext,
-                display, binder);
-
-        mSurfaceHeight = height;
-        mSurfaceWidth = width;
-
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(CONTENT_AREA_SURFACE_PACKAGE,
-                mSurfaceControlViewHost.getSurfacePackage());
-        mInputMethodManager.sendAppPrivateCommand(mTextView, WIDE_SCREEN_ACTION, bundle);
-    }
-
-    private void reLayout(int width, int height) {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
-            // Other code like getSearchCapabilities().canShowSearchResultsView() returning false
-            // should prevent us from getting here.
-            throw new IllegalStateException("Views in the widescreen ime aren't supported pre R");
-        }
-        mSurfaceHeight = height;
-        mSurfaceWidth = width;
-
-        if (mSurfaceControlViewHost != null) {
-            mSurfaceControlViewHost.relayout(width, height);
-        }
-    }
-
-    private void onPostLoadSearchResults() {
-        Uri contentUri = SearchResultsProvider.getSearchResultsTableUri(mContext);
-        mContext.getContentResolver().delete(contentUri, null, null);
-    }
-
-    /**
-     * Gets a listener that should be called when the text view passed to {@link #setTextView}
-     * receives a call to it's {@link TextView#onPrivateIMECommand}
-     */
-    public BiConsumer<String, Bundle> getOnPrivateImeCommandListener() {
-        return (action, data) -> {
-            if (WIDE_SCREEN_CLEAR_DATA_ACTION.equals(action) && mTextView != null) {
-                // clear the text.
-                mTextView.setText("");
-            }
-
-            if (WIDE_SCREEN_POST_LOAD_SEARCH_RESULTS_ACTION.equals(action)) {
-                onPostLoadSearchResults();
-            }
-
-            if (data == null) {
-                return;
-            }
-
-            if (data.getString(SEARCH_RESULT_ITEM_ID_LIST) != null) {
-                onItemClicked(data.getString(SEARCH_RESULT_ITEM_ID_LIST));
-            }
-
-            if (data.getString(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST) != null) {
-                onSecondaryImageClicked(data.getString(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST));
-            }
-
-            int displayId = data.getInt(CONTENT_AREA_SURFACE_DISPLAY_ID);
-            int height = data.getInt(CONTENT_AREA_SURFACE_HEIGHT);
-            int width = data.getInt(CONTENT_AREA_SURFACE_WIDTH);
-            IBinder binder = data.getBinder(CONTENT_AREA_SURFACE_HOST_TOKEN);
-
-            if (binder != null) {
-                onSurfaceInfo(displayId, binder, width, height);
-                return;
-            }
-
-            if (height != 0 || width != 0) {
-                reLayout(width, height);
-            }
-        };
-    }
-
-    /**
-     * Gets the {@link SearchCapabilities} that the system currently supports.
-     *
-     * This non-static version does not require a context to be passed in explicitly.
-     */
-    public SearchCapabilities getSearchCapabilities() {
-        return getSearchCapabilities(mContext);
-    }
-
-    /**
-     * Gets the {@link SearchCapabilities} that the system currently supports.
-     */
-    public static SearchCapabilities getSearchCapabilities(Context context) {
-        boolean isWideScreenMode = getBooleanSystemProperty(context.getResources(),
-                R.string.car_ui_ime_wide_screen_system_property_name, false)
-                && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
-
-        boolean allowAllAppsToShowSearchResultsView = context.getResources().getBoolean(
-                R.bool.car_ui_ime_wide_screen_allow_app_hide_content_area);
-
-        String[] allowedPackageNames = context.getResources()
-                .getStringArray(R.array.car_ui_ime_wide_screen_allowed_package_list);
-        boolean packageNameAllowed = false;
-        for (String name : allowedPackageNames) {
-            if (name.equals(context.getPackageName())) {
-                packageNameAllowed = true;
-                break;
-            }
-        }
-
-        boolean canShowSearchResultsView = isWideScreenMode
-                && (packageNameAllowed || allowAllAppsToShowSearchResultsView);
-
-        return SearchCapabilities.builder()
-                .setCanShowSearchResultsView(canShowSearchResultsView)
-                .setCanShowSearchResultItems(isWideScreenMode)
-                .build();
-    }
-
-    private static byte[] bitmapToByteArray(Bitmap bitmap) {
-        Parcel parcel = Parcel.obtain();
-        bitmap.writeToParcel(parcel, 0);
-        byte[] bytes = parcel.marshall();
-        parcel.recycle();
-        return bytes;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Tab.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Tab.java
deleted file mode 100644
index 63b3cd1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Tab.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * This is a data class the represents a tab in the toolbar. They can be added to the
- * toolbar via {@link ToolbarController#setTabs(List)}.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class Tab {
-    @Nullable
-    private final String mText;
-    @Nullable
-    private final Drawable mIcon;
-    @Nullable
-    private final Consumer<Tab> mSelectedListener;
-
-    private Tab(@NonNull Builder builder) {
-        mText = builder.mText;
-        mIcon = builder.mIcon;
-        mSelectedListener = builder.mSelectedListener;
-    }
-
-    /** Gets the tab's text */
-    @Nullable
-    public String getText() {
-        return mText;
-    }
-
-    /** Gets the tab's icon */
-    @Nullable
-    public Drawable getIcon() {
-        return mIcon;
-    }
-
-    /** Gets the listener to call when the tab is selected */
-    @Nullable
-    public Consumer<Tab> getSelectedListener() {
-        return mSelectedListener;
-    }
-
-    /** Creates a new {@link Builder} */
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /** Builder for {@link Tab} */
-    public static class Builder {
-        @Nullable
-        private String mText = null;
-        @Nullable
-        private Drawable mIcon = null;
-        @Nullable
-        private Consumer<Tab> mSelectedListener = null;
-
-        private Builder() {
-        }
-
-        /** Sets the tab's text */
-        public Builder setText(String text) {
-            mText = text;
-            return this;
-        }
-
-        /** Sets the tab's icon */
-        public Builder setIcon(Drawable icon) {
-            mIcon = icon;
-            return this;
-        }
-
-        /** Sets a listener that is called when the tab is selected */
-        public Builder setSelectedListener(Consumer<Tab> callback) {
-            mSelectedListener = callback;
-            return this;
-        }
-
-        /** Builds the final {@link Tab} */
-        public Tab build() {
-            return new Tab(this);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TabAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TabAdapterV1.java
deleted file mode 100644
index 543a10d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TabAdapterV1.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.TabOEMV1;
-
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-class TabAdapterV1 {
-
-    private final Tab mClientTab;
-    private final TabOEMV1 mSharedLibraryTab;
-
-    TabAdapterV1(Tab clientTab) {
-        mClientTab = clientTab;
-        Consumer<Tab> selectedListener = mClientTab.getSelectedListener();
-        mSharedLibraryTab = TabOEMV1.builder()
-                .setIcon(mClientTab.getIcon())
-                .setTitle(mClientTab.getText())
-                .setOnSelectedListener(selectedListener == null
-                        ? null
-                        : () -> selectedListener.accept(mClientTab))
-                .build();
-    }
-
-    public Tab getClientTab() {
-        return mClientTab;
-    }
-
-    public TabOEMV1 getSharedLibraryTab() {
-        return mSharedLibraryTab;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TabLayout.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TabLayout.java
deleted file mode 100644
index cfd6acf..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TabLayout.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.LayoutRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.R;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * Custom tab layout which supports adding tabs dynamically
- *
- * <p>It supports two layout modes:
- * <ul><li>Flexible layout which will fill the width
- * <li>Non-flexible layout which wraps content with a minimum tab width. By setting tab gravity,
- * it can left aligned, right aligned or center aligned.
- *
- * <p>Scrolling function is not supported. If a tab item runs out of the tab layout bound, there
- * is no way to access it. It's better to set the layout mode to flexible in this case.
- *
- * <p>Default tab item inflates from R.layout.car_ui_tab_item, but it also supports custom layout
- * id, by overlaying R.layout.car_ui_tab_item_layout. By doing this, appearance of tab item view
- * can be customized.
- *
- * <p>Touch feedback is using @android:attr/selectableItemBackground.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class TabLayout extends LinearLayout {
-    @LayoutRes
-    private final int mTabLayoutRes;
-    @NonNull
-    private List<com.android.car.ui.toolbar.Tab> mTabs = Collections.emptyList();
-    private int mSelectedTab = -1;
-
-    public TabLayout(@NonNull Context context) {
-        this(context, null);
-    }
-
-    public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        Resources resources = context.getResources();
-
-        boolean tabFlexibleLayout = resources.getBoolean(R.bool.car_ui_toolbar_tab_flexible_layout);
-        mTabLayoutRes = tabFlexibleLayout
-                ? R.layout.car_ui_toolbar_tab_item_layout_flexible
-                : R.layout.car_ui_toolbar_tab_item_layout;
-    }
-
-    /** Sets the tabs to show */
-    public void setTabs(List<com.android.car.ui.toolbar.Tab> tabs, int selectedTab) {
-        if (tabs == null) {
-            mTabs = Collections.emptyList();
-        } else {
-            mTabs = Collections.unmodifiableList(new ArrayList<>(tabs));
-        }
-        mSelectedTab = selectedTab;
-        recreateViews();
-    }
-
-    public List<com.android.car.ui.toolbar.Tab> getTabs() {
-        return mTabs;
-    }
-
-    /** Returns the currently selected tab, or -1 if no tabs exist */
-    public int getSelectedTab() {
-        if (mTabs.isEmpty() && mSelectedTab != -1) {
-            throw new IllegalStateException("mSelectedTab should've been -1");
-        }
-        return mSelectedTab;
-    }
-
-    /**
-     * Returns if this TabLayout has tabs. That is, if the most recent call to
-     * {@link #setTabs(List)} contained a non-empty list.
-     */
-    public boolean hasTabs() {
-        return !mTabs.isEmpty();
-    }
-
-    /** Set the tab at given position as the current selected tab. */
-    public void selectTab(int position) {
-        if (position < 0 || position > mTabs.size()) {
-            position = mTabs.isEmpty() ? -1 : 0;
-        }
-        if (position == mSelectedTab) {
-            return;
-        }
-
-        int oldPosition = mSelectedTab;
-        mSelectedTab = position;
-        presentTabView(oldPosition);
-        presentTabView(position);
-
-        if (position >= 0) {
-            com.android.car.ui.toolbar.Tab tab = mTabs.get(position);
-            Consumer<com.android.car.ui.toolbar.Tab> listener = tab.getSelectedListener();
-            if (listener != null) {
-                listener.accept(tab);
-            }
-        }
-    }
-
-    private void recreateViews() {
-        removeAllViews();
-        for (int i = 0; i < mTabs.size(); i++) {
-            View tabView = LayoutInflater.from(getContext())
-                    .inflate(mTabLayoutRes, this, false);
-            addView(tabView);
-            presentTabView(i);
-        }
-    }
-
-    private void presentTabView(int position) {
-        if (position < 0 || position > mTabs.size()) {
-            return;
-        }
-        View tabView = getChildAt(position);
-        com.android.car.ui.toolbar.Tab tab = mTabs.get(position);
-        ImageView iconView = requireViewByRefId(tabView, R.id.car_ui_toolbar_tab_item_icon);
-        TextView textView = requireViewByRefId(tabView, R.id.car_ui_toolbar_tab_item_text);
-
-        tabView.setOnClickListener(view -> selectTab(position));
-        textView.setText(tab.getText());
-        iconView.setImageDrawable(tab.getIcon());
-        tabView.setActivated(position == mSelectedTab);
-        textView.setTextAppearance(position == mSelectedTab
-                ? R.style.TextAppearance_CarUi_Widget_Toolbar_Tab_Selected
-                : R.style.TextAppearance_CarUi_Widget_Toolbar_Tab);
-    }
-
-    /**
-     * Tab entity.
-     *
-     * @deprecated Use {@link com.android.car.ui.toolbar.Tab} instead.
-     */
-    @Deprecated
-    public static class Tab {
-        private final Drawable mIcon;
-        private final CharSequence mText;
-        private boolean mIsSelected;
-
-        public Tab(@Nullable Drawable icon, @Nullable CharSequence text) {
-            mIcon = icon;
-            mText = text;
-        }
-
-        /** Set tab text. */
-        protected void bindText(TextView textView) {
-            textView.setText(mText);
-        }
-
-        /**
-         * Do not use, this method is here for the shared library adapters, which cannot
-         * call the protected version due to being in a different classloader.
-         */
-        public final void bindTextPublic(TextView textView) {
-            bindText(textView);
-        }
-
-        /** Set icon drawable. TODO(b/139444064): revise this api.*/
-        protected void bindIcon(ImageView imageView) {
-            imageView.setImageDrawable(mIcon);
-        }
-
-        /**
-         * Do not use, this method is here for the shared library adapters, which cannot
-         * call the protected version due to being in a different classloader.
-         */
-        public final void bindIconPublic(ImageView imageView) {
-            bindIcon(imageView);
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TextViewListener.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TextViewListener.java
deleted file mode 100644
index ca6152a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/TextViewListener.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import android.content.Context;
-import android.widget.TextView;
-
-import java.util.function.Consumer;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class TextViewListener extends TextView {
-    private Consumer<CharSequence> mTextListener;
-
-    public TextViewListener(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void setText(CharSequence text, BufferType bufferType) {
-        super.setText(text, bufferType);
-
-        if (mTextListener != null) {
-            mTextListener.accept(text);
-        }
-    }
-
-    public void setTextListener(Consumer<CharSequence> textListener) {
-        mTextListener = textListener;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Toolbar.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Toolbar.java
deleted file mode 100644
index 4a86f09..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/Toolbar.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.toolbar;
-
-/**
- * This is a legacy toolbar class, that now no longer functions as a toolbar, but instead
- * just holds deprecated inner classes.
- *
- * @deprecated Instead of creating this class, use Theme.CarUi.WithToolbar, and get access to it
- * via {@link com.android.car.ui.core.CarUi#requireToolbar(android.app.Activity)}
- */
-@Deprecated
-public final class Toolbar {
-
-    /** Callback that will be issued whenever the height of toolbar is changed. */
-    public interface OnHeightChangedListener {
-        /**
-         * Will be called when the height of the toolbar is changed.
-         *
-         * @param height new height of the toolbar
-         */
-        void onHeightChanged(int height);
-    }
-
-    /** Back button listener */
-    public interface OnBackListener {
-        /**
-         * Invoked when the user clicks on the back button. By default, the toolbar will call
-         * the Activity's {@link android.app.Activity#onBackPressed()}. Returning true from
-         * this method will absorb the back press and prevent that behavior.
-         */
-        boolean onBack();
-    }
-
-    /** Tab selection listener */
-    public interface OnTabSelectedListener {
-        /** Called when a {@link TabLayout.Tab} is selected */
-        void onTabSelected(TabLayout.Tab tab);
-    }
-
-    /** Search listener */
-    public interface OnSearchListener {
-        /**
-         * Invoked when the user edits a search query.
-         *
-         * <p>This is called for every letter the user types, and also empty strings if the user
-         * erases everything.
-         */
-        void onSearch(String query);
-    }
-
-    /** Search completed listener */
-    public interface OnSearchCompletedListener {
-        /**
-         * Invoked when the user submits a search query by clicking the keyboard's search / done
-         * button.
-         */
-        void onSearchCompleted();
-    }
-
-    /** Enum of states the toolbar can be in. Controls what elements of the toolbar are displayed */
-    public enum State {
-        /**
-         * In the HOME state, the logo will be displayed if there is one, and no navigation icon
-         * will be displayed. The tab bar will be visible. The title will be displayed if there
-         * is space. MenuItems will be displayed.
-         */
-        HOME,
-        /**
-         * In the SUBPAGE state, the logo will be replaced with a back button, the tab bar won't
-         * be visible. The title and MenuItems will be displayed.
-         */
-        SUBPAGE,
-        /**
-         * In the SEARCH state, only the back button and the search bar will be visible.
-         */
-        SEARCH,
-        /**
-         * In the EDIT state, the search bar will look like a regular text box, but will be
-         * functionally identical to the SEARCH state.
-         */
-        EDIT,
-    }
-
-    /**
-     * An enum of possible styles the nav button could be in. All styles will still call
-     * {@link OnBackListener#onBack()}.
-     */
-    public enum NavButtonMode {
-        /** A back button */
-        BACK,
-        /** A close button */
-        CLOSE,
-        /** A down button, used to indicate that the page will animate down when navigating away */
-        DOWN,
-        /** Don't show the nav button */
-        DISABLED,
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarController.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarController.java
deleted file mode 100644
index cf524fe..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarController.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.annotation.XmlRes;
-
-import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.toolbar.SearchConfig.SearchConfigBuilder;
-
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-/**
- * An interface for accessing a Chassis Toolbar, regardless of how the underlying
- * views are represented.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public interface ToolbarController {
-
-    /**
-     * Sets the title of the toolbar to a string resource.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    void setTitle(@StringRes int title);
-
-    /**
-     * Sets the title of the toolbar to a CharSequence.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    void setTitle(CharSequence title);
-
-    /**
-     * Gets the current toolbar title.
-     */
-    CharSequence getTitle();
-
-    /**
-     * Sets the subtitle of the toolbar to a string resource.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    void setSubtitle(@StringRes int title);
-
-    /**
-     * Sets the subtitle of the toolbar to a CharSequence.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    void setSubtitle(CharSequence title);
-
-    /**
-     * Gets the current toolbar subtitle.
-     */
-    CharSequence getSubtitle();
-
-    /**
-     * Sets the tabs to display.
-     *
-     * @param tabs A list of {@link Tab}
-     * @see #setTabs(List, int)
-     */
-    void setTabs(@Nullable List<Tab> tabs);
-
-    /**
-     * Sets the tabs to display. This version will also take the index of a tab to start selected.
-     * This will not cause a callback to the tab's selected listener, unlike using
-     * {@link #setTabs(List)} followed by {@link #selectTab(int)}.
-     *
-     * @param tabs A list of {@link Tab}
-     * @param selectedTab The index of the tab to be initially selected
-     */
-    void setTabs(@Nullable List<Tab> tabs, int selectedTab);
-
-    /**
-     * Gets the list of tabs being displayed. The returned list will be unmodifiable.
-     */
-    List<Tab> getTabs();
-
-    /**
-     * Gets the number of tabs in the toolbar. The tabs can be retrieved using
-     * {@link #getTab(int)}.
-     *
-     * @deprecated Use {@link #getTabs getTabs().size()} instead.
-     */
-    @Deprecated
-    int getTabCount();
-
-    /**
-     * Gets the index of the tab.
-     *
-     * @deprecated Use {@link #getTabs getTabs().indexOf(tab)} instead.
-     */
-    @Deprecated
-    int getTabPosition(TabLayout.Tab tab);
-
-    /**
-     * Adds a tab to this toolbar. You can listen for when it is selected via
-     * {@link #registerOnTabSelectedListener(Toolbar.OnTabSelectedListener)}.
-     *
-     * @deprecated Use {@link #setTabs(List)} instead.
-     */
-    @Deprecated
-    void addTab(TabLayout.Tab tab);
-
-    /**
-     * Removes all the tabs.
-     *
-     * @deprecated Use {{@link #setTabs(List)}} instead, passing it
-     * {@link java.util.Collections#emptyList()}
-     */
-    @Deprecated
-    void clearAllTabs();
-
-    /**
-     * Gets a tab added to this toolbar. See
-     * {@link #addTab(TabLayout.Tab)}.
-     *
-     * @deprecated Use {@link #getTabs getTabs().get(position)} instead.
-     */
-    @Deprecated
-    TabLayout.Tab getTab(int position);
-
-    /**
-     * Selects a tab added to this toolbar.
-     *
-     * @see #setTabs(List)
-     */
-    void selectTab(int position);
-
-    /**
-     * Returns the index of the currently selected tab. If there are no tabs, this method returns
-     * -1.
-     */
-    int getSelectedTab();
-
-    /**
-     * Sets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
-     *
-     * @deprecated When not using {@link #setState(Toolbar.State)}, this method is not necessary.
-     * Simply add tabs to the toolbar when they should be shown.
-     */
-    @Deprecated
-    void setShowTabsInSubpage(boolean showTabs);
-
-    /**
-     * Gets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
-     *
-     * @deprecated When not using {@link #setState(Toolbar.State)},
-     * {@link #setShowTabsInSubpage(boolean)} is not necessary.
-     * Simply add tabs to the toolbar when they should be shown.
-     */
-    @Deprecated
-    boolean getShowTabsInSubpage();
-
-    /**
-     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
-     * will be displayed next to the title.
-     */
-    void setLogo(@DrawableRes int resId);
-
-    /**
-     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
-     * will be displayed next to the title.
-     */
-    void setLogo(Drawable drawable);
-
-    /** Sets the hint for the search bar. */
-    void setSearchHint(@StringRes int resId);
-
-    /** Sets the hint for the search bar. */
-    void setSearchHint(CharSequence hint);
-
-    /** Gets the search hint */
-    CharSequence getSearchHint();
-
-    /**
-     * Sets the icon to display in the search box.
-     *
-     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
-     * a similar place.
-     */
-    void setSearchIcon(@DrawableRes int resId);
-
-    /**
-     * Sets the icon to display in the search box.
-     *
-     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
-     * a similar place.
-     */
-    void setSearchIcon(Drawable d);
-
-    /**
-     * Sets the search mode, which can enable/disable the search bar in the toolbar.
-     *
-     * See {@link SearchMode}.
-     */
-    void setSearchMode(SearchMode mode);
-
-    /**
-     * Sets the {@link Toolbar.NavButtonMode}
-     *
-     * @deprecated Use {@link #setNavButtonMode(NavButtonMode)} instead.
-     */
-    @Deprecated
-    void setNavButtonMode(Toolbar.NavButtonMode style);
-
-    /** Sets the {@link NavButtonMode} */
-    void setNavButtonMode(NavButtonMode mode);
-
-    /**
-     * Gets the {@link Toolbar.NavButtonMode}.
-     *
-     * @deprecated No equivalent replacement. Maintain the current mode locally in the app if
-     * needed. If this is for a test, you can use this espresso code to check that the toolbar
-     * back button is shown:
-     * {@code onView(withContentDescription("Back")).check(matches(isDisplayed()));}
-     */
-    @Deprecated
-    Toolbar.NavButtonMode getNavButtonMode();
-
-    /** Show/hide the background. When hidden, the toolbar is completely transparent. */
-    void setBackgroundShown(boolean shown);
-
-    /** Returns true is the toolbar background is shown */
-    boolean getBackgroundShown();
-
-    /**
-     * Sets the {@link MenuItem Menuitems} to display.
-     */
-    void setMenuItems(@Nullable List<MenuItem> items);
-
-    /**
-     * Sets the {@link MenuItem Menuitems} to display to a list defined in XML.
-     *
-     * <p>If this method is called twice with the same argument (and {@link #setMenuItems(List)}
-     * wasn't called), nothing will happen the second time, even if the MenuItems were changed.
-     *
-     * <p>The XML file must have one <MenuItems> tag, with a variable number of <MenuItem>
-     * child tags. See CarUiToolbarMenuItem in CarUi's attrs.xml for a list of available attributes.
-     *
-     * Example:
-     * <pre>
-     * <MenuItems>
-     *     <MenuItem
-     *         app:title="Foo"/>
-     *     <MenuItem
-     *         app:title="Bar"
-     *         app:icon="@drawable/ic_tracklist"
-     *         app:onClick="xmlMenuItemClicked"/>
-     *     <MenuItem
-     *         app:title="Bar"
-     *         app:checkable="true"
-     *         app:uxRestrictions="FULLY_RESTRICTED"
-     *         app:onClick="xmlMenuItemClicked"/>
-     * </MenuItems>
-     * </pre>
-     *
-     * @return The MenuItems that were loaded from XML.
-     * @see #setMenuItems(List)
-     */
-    List<MenuItem> setMenuItems(@XmlRes int resId);
-
-    /** Gets the {@link MenuItem MenuItems} currently displayed */
-    @NonNull
-    List<MenuItem> getMenuItems();
-
-    /** Gets a {@link MenuItem} by id. */
-    @Nullable
-    MenuItem findMenuItemById(int id);
-
-    /** Gets a {@link MenuItem} by id. Will throw an IllegalArgumentException if not found. */
-    @NonNull
-    MenuItem requireMenuItemById(int id);
-
-    /**
-     * Set whether or not to show the {@link MenuItem MenuItems} while searching. Default false.
-     * Even if this is set to true, the {@link MenuItem} created by
-     * {@link MenuItem.Builder#setToSearch()} will still be hidden.
-     */
-    void setShowMenuItemsWhileSearching(boolean showMenuItems);
-
-    /** Returns if {@link MenuItem MenuItems} are shown while searching */
-    boolean getShowMenuItemsWhileSearching();
-
-    /**
-     * Sets the search query.
-     */
-    void setSearchQuery(String query);
-
-    /**
-     * Sets the state of the toolbar. This will show/hide the appropriate elements of the toolbar
-     * for the desired state.
-     *
-     * @deprecated Instead of using setState(), simply add the elements you want to see when
-     * you want to see them. The back button visibility can be controlled with the
-     * {@link com.android.car.ui.toolbar.Toolbar.NavButtonMode#DISABLED} enum,
-     * and the search bar can also be controlled with the {@link SearchMode} enum.
-     */
-    @Deprecated
-    void setState(Toolbar.State state);
-
-    /**
-     * Gets the current {@link Toolbar.State} of the toolbar.
-     *
-     * @deprecated See {@link #setState(Toolbar.State)} for details.
-     */
-    @Deprecated
-    Toolbar.State getState();
-
-    /**
-     * Returns whether or not the state of the toolbar was previously set.
-     *
-     * @deprecated See {@link #setState(Toolbar.State)} for details.
-     */
-    @Deprecated
-    boolean isStateSet();
-
-    /**
-     * Registers a new {@link Toolbar.OnTabSelectedListener} to the list of listeners.
-     *
-     * @deprecated The tabs set via {@link #setTabs(List)} have their own selected callbacks.
-     */
-    @Deprecated
-    void registerOnTabSelectedListener(Toolbar.OnTabSelectedListener listener);
-
-    /**
-     * Unregisters an existing {@link Toolbar.OnTabSelectedListener} from the list of listeners.
-     *
-     * @deprecated The tabs set via {@link #setTabs(List)} have their own selected callbacks.
-     */
-    @Deprecated
-    boolean unregisterOnTabSelectedListener(Toolbar.OnTabSelectedListener listener);
-
-    /** Registers a new {@link Toolbar.OnSearchListener} to the list of listeners. */
-    void registerOnSearchListener(Toolbar.OnSearchListener listener);
-
-    /** Unregisters an existing {@link Toolbar.OnSearchListener} from the list of listeners. */
-    boolean unregisterOnSearchListener(Toolbar.OnSearchListener listener);
-
-    /** Registers a new {@link Consumer} to the list of listeners. */
-    void registerSearchListener(Consumer<String> listener);
-
-    /** Unregisters an existing {@link Consumer} from the list of listeners. */
-    boolean unregisterSearchListener(Consumer<String> listener);
-
-    /**
-     * Sets the search info to be displayed within the widescreen IME.
-     */
-    void setSearchConfig(@Nullable SearchConfig searchConfig);
-
-    /**
-     * Returns the capabilities of what toolbar can do with Search
-     */
-    SearchCapabilities getSearchCapabilities();
-
-    /**
-     * Returns true if the toolbar can display search result items. One example of this is when the
-     * system is configured to display search items in the IME instead of in the app.
-     *
-     * @deprecated See {@link SearchCapabilities#canShowSearchResultItems()} for details.
-     */
-    @Deprecated
-    boolean canShowSearchResultItems();
-
-    /**
-     * Returns true if the app is allowed to set search results view.
-     *
-     * @deprecated See {@link SearchCapabilities#canShowSearchResultsView()} for details.
-     */
-    @Deprecated
-    boolean canShowSearchResultsView();
-
-    /**
-     * Add a view within a container that will animate with the wide screen IME to display search
-     * results.
-     *
-     * <p>Note: Apps can only call this method if the package name is allowed via OEM to render
-     * their view.  To check if the application have the permission to do so or not first call
-     * {@link SearchCapabilities#canShowSearchResultsView()}. If the app is not allowed this
-     * method
-     * will throw an {@link IllegalStateException}
-     *
-     * @param view to be added in the container.
-     * @deprecated See {@link SearchConfigBuilder#setSearchResultsView(View)} for details.
-     */
-    @Deprecated
-    void setSearchResultsView(@Nullable View view);
-
-    /**
-     * Set the icon to be displayed within the input field of IME window.
-     *
-     * @deprecated See {@link SearchConfigBuilder#setSearchResultsInputViewIcon(Drawable)} )} for
-     * details.
-     */
-    @Deprecated
-    void setSearchResultsInputViewIcon(@NonNull Drawable drawable);
-
-    /**
-     * Sets list of search item {@link CarUiListItem} to be displayed in the IMS
-     * template. This method should be called when system is running in a wide screen mode. Apps
-     * can check that by using {@link SearchCapabilities#canShowSearchResultItems()}
-     * Else, this method will throw an {@link IllegalStateException}
-     *
-     * @deprecated See {@link SearchConfigBuilder#setSearchResultItems(List)} )} for details.
-     */
-    @Deprecated
-    void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems);
-
-    /**
-     * Registers a new {@link Toolbar.OnSearchCompletedListener} to the list of listeners.
-     *
-     * @deprecated Use {@link #registerSearchCompletedListener(Runnable)} instead.
-     */
-    @Deprecated
-    void registerOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener);
-
-    /**
-     * Unregisters an existing {@link Toolbar.OnSearchCompletedListener} from the list of
-     * listeners.
-     *
-     * @deprecated Use {@link #unregisterSearchCompletedListener(Runnable)} instead.
-     */
-    @Deprecated
-    boolean unregisterOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener);
-
-    /** Registers a new {@link Runnable} to the list of listeners. */
-    void registerSearchCompletedListener(Runnable listener);
-
-    /**
-     * Unregisters an existing {@link Runnable} from the list of
-     * listeners.
-     */
-    boolean unregisterSearchCompletedListener(Runnable listener);
-
-    /**
-     * Registers a new {@link Toolbar.OnBackListener} to the list of listeners.
-     *
-     * @deprecated Use {@link #registerBackListener(Supplier)} instead.
-     */
-    @Deprecated
-    void registerOnBackListener(Toolbar.OnBackListener listener);
-
-    /**
-     * Unregisters an existing {@link Toolbar.OnBackListener} from the list of listeners.
-     *
-     * @deprecated Use {@link #unregisterBackListener(Supplier)} instead.
-     */
-    @Deprecated
-    boolean unregisterOnBackListener(Toolbar.OnBackListener listener);
-
-    /** Registers a new {@link Supplier<Boolean>} to the list of listeners. */
-    void registerBackListener(Supplier<Boolean> listener);
-
-    /** Unregisters an existing {@link Runnable} from the list of listeners. */
-    boolean unregisterBackListener(Supplier<Boolean> listener);
-
-    /** Gets a {@link ProgressBarController} */
-    ProgressBarController getProgressBar();
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerAdapterV1.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerAdapterV1.java
deleted file mode 100644
index 8742961..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerAdapterV1.java
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import static com.android.car.ui.utils.CarUiUtils.charSequenceToString;
-import static com.android.car.ui.utils.CarUiUtils.convertList;
-
-import static java.util.stream.Collectors.toList;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.IdRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
-
-import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ImeSearchInterfaceOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1;
-import com.android.car.ui.toolbar.Toolbar.OnBackListener;
-import com.android.car.ui.toolbar.Toolbar.OnSearchCompletedListener;
-import com.android.car.ui.toolbar.Toolbar.OnSearchListener;
-import com.android.car.ui.toolbar.Toolbar.OnTabSelectedListener;
-import com.android.car.ui.toolbar.Toolbar.State;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-/**
- * Adapts a {@link com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1}
- * into a {@link ToolbarController}
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class ToolbarControllerAdapterV1 implements ToolbarController {
-
-    private static final String TAG = ToolbarControllerAdapterV1.class.getName();
-
-    private final ToolbarControllerOEMV1 mOemToolbar;
-    private final Context mContext;
-
-    private ToolbarAdapterState mAdapterState = new ToolbarAdapterState();
-    private final Set<OnTabSelectedListener> mOnTabSelectedListeners = new HashSet<>();
-    private final Set<OnBackListener> mDeprecatedBackListeners = new HashSet<>();
-    private final Set<Supplier<Boolean>> mBackListeners = new HashSet<>();
-    private final Set<OnSearchListener> mDeprecatedSearchListeners = new HashSet<>();
-    private final Set<OnSearchCompletedListener> mDeprecatedSearchCompletedListeners =
-            new HashSet<>();
-    private final Set<Consumer<String>> mSearchListeners = new HashSet<>();
-    private final Set<Runnable> mSearchCompletedListeners = new HashSet<>();
-    private final ProgressBarControllerAdapterV1 mProgressBar;
-    private String mSearchHint;
-    private final SearchConfig.SearchConfigBuilder mSearchConfigBuilder;
-    private List<MenuItem> mClientMenuItems = Collections.emptyList();
-    private final List<DeprecatedTabWrapper> mDeprecatedTabs = new ArrayList<>();
-    private final SearchWidescreenController mSearchWidescreenController;
-    private final boolean mSupportsImeSearch;
-
-    public ToolbarControllerAdapterV1(
-            @NonNull Context context,
-            @NonNull ToolbarControllerOEMV1 oemToolbar) {
-        mOemToolbar = oemToolbar;
-        mProgressBar = new ProgressBarControllerAdapterV1(mOemToolbar.getProgressBar());
-        mContext = context;
-        mSearchConfigBuilder = SearchConfig.builder();
-        Activity activity = CarUiUtils.getActivity(mContext);
-
-        mSearchWidescreenController = new SearchWidescreenController(context);
-        ImeSearchInterfaceOEMV1 imeSearchInterface = mOemToolbar.getImeSearchInterface();
-        mSupportsImeSearch = imeSearchInterface != null;
-        if (imeSearchInterface != null) {
-            imeSearchInterface.setOnPrivateImeCommandListener(
-                    mSearchWidescreenController.getOnPrivateImeCommandListener());
-            imeSearchInterface.setSearchTextViewConsumer(mSearchWidescreenController::setTextView);
-        }
-
-        oemToolbar.setBackListener(() -> {
-            boolean handled = false;
-            for (OnBackListener listener : mDeprecatedBackListeners) {
-                handled |= listener.onBack();
-            }
-            for (Supplier<Boolean> listener : mBackListeners) {
-                handled |= listener.get();
-            }
-            if (!handled && activity != null) {
-                activity.onBackPressed();
-            }
-        });
-
-        oemToolbar.setSearchListener(query -> {
-            for (OnSearchListener listener : mDeprecatedSearchListeners) {
-                listener.onSearch(query);
-            }
-            for (Consumer<String> listener : mSearchListeners) {
-                listener.accept(query);
-            }
-        });
-        oemToolbar.setSearchCompletedListener(() -> {
-            for (OnSearchCompletedListener listener : mDeprecatedSearchCompletedListeners) {
-                listener.onSearchCompleted();
-            }
-            for (Runnable listener : mSearchCompletedListeners) {
-                listener.run();
-            }
-        });
-    }
-
-    @Override
-    public void setTitle(int title) {
-        setTitle(title == 0 ? null : mContext.getString(title));
-    }
-
-    @Override
-    public void setTitle(CharSequence title) {
-        update(mAdapterState.copy().setTitle(charSequenceToString(title)).build());
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mAdapterState.getTitle();
-    }
-
-    @Override
-    public void setSubtitle(int title) {
-        setSubtitle(title == 0 ? null : mContext.getString(title));
-    }
-
-    @Override
-    public void setSubtitle(CharSequence subtitle) {
-        update(mAdapterState.copy().setSubtitle(charSequenceToString(subtitle)).build());
-    }
-
-    @Override
-    public CharSequence getSubtitle() {
-        return mAdapterState.getSubtitle();
-    }
-
-    @Override
-    public void setTabs(@Nullable List<Tab> tabs) {
-        setTabs(tabs, 0);
-    }
-
-    @Override
-    public void setTabs(@Nullable List<Tab> tabs, int selectedTab) {
-        mDeprecatedTabs.clear();
-        if (tabs == null || tabs.isEmpty()) {
-            selectedTab = 0;
-        } else if (selectedTab < 0 || selectedTab >= tabs.size()) {
-            throw new IllegalArgumentException("Tab position is invalid: " + selectedTab);
-        }
-        update(mAdapterState.copy()
-                .setTabs(convertList(tabs, TabAdapterV1::new))
-                .setSelectedTab(selectedTab)
-                .build());
-    }
-
-    @Override
-    public List<Tab> getTabs() {
-        return Collections.unmodifiableList(mAdapterState.getTabs().stream()
-                .map(TabAdapterV1::getClientTab)
-                .collect(toList()));
-    }
-
-    @Override
-    public int getTabCount() {
-        return mDeprecatedTabs.size();
-    }
-
-    @Override
-    public int getTabPosition(TabLayout.Tab tab) {
-        for (int i = 0; i < mDeprecatedTabs.size(); i++) {
-            if (mDeprecatedTabs.get(i).getDeprecatedTab() == tab) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    @Override
-    public void addTab(TabLayout.Tab clientTab) {
-        mDeprecatedTabs.add(new DeprecatedTabWrapper(mContext, clientTab,
-                this::updateModernTabsFromDeprecatedOnes, (tab) -> {
-            for (Toolbar.OnTabSelectedListener listener : mOnTabSelectedListeners) {
-                listener.onTabSelected(clientTab);
-            }
-        }));
-        updateModernTabsFromDeprecatedOnes();
-    }
-
-    private void updateModernTabsFromDeprecatedOnes() {
-        List<Tab> modernTabs = new ArrayList<>();
-
-        for (DeprecatedTabWrapper tab : mDeprecatedTabs) {
-            modernTabs.add(tab.getModernTab());
-        }
-
-        update(mAdapterState.copy().setTabs(convertList(modernTabs, TabAdapterV1::new)).build());
-    }
-
-    @Override
-    public void clearAllTabs() {
-        setTabs(Collections.emptyList());
-    }
-
-    @Override
-    public TabLayout.Tab getTab(int position) {
-        return mDeprecatedTabs.get(position).getDeprecatedTab();
-    }
-
-    @Override
-    public void selectTab(int position) {
-        if (position < 0 || position >= mAdapterState.getTabs().size()) {
-            throw new IllegalArgumentException("Tab position is invalid: " + position);
-        }
-        update(mAdapterState.copy()
-                .setSelectedTab(position)
-                .build());
-    }
-
-    @Override
-    public int getSelectedTab() {
-        int selectedTab = mAdapterState.getSelectedTab();
-        if (mAdapterState.getTabs().isEmpty() && selectedTab != -1) {
-            throw new IllegalStateException("mSelectedTab should've been -1");
-        }
-        return selectedTab;
-    }
-
-    @Override
-    public void setShowTabsInSubpage(boolean showTabs) {
-        update(mAdapterState.copy().setShowTabsInSubpage(showTabs).build());
-    }
-
-    @Override
-    public boolean getShowTabsInSubpage() {
-        return mAdapterState.getShowTabsInSubpage();
-    }
-
-    @Override
-    public void setLogo(@IdRes int resId) {
-        setLogo(getDrawable(resId));
-    }
-
-    @Override
-    public void setLogo(Drawable drawable) {
-        update(mAdapterState.copy().setLogo(drawable).build());
-    }
-
-    @Override
-    public void setSearchHint(int resId) {
-        setSearchHint(mContext.getString(resId));
-    }
-
-    @Override
-    public void setSearchHint(CharSequence hint) {
-        mSearchHint = charSequenceToString(hint);
-        mOemToolbar.setSearchHint(mSearchHint);
-    }
-
-    @Override
-    public CharSequence getSearchHint() {
-        return mSearchHint;
-    }
-
-    @Override
-    public void setSearchIcon(int resId) {
-        setSearchIcon(getDrawable(resId));
-    }
-
-    @Override
-    public void setSearchIcon(Drawable d) {
-        mOemToolbar.setSearchIcon(d);
-    }
-
-    @Override
-    public void setSearchMode(SearchMode mode) {
-        update(mAdapterState.copy().setSearchMode(mode).build());
-    }
-
-    @Override
-    public void setNavButtonMode(Toolbar.NavButtonMode style) {
-        switch (style) {
-            case BACK:
-                setNavButtonMode(NavButtonMode.BACK);
-                break;
-            case DOWN:
-                setNavButtonMode(NavButtonMode.DOWN);
-                break;
-            case CLOSE:
-                setNavButtonMode(NavButtonMode.CLOSE);
-                break;
-            case DISABLED:
-            default:
-                setNavButtonMode(NavButtonMode.DISABLED);
-                break;
-        }
-    }
-
-    @Override
-    public void setNavButtonMode(NavButtonMode mode) {
-        update(mAdapterState.copy().setNavButtonMode(mode).build());
-    }
-
-    @Override
-    public Toolbar.NavButtonMode getNavButtonMode() {
-        NavButtonMode mode = mAdapterState.getNavButtonMode();
-        switch (mode) {
-            case BACK:
-                return Toolbar.NavButtonMode.BACK;
-            case DOWN:
-                return Toolbar.NavButtonMode.DOWN;
-            case CLOSE:
-                return Toolbar.NavButtonMode.CLOSE;
-            case DISABLED:
-            default:
-                return Toolbar.NavButtonMode.DISABLED;
-        }
-    }
-
-    @Override
-    public void setBackgroundShown(boolean shown) {
-        Log.w(TAG, "Unsupported operation setBackgroundShown() called, ignoring");
-    }
-
-    @Override
-    public boolean getBackgroundShown() {
-        return true;
-    }
-
-    @Override
-    public void setMenuItems(@Nullable List<MenuItem> items) {
-        mClientMenuItems = items;
-        update(mAdapterState.copy()
-                .setMenuItems(convertList(items, MenuItemAdapterV1::new))
-                .build());
-    }
-
-    @Override
-    public List<MenuItem> setMenuItems(int resId) {
-        List<MenuItem> menuItems = MenuItemXmlParserUtil.readMenuItemList(mContext, resId);
-        setMenuItems(menuItems);
-        return menuItems;
-    }
-
-    @NonNull
-    @Override
-    public List<MenuItem> getMenuItems() {
-        return mClientMenuItems;
-    }
-
-    @Nullable
-    @Override
-    public MenuItem findMenuItemById(int id) {
-        for (MenuItem item : getMenuItems()) {
-            if (item.getId() == id) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    @NonNull
-    @Override
-    public MenuItem requireMenuItemById(int id) {
-        MenuItem result = findMenuItemById(id);
-
-        if (result == null) {
-            throw new IllegalArgumentException("ID does not reference a MenuItem on this Toolbar");
-        }
-
-        return result;
-    }
-
-    @Override
-    public void setShowMenuItemsWhileSearching(boolean showMenuItems) {
-        update(mAdapterState.copy().setShowMenuItemsWhileSearching(showMenuItems).build());
-    }
-
-    @Override
-    public boolean getShowMenuItemsWhileSearching() {
-        return mAdapterState.getShowMenuItemsWhileSearching();
-    }
-
-    @Override
-    public void setSearchQuery(String query) {
-        mOemToolbar.setSearchQuery(query);
-    }
-
-    @Override
-    public void setState(State state) {
-        update(mAdapterState.copy().setState(state).build());
-    }
-
-    /**
-     * This method takes a new {@link ToolbarAdapterState} and compares it to the current
-     * {@link #mAdapterState}. It then sends any differences it detects to the shared library
-     * toolbar.
-     *
-     * This is also the core of the logic that adapts from the client's toolbar interface to
-     * the OEM apis toolbar interface. For example, when you are in the HOME state and add tabs,
-     * it will call setTitle(null) on the shared library toolbar. This is because the client
-     * interface
-     */
-    private void update(ToolbarAdapterState newAdapterState) {
-        ToolbarAdapterState oldAdapterState = mAdapterState;
-        mAdapterState = newAdapterState;
-
-        if (!TextUtils.equals(newAdapterState.getShownTitle(), oldAdapterState.getShownTitle())) {
-            mOemToolbar.setTitle(newAdapterState.getTitle());
-        }
-        if (!TextUtils.equals(newAdapterState.getShownSubtitle(),
-                oldAdapterState.getShownSubtitle())) {
-            mOemToolbar.setSubtitle(newAdapterState.getSubtitle());
-        }
-
-        // This first check just checks if the logo is changing nullity, the second one checks
-        // if it's actually a different image.
-        if (newAdapterState.getShownLogo() != oldAdapterState.getShownLogo()) {
-            mOemToolbar.setLogo(newAdapterState.getShownLogo());
-        } else if (newAdapterState.getShownLogo() != null && newAdapterState.getLogoDirty()) {
-            mOemToolbar.setLogo(newAdapterState.getShownLogo());
-        }
-
-        if (newAdapterState.getSearchMode() != oldAdapterState.getSearchMode()) {
-            switch (newAdapterState.getSearchMode()) {
-                case SEARCH:
-                    mOemToolbar.setSearchMode(ToolbarControllerOEMV1.SEARCH_MODE_SEARCH);
-                    break;
-                case EDIT:
-                    mOemToolbar.setSearchMode(ToolbarControllerOEMV1.SEARCH_MODE_EDIT);
-                    break;
-                default:
-                    mOemToolbar.setSearchMode(ToolbarControllerOEMV1.SEARCH_MODE_DISABLED);
-            }
-        }
-
-        if (oldAdapterState.getNavButtonMode() != newAdapterState.getNavButtonMode()) {
-            if (newAdapterState.getNavButtonMode() == NavButtonMode.DISABLED) {
-                mOemToolbar.setNavButtonMode(ToolbarControllerOEMV1.NAV_BUTTON_MODE_DISABLED);
-            } else if (newAdapterState.getNavButtonMode() == NavButtonMode.CLOSE) {
-                mOemToolbar.setNavButtonMode(ToolbarControllerOEMV1.NAV_BUTTON_MODE_CLOSE);
-            } else if (newAdapterState.getNavButtonMode() == NavButtonMode.DOWN) {
-                mOemToolbar.setNavButtonMode(ToolbarControllerOEMV1.NAV_BUTTON_MODE_DOWN);
-            } else {
-                mOemToolbar.setNavButtonMode(ToolbarControllerOEMV1.NAV_BUTTON_MODE_BACK);
-            }
-        }
-
-        boolean gainingTabs = newAdapterState.hasTabs() && !oldAdapterState.hasTabs();
-        boolean losingTabs = !newAdapterState.hasTabs() && oldAdapterState.hasTabs();
-        if (gainingTabs) {
-            mOemToolbar.setTabs(newAdapterState.getTabs()
-                    .stream()
-                    .map(TabAdapterV1::getSharedLibraryTab)
-                    .collect(toList()),
-                    newAdapterState.getSelectedTab());
-        } else if (losingTabs) {
-            mOemToolbar.setTabs(Collections.emptyList(), -1);
-        } else if (newAdapterState.hasTabs() && newAdapterState.getTabsDirty()) {
-            mOemToolbar.setTabs(newAdapterState.getTabs()
-                            .stream()
-                            .map(TabAdapterV1::getSharedLibraryTab)
-                            .collect(toList()),
-                    newAdapterState.getSelectedTab());
-        } else if (newAdapterState.hasTabs()
-                && newAdapterState.getSelectedTab() != oldAdapterState.getSelectedTab()) {
-            mOemToolbar.selectTab(newAdapterState.getSelectedTab(), true);
-        }
-
-        if (!Objects.equals(
-                newAdapterState.getShownMenuItems(), oldAdapterState.getShownMenuItems())) {
-            mOemToolbar.setMenuItems(newAdapterState.getShownMenuItems());
-        }
-    }
-
-    @Override
-    public State getState() {
-        return mAdapterState.getState();
-    }
-
-    @Override
-    public boolean isStateSet() {
-        return mAdapterState.isStateSet();
-    }
-
-    @Override
-    public void registerOnTabSelectedListener(OnTabSelectedListener listener) {
-        mOnTabSelectedListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterOnTabSelectedListener(OnTabSelectedListener listener) {
-        return mOnTabSelectedListeners.remove(listener);
-    }
-
-    @Override
-    public void registerOnSearchListener(OnSearchListener listener) {
-        mDeprecatedSearchListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterOnSearchListener(OnSearchListener listener) {
-        return mDeprecatedSearchListeners.remove(listener);
-    }
-
-    @Override
-    public void registerSearchListener(Consumer<String> listener) {
-        mSearchListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterSearchListener(Consumer<String> listener) {
-        return mSearchListeners.remove(listener);
-    }
-
-    @Override
-    public void setSearchConfig(SearchConfig searchConfig) {
-        mSearchWidescreenController.setSearchConfig(searchConfig);
-    }
-
-    @Override
-    public SearchCapabilities getSearchCapabilities() {
-        if (!mSupportsImeSearch) {
-            return SearchCapabilities.builder().build();
-        } else {
-            return mSearchWidescreenController.getSearchCapabilities();
-        }
-    }
-
-    @Override
-    public boolean canShowSearchResultItems() {
-        return getSearchCapabilities().canShowSearchResultItems();
-    }
-
-    @Override
-    public boolean canShowSearchResultsView() {
-        return getSearchCapabilities().canShowSearchResultsView();
-    }
-
-    @Override
-    public void setSearchResultsView(View view) {
-        mSearchConfigBuilder.setSearchResultsView(view);
-        setSearchConfig(mSearchConfigBuilder.build());
-    }
-
-    @Override
-    public void setSearchResultsInputViewIcon(Drawable drawable) {
-        mSearchConfigBuilder.setSearchResultsInputViewIcon(drawable);
-        setSearchConfig(mSearchConfigBuilder.build());
-    }
-
-    @Override
-    public void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems) {
-        mSearchConfigBuilder.setSearchResultItems(searchItems);
-        setSearchConfig(mSearchConfigBuilder.build());
-    }
-
-    @Override
-    public void registerOnSearchCompletedListener(OnSearchCompletedListener listener) {
-        mDeprecatedSearchCompletedListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterOnSearchCompletedListener(OnSearchCompletedListener listener) {
-        return mDeprecatedSearchCompletedListeners.remove(listener);
-    }
-
-    @Override
-    public void registerSearchCompletedListener(Runnable listener) {
-        mSearchCompletedListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterSearchCompletedListener(Runnable listener) {
-        return mSearchCompletedListeners.remove(listener);
-    }
-
-    @Override
-    public void registerOnBackListener(OnBackListener listener) {
-        mDeprecatedBackListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterOnBackListener(OnBackListener listener) {
-        return mDeprecatedBackListeners.remove(listener);
-    }
-
-    @Override
-    public void registerBackListener(Supplier<Boolean> listener) {
-        mBackListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterBackListener(Supplier<Boolean> listener) {
-        return mBackListeners.remove(listener);
-    }
-
-    @Override
-    public ProgressBarController getProgressBar() {
-        return mProgressBar;
-    }
-
-    private Drawable getDrawable(@DrawableRes int drawable) {
-        if (drawable == 0) {
-            return null;
-        } else {
-            return ContextCompat.getDrawable(mContext, drawable);
-        }
-    }
-
-    private static class ToolbarAdapterState {
-        private final State mState;
-        private final boolean mStateSet;
-        private final boolean mShowTabsInSubpage;
-        @NonNull
-        private final List<TabAdapterV1> mTabs;
-        @NonNull
-        private final List<MenuItemAdapterV1> mMenuItems;
-        private final int mSelectedTab;
-        private final String mTitle;
-        private final String mSubtitle;
-        private final Drawable mLogo;
-        private final boolean mShowMenuItemsWhileSearching;
-        private final boolean mTabsDirty;
-        private final boolean mLogoDirty;
-        private final NavButtonMode mNavButtonMode;
-        private final SearchMode mSearchMode;
-
-        ToolbarAdapterState() {
-            mState = State.HOME;
-            mStateSet = false;
-            mShowTabsInSubpage = false;
-            mTabs = Collections.emptyList();
-            mMenuItems = Collections.emptyList();
-            mSelectedTab = -1;
-            mTitle = null;
-            mSubtitle = null;
-            mLogo = null;
-            mShowMenuItemsWhileSearching = false;
-            mTabsDirty = false;
-            mLogoDirty = false;
-            mNavButtonMode = NavButtonMode.DISABLED;
-            mSearchMode = SearchMode.DISABLED;
-        }
-
-        private ToolbarAdapterState(Builder builder) {
-            mState = builder.mState;
-            mStateSet = builder.mStateSet;
-            mShowTabsInSubpage = builder.mShowTabsInSubpage;
-            mTabs = builder.mTabs;
-            mMenuItems = builder.mMenuItems;
-            mSelectedTab = builder.mSelectedTab;
-            mTitle = builder.mTitle;
-            mSubtitle = builder.mSubtitle;
-            mLogo = builder.mLogo;
-            mShowMenuItemsWhileSearching = builder.mShowMenuItemsWhileSearching;
-            mTabsDirty = builder.mTabsDirty;
-            mLogoDirty = builder.mLogoDirty;
-            mNavButtonMode = builder.mNavButtonMode;
-            mSearchMode = builder.mSearchMode;
-        }
-
-        public State getState() {
-            return mState;
-        }
-
-        public boolean isStateSet() {
-            return mStateSet;
-        }
-
-        public boolean getShowTabsInSubpage() {
-            return mShowTabsInSubpage;
-        }
-
-        @NonNull
-        public List<TabAdapterV1> getTabs() {
-            return mTabs;
-        }
-
-        public boolean getTabsDirty() {
-            return mTabsDirty;
-        }
-
-        public int getSelectedTab() {
-            return mSelectedTab;
-        }
-
-        public String getTitle() {
-            return mTitle == null ? "" : mTitle;
-        }
-
-        public String getShownTitle() {
-            if (mStateSet && (mState != State.HOME && mState != State.SUBPAGE)) {
-                return "";
-            }
-            return mTitle == null ? "" : mTitle;
-        }
-
-        public String getSubtitle() {
-            return mSubtitle == null ? "" : mSubtitle;
-        }
-
-        public String getShownSubtitle() {
-            if (mStateSet && (mState != State.HOME && mState != State.SUBPAGE)) {
-                return "";
-            }
-            return mSubtitle == null ? "" : mSubtitle;
-        }
-
-        public Drawable getLogo() {
-            return mLogo;
-        }
-
-        public Drawable getShownLogo() {
-            if (mStateSet && (mState != State.HOME && mState != State.SUBPAGE)) {
-                return null;
-            }
-            return mLogo;
-        }
-
-        public boolean getLogoDirty() {
-            return mLogoDirty;
-        }
-
-        public boolean getShowMenuItemsWhileSearching() {
-            return mShowMenuItemsWhileSearching;
-        }
-
-        public NavButtonMode getNavButtonMode() {
-            if (mStateSet && mNavButtonMode == NavButtonMode.DISABLED
-                    && mState != State.HOME) {
-                return NavButtonMode.BACK;
-            }
-            return mNavButtonMode;
-        }
-
-        private boolean hasTabs() {
-            if (!mStateSet) {
-                return !getTabs().isEmpty();
-            }
-            return (mState == State.HOME || (mState == State.SUBPAGE && getShowTabsInSubpage()))
-                    && !getTabs().isEmpty();
-        }
-
-        private List<MenuItemAdapterV1> getShownMenuItems() {
-            SearchMode searchMode = getSearchMode();
-            if (searchMode == SearchMode.EDIT) {
-                return mShowMenuItemsWhileSearching ? mMenuItems : Collections.emptyList();
-            } else if (searchMode == SearchMode.SEARCH) {
-                return mShowMenuItemsWhileSearching
-                        ? mMenuItems.stream().filter(i -> !i.isSearch()).collect(toList())
-                        : Collections.emptyList();
-            } else {
-                return mMenuItems;
-            }
-        }
-
-        private SearchMode getSearchMode() {
-            if (mStateSet) {
-                if (mState == State.SEARCH) {
-                    return SearchMode.SEARCH;
-                } else if (mState == State.EDIT) {
-                    return SearchMode.EDIT;
-                } else {
-                    return SearchMode.DISABLED;
-                }
-            }
-            return mSearchMode;
-        }
-
-        public Builder copy() {
-            return new Builder(this);
-        }
-
-        public static class Builder {
-            private final ToolbarAdapterState mStateClonedFrom;
-            private boolean mWasChanged = false;
-            private State mState;
-            private boolean mStateSet;
-            private boolean mShowTabsInSubpage;
-            @NonNull
-            private List<TabAdapterV1> mTabs;
-            @NonNull
-            private List<MenuItemAdapterV1> mMenuItems;
-            private int mSelectedTab;
-            private String mTitle;
-            private String mSubtitle;
-            private Drawable mLogo;
-            private boolean mShowMenuItemsWhileSearching;
-            private boolean mTabsDirty = false;
-            private boolean mLogoDirty = false;
-            private NavButtonMode mNavButtonMode;
-            private SearchMode mSearchMode;
-
-            Builder(ToolbarAdapterState state) {
-                mStateClonedFrom = state;
-                mState = state.mState;
-                mStateSet = state.mStateSet;
-                mShowTabsInSubpage = state.mShowTabsInSubpage;
-                mTabs = state.mTabs;
-                mMenuItems = state.mMenuItems;
-                mShowMenuItemsWhileSearching = state.mShowMenuItemsWhileSearching;
-                mSelectedTab = state.mSelectedTab;
-                mTitle = state.mTitle;
-                mSubtitle = state.mSubtitle;
-                mLogo = state.mLogo;
-                mNavButtonMode = state.mNavButtonMode;
-                mSearchMode = state.mSearchMode;
-            }
-
-            public ToolbarAdapterState build() {
-                if (!mWasChanged) {
-                    return mStateClonedFrom;
-                } else {
-                    return new ToolbarAdapterState(this);
-                }
-            }
-
-            public Builder setState(State state) {
-                if (mSearchMode != SearchMode.DISABLED) {
-                    throw new IllegalStateException("Cannot use setSearchMode() with setState()");
-                }
-                if (state != mState) {
-                    mState = state;
-                    mStateSet = true;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setShowTabsInSubpage(boolean showTabsInSubpage) {
-                if (mShowTabsInSubpage != showTabsInSubpage) {
-                    mShowTabsInSubpage = showTabsInSubpage;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setTabs(
-                    @Nullable List<TabAdapterV1> tabs) {
-                if (tabs == null) {
-                    tabs = Collections.emptyList();
-                }
-                if (!Objects.equals(tabs, mTabs)) {
-                    mTabs = Collections.unmodifiableList(tabs);
-                    mSelectedTab = mTabs.isEmpty() ? -1 : 0;
-                    mWasChanged = true;
-                    mTabsDirty = true;
-                }
-                return this;
-            }
-
-            public Builder addTab(@NonNull TabAdapterV1 tab) {
-                List<TabAdapterV1> newTabs = new ArrayList<>(mTabs);
-                newTabs.add(tab);
-                mTabs = Collections.unmodifiableList(newTabs);
-                mWasChanged = true;
-                mTabsDirty = true;
-                return this;
-            }
-
-            public Builder setSelectedTab(int selectedTab) {
-                if (mSelectedTab != selectedTab) {
-                    mSelectedTab = selectedTab;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setTitle(String title) {
-                if (!Objects.equals(mTitle, title)) {
-                    mTitle = title;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setSubtitle(String subtitle) {
-                if (!Objects.equals(mSubtitle, subtitle)) {
-                    mSubtitle = subtitle;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setLogo(Drawable logo) {
-                if (mLogo != logo) {
-                    mLogo = logo;
-                    mWasChanged = true;
-                    mLogoDirty = true;
-                }
-                return this;
-            }
-
-            public Builder setShowMenuItemsWhileSearching(boolean showMenuItemsWhileSearching) {
-                if (mShowMenuItemsWhileSearching != showMenuItemsWhileSearching) {
-                    mShowMenuItemsWhileSearching = showMenuItemsWhileSearching;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setMenuItems(List<MenuItemAdapterV1> menuItems) {
-                if (menuItems == null) {
-                    menuItems = Collections.emptyList();
-                }
-
-                if (!Objects.equals(mMenuItems, menuItems)) {
-                    mMenuItems = menuItems;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setNavButtonMode(NavButtonMode newMode) {
-                if (newMode != mNavButtonMode) {
-                    mNavButtonMode = newMode;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-
-            public Builder setSearchMode(SearchMode searchMode) {
-                if (mStateSet) {
-                    throw new IllegalStateException("Cannot use setSearchMode() with setState()");
-                }
-                if (mSearchMode != searchMode) {
-                    mSearchMode = searchMode;
-                    mWasChanged = true;
-                }
-                return this;
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerImpl.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerImpl.java
deleted file mode 100644
index 9191239..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ToolbarControllerImpl.java
+++ /dev/null
@@ -1,1174 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.toolbar;
-
-import static android.view.View.GONE;
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-
-import static com.android.car.ui.utils.CarUiUtils.findViewByRefId;
-import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.text.PrecomputedText;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.annotation.XmlRes;
-import androidx.core.content.ContextCompat;
-
-import com.android.car.ui.AlertDialogBuilder;
-import com.android.car.ui.R;
-import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.utils.CarUiUtils;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-/**
- * The implementation of {@link ToolbarController}. This class takes a ViewGroup, and looks
- * in the ViewGroup to find all the toolbar-related views to control.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class ToolbarControllerImpl implements ToolbarController {
-    private static final String TAG = "CarUiToolbarController";
-
-    @Nullable
-    private View mBackground;
-    private ImageView mNavIcon;
-    private ImageView mLogoInNavIconSpace;
-    private ViewGroup mNavIconContainer;
-    private ViewGroup mTitleContainer;
-    private TextView mTitle;
-    @NonNull
-    private CharSequence mTitleText = "";
-    private TextView mSubtitle;
-    @NonNull
-    private CharSequence mSubtitleText = "";
-    private ImageView mTitleLogo;
-    private ViewGroup mTitleLogoContainer;
-    private TabLayout mTabLayout;
-    private ViewGroup mMenuItemsContainer;
-    private SearchConfig.SearchConfigBuilder mSearchConfigBuilder;
-    private final FrameLayout mSearchViewContainer;
-    private SearchView mSearchView;
-
-    // Cached values that we will send to views when they are inflated
-    private CharSequence mSearchHint;
-    private Drawable mSearchIcon;
-    private String mSearchQuery;
-    private final Context mContext;
-    private final Set<Consumer<String>> mOnSearchListeners = new HashSet<>();
-    private final Set<Runnable> mOnSearchCompletedListeners = new HashSet<>();
-    private final Set<Toolbar.OnSearchListener> mDeprecatedSearchListeners = new HashSet<>();
-    private final Set<Toolbar.OnSearchCompletedListener> mDeprecatedSearchCompletedListeners =
-            new HashSet<>();
-
-    private final Set<Toolbar.OnBackListener> mDeprecatedBackListeners = new HashSet<>();
-    private final Set<Supplier<Boolean>> mBackListeners = new HashSet<>();
-    private final Set<Toolbar.OnTabSelectedListener> mOnTabSelectedListeners = new HashSet<>();
-
-    private final MenuItem mOverflowButton;
-    private final boolean mIsTabsInSecondRow;
-    private boolean mShowTabsInSubpage = false;
-    private boolean mHasLogo = false;
-    private boolean mShowMenuItemsWhileSearching;
-    private Toolbar.State mState = Toolbar.State.HOME;
-    private boolean mStateSet = false;
-    private NavButtonMode mNavButtonMode = NavButtonMode.DISABLED;
-    private SearchMode mSearchMode = SearchMode.DISABLED;
-    @NonNull
-    private List<MenuItem> mMenuItems = Collections.emptyList();
-    private List<MenuItem> mOverflowItems = new ArrayList<>();
-    private final List<CarUiListItem> mUiOverflowItems = new ArrayList<>();
-    private final CarUiListItemAdapter mOverflowAdapter;
-    private final List<MenuItemRenderer> mMenuItemRenderers = new ArrayList<>();
-    private final List<DeprecatedTabWrapper> mDeprecatedTabs = new ArrayList<>();
-    private View[] mMenuItemViews;
-    private int mMenuItemsXmlId = 0;
-    private AlertDialog mOverflowDialog;
-    private final boolean mNavIconSpaceReserved;
-    private final boolean mLogoFillsNavIconSpace;
-    private final boolean mShowLogo;
-    private SearchConfig mSearchConfigForWidescreen;
-    private final ProgressBarController mProgressBar;
-    private final MenuItem.Listener mOverflowItemListener = item -> {
-        updateOverflowDialog(item);
-        update();
-    };
-
-
-    public ToolbarControllerImpl(View view) {
-        mContext = view.getContext();
-        mOverflowButton = MenuItem.builder(getContext())
-                .setIcon(R.drawable.car_ui_icon_overflow_menu)
-                .setTitle(R.string.car_ui_toolbar_menu_item_overflow_title)
-                .setOnClickListener(v -> {
-                    if (mOverflowDialog == null) {
-                        if (Log.isLoggable(TAG, Log.ERROR)) {
-                            Log.e(TAG, "Overflow dialog was null when trying to show it!");
-                        }
-                    } else {
-                        mOverflowDialog.show();
-                    }
-                })
-                .build();
-
-        mIsTabsInSecondRow = getContext().getResources().getBoolean(
-                R.bool.car_ui_toolbar_tabs_on_second_row);
-        mNavIconSpaceReserved = getContext().getResources().getBoolean(
-                R.bool.car_ui_toolbar_nav_icon_reserve_space);
-        mLogoFillsNavIconSpace = getContext().getResources().getBoolean(
-                R.bool.car_ui_toolbar_logo_fills_nav_icon_space);
-        mShowLogo = getContext().getResources().getBoolean(
-                R.bool.car_ui_toolbar_show_logo);
-        mSearchHint = getContext().getString(R.string.car_ui_toolbar_default_search_hint);
-
-        mBackground = findViewByRefId(view, R.id.car_ui_toolbar_background);
-        mTabLayout = requireViewByRefId(view, R.id.car_ui_toolbar_tabs);
-        mNavIcon = requireViewByRefId(view, R.id.car_ui_toolbar_nav_icon);
-        mLogoInNavIconSpace = requireViewByRefId(view, R.id.car_ui_toolbar_logo);
-        mNavIconContainer = requireViewByRefId(view, R.id.car_ui_toolbar_nav_icon_container);
-        mMenuItemsContainer = requireViewByRefId(view, R.id.car_ui_toolbar_menu_items_container);
-        mTitleContainer = requireViewByRefId(view, R.id.car_ui_toolbar_title_container);
-        mSubtitle = requireViewByRefId(view, R.id.car_ui_toolbar_subtitle);
-        mTitle = requireViewByRefId(view, R.id.car_ui_toolbar_title);
-        mTitleLogoContainer = requireViewByRefId(view, R.id.car_ui_toolbar_title_logo_container);
-        mTitleLogo = requireViewByRefId(view, R.id.car_ui_toolbar_title_logo);
-        mSearchViewContainer = requireViewByRefId(view, R.id.car_ui_toolbar_search_view_container);
-        mProgressBar = new ProgressBarControllerImpl(
-                requireViewByRefId(view, R.id.car_ui_toolbar_progress_bar));
-        mSearchConfigBuilder = SearchConfig.builder();
-
-        setBackgroundShown(true);
-
-        mOverflowAdapter = new CarUiListItemAdapter(mUiOverflowItems);
-    }
-
-    private Context getContext() {
-        return mContext;
-    }
-
-    private Drawable getDrawable(@DrawableRes int resId) {
-        if (resId == 0) {
-            return null;
-        } else {
-            return ContextCompat.getDrawable(getContext(), resId);
-        }
-    }
-
-    /**
-     * Sets the title of the toolbar to a string resource.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    @Override
-    public void setTitle(@StringRes int title) {
-        setTitle(title == 0 ? null : getContext().getString(title));
-    }
-
-    /**
-     * Sets the title of the toolbar to a CharSequence.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    @Override
-    public void setTitle(CharSequence title) {
-        mTitleText = title == null ? "" : title;
-        asyncSetText(mTitle, mTitleText, Runnable::run);
-        update();
-    }
-
-    private void asyncSetText(TextView textView, @NonNull CharSequence title, Executor bgExecutor) {
-        // construct precompute related parameters using the TextView that we will set the text on.
-        PrecomputedText.Params params = textView.getTextMetricsParams();
-        WeakReference<TextView> textViewRef = new WeakReference<>(textView);
-        bgExecutor.execute(() -> {
-            // background thread
-            TextView tv = textViewRef.get();
-            if (tv == null) {
-                return;
-            }
-            PrecomputedText precomputedText = PrecomputedText.create(title, params);
-            tv.post(() -> {
-                // UI thread
-                TextView tvUi = textViewRef.get();
-                if (tvUi == null) return;
-                try {
-                    tvUi.setTextMetricsParams(precomputedText.getParams());
-                    tvUi.setText(precomputedText);
-                } catch (IllegalArgumentException e) {
-                    tvUi.setText(title);
-                }
-            });
-        });
-    }
-
-    @Override
-    public CharSequence getTitle() {
-        return mTitleText;
-    }
-
-    /**
-     * Sets the subtitle of the toolbar to a string resource.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    @Override
-    public void setSubtitle(@StringRes int subTitle) {
-        setSubtitle(subTitle == 0 ? null : getContext().getString(subTitle));
-    }
-
-    /**
-     * Sets the subtitle of the toolbar to a CharSequence.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    @Override
-    public void setSubtitle(CharSequence subTitle) {
-        mSubtitleText = subTitle == null ? "" : subTitle;
-        asyncSetText(mSubtitle, mSubtitleText, Runnable::run);
-        update();
-    }
-
-    @Override
-    public CharSequence getSubtitle() {
-        return mSubtitleText;
-    }
-
-    @Override
-    public void setTabs(@Nullable List<Tab> tabs) {
-        setTabs(tabs, 0);
-    }
-
-    @Override
-    public void setTabs(@Nullable List<Tab> tabs, int selectedTab) {
-        mDeprecatedTabs.clear();
-        setTabsInternal(tabs, selectedTab);
-    }
-
-    @Override
-    public List<Tab> getTabs() {
-        return mTabLayout.getTabs();
-    }
-
-    private void setTabsInternal(@Nullable List<Tab> tabs, int selectedTab) {
-        if (tabs == null || tabs.isEmpty()) {
-            selectedTab = -1;
-        } else if (selectedTab < 0 || selectedTab >= tabs.size()) {
-            throw new IllegalArgumentException("Tab position is invalid: " + selectedTab);
-        }
-        mTabLayout.setTabs(tabs, selectedTab);
-        update();
-    }
-
-    /**
-     * Gets the number of tabs in the toolbar. The tabs can be retrieved using
-     * {@link #getTab(int)}.
-     */
-    @Override
-    public int getTabCount() {
-        return mDeprecatedTabs.size();
-    }
-
-    @Override
-    public int getTabPosition(TabLayout.Tab tab) {
-        for (int i = 0; i < mDeprecatedTabs.size(); i++) {
-            if (mDeprecatedTabs.get(i).getDeprecatedTab() == tab) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    @Override
-    public void addTab(TabLayout.Tab newTab) {
-        mDeprecatedTabs.add(new DeprecatedTabWrapper(getContext(), newTab,
-                this::updateModernTabsFromDeprecatedOnes, (tab) -> {
-            for (Toolbar.OnTabSelectedListener listener : mOnTabSelectedListeners) {
-                listener.onTabSelected(newTab);
-            }
-        }));
-        updateModernTabsFromDeprecatedOnes();
-    }
-
-    private void updateModernTabsFromDeprecatedOnes() {
-        List<Tab> modernTabs = new ArrayList<>();
-
-        for (DeprecatedTabWrapper tab : mDeprecatedTabs) {
-            modernTabs.add(tab.getModernTab());
-        }
-
-        setTabsInternal(modernTabs, 0);
-    }
-
-    @Override
-    public void clearAllTabs() {
-        mDeprecatedTabs.clear();
-        setTabs(null);
-    }
-
-    @Override
-    public TabLayout.Tab getTab(int position) {
-        return mDeprecatedTabs.get(position).getDeprecatedTab();
-    }
-
-    /**
-     * Selects a tab added to this toolbar. See
-     * {@link #addTab(TabLayout.Tab)}.
-     */
-    @Override
-    public void selectTab(int position) {
-        mTabLayout.selectTab(position);
-    }
-
-    @Override
-    public int getSelectedTab() {
-        return mTabLayout.getSelectedTab();
-    }
-
-    /**
-     * Sets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
-     */
-    @Override
-    public void setShowTabsInSubpage(boolean showTabs) {
-        if (showTabs != mShowTabsInSubpage) {
-            mShowTabsInSubpage = showTabs;
-            update();
-        }
-    }
-
-    /**
-     * Gets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
-     */
-    @Override
-    public boolean getShowTabsInSubpage() {
-        return mShowTabsInSubpage;
-    }
-
-    /**
-     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
-     * will be displayed next to the title.
-     */
-    @Override
-    public void setLogo(@DrawableRes int resId) {
-        asyncSetLogo(resId, Runnable::run);
-    }
-
-    private void asyncSetLogo(int resId, Executor bgExecutor) {
-        if (!mShowLogo) {
-            // If no logo should be shown then we act as if we never received one.
-            return;
-        }
-        if (resId != 0) {
-            bgExecutor.execute(() -> {
-                // load resource on background thread.
-                Drawable drawable = getDrawable(resId);
-                mTitleLogo.post(() -> {
-                    // UI thread.
-                    mLogoInNavIconSpace.setImageDrawable(drawable);
-                    mTitleLogo.setImageDrawable(drawable);
-                });
-            });
-            mHasLogo = true;
-        } else {
-            mHasLogo = false;
-        }
-        update();
-    }
-
-    /**
-     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
-     * will be displayed next to the title.
-     */
-    @Override
-    public void setLogo(Drawable drawable) {
-        if (!mShowLogo) {
-            // If no logo should be shown then we act as if we never received one.
-            return;
-        }
-        if (drawable != null) {
-            mLogoInNavIconSpace.setImageDrawable(drawable);
-            mTitleLogo.setImageDrawable(drawable);
-            mHasLogo = true;
-        } else {
-            mHasLogo = false;
-        }
-
-        update();
-    }
-
-    /**
-     * Sets the hint for the search bar.
-     */
-    @Override
-    public void setSearchHint(@StringRes int resId) {
-        setSearchHint(getContext().getString(resId));
-    }
-
-    /**
-     * Sets the hint for the search bar.
-     */
-    public void setSearchHint(CharSequence hint) {
-        mSearchHint = hint;
-        if (mSearchView != null) {
-            mSearchView.setHint(mSearchHint);
-        }
-    }
-
-    /**
-     * Gets the search hint
-     */
-    @Override
-    public CharSequence getSearchHint() {
-        return mSearchHint;
-    }
-
-    /**
-     * Sets the icon to display in the search box.
-     *
-     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
-     * a similar place.
-     */
-    @Override
-    public void setSearchIcon(@DrawableRes int resId) {
-        setSearchIcon(getDrawable(resId));
-    }
-
-    /**
-     * Sets the icon to display in the search box.
-     *
-     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
-     * a similar place.
-     */
-    @Override
-    public void setSearchIcon(Drawable d) {
-        if (!Objects.equals(d, mSearchIcon)) {
-            mSearchIcon = d;
-            if (mSearchView != null) {
-                mSearchView.setIcon(mSearchIcon);
-            }
-        }
-    }
-
-
-    /**
-     * Sets the {@link Toolbar.NavButtonMode}
-     */
-    @Override
-    public void setNavButtonMode(Toolbar.NavButtonMode mode) {
-        NavButtonMode modernMode;
-        switch (mode) {
-            case BACK:
-                modernMode = NavButtonMode.BACK;
-                break;
-            case DOWN:
-                modernMode = NavButtonMode.DOWN;
-                break;
-            case CLOSE:
-                modernMode = NavButtonMode.CLOSE;
-                break;
-            case DISABLED:
-            default:
-                modernMode = NavButtonMode.DISABLED;
-                break;
-        }
-        setNavButtonMode(modernMode);
-    }
-
-    @Override
-    public void setNavButtonMode(NavButtonMode mode) {
-        if (mode != mNavButtonMode) {
-            mNavButtonMode = mode;
-            update();
-        }
-    }
-
-    /**
-     * Gets the {@link Toolbar.NavButtonMode}
-     */
-    @Override
-    public Toolbar.NavButtonMode getNavButtonMode() {
-        if (mStateSet && mNavButtonMode == NavButtonMode.DISABLED
-                && mState != Toolbar.State.HOME) {
-            return Toolbar.NavButtonMode.BACK;
-        }
-        switch (mNavButtonMode) {
-            case BACK:
-                return Toolbar.NavButtonMode.BACK;
-            case DOWN:
-                return Toolbar.NavButtonMode.DOWN;
-            case CLOSE:
-                return Toolbar.NavButtonMode.CLOSE;
-            case DISABLED:
-            default:
-                return Toolbar.NavButtonMode.DISABLED;
-        }
-    }
-
-    /**
-     * Show/hide the background. When hidden, the toolbar is completely transparent.
-     */
-    @Override
-    public void setBackgroundShown(boolean shown) {
-        if (mBackground == null) {
-            return;
-        }
-
-        if (shown) {
-            mBackground.setBackground(getDrawable(R.drawable.car_ui_toolbar_background));
-        } else {
-            mBackground.setBackground(null);
-        }
-    }
-
-    /**
-     * Returns true is the toolbar background is shown
-     */
-    @Override
-    public boolean getBackgroundShown() {
-        if (mBackground == null) {
-            return true;
-        }
-
-        return mBackground.getBackground() != null;
-    }
-
-    private void setMenuItemsInternal(@Nullable List<MenuItem> items) {
-        if (items == null) {
-            items = Collections.emptyList();
-        }
-
-        List<MenuItem> visibleMenuItems = new ArrayList<>();
-        List<MenuItem> overflowItems = new ArrayList<>();
-        AtomicInteger loadedMenuItems = new AtomicInteger(0);
-
-        synchronized (this) {
-            if (items.equals(mMenuItems)) {
-                return;
-            }
-
-            for (MenuItem item : items) {
-                if (item.getDisplayBehavior() == MenuItem.DisplayBehavior.NEVER) {
-                    overflowItems.add(item);
-                    item.setListener(mOverflowItemListener);
-                } else {
-                    visibleMenuItems.add(item);
-                }
-            }
-
-            // Copy the list so that if the list is modified and setMenuItems is called again,
-            // the equals() check will fail. Note that the MenuItems are not copied here.
-            mMenuItems = new ArrayList<>(items);
-            mOverflowItems = overflowItems;
-            mMenuItemRenderers.clear();
-            mMenuItemsContainer.removeAllViews();
-
-            if (!overflowItems.isEmpty()) {
-                visibleMenuItems.add(mOverflowButton);
-                createOverflowDialog();
-            }
-
-            View[] menuItemViews = new View[visibleMenuItems.size()];
-            mMenuItemViews = menuItemViews;
-
-            for (int i = 0; i < visibleMenuItems.size(); ++i) {
-                int index = i;
-                MenuItem item = visibleMenuItems.get(i);
-                MenuItemRenderer renderer = new MenuItemRenderer(item, mMenuItemsContainer);
-                mMenuItemRenderers.add(renderer);
-                renderer.createView(view -> {
-                    synchronized (ToolbarControllerImpl.this) {
-                        if (menuItemViews != mMenuItemViews) {
-                            return;
-                        }
-
-                        menuItemViews[index] = view;
-                        if (loadedMenuItems.addAndGet(1) == menuItemViews.length) {
-                            for (View v : menuItemViews) {
-                                mMenuItemsContainer.addView(v);
-                            }
-                        }
-                    }
-                });
-            }
-        }
-
-        update();
-    }
-
-    /**
-     * Sets the {@link MenuItem Menuitems} to display.
-     */
-    @Override
-    public void setMenuItems(@Nullable List<MenuItem> items) {
-        mMenuItemsXmlId = 0;
-        setMenuItemsInternal(items);
-    }
-
-    /**
-     * Sets the {@link MenuItem Menuitems} to display to a list defined in XML.
-     *
-     * <p>If this method is called twice with the same argument (and {@link #setMenuItems(List)}
-     * wasn't called), nothing will happen the second time, even if the MenuItems were changed.
-     *
-     * <p>The XML file must have one <MenuItems> tag, with a variable number of <MenuItem>
-     * child tags. See CarUiToolbarMenuItem in CarUi's attrs.xml for a list of available attributes.
-     * <p>
-     * Example:
-     * <pre>
-     * <MenuItems>
-     *     <MenuItem
-     *         app:title="Foo"/>
-     *     <MenuItem
-     *         app:title="Bar"
-     *         app:icon="@drawable/ic_tracklist"
-     *         app:onClick="xmlMenuItemClicked"/>
-     *     <MenuItem
-     *         app:title="Bar"
-     *         app:checkable="true"
-     *         app:uxRestrictions="FULLY_RESTRICTED"
-     *         app:onClick="xmlMenuItemClicked"/>
-     * </MenuItems>
-     * </pre>
-     *
-     * @return The MenuItems that were loaded from XML.
-     * @see #setMenuItems(List)
-     */
-    @Override
-    public List<MenuItem> setMenuItems(@XmlRes int resId) {
-        if (mMenuItemsXmlId != 0 && mMenuItemsXmlId == resId) {
-            return mMenuItems;
-        }
-
-        mMenuItemsXmlId = resId;
-        List<MenuItem> menuItems = MenuItemXmlParserUtil.readMenuItemList(getContext(), resId);
-        setMenuItemsInternal(menuItems);
-        return menuItems;
-    }
-
-    /**
-     * Gets the {@link MenuItem MenuItems} currently displayed
-     */
-    @Override
-    @NonNull
-    public List<MenuItem> getMenuItems() {
-        return Collections.unmodifiableList(mMenuItems);
-    }
-
-    /**
-     * Gets a {@link MenuItem} by id.
-     */
-    @Override
-    @Nullable
-    public MenuItem findMenuItemById(int id) {
-        for (MenuItem item : mMenuItems) {
-            if (item.getId() == id) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Gets a {@link MenuItem} by id. Will throw an IllegalArgumentException if not found.
-     */
-    @Override
-    @NonNull
-    public MenuItem requireMenuItemById(int id) {
-        MenuItem result = findMenuItemById(id);
-
-        if (result == null) {
-            throw new IllegalArgumentException("ID does not reference a MenuItem on this Toolbar");
-        }
-
-        return result;
-    }
-
-    private int countVisibleOverflowItems() {
-        int numVisibleItems = 0;
-        for (MenuItem item : mOverflowItems) {
-            if (item.isVisible()) {
-                numVisibleItems++;
-            }
-        }
-        return numVisibleItems;
-    }
-
-    private void createOverflowDialog() {
-        mUiOverflowItems.clear();
-        for (MenuItem menuItem : mOverflowItems) {
-            if (menuItem.isVisible()) {
-                mUiOverflowItems.add(toCarUiContentListItem(menuItem));
-            }
-        }
-
-        mOverflowDialog = new AlertDialogBuilder(getContext())
-                .setAdapter(mOverflowAdapter)
-                .create();
-    }
-
-    private void updateOverflowDialog(MenuItem changedItem) {
-        int itemIndex = mOverflowItems.indexOf(changedItem);
-        if (itemIndex >= 0) {
-            mUiOverflowItems.set(itemIndex, toCarUiContentListItem(changedItem));
-            mOverflowAdapter.notifyItemChanged(itemIndex);
-        } else {
-            createOverflowDialog();
-        }
-    }
-
-    private CarUiContentListItem toCarUiContentListItem(MenuItem menuItem) {
-        CarUiContentListItem carUiItem;
-        if (menuItem.isCheckable()) {
-            carUiItem = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
-        } else {
-            carUiItem = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        }
-        carUiItem.setIcon(menuItem.getIcon());
-        carUiItem.setActivated(menuItem.isActivated());
-        carUiItem.setChecked(menuItem.isChecked());
-        carUiItem.setEnabled(menuItem.isEnabled());
-        carUiItem.setTitle(menuItem.getTitle());
-        carUiItem.setOnItemClickedListener(item -> {
-            menuItem.performClick();
-            mOverflowDialog.hide();
-        });
-        return carUiItem;
-    }
-
-    /**
-     * Set whether or not to show the {@link MenuItem MenuItems} while searching. Default false.
-     * Even if this is set to true, the {@link MenuItem} created by
-     * {@link MenuItem.Builder#setToSearch()} will still be hidden.
-     */
-    @Override
-    public void setShowMenuItemsWhileSearching(boolean showMenuItems) {
-        mShowMenuItemsWhileSearching = showMenuItems;
-        update();
-    }
-
-    /**
-     * Returns if {@link MenuItem MenuItems} are shown while searching
-     */
-    @Override
-    public boolean getShowMenuItemsWhileSearching() {
-        return mShowMenuItemsWhileSearching;
-    }
-
-    /**
-     * Sets the search query.
-     */
-    @Override
-    public void setSearchQuery(String query) {
-        if (mSearchView != null) {
-            mSearchView.setSearchQuery(query);
-        } else {
-            mSearchQuery = query;
-            for (Toolbar.OnSearchListener listener : mDeprecatedSearchListeners) {
-                listener.onSearch(query);
-            }
-            for (Consumer<String> listener : mOnSearchListeners) {
-                listener.accept(query);
-            }
-        }
-    }
-
-    /**
-     * Sets the state of the toolbar. This will show/hide the appropriate elements of the toolbar
-     * for the desired state.
-     */
-    @Override
-    public void setState(Toolbar.State state) {
-        if (mState != state || !mStateSet) {
-            mState = state;
-            mStateSet = true;
-            update();
-        }
-    }
-
-    @Override
-    public void setSearchMode(SearchMode mode) {
-        if (mStateSet) {
-            throw new IllegalStateException("Cannot set search mode when using setState()");
-        }
-        if (mSearchMode != mode) {
-            mSearchMode = mode;
-            update();
-        }
-    }
-
-    private void update() {
-        // Start by removing mState/mStateSet from the equation by incorporating them into other
-        // variables.
-        NavButtonMode navButtonMode = mNavButtonMode;
-        if (mStateSet) {
-            if (mState == Toolbar.State.HOME) {
-                navButtonMode = NavButtonMode.DISABLED;
-            } else if (navButtonMode == NavButtonMode.DISABLED) {
-                navButtonMode = NavButtonMode.BACK;
-            }
-        }
-
-        SearchMode searchMode = mSearchMode;
-        if (mStateSet) {
-            if (mState == Toolbar.State.SEARCH) {
-                searchMode = SearchMode.SEARCH;
-            } else if (mState == Toolbar.State.EDIT) {
-                searchMode = SearchMode.EDIT;
-            } else {
-                searchMode = SearchMode.DISABLED;
-            }
-        }
-
-        boolean hasLogo = mHasLogo;
-        if (mStateSet && (mState == Toolbar.State.SEARCH || mState == Toolbar.State.EDIT)) {
-            hasLogo = false;
-        }
-
-        boolean hasTabs = mTabLayout.hasTabs();
-        if (mStateSet && mState != Toolbar.State.HOME
-                && !(mState == Toolbar.State.SUBPAGE && mShowTabsInSubpage)) {
-            hasTabs = false;
-        }
-
-        boolean isSearching = searchMode != SearchMode.DISABLED;
-        if (mSearchView == null && isSearching) {
-            inflateSearchView();
-        }
-
-        for (MenuItemRenderer renderer : mMenuItemRenderers) {
-            renderer.setToolbarIsSearching(searchMode == SearchMode.SEARCH);
-        }
-
-        View.OnClickListener backClickListener = (v) -> {
-            boolean absorbed = false;
-            List<Toolbar.OnBackListener> deprecatedListenersCopy =
-                    new ArrayList<>(mDeprecatedBackListeners);
-            List<Supplier<Boolean>> listenersCopy = new ArrayList<>(mBackListeners);
-            for (Toolbar.OnBackListener listener : deprecatedListenersCopy) {
-                absorbed = absorbed || listener.onBack();
-            }
-            for (Supplier<Boolean> listener : listenersCopy) {
-                absorbed = absorbed || listener.get();
-            }
-
-            if (!absorbed) {
-                Activity activity = CarUiUtils.getActivity(getContext());
-                if (activity != null) {
-                    activity.onBackPressed();
-                }
-            }
-        };
-
-        switch (navButtonMode) {
-            case CLOSE:
-                mNavIcon.setImageResource(R.drawable.car_ui_icon_close);
-                break;
-            case DOWN:
-                mNavIcon.setImageResource(R.drawable.car_ui_icon_down);
-                break;
-            default:
-                mNavIcon.setImageResource(R.drawable.car_ui_icon_arrow_back);
-                break;
-        }
-
-        mNavIcon.setVisibility(navButtonMode != NavButtonMode.DISABLED
-                ? VISIBLE : GONE);
-
-        // Show the logo in the nav space if that's enabled, we have a logo,
-        // and we don't have a nav button.
-        mLogoInNavIconSpace.setVisibility(hasLogo
-                && navButtonMode == NavButtonMode.DISABLED
-                && mLogoFillsNavIconSpace
-                ? VISIBLE : INVISIBLE);
-
-        // Show logo next to the title if we have a back button or we're configured to not show
-        // the logo in the nav icon space.
-        mTitleLogoContainer.setVisibility(hasLogo
-                && (navButtonMode != NavButtonMode.DISABLED || !mLogoFillsNavIconSpace)
-                ? VISIBLE : GONE);
-
-        // Show the nav icon container if we're not in the home space or the logo fills the nav icon
-        // container. If car_ui_toolbar_nav_icon_reserve_space is true, hiding it will still reserve
-        // its space
-        mNavIconContainer.setVisibility(
-                navButtonMode != NavButtonMode.DISABLED
-                        || (hasLogo && mLogoFillsNavIconSpace)
-                        ? VISIBLE : (mNavIconSpaceReserved ? INVISIBLE : GONE));
-        mNavIconContainer.setOnClickListener(
-                navButtonMode != NavButtonMode.DISABLED ? backClickListener : null);
-        mNavIconContainer.setClickable(navButtonMode != NavButtonMode.DISABLED);
-        mNavIconContainer.setContentDescription(navButtonMode != NavButtonMode.DISABLED
-                ? getContext().getString(R.string.car_ui_toolbar_nav_icon_content_description)
-                : null);
-
-        // Show the title if we're in the subpage state, or in the home state with no tabs or tabs
-        // on the second row
-        mTitleContainer.setVisibility((!hasTabs || mIsTabsInSecondRow) && !isSearching
-                ? VISIBLE : GONE);
-        mSubtitle.setVisibility(
-                TextUtils.isEmpty(getSubtitle()) ? GONE : VISIBLE);
-
-        mTabLayout.setVisibility(hasTabs
-                && (mSearchMode == SearchMode.DISABLED || mIsTabsInSecondRow) ? VISIBLE : GONE);
-
-        if (mSearchView != null) {
-            if (isSearching) {
-                mSearchView.setPlainText(searchMode == SearchMode.EDIT);
-                mSearchView.setVisibility(VISIBLE);
-            } else {
-                mSearchView.setVisibility(GONE);
-            }
-        }
-
-        boolean showButtons = !isSearching || mShowMenuItemsWhileSearching;
-        mMenuItemsContainer.setVisibility(showButtons ? VISIBLE : GONE);
-        mOverflowButton.setVisible(showButtons && countVisibleOverflowItems() > 0);
-    }
-
-    private void inflateSearchView() {
-        SearchView searchView = new SearchView(getContext());
-        searchView.setHint(mSearchHint);
-        searchView.setIcon(mSearchIcon);
-        searchView.setSearchQuery(mSearchQuery);
-        searchView.setSearchListeners(
-                mDeprecatedSearchListeners, mOnSearchListeners);
-        searchView.setSearchCompletedListeners(
-                mDeprecatedSearchCompletedListeners, mOnSearchCompletedListeners);
-        searchView.setVisibility(GONE);
-
-        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT);
-        mSearchViewContainer.addView(searchView, layoutParams);
-
-        searchView.setSearchConfig(mSearchConfigForWidescreen);
-
-        mSearchView = searchView;
-    }
-
-    /**
-     * Add a view within a container that will animate with the wide screen IME to display search
-     * results.
-     *
-     * <p>Note: Apps can only call this method if the package name is allowed via OEM to render
-     * their view.  To check if the application have the permission to do so or not first call
-     * {@link SearchCapabilities#canShowSearchResultsView()}. If the app is not allowed this
-     * method
-     * will throw an {@link IllegalStateException}
-     *
-     * @param view to be added in the container.
-     */
-    @Override
-    public void setSearchResultsView(View view) {
-        if (!getSearchCapabilities().canShowSearchResultsView()) {
-            throw new IllegalStateException(
-                    "not allowed to add view to wide screen IME, package name: "
-                            + getContext().getPackageName());
-        }
-
-        setSearchConfig(mSearchConfigBuilder.setSearchResultsView(view).build());
-    }
-
-    @Override
-    public void setSearchResultsInputViewIcon(@NonNull Drawable drawable) {
-        setSearchConfig(mSearchConfigBuilder.setSearchResultsInputViewIcon(drawable).build());
-    }
-
-    /**
-     * Sets list of search item {@link CarUiListItem} to be displayed in the IMS
-     * template. This method should be called when system is running in a wide screen mode. Apps
-     * can check that by using {@link SearchCapabilities#canShowSearchResultItems()}
-     * Else, this method will throw an {@link IllegalStateException}
-     */
-    @Override
-    public void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems) {
-        if (!getSearchCapabilities().canShowSearchResultItems()) {
-            throw new IllegalStateException(
-                    "system not in wide screen mode, not allowed to set search result items ");
-        }
-
-        setSearchConfig(mSearchConfigBuilder.setSearchResultItems(searchItems).build());
-    }
-
-    @Override
-    public void setSearchConfig(SearchConfig searchConfig) {
-        mSearchConfigForWidescreen = searchConfig;
-        if (mSearchView != null) {
-            mSearchView.setSearchConfig(mSearchConfigForWidescreen);
-        }
-    }
-
-    @Override
-    public SearchCapabilities getSearchCapabilities() {
-        return SearchWidescreenController.getSearchCapabilities(mContext);
-    }
-
-    @Override
-    public boolean canShowSearchResultItems() {
-        return getSearchCapabilities().canShowSearchResultItems();
-    }
-
-    @Override
-    public boolean canShowSearchResultsView() {
-        return getSearchCapabilities().canShowSearchResultsView();
-    }
-
-    /**
-     * Gets the current {@link Toolbar.State} of the toolbar.
-     */
-    @Override
-    public Toolbar.State getState() {
-        return mState;
-    }
-
-    /**
-     * Returns whether or not the state of the toolbar was previously set.
-     */
-    @Override
-    public boolean isStateSet() {
-        return mStateSet;
-    }
-
-    /**
-     * Registers a new {@link Toolbar.OnTabSelectedListener} to the list of listeners.
-     */
-    @Override
-    public void registerOnTabSelectedListener(Toolbar.OnTabSelectedListener listener) {
-        mOnTabSelectedListeners.add(listener);
-    }
-
-    /**
-     * Unregisters an existing {@link Toolbar.OnTabSelectedListener} from the list of listeners.
-     */
-    @Override
-    public boolean unregisterOnTabSelectedListener(Toolbar.OnTabSelectedListener listener) {
-        return mOnTabSelectedListeners.remove(listener);
-    }
-
-    /**
-     * Registers a new {@link Toolbar.OnSearchListener} to the list of listeners.
-     */
-    @Override
-    public void registerOnSearchListener(Toolbar.OnSearchListener listener) {
-        mDeprecatedSearchListeners.add(listener);
-    }
-
-    /**
-     * Unregisters an existing {@link Toolbar.OnSearchListener} from the list of listeners.
-     */
-    @Override
-    public boolean unregisterOnSearchListener(Toolbar.OnSearchListener listener) {
-        return mDeprecatedSearchListeners.remove(listener);
-    }
-
-    @Override
-    public void registerSearchListener(Consumer<String> listener) {
-        mOnSearchListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterSearchListener(Consumer<String> listener) {
-        return mOnSearchListeners.remove(listener);
-    }
-
-    /**
-     * Registers a new {@link Toolbar.OnSearchCompletedListener} to the list of listeners.
-     */
-    @Override
-    public void registerOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener) {
-        mDeprecatedSearchCompletedListeners.add(listener);
-    }
-
-    /**
-     * Unregisters an existing {@link Toolbar.OnSearchCompletedListener} from the list of
-     * listeners.
-     */
-    @Override
-    public boolean unregisterOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener) {
-        return mDeprecatedSearchCompletedListeners.remove(listener);
-    }
-
-    @Override
-    public void registerSearchCompletedListener(Runnable listener) {
-        mOnSearchCompletedListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterSearchCompletedListener(Runnable listener) {
-        return mOnSearchCompletedListeners.remove(listener);
-    }
-
-    /**
-     * Registers a new {@link Toolbar.OnBackListener} to the list of listeners.
-     */
-    @Override
-    public void registerOnBackListener(Toolbar.OnBackListener listener) {
-        mDeprecatedBackListeners.add(listener);
-    }
-
-    /**
-     * Unregisters an existing {@link Toolbar.OnBackListener} from the list of listeners.
-     */
-    @Override
-    public boolean unregisterOnBackListener(Toolbar.OnBackListener listener) {
-        return mDeprecatedBackListeners.remove(listener);
-    }
-
-    @Override
-    public void registerBackListener(Supplier<Boolean> listener) {
-        mBackListeners.add(listener);
-    }
-
-    @Override
-    public boolean unregisterBackListener(Supplier<Boolean> listener) {
-        return mBackListeners.remove(listener);
-    }
-
-    /**
-     * Returns the progress bar
-     */
-    @Override
-    public ProgressBarController getProgressBar() {
-        return mProgressBar;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/CarUiUtils.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/CarUiUtils.java
deleted file mode 100644
index 202617b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/CarUiUtils.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.utils;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.DimenRes;
-import androidx.annotation.IdRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StyleRes;
-import androidx.annotation.UiThread;
-
-import com.android.car.ui.R;
-import com.android.car.ui.uxr.DrawableStateView;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-
-/**
- * Collection of utility methods
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class CarUiUtils {
-
-    private static final String TAG = "CarUiUtils";
-    private static final String READ_ONLY_SYSTEM_PROPERTY_PREFIX = "ro.";
-    /** A map to cache read-only system properties. */
-    private static final SparseArray<String> READ_ONLY_SYSTEM_PROPERTY_MAP = new SparseArray<>();
-
-    private static int[] sRestrictedState;
-
-    /** This is a utility class */
-    private CarUiUtils() {
-    }
-
-    /**
-     * Reads a float value from a dimens resource. This is necessary as {@link Resources#getFloat}
-     * is not currently public.
-     *
-     * @param res   {@link Resources} to read values from
-     * @param resId Id of the dimens resource to read
-     */
-    public static float getFloat(Resources res, @DimenRes int resId) {
-        TypedValue outValue = new TypedValue();
-        res.getValue(resId, outValue, true);
-        return outValue.getFloat();
-    }
-
-    /** Returns the identifier of the resolved resource assigned to the given attribute. */
-    public static int getAttrResourceId(Context context, int attr) {
-        return getAttrResourceId(context, /*styleResId=*/ 0, attr);
-    }
-
-    /**
-     * Returns the identifier of the resolved resource assigned to the given attribute defined in
-     * the given style.
-     */
-    public static int getAttrResourceId(Context context, @StyleRes int styleResId, int attr) {
-        TypedArray ta = context.obtainStyledAttributes(styleResId, new int[]{attr});
-        int resId = ta.getResourceId(0, 0);
-        ta.recycle();
-        return resId;
-    }
-
-    /**
-     * Gets the {@link Activity} for a certain {@link Context}.
-     *
-     * <p>It is possible the Context is not associated with an Activity, in which case
-     * this method will return null.
-     */
-    @Nullable
-    public static Activity getActivity(@Nullable Context context) {
-        while (context instanceof ContextWrapper) {
-            if (context instanceof Activity) {
-                return (Activity) context;
-            }
-            context = ((ContextWrapper) context).getBaseContext();
-        }
-        return null;
-    }
-
-    /**
-     * It behaves similarly to {@link View#findViewById(int)}, except that on Q and below,
-     * it will first resolve the id to whatever it references.
-     *
-     * This is to support layout RROs before the new RRO features in R.
-     *
-     * @param id the ID to search for
-     * @return a view with given ID if found, or {@code null} otherwise
-     * @see View#requireViewById(int)
-     */
-    @Nullable
-    @UiThread
-    public static <T extends View> T findViewByRefId(@NonNull View root, @IdRes int id) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-            return root.findViewById(id);
-        }
-
-        if (id == View.NO_ID) {
-            return null;
-        }
-
-        TypedValue value = new TypedValue();
-        root.getResources().getValue(id, value, true);
-        return root.findViewById(value.resourceId);
-    }
-
-    /**
-     * It behaves similarly to {@link View#requireViewById(int)}, except that on Q and below,
-     * it will first resolve the id to whatever it references.
-     *
-     * This is to support layout RROs before the new RRO features in R.
-     *
-     * @param id the ID to search for
-     * @return a view with given ID
-     * @see View#findViewById(int)
-     */
-    @NonNull
-    @UiThread
-    public static <T extends View> T requireViewByRefId(@NonNull View root, @IdRes int id) {
-        T view = findViewByRefId(root, id);
-        if (view == null) {
-            throw new IllegalArgumentException("ID "
-                    + root.getResources().getResourceName(id)
-                    + " does not reference a View inside this View");
-        }
-        return view;
-    }
-
-    /**
-     * Returns the system property of type boolean. This method converts the boolean value in string
-     * returned by {@link #getSystemProperty(Resources, int)}
-     */
-    public static boolean getBooleanSystemProperty(
-            @NonNull Resources resources, int propertyResId, boolean defaultValue) {
-        String value = getSystemProperty(resources, propertyResId);
-
-        if (!TextUtils.isEmpty(value)) {
-            return Boolean.parseBoolean(value);
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Use reflection to interact with the hidden API <code>android.os.SystemProperties</code>.
-     *
-     * <p>This method caches read-only properties. CAVEAT: Please do not set read-only properties
-     * by 'adb setprop' after app started. Read-only properties CAN BE SET ONCE if it is unset.
-     * Thus, read-only properties MAY BE CHANGED from unset to set during application's lifetime if
-     * you use 'adb setprop' command to set read-only properties after app started. For the sake of
-     * performance, this method also caches the unset state. Otherwise, cache may not effective if
-     * the system property is unset (which is most-likely).
-     *
-     * @param resources     resources object to fetch string
-     * @param propertyResId the property resource id.
-     * @return The value of the property if defined, else null. Does not return empty strings.
-     */
-    @Nullable
-    public static String getSystemProperty(@NonNull Resources resources, int propertyResId) {
-        String propertyName = resources.getString(propertyResId);
-        boolean isReadOnly = propertyName.startsWith(READ_ONLY_SYSTEM_PROPERTY_PREFIX);
-        if (!isReadOnly) {
-            return readSystemProperty(propertyName);
-        }
-        synchronized (READ_ONLY_SYSTEM_PROPERTY_MAP) {
-            // readOnlySystemPropertyMap may contain null values.
-            if (READ_ONLY_SYSTEM_PROPERTY_MAP.indexOfKey(propertyResId) >= 0) {
-                return READ_ONLY_SYSTEM_PROPERTY_MAP.get(propertyResId);
-            }
-            String value = readSystemProperty(propertyName);
-            READ_ONLY_SYSTEM_PROPERTY_MAP.put(propertyResId, value);
-            return value;
-        }
-    }
-
-    @Nullable
-    private static String readSystemProperty(String propertyName) {
-        Class<?> systemPropertiesClass;
-        try {
-            systemPropertiesClass = Class.forName("android.os.SystemProperties");
-        } catch (ClassNotFoundException e) {
-            Log.w(TAG, "Cannot find android.os.SystemProperties: ", e);
-            return null;
-        }
-
-        Method getMethod;
-        try {
-            getMethod = systemPropertiesClass.getMethod("get", String.class);
-        } catch (NoSuchMethodException e) {
-            Log.w(TAG, "Cannot find SystemProperties.get(): ", e);
-            return null;
-        }
-
-        try {
-            Object[] params = new Object[]{propertyName};
-            String value = (String) getMethod.invoke(systemPropertiesClass, params);
-            return TextUtils.isEmpty(value) ? null : value;
-        } catch (Exception e) {
-            Log.w(TAG, "Failed to invoke SystemProperties.get(): ", e);
-            return null;
-        }
-    }
-
-    /**
-     * Converts a drawable to bitmap. This value should not be null.
-     */
-    public static Bitmap drawableToBitmap(@NonNull Drawable drawable) {
-        Bitmap bitmap;
-
-        if (drawable instanceof BitmapDrawable) {
-            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
-            if (bitmapDrawable.getBitmap() != null) {
-                return bitmapDrawable.getBitmap();
-            }
-        }
-
-        if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
-            bitmap = Bitmap.createBitmap(1, 1,
-                    Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
-        } else {
-            bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
-                    drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-        }
-
-        Canvas canvas = new Canvas(bitmap);
-        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
-        drawable.draw(canvas);
-        return bitmap;
-    }
-
-    /**
-     * Exact copy from Androidx.TypedArrayUtils class
-     * @return The resource ID value in the {@code context} specified by {@code attr}. If it does
-     * not exist, {@code fallbackAttr}.
-     */
-    public static int getAttr(@NonNull Context context, int attr, int fallbackAttr) {
-        TypedValue value = new TypedValue();
-        context.getTheme().resolveAttribute(attr, value, true);
-        if (value.resourceId != 0) {
-            return attr;
-        }
-        return fallbackAttr;
-    }
-
-    /**
-     * Converts a {@link CharSequence} to a {@link String}.
-     *
-     * This is the same as calling {@link CharSequence#toString()}, except it will handle
-     * null CharSequences, returning a null string.
-     */
-    public static String charSequenceToString(@Nullable CharSequence charSequence) {
-        return charSequence == null ? null : charSequence.toString();
-    }
-
-    /**
-     * Given a list of T and a function to convert from T to U, return a list of U.
-     *
-     * This will create a new list.
-     */
-    public static <T, U> List<U> convertList(List<T> list, Function<T, U> f) {
-        if (list == null) {
-            return null;
-        }
-
-        List<U> result = new ArrayList<>();
-        for (T item : list) {
-            result.add(f.apply(item));
-        }
-        return result;
-    }
-
-    /**
-     * Traverses the view hierarchy, and whenever it sees a {@link DrawableStateView}, adds
-     * state_ux_restricted to it.
-     *
-     * Note that this will remove any other drawable states added by other calls to
-     * {@link DrawableStateView#setExtraDrawableState(int[], int[])}
-     */
-    public static void makeAllViewsUxRestricted(@Nullable View view, boolean restricted) {
-        if (view instanceof DrawableStateView) {
-            if (sRestrictedState == null) {
-                int androidStateUxRestricted = view.getResources()
-                        .getIdentifier("state_ux_restricted", "attr", "android");
-
-                if (androidStateUxRestricted == 0) {
-                    sRestrictedState = new int[] { R.attr.state_ux_restricted };
-                } else {
-                    sRestrictedState = new int[] {
-                            R.attr.state_ux_restricted,
-                            androidStateUxRestricted
-                    };
-                }
-            }
-
-            ((DrawableStateView) view).setExtraDrawableState(
-                    restricted ? sRestrictedState : null, null);
-        }
-
-        if (view instanceof ViewGroup) {
-            ViewGroup vg = (ViewGroup) view;
-            for (int i = 0; i < vg.getChildCount(); i++) {
-                makeAllViewsUxRestricted(vg.getChildAt(i), restricted);
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/CarUxRestrictionsUtil.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/CarUxRestrictionsUtil.java
deleted file mode 100644
index 19f2fbb..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/CarUxRestrictionsUtil.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.utils;
-
-import static android.car.drivingstate.CarUxRestrictions.UX_RESTRICTIONS_LIMIT_STRING_LENGTH;
-
-import android.car.Car;
-import android.car.drivingstate.CarUxRestrictions;
-import android.car.drivingstate.CarUxRestrictions.CarUxRestrictionsInfo;
-import android.car.drivingstate.CarUxRestrictionsManager;
-import android.content.Context;
-import android.os.Build;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.ui.R;
-
-import java.util.Collections;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-/**
- * Utility class to access Car Restriction Manager.
- *
- * <p>This class must be a singleton because only one listener can be registered with {@link
- * CarUxRestrictionsManager} at a time, as documented in {@link
- * CarUxRestrictionsManager#registerListener}.
- */
-public class CarUxRestrictionsUtil {
-    private static final String TAG = "CarUxRestrictionsUtil";
-
-    @NonNull
-    private CarUxRestrictions mCarUxRestrictions = getDefaultRestrictions();
-
-    private final Set<OnUxRestrictionsChangedListener> mObservers =
-            Collections.newSetFromMap(new WeakHashMap<>());
-    private static CarUxRestrictionsUtil sInstance = null;
-
-    private CarUxRestrictionsUtil(Context context) {
-        CarUxRestrictionsManager.OnUxRestrictionsChangedListener listener =
-                (carUxRestrictions) -> {
-                    if (carUxRestrictions == null) {
-                        mCarUxRestrictions = getDefaultRestrictions();
-                    } else {
-                        mCarUxRestrictions = carUxRestrictions;
-                    }
-
-                    for (OnUxRestrictionsChangedListener observer : mObservers) {
-                        observer.onRestrictionsChanged(mCarUxRestrictions);
-                    }
-                };
-
-        try {
-            // copybara:strip_begin
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-                Car.createCar(context.getApplicationContext(), null,
-                    Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
-                    (Car car, boolean ready) -> {
-                        if (ready) {
-                            CarUxRestrictionsManager carUxRestrictionsManager =
-                                (CarUxRestrictionsManager) car.getCarManager(
-                                    Car.CAR_UX_RESTRICTION_SERVICE);
-                            carUxRestrictionsManager.registerListener(listener);
-                            listener.onUxRestrictionsChanged(
-                                carUxRestrictionsManager.getCurrentCarUxRestrictions());
-                        } else {
-                            Log.w(TAG, "Car service disconnected, assuming fully restricted uxr");
-                            listener.onUxRestrictionsChanged(null);
-                        }
-                    });
-            } else {
-                // copybara:strip_end
-                Car carApi = Car.createCar(context.getApplicationContext());
-
-                try {
-                    CarUxRestrictionsManager carUxRestrictionsManager =
-                        (CarUxRestrictionsManager) carApi.getCarManager(
-                            Car.CAR_UX_RESTRICTION_SERVICE);
-                    carUxRestrictionsManager.registerListener(listener);
-                    listener.onUxRestrictionsChanged(
-                        carUxRestrictionsManager.getCurrentCarUxRestrictions());
-                } catch (NullPointerException e) {
-                    Log.e(TAG, "Car not connected", e);
-                    // mCarUxRestrictions will be the default
-                }
-                // copybara:strip_begin
-            }
-            // copybara:strip_end
-        } catch (SecurityException e) {
-            Log.w(TAG, "Unable to connect to car service, assuming unrestricted", e);
-            listener.onUxRestrictionsChanged(new CarUxRestrictions.Builder(
-                false, CarUxRestrictions.UX_RESTRICTIONS_BASELINE, 0)
-                .build());
-        }
-    }
-
-    @NonNull
-    private static CarUxRestrictions getDefaultRestrictions() {
-        return new CarUxRestrictions.Builder(
-                true, CarUxRestrictions.UX_RESTRICTIONS_FULLY_RESTRICTED, 0)
-                .build();
-    }
-
-    /** Listener interface used to update clients on UxRestrictions changes */
-    public interface OnUxRestrictionsChangedListener {
-        /** Called when CarUxRestrictions changes */
-        void onRestrictionsChanged(@NonNull CarUxRestrictions carUxRestrictions);
-    }
-
-    /** Returns the singleton sInstance of this class */
-    @NonNull
-    public static CarUxRestrictionsUtil getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = new CarUxRestrictionsUtil(context);
-        }
-
-        return sInstance;
-    }
-
-    /**
-     * Registers a listener on this class for updates to CarUxRestrictions. Multiple listeners may
-     * be registered. Note that this class will only hold a weak reference to the listener, you
-     * must maintain a strong reference to it elsewhere.
-     */
-    public void register(OnUxRestrictionsChangedListener listener) {
-        mObservers.add(listener);
-        listener.onRestrictionsChanged(mCarUxRestrictions);
-    }
-
-    /** Unregisters a registered listener */
-    public void unregister(OnUxRestrictionsChangedListener listener) {
-        mObservers.remove(listener);
-    }
-
-    @NonNull
-    public CarUxRestrictions getCurrentRestrictions() {
-        return mCarUxRestrictions;
-    }
-
-    /**
-     * Returns whether any of the given flags are blocked by the specified restrictions. If null is
-     * given, the method returns true for safety.
-     */
-    public static boolean isRestricted(
-            @CarUxRestrictionsInfo int restrictionFlags, @Nullable CarUxRestrictions uxr) {
-        return (uxr == null) || ((uxr.getActiveRestrictions() & restrictionFlags) != 0);
-    }
-
-    /**
-     * Complies the input string with the given UX restrictions. Returns the original string if
-     * already compliant, otherwise a shortened ellipsized string.
-     */
-    public static String complyString(Context context, String str, CarUxRestrictions uxr) {
-
-        if (isRestricted(UX_RESTRICTIONS_LIMIT_STRING_LENGTH, uxr)) {
-            int maxLength =
-                    uxr == null
-                            ? context.getResources().getInteger(
-                            R.integer.car_ui_default_max_string_length)
-                            : uxr.getMaxRestrictedStringLength();
-
-            if (str.length() > maxLength) {
-                return str.substring(0, maxLength) + context.getString(R.string.car_ui_ellipsis);
-            }
-        }
-
-        return str;
-    }
-
-    /** Sets car UX restrictions. Only used for testing. */
-    @VisibleForTesting
-    public void setUxRestrictions(CarUxRestrictions carUxRestrictions) {
-        mCarUxRestrictions = carUxRestrictions;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/DirectManipulationHelper.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/DirectManipulationHelper.java
deleted file mode 100644
index 09d1662..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/DirectManipulationHelper.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.utils;
-
-import static android.os.Build.VERSION_CODES.R;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-
-/** Helper class to toggle direct manipulation mode. */
-public final class DirectManipulationHelper {
-
-    /**
-     * ContentDescription for a {@link View} to support direct manipulation mode. It's also used as
-     * class name of {@link AccessibilityEvent} to indicate that the AccessibilityEvent represents
-     * a request to toggle direct manipulation mode.
-     */
-    @VisibleForTesting
-    public static final String DIRECT_MANIPULATION =
-            "com.android.car.ui.utils.DIRECT_MANIPULATION";
-
-    /** This is a utility class. */
-    private DirectManipulationHelper() {
-    }
-
-    /**
-     * Enables or disables direct manipulation mode. This method sends an {@link AccessibilityEvent}
-     * to tell {@link com.android.car.rotary.RotaryService} to enter or exit direct manipulation
-     * mode. Typically pressing the center button of the rotary controller with a direct
-     * manipulation view focused will enter direct manipulation mode, while pressing the Back button
-     * will exit direct manipulation mode.
-     *
-     * @param view   the direct manipulation view
-     * @param enable true to enter direct manipulation mode, false to exit direct manipulation mode
-     * @return whether the AccessibilityEvent was sent
-     */
-    public static boolean enableDirectManipulationMode(@NonNull View view, boolean enable) {
-        AccessibilityManager accessibilityManager = (AccessibilityManager)
-                view.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
-        if (accessibilityManager == null || !accessibilityManager.isEnabled()) {
-            return false;
-        }
-        AccessibilityEvent event = AccessibilityEvent.obtain();
-        event.setClassName(DIRECT_MANIPULATION);
-        event.setSource(view);
-        event.setEventType(enable
-                ? AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
-                : AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
-        accessibilityManager.sendAccessibilityEvent(event);
-        return true;
-    }
-
-    /** Returns whether the given {@code event} is for direct manipulation. */
-    public static boolean isDirectManipulation(@NonNull AccessibilityEvent event) {
-        return TextUtils.equals(DIRECT_MANIPULATION, event.getClassName());
-    }
-
-    /** Returns whether the given {@code node} supports rotate directly. */
-    @TargetApi(R)
-    public static boolean supportRotateDirectly(@NonNull AccessibilityNodeInfo node) {
-        return TextUtils.equals(DIRECT_MANIPULATION, node.getContentDescription());
-    }
-
-    /**
-     * Sets whether the given {@code view} supports rotate directly.
-     * <p>
-     * If the view supports rotate directly, when it's focused but not in direct manipulation mode,
-     * clicking the center button of the rotary controller will make RotaryService enter direct
-     * manipulation mode. In this mode, the view's selected state is toggled, and only controller
-     * rotation and Back button press are supported.
-     * <ul>
-     *   <li>When the controller is rotated, the view will be asked to perform ACTION_SCROLL_FORWARD
-     *       or ACTION_SCROLL_BACKWARD.
-     *   <li>When Back button is pressed, RotaryService will toggle off the view's selected state
-     *       and exit this mode.
-     * </ul>
-     * To support controller nudges as well in direct manipulation mode, use {@link
-     * #enableDirectManipulationMode} instead.
-     */
-    @TargetApi(R)
-    public static void setSupportsRotateDirectly(@NonNull View view, boolean enable) {
-        view.setContentDescription(enable ? DIRECT_MANIPULATION : null);
-    }
-
-    /**
-     * Returns whether the given {@code node} supports rotate directly.
-     *
-     * @deprecated use {@link #supportRotateDirectly} instead
-     */
-    @Deprecated
-    public static boolean supportDirectManipulation(@NonNull AccessibilityNodeInfo node) {
-        return supportRotateDirectly(node);
-    }
-
-    /**
-     * Sets whether the given {@code view} supports rotate directly.
-     *
-     * @deprecated use {@link #setSupportsRotateDirectly} instead
-     */
-    @Deprecated
-    public static void setSupportsDirectManipulation(@NonNull View view, boolean enable) {
-        setSupportsRotateDirectly(view, enable);
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateButton.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateButton.java
deleted file mode 100644
index bf7fcb1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateButton.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Button;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link Button} that implements {@link DrawableStateView}, for allowing additional states
- * such as ux restriction.
- */
-public class DrawableStateButton extends Button implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateButton(Context context) {
-        super(context);
-    }
-
-    public DrawableStateButton(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateConstraintLayout.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateConstraintLayout.java
deleted file mode 100644
index 647bfa4..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateConstraintLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import androidx.annotation.Nullable;
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-/**
- * A {@link ConstraintLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateConstraintLayout extends ConstraintLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateConstraintLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateConstraintLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateConstraintLayout(Context context,
-            @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateFrameLayout.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateFrameLayout.java
deleted file mode 100644
index f743043..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateFrameLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link FrameLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateFrameLayout extends FrameLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateFrameLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateFrameLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateFrameLayout(Context context,
-            @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateImageView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateImageView.java
deleted file mode 100644
index 511da66..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateImageView.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link ImageView} that implements {@link DrawableStateView}, for allowing additional states
- * such as ux restriction.
- */
-public class DrawableStateImageView extends ImageView implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateImageView(Context context) {
-        super(context);
-    }
-
-    public DrawableStateImageView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateLinearLayout.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateLinearLayout.java
deleted file mode 100644
index 689a32f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateLinearLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link LinearLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateLinearLayout extends LinearLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateLinearLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateLinearLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateLinearLayout(Context context, @Nullable AttributeSet attrs,
-            int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateRelativeLayout.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateRelativeLayout.java
deleted file mode 100644
index 1c69300..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateRelativeLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.RelativeLayout;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link RelativeLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateRelativeLayout extends RelativeLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateRelativeLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateRelativeLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateRelativeLayout(Context context,
-            @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateSwitch.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateSwitch.java
deleted file mode 100644
index e786070..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateSwitch.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Switch;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link Switch} that implements {@link DrawableStateView}, for allowing additional states
- * such as ux restriction.
- */
-public class DrawableStateSwitch extends Switch implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateSwitch(Context context) {
-        super(context);
-    }
-
-    public DrawableStateSwitch(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateSwitch(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateTextView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateTextView.java
deleted file mode 100644
index 42324fe..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateTextView.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link TextView} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateTextView extends TextView implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateTextView(Context context) {
-        super(context);
-    }
-
-    public DrawableStateTextView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateToggleButton.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateToggleButton.java
deleted file mode 100644
index b48270f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateToggleButton.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.ToggleButton;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link ToggleButton} that implements {@link DrawableStateView}, for allowing additional states
- * such as ux restriction.
- */
-public class DrawableStateToggleButton extends ToggleButton implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateToggleButton(Context context) {
-        super(context);
-    }
-
-    public DrawableStateToggleButton(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateToggleButton(Context context, @Nullable AttributeSet attrs,
-            int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateUtil.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateUtil.java
deleted file mode 100644
index 09906cb..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateUtil.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.function.Function;
-
-/**
- * This is a utility class designed to make it easier to create a new {@link DrawableStateView}.
- *
- * To use, subclass a view and forward it's {@link View#onCreateDrawableState(int)} and
- * {@link DrawableStateView#setExtraDrawableState(int[], int[])} methods to this object.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-class DrawableStateUtil implements DrawableStateView {
-
-    private final View mView;
-    @Nullable
-    private int[] mStateToAdd;
-    @Nullable
-    private int[] mStateToRemove;
-
-    DrawableStateUtil(View view) {
-        mView = view;
-    }
-
-    /**
-     * Forward the View's onCreateDrawableState to this method.
-     *
-     * @param extraSpace The extraSpace parameter passed to the View's onCreateDrawableState
-     * @param callSuper  A reference to the View's super.onCreateDrawableState()
-     * @return The intended result of the View's onCreateDrawableState()
-     */
-    public int[] onCreateDrawableState(int extraSpace, Function<Integer, int[]> callSuper) {
-        int[] result;
-        if (mStateToAdd == null) {
-            result = callSuper.apply(extraSpace);
-        } else {
-            result = mergeDrawableStates(
-                    callSuper.apply(extraSpace + mStateToAdd.length), mStateToAdd);
-        }
-
-        if (mStateToRemove != null && mStateToRemove.length != 0) {
-            result = Arrays.stream(result)
-                    .filter(state -> Arrays.stream(mStateToRemove).noneMatch(
-                            toRemove -> state == toRemove))
-                    .toArray();
-        }
-
-        return result;
-    }
-
-    /**
-     * Forward your View's setExtraDrawableState here.
-     */
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        mStateToAdd = stateToAdd;
-        mStateToRemove = stateToRemove;
-        mView.refreshDrawableState();
-    }
-
-    /** Copied from {@link View} */
-    private static int[] mergeDrawableStates(int[] baseState, int[] additionalState) {
-        int i = baseState.length - 1;
-        while (i >= 0 && baseState[i] == 0) {
-            i--;
-        }
-        System.arraycopy(additionalState, 0, baseState, i + 1, additionalState.length);
-        return baseState;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateView.java
deleted file mode 100644
index 87aa8a9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/uxr/DrawableStateView.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.uxr;
-
-import androidx.annotation.Nullable;
-
-/**
- * An Interface to manipulate a view's drawable state.
- *
- * <p>Used by {@link com.android.car.ui.toolbar.MenuItem MenuItems} to make the views display
- * if they are ux restricted.
- */
-public interface DrawableStateView {
-    /**
-     * Sets the drawable state. This should merge with existing drawable states
-     *
-     * @param stateToAdd An array of drawable states to add to the view's drawable state, along
-     *                   with any drawable state that would normally be there.
-     * @param stateToRemove An array of drawable states to remove from what would normally be
-     *                      used to display the view.
-     */
-    void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove);
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/widget/CarUiTextView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/widget/CarUiTextView.java
deleted file mode 100644
index 8aa308e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/widget/CarUiTextView.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.widget;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.CarUiLayoutInflaterFactory;
-import com.android.car.ui.CarUiText;
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryFactorySingleton;
-
-import java.util.List;
-
-/**
- * This is aa definition for a {@link TextView} extension that supports rendering {@link
- * CarUiText}.
- */
-@SuppressLint("AppCompatCustomView")
-public abstract class CarUiTextView extends TextView {
-
-    /**
-     * Creates a CarUiTextView.
-     *
-     * Most of the time, you should prefer creating a CarUiButton with a {@code <CarUiTextView>}
-     * tag in your layout file. This is only for if you need to create a CarUiTextView in java code.
-     * The CarUiTextView xml tag is enabled by the usage of {@link CarUiLayoutInflaterFactory}.
-     */
-    public static CarUiTextView create(@NonNull Context context) {
-        return CarUiTextView.create(context, null);
-    }
-
-    /**
-     * Creates a CarUiTextView.
-     *
-     * Most of the time, you should prefer creating a CarUiButton with a {@code <CarUiTextView>}
-     * tag in your layout file. This is only for if you need to create a CarUiTextView in java code.
-     * The CarUiTextView xml tag is enabled by the usage of {@link CarUiLayoutInflaterFactory}.
-     */
-    static CarUiTextView create(@NonNull Context context, @Nullable AttributeSet attrs) {
-        return SharedLibraryFactorySingleton.get(context)
-                .createTextView(context, attrs);
-    }
-
-    public CarUiTextView(Context context) {
-        super(context);
-    }
-
-    public CarUiTextView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public CarUiTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    /**
-     * Set text to display.
-     *
-     * @param textList list of text to display. Each {@link CarUiText} in the list will be rendered
-     *                 on a new line, separated by a line break
-     */
-    public abstract void setText(@NonNull List<CarUiText> textList);
-
-    /**
-     * Set text to display.
-     */
-    public abstract void setText(@NonNull CarUiText text);
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/widget/CarUiTextViewImpl.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/widget/CarUiTextViewImpl.java
deleted file mode 100644
index a5b8eac..0000000
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/widget/CarUiTextViewImpl.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.widget;
-
-import static java.util.Objects.requireNonNull;
-
-import android.content.Context;
-import android.text.Layout;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.view.OneShotPreDrawListener;
-
-import com.android.car.ui.CarUiText;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Scanner;
-
-/**
- * Extension of {@link TextView} that supports {@link CarUiText}.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class CarUiTextViewImpl extends CarUiTextView {
-
-    @NonNull
-    private List<CarUiText> mText = Collections.emptyList();
-    private OneShotPreDrawListener mOneShotPreDrawListener;
-
-    public CarUiTextViewImpl(Context context) {
-        super(context);
-    }
-
-    public CarUiTextViewImpl(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CarUiTextViewImpl(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public CarUiTextViewImpl(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-                             int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    /**
-     * Set text to display.
-     *
-     * @param textList list of text to display. Each {@link CarUiText} in the list will be rendered
-     *                 on a new line, separated by a line break
-     */
-    @Override
-    public void setText(@NonNull List<CarUiText> textList) {
-        mText = requireNonNull(textList);
-        if (mOneShotPreDrawListener == null) {
-            mOneShotPreDrawListener = OneShotPreDrawListener.add(this, this::updateText);
-        }
-        setText(CarUiText.combineMultiLine(textList));
-    }
-
-    /**
-     * Set text to display.
-     */
-    @Override
-    public void setText(@NonNull CarUiText text) {
-        mText = Collections.singletonList(requireNonNull(text));
-        if (mOneShotPreDrawListener == null) {
-            mOneShotPreDrawListener = OneShotPreDrawListener.add(this, this::updateText);
-        }
-        setText(text.getPreferredText());
-    }
-
-    private void updateText() {
-        requireNonNull(mText);
-        if (getLayout() == null) {
-            mOneShotPreDrawListener = OneShotPreDrawListener.add(this, this::updateText);
-            return;
-        }
-
-        mOneShotPreDrawListener = null;
-
-        // If all lines of text have no limits, the preferred text set at invocation of
-        // setText(List<CarUiText>)/ setText(CarUiText) does not need updating
-        if (mText.stream().allMatch(line ->
-                line.getMaxLines() == Integer.MAX_VALUE
-                        && line.getMaxChars() == Integer.MAX_VALUE)) {
-            return;
-        }
-
-        // Update rendered text if preferred text is truncated
-        SpannableStringBuilder builder = new SpannableStringBuilder();
-        CharSequence delimiter = "";
-        for (int i = 0; i < mText.size(); i++) {
-            CarUiText line = mText.get(i);
-            builder.append(delimiter).append(getBestVariant(line));
-            delimiter = "\n";
-        }
-
-        setText(builder);
-    }
-
-    private CharSequence getBestVariant(CarUiText text) {
-        if (text.getTextVariants().size() > 1) {
-            for (CharSequence variant : text.getTextVariants()) {
-                if (variant.length() <= text.getMaxChars() && TextUtils.equals(variant,
-                        getTruncatedText(variant, text.getMaxLines()))) {
-                    return variant;
-                }
-            }
-        }
-
-        // If no text variant can be rendered without truncation, use the preferred text
-        return getTruncatedText(text.getPreferredText(), text.getMaxLines());
-    }
-
-    private CharSequence getTruncatedText(CharSequence text, int maxLines) {
-        Layout layout = requireNonNull(getLayout());
-        int maxWidth = layout.getWidth();
-
-        if (maxLines == 1) {
-            return TextUtils.ellipsize(text, getPaint(), maxWidth, TextUtils.TruncateAt.END);
-        }
-
-        int lineCount = 0;
-        int index = 0;
-        int lastLineStart = 0;
-        int length = text.length();
-        boolean isTruncationComplete = false;
-
-        while (!isTruncationComplete) {
-            lastLineStart = index;
-            // Measure the text, stopping early if the measured width exceeds textView width
-            index += getPaint().breakText(text, index, length, true, maxWidth, null);
-
-            // Break early if manual line break is present
-            int lineBreak = TextUtils.indexOf(text, "\n", lastLineStart, index);
-            if (lineBreak != -1) {
-                index = Math.min(index, lineBreak + 1);
-            }
-
-            lineCount++;
-            // Hitting maxLine limit or reaching the end of the CharSequence means truncation is
-            // complete
-            if (lineCount == maxLines || index > length - 1) {
-                isTruncationComplete = true;
-            }
-
-            // Account for word wrapping by removing partial words at end of line by moving index
-            // back to last whitespace character
-            if (!isTruncationComplete && !Character.isWhitespace(text.charAt(index))) {
-                int offset = 0;
-                while (!Character.isWhitespace(text.charAt(index - offset - 1))) {
-                    offset++;
-                    // partial word reaches to the start of line, so it must be kept
-                    if (index - offset == lastLineStart || offset >= index) {
-                        offset = 0;
-                        break;
-                    }
-                }
-
-                index -= offset;
-            }
-        }
-
-        SpannableStringBuilder builder = new SpannableStringBuilder();
-        // Get text up until the last line
-        builder.append(text.subSequence(0, lastLineStart));
-
-        Scanner scanner = new Scanner(text.subSequence(lastLineStart, length).toString());
-        if (scanner.hasNextLine()) {
-            String lastLine = scanner.nextLine();
-            // Add truncation ellipsis to last line if required
-            builder.append(
-                    TextUtils.ellipsize(lastLine, getPaint(), maxWidth, TextUtils.TruncateAt.END));
-            if (text instanceof Spanned) {
-                TextUtils.copySpansFrom(
-                        (Spanned) text, 0, builder.length(), Object.class, builder, 0);
-            }
-        }
-
-        return builder;
-    }
-}
diff --git a/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml b/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
deleted file mode 100644
index d65d18f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
+++ /dev/null
@@ -1,540 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!--Copyright (C) 2021 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.-->
-<!-- THIS FILE WAS AUTO GENERATED, DO NOT EDIT MANUALLY. -->
-<resources>
-  <overlayable name="car-ui-lib">
-    <policy type="public">
-      <item type="array" name="car_ui_ime_wide_screen_allowed_package_list"/>
-      <item type="attr" name="CarUiToolbarStyle"/>
-      <item type="attr" name="barrierDirection"/>
-      <item type="attr" name="carUiPreferenceStyle"/>
-      <item type="attr" name="carUiRecyclerViewStyle"/>
-      <item type="attr" name="chainUseRtl"/>
-      <item type="attr" name="constraintSet"/>
-      <item type="attr" name="constraint_referenced_ids"/>
-      <item type="attr" name="layout_constraintBaseline_creator"/>
-      <item type="attr" name="layout_constraintBaseline_toBaselineOf"/>
-      <item type="attr" name="layout_constraintBottom_creator"/>
-      <item type="attr" name="layout_constraintBottom_toBottomOf"/>
-      <item type="attr" name="layout_constraintBottom_toTopOf"/>
-      <item type="attr" name="layout_constraintDimensionRatio"/>
-      <item type="attr" name="layout_constraintEnd_toEndOf"/>
-      <item type="attr" name="layout_constraintEnd_toStartOf"/>
-      <item type="attr" name="layout_constraintGuide_begin"/>
-      <item type="attr" name="layout_constraintGuide_end"/>
-      <item type="attr" name="layout_constraintGuide_percent"/>
-      <item type="attr" name="layout_constraintHeight_default"/>
-      <item type="attr" name="layout_constraintHeight_max"/>
-      <item type="attr" name="layout_constraintHeight_min"/>
-      <item type="attr" name="layout_constraintHeight_percent"/>
-      <item type="attr" name="layout_constraintHorizontal_bias"/>
-      <item type="attr" name="layout_constraintHorizontal_chainStyle"/>
-      <item type="attr" name="layout_constraintHorizontal_weight"/>
-      <item type="attr" name="layout_constraintLeft_creator"/>
-      <item type="attr" name="layout_constraintLeft_toLeftOf"/>
-      <item type="attr" name="layout_constraintLeft_toRightOf"/>
-      <item type="attr" name="layout_constraintRight_creator"/>
-      <item type="attr" name="layout_constraintRight_toLeftOf"/>
-      <item type="attr" name="layout_constraintRight_toRightOf"/>
-      <item type="attr" name="layout_constraintStart_toEndOf"/>
-      <item type="attr" name="layout_constraintStart_toStartOf"/>
-      <item type="attr" name="layout_constraintTop_creator"/>
-      <item type="attr" name="layout_constraintTop_toBottomOf"/>
-      <item type="attr" name="layout_constraintTop_toTopOf"/>
-      <item type="attr" name="layout_constraintVertical_bias"/>
-      <item type="attr" name="layout_constraintVertical_chainStyle"/>
-      <item type="attr" name="layout_constraintVertical_weight"/>
-      <item type="attr" name="layout_constraintWidth_default"/>
-      <item type="attr" name="layout_constraintWidth_max"/>
-      <item type="attr" name="layout_constraintWidth_min"/>
-      <item type="attr" name="layout_constraintWidth_percent"/>
-      <item type="attr" name="layout_editor_absoluteX"/>
-      <item type="attr" name="layout_editor_absoluteY"/>
-      <item type="attr" name="layout_goneMarginBottom"/>
-      <item type="attr" name="layout_goneMarginEnd"/>
-      <item type="attr" name="layout_goneMarginLeft"/>
-      <item type="attr" name="layout_goneMarginRight"/>
-      <item type="attr" name="layout_goneMarginStart"/>
-      <item type="attr" name="layout_goneMarginTop"/>
-      <item type="attr" name="layout_optimizationLevel"/>
-      <item type="attr" name="preferenceStyle"/>
-      <item type="attr" name="state_ux_restricted"/>
-      <item type="attr" name="title"/>
-      <item type="bool" name="car_ui_alert_dialog_force_dismiss_button"/>
-      <item type="bool" name="car_ui_escrow_check_components_automatically"/>
-      <item type="bool" name="car_ui_ime_wide_screen_aligned_left"/>
-      <item type="bool" name="car_ui_ime_wide_screen_allow_app_hide_content_area"/>
-      <item type="bool" name="car_ui_list_item_single_line_title"/>
-      <item type="bool" name="car_ui_preference_list_instant_change_callback"/>
-      <item type="bool" name="car_ui_preference_list_show_full_screen"/>
-      <item type="bool" name="car_ui_preference_show_chevron"/>
-      <item type="bool" name="car_ui_scrollbar_enable"/>
-      <item type="bool" name="car_ui_toolbar_logo_fills_nav_icon_space"/>
-      <item type="bool" name="car_ui_toolbar_menuitem_individual_click_listeners"/>
-      <item type="bool" name="car_ui_toolbar_nav_icon_reserve_space"/>
-      <item type="bool" name="car_ui_toolbar_show_logo"/>
-      <item type="bool" name="car_ui_toolbar_tab_flexible_layout"/>
-      <item type="bool" name="car_ui_toolbar_tabs_on_second_row"/>
-      <item type="color" name="car_ui_activity_background_color"/>
-      <item type="color" name="car_ui_color_accent"/>
-      <item type="color" name="car_ui_dialog_icon_color"/>
-      <item type="color" name="car_ui_ime_wide_screen_description_color"/>
-      <item type="color" name="car_ui_ime_wide_screen_description_title_color"/>
-      <item type="color" name="car_ui_ime_wide_screen_divider_color"/>
-      <item type="color" name="car_ui_ime_wide_screen_error_text_color"/>
-      <item type="color" name="car_ui_ime_wide_screen_search_item_sub_title_color"/>
-      <item type="color" name="car_ui_ime_wide_screen_search_item_title_color"/>
-      <item type="color" name="car_ui_list_item_divider"/>
-      <item type="color" name="car_ui_preference_icon_color"/>
-      <item type="color" name="car_ui_preference_two_action_divider_color"/>
-      <item type="color" name="car_ui_recyclerview_divider_color"/>
-      <item type="color" name="car_ui_ripple_color"/>
-      <item type="color" name="car_ui_scrollbar_arrow"/>
-      <item type="color" name="car_ui_scrollbar_thumb"/>
-      <item type="color" name="car_ui_text_color_hint"/>
-      <item type="color" name="car_ui_text_color_primary"/>
-      <item type="color" name="car_ui_text_color_secondary"/>
-      <item type="color" name="car_ui_toolbar_menu_item_icon_background_color"/>
-      <item type="color" name="car_ui_toolbar_menu_item_icon_color"/>
-      <item type="color" name="car_ui_toolbar_nav_icon_color"/>
-      <item type="color" name="car_ui_toolbar_search_hint_text_color"/>
-      <item type="color" name="car_ui_toolbar_tab_item_selector"/>
-      <item type="color" name="car_ui_toolbar_tab_selected_color"/>
-      <item type="color" name="car_ui_toolbar_tab_unselected_color"/>
-      <item type="dimen" name="car_ui_app_styled_dialog_height"/>
-      <item type="dimen" name="car_ui_app_styled_dialog_position_x"/>
-      <item type="dimen" name="car_ui_app_styled_dialog_position_y"/>
-      <item type="dimen" name="car_ui_app_styled_dialog_width"/>
-      <item type="dimen" name="car_ui_body1_size"/>
-      <item type="dimen" name="car_ui_body2_size"/>
-      <item type="dimen" name="car_ui_body3_size"/>
-      <item type="dimen" name="car_ui_button_disabled_alpha"/>
-      <item type="dimen" name="car_ui_dialog_edittext_height"/>
-      <item type="dimen" name="car_ui_dialog_edittext_margin_bottom"/>
-      <item type="dimen" name="car_ui_dialog_edittext_margin_end"/>
-      <item type="dimen" name="car_ui_dialog_edittext_margin_start"/>
-      <item type="dimen" name="car_ui_dialog_edittext_margin_top"/>
-      <item type="dimen" name="car_ui_dialog_icon_size"/>
-      <item type="dimen" name="car_ui_dialog_title_margin"/>
-      <item type="dimen" name="car_ui_divider_width"/>
-      <item type="dimen" name="car_ui_header_list_item_text_start_margin"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_action_button_height"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_action_button_margin_bottom"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_action_button_margin_left"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_action_button_text_size"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_description_padding_top"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_description_text_size"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_description_title_margin_top"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_description_title_padding_left"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_description_title_text_size"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_divider_width"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_error_text_padding_start"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_error_text_size"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_input_area_height"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_input_area_padding_end"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_input_area_padding_top"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_input_edit_text_padding_left"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_input_edit_text_padding_right"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_input_edit_text_size"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_input_padding_start"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_keyboard_area_padding_bottom"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_keyboard_area_padding_end"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_keyboard_area_padding_start"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_keyboard_width"/>
-      <item type="dimen" name="car_ui_ime_wide_screen_recycler_view_padding_top"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_icon_size"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_secondary_image_padding_left"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_sub_title_padding_left"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_sub_title_padding_top"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_sub_title_text_size"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_title_padding_left"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_title_padding_top"/>
-      <item type="dimen" name="car_ui_ime_wide_search_item_title_text_size"/>
-      <item type="dimen" name="car_ui_list_item_action_divider_height"/>
-      <item type="dimen" name="car_ui_list_item_action_divider_width"/>
-      <item type="dimen" name="car_ui_list_item_avatar_icon_height"/>
-      <item type="dimen" name="car_ui_list_item_avatar_icon_width"/>
-      <item type="dimen" name="car_ui_list_item_content_icon_height"/>
-      <item type="dimen" name="car_ui_list_item_content_icon_width"/>
-      <item type="dimen" name="car_ui_list_item_end_inset"/>
-      <item type="dimen" name="car_ui_list_item_header_height"/>
-      <item type="dimen" name="car_ui_list_item_header_start_inset"/>
-      <item type="dimen" name="car_ui_list_item_height"/>
-      <item type="dimen" name="car_ui_list_item_icon_container_width"/>
-      <item type="dimen" name="car_ui_list_item_icon_size"/>
-      <item type="dimen" name="car_ui_list_item_start_inset"/>
-      <item type="dimen" name="car_ui_list_item_supplemental_icon_size"/>
-      <item type="dimen" name="car_ui_list_item_text_no_icon_start_margin"/>
-      <item type="dimen" name="car_ui_list_item_text_start_margin"/>
-      <item type="dimen" name="car_ui_margin"/>
-      <item type="dimen" name="car_ui_padding_0"/>
-      <item type="dimen" name="car_ui_padding_1"/>
-      <item type="dimen" name="car_ui_padding_2"/>
-      <item type="dimen" name="car_ui_padding_3"/>
-      <item type="dimen" name="car_ui_padding_4"/>
-      <item type="dimen" name="car_ui_padding_5"/>
-      <item type="dimen" name="car_ui_padding_6"/>
-      <item type="dimen" name="car_ui_padding_7"/>
-      <item type="dimen" name="car_ui_padding_8"/>
-      <item type="dimen" name="car_ui_preference_category_icon_margin_end"/>
-      <item type="dimen" name="car_ui_preference_category_icon_size"/>
-      <item type="dimen" name="car_ui_preference_category_min_height"/>
-      <item type="dimen" name="car_ui_preference_content_margin_bottom"/>
-      <item type="dimen" name="car_ui_preference_content_margin_top"/>
-      <item type="dimen" name="car_ui_preference_dropdown_padding_start"/>
-      <item type="dimen" name="car_ui_preference_edit_text_dialog_margin_bottom"/>
-      <item type="dimen" name="car_ui_preference_edit_text_dialog_margin_top"/>
-      <item type="dimen" name="car_ui_preference_edit_text_dialog_message_margin_bottom"/>
-      <item type="dimen" name="car_ui_preference_edit_text_dialog_message_margin_end"/>
-      <item type="dimen" name="car_ui_preference_edit_text_dialog_message_margin_start"/>
-      <item type="dimen" name="car_ui_preference_edit_text_dialog_text_margin_end"/>
-      <item type="dimen" name="car_ui_preference_edit_text_dialog_text_margin_start"/>
-      <item type="dimen" name="car_ui_preference_icon_margin_end"/>
-      <item type="dimen" name="car_ui_preference_icon_size"/>
-      <item type="dimen" name="car_ui_primary_icon_size"/>
-      <item type="dimen" name="car_ui_recyclerview_divider_bottom_margin"/>
-      <item type="dimen" name="car_ui_recyclerview_divider_end_margin"/>
-      <item type="dimen" name="car_ui_recyclerview_divider_height"/>
-      <item type="dimen" name="car_ui_recyclerview_divider_start_margin"/>
-      <item type="dimen" name="car_ui_recyclerview_divider_top_margin"/>
-      <item type="dimen" name="car_ui_scrollbar_button_size"/>
-      <item type="dimen" name="car_ui_scrollbar_container_width"/>
-      <item type="dimen" name="car_ui_scrollbar_decelerate_interpolator_factor"/>
-      <item type="dimen" name="car_ui_scrollbar_deceleration_times_divisor"/>
-      <item type="dimen" name="car_ui_scrollbar_margin"/>
-      <item type="dimen" name="car_ui_scrollbar_milliseconds_per_inch"/>
-      <item type="dimen" name="car_ui_scrollbar_min_thumb_height"/>
-      <item type="dimen" name="car_ui_scrollbar_padding_bottom"/>
-      <item type="dimen" name="car_ui_scrollbar_padding_top"/>
-      <item type="dimen" name="car_ui_scrollbar_separator_margin"/>
-      <item type="dimen" name="car_ui_scrollbar_thumb_radius"/>
-      <item type="dimen" name="car_ui_scrollbar_thumb_width"/>
-      <item type="dimen" name="car_ui_sub1_size"/>
-      <item type="dimen" name="car_ui_sub2_size"/>
-      <item type="dimen" name="car_ui_sub3_size"/>
-      <item type="dimen" name="car_ui_toolbar_bottom_inset"/>
-      <item type="dimen" name="car_ui_toolbar_bottom_view_height"/>
-      <item type="dimen" name="car_ui_toolbar_end_inset"/>
-      <item type="dimen" name="car_ui_toolbar_first_row_height"/>
-      <item type="dimen" name="car_ui_toolbar_logo_size"/>
-      <item type="dimen" name="car_ui_toolbar_margin"/>
-      <item type="dimen" name="car_ui_toolbar_menu_item_icon_background_size"/>
-      <item type="dimen" name="car_ui_toolbar_menu_item_icon_ripple_radius"/>
-      <item type="dimen" name="car_ui_toolbar_menu_item_icon_size"/>
-      <item type="dimen" name="car_ui_toolbar_menu_item_margin"/>
-      <item type="dimen" name="car_ui_toolbar_nav_icon_size"/>
-      <item type="dimen" name="car_ui_toolbar_row_height"/>
-      <item type="dimen" name="car_ui_toolbar_search_close_icon_container_width"/>
-      <item type="dimen" name="car_ui_toolbar_search_close_icon_size"/>
-      <item type="dimen" name="car_ui_toolbar_search_height"/>
-      <item type="dimen" name="car_ui_toolbar_search_search_icon_container_width"/>
-      <item type="dimen" name="car_ui_toolbar_search_search_icon_size"/>
-      <item type="dimen" name="car_ui_toolbar_second_row_height"/>
-      <item type="dimen" name="car_ui_toolbar_separator_height"/>
-      <item type="dimen" name="car_ui_toolbar_start_inset"/>
-      <item type="dimen" name="car_ui_toolbar_tab_icon_height"/>
-      <item type="dimen" name="car_ui_toolbar_tab_icon_width"/>
-      <item type="dimen" name="car_ui_toolbar_tab_padding_x"/>
-      <item type="dimen" name="car_ui_toolbar_tab_text_width"/>
-      <item type="dimen" name="car_ui_toolbar_title_logo_padding"/>
-      <item type="dimen" name="car_ui_toolbar_title_margin_start"/>
-      <item type="dimen" name="car_ui_toolbar_title_no_logo_margin_start"/>
-      <item type="dimen" name="car_ui_toolbar_top_inset"/>
-      <item type="dimen" name="car_ui_touch_target_height"/>
-      <item type="dimen" name="car_ui_touch_target_size"/>
-      <item type="dimen" name="car_ui_touch_target_width"/>
-      <item type="dimen" name="wrap_content"/>
-      <item type="drawable" name="car_ui_activity_background"/>
-      <item type="drawable" name="car_ui_divider"/>
-      <item type="drawable" name="car_ui_icon_add"/>
-      <item type="drawable" name="car_ui_icon_arrow_back"/>
-      <item type="drawable" name="car_ui_icon_chevron"/>
-      <item type="drawable" name="car_ui_icon_close"/>
-      <item type="drawable" name="car_ui_icon_delete"/>
-      <item type="drawable" name="car_ui_icon_down"/>
-      <item type="drawable" name="car_ui_icon_edit"/>
-      <item type="drawable" name="car_ui_icon_error"/>
-      <item type="drawable" name="car_ui_icon_lock"/>
-      <item type="drawable" name="car_ui_icon_overflow_menu"/>
-      <item type="drawable" name="car_ui_icon_save"/>
-      <item type="drawable" name="car_ui_icon_search"/>
-      <item type="drawable" name="car_ui_icon_search_nav_icon"/>
-      <item type="drawable" name="car_ui_icon_settings"/>
-      <item type="drawable" name="car_ui_ime_wide_screen_background"/>
-      <item type="drawable" name="car_ui_ime_wide_screen_content_area_background"/>
-      <item type="drawable" name="car_ui_ime_wide_screen_input_area_background"/>
-      <item type="drawable" name="car_ui_ime_wide_screen_input_area_tint_color"/>
-      <item type="drawable" name="car_ui_ime_wide_screen_input_area_tint_error_color"/>
-      <item type="drawable" name="car_ui_ime_wide_screen_no_content_background"/>
-      <item type="drawable" name="car_ui_list_header_background"/>
-      <item type="drawable" name="car_ui_list_item_avatar_icon_outline"/>
-      <item type="drawable" name="car_ui_list_item_background"/>
-      <item type="drawable" name="car_ui_list_item_divider"/>
-      <item type="drawable" name="car_ui_list_limiting_message_background"/>
-      <item type="drawable" name="car_ui_preference_icon_chevron"/>
-      <item type="drawable" name="car_ui_preference_icon_chevron_disabled"/>
-      <item type="drawable" name="car_ui_preference_icon_chevron_enabled"/>
-      <item type="drawable" name="car_ui_recyclerview_button_ripple_background"/>
-      <item type="drawable" name="car_ui_recyclerview_divider"/>
-      <item type="drawable" name="car_ui_recyclerview_ic_down"/>
-      <item type="drawable" name="car_ui_recyclerview_ic_up"/>
-      <item type="drawable" name="car_ui_recyclerview_scrollbar_thumb"/>
-      <item type="drawable" name="car_ui_toolbar_background"/>
-      <item type="drawable" name="car_ui_toolbar_menu_item_divider"/>
-      <item type="drawable" name="car_ui_toolbar_menu_item_icon_background"/>
-      <item type="drawable" name="car_ui_toolbar_menu_item_icon_ripple"/>
-      <item type="drawable" name="car_ui_toolbar_search_close_icon"/>
-      <item type="drawable" name="car_ui_toolbar_search_search_icon"/>
-      <item type="id" name="action_widget_container"/>
-      <item type="id" name="car_ui_alert_icon"/>
-      <item type="id" name="car_ui_alert_subtitle"/>
-      <item type="id" name="car_ui_alert_title"/>
-      <item type="id" name="car_ui_base_layout_content_container"/>
-      <item type="id" name="car_ui_closeKeyboard"/>
-      <item type="id" name="car_ui_component_reference"/>
-      <item type="id" name="car_ui_contentAreaAutomotive"/>
-      <item type="id" name="car_ui_divider"/>
-      <item type="id" name="car_ui_first_action_container"/>
-      <item type="id" name="car_ui_focus_area"/>
-      <item type="id" name="car_ui_fullscreenArea"/>
-      <item type="id" name="car_ui_imeWideScreenInputArea"/>
-      <item type="id" name="car_ui_ime_carboard_area"/>
-      <item type="id" name="car_ui_ime_surface"/>
-      <item type="id" name="car_ui_inputExtractActionAutomotive"/>
-      <item type="id" name="car_ui_inputExtractEditTextContainer"/>
-      <item type="id" name="car_ui_list_item_action_container"/>
-      <item type="id" name="car_ui_list_item_action_container_touch_interceptor"/>
-      <item type="id" name="car_ui_list_item_action_divider"/>
-      <item type="id" name="car_ui_list_item_avatar_icon"/>
-      <item type="id" name="car_ui_list_item_body"/>
-      <item type="id" name="car_ui_list_item_checkbox_widget"/>
-      <item type="id" name="car_ui_list_item_content_icon"/>
-      <item type="id" name="car_ui_list_item_end_guideline"/>
-      <item type="id" name="car_ui_list_item_icon"/>
-      <item type="id" name="car_ui_list_item_icon_container"/>
-      <item type="id" name="car_ui_list_item_radio_button_widget"/>
-      <item type="id" name="car_ui_list_item_reduced_touch_interceptor"/>
-      <item type="id" name="car_ui_list_item_start_guideline"/>
-      <item type="id" name="car_ui_list_item_supplemental_icon"/>
-      <item type="id" name="car_ui_list_item_switch_widget"/>
-      <item type="id" name="car_ui_list_item_title"/>
-      <item type="id" name="car_ui_list_item_touch_interceptor"/>
-      <item type="id" name="car_ui_list_limiting_message"/>
-      <item type="id" name="car_ui_preference_container_without_widget"/>
-      <item type="id" name="car_ui_recycler_view"/>
-      <item type="id" name="car_ui_scroll_bar"/>
-      <item type="id" name="car_ui_scrollbar_page_down"/>
-      <item type="id" name="car_ui_scrollbar_page_up"/>
-      <item type="id" name="car_ui_scrollbar_thumb"/>
-      <item type="id" name="car_ui_scrollbar_track"/>
-      <item type="id" name="car_ui_second_action_container"/>
-      <item type="id" name="car_ui_secondary_action"/>
-      <item type="id" name="car_ui_secondary_action_concrete"/>
-      <item type="id" name="car_ui_toolbar_background"/>
-      <item type="id" name="car_ui_toolbar_bottom_guideline"/>
-      <item type="id" name="car_ui_toolbar_bottom_styleable"/>
-      <item type="id" name="car_ui_toolbar_end_guideline"/>
-      <item type="id" name="car_ui_toolbar_logo"/>
-      <item type="id" name="car_ui_toolbar_menu_item_icon"/>
-      <item type="id" name="car_ui_toolbar_menu_item_icon_container"/>
-      <item type="id" name="car_ui_toolbar_menu_item_switch"/>
-      <item type="id" name="car_ui_toolbar_menu_item_text"/>
-      <item type="id" name="car_ui_toolbar_menu_item_text_with_icon"/>
-      <item type="id" name="car_ui_toolbar_menu_items_container"/>
-      <item type="id" name="car_ui_toolbar_nav_icon"/>
-      <item type="id" name="car_ui_toolbar_nav_icon_container"/>
-      <item type="id" name="car_ui_toolbar_progress_bar"/>
-      <item type="id" name="car_ui_toolbar_row_separator"/>
-      <item type="id" name="car_ui_toolbar_row_separator_guideline"/>
-      <item type="id" name="car_ui_toolbar_search_bar"/>
-      <item type="id" name="car_ui_toolbar_search_close"/>
-      <item type="id" name="car_ui_toolbar_search_icon"/>
-      <item type="id" name="car_ui_toolbar_search_view_container"/>
-      <item type="id" name="car_ui_toolbar_start_guideline"/>
-      <item type="id" name="car_ui_toolbar_subtitle"/>
-      <item type="id" name="car_ui_toolbar_tab_item_icon"/>
-      <item type="id" name="car_ui_toolbar_tab_item_text"/>
-      <item type="id" name="car_ui_toolbar_tabs"/>
-      <item type="id" name="car_ui_toolbar_title"/>
-      <item type="id" name="car_ui_toolbar_title_container"/>
-      <item type="id" name="car_ui_toolbar_title_logo"/>
-      <item type="id" name="car_ui_toolbar_title_logo_container"/>
-      <item type="id" name="car_ui_toolbar_top_guideline"/>
-      <item type="id" name="car_ui_wideScreenClearData"/>
-      <item type="id" name="car_ui_wideScreenDescription"/>
-      <item type="id" name="car_ui_wideScreenDescriptionTitle"/>
-      <item type="id" name="car_ui_wideScreenError"/>
-      <item type="id" name="car_ui_wideScreenErrorMessage"/>
-      <item type="id" name="car_ui_wideScreenExtractedTextIcon"/>
-      <item type="id" name="car_ui_wideScreenInputArea"/>
-      <item type="id" name="car_ui_wideScreenSearchResultList"/>
-      <item type="id" name="container"/>
-      <item type="id" name="list"/>
-      <item type="id" name="nested_recycler_view_layout"/>
-      <item type="id" name="radio_button"/>
-      <item type="id" name="recycler_view"/>
-      <item type="id" name="search"/>
-      <item type="id" name="seek_bar"/>
-      <item type="id" name="seek_bar_text_left"/>
-      <item type="id" name="seek_bar_text_right"/>
-      <item type="id" name="seek_bar_text_top"/>
-      <item type="id" name="seekbar"/>
-      <item type="id" name="seekbar_value"/>
-      <item type="id" name="spinner"/>
-      <item type="id" name="textbox"/>
-      <item type="id" name="title_template"/>
-      <item type="integer" name="car_ui_default_max_string_length"/>
-      <item type="integer" name="car_ui_scrollbar_longpress_initial_delay"/>
-      <item type="integer" name="car_ui_scrollbar_longpress_repeat_interval"/>
-      <item type="layout" name="car_ui_alert_dialog_edit_text"/>
-      <item type="layout" name="car_ui_alert_dialog_list"/>
-      <item type="layout" name="car_ui_alert_dialog_title_with_subtitle"/>
-      <item type="layout" name="car_ui_base_layout"/>
-      <item type="layout" name="car_ui_base_layout_toolbar"/>
-      <item type="layout" name="car_ui_header_list_item"/>
-      <item type="layout" name="car_ui_ims_wide_screen_input_view"/>
-      <item type="layout" name="car_ui_list_item"/>
-      <item type="layout" name="car_ui_list_item_compact"/>
-      <item type="layout" name="car_ui_list_limiting_message"/>
-      <item type="layout" name="car_ui_list_preference"/>
-      <item type="layout" name="car_ui_preference"/>
-      <item type="layout" name="car_ui_preference_category"/>
-      <item type="layout" name="car_ui_preference_chevron"/>
-      <item type="layout" name="car_ui_preference_dialog_edittext"/>
-      <item type="layout" name="car_ui_preference_dropdown"/>
-      <item type="layout" name="car_ui_preference_fragment"/>
-      <item type="layout" name="car_ui_preference_two_action_icon"/>
-      <item type="layout" name="car_ui_preference_two_action_switch"/>
-      <item type="layout" name="car_ui_preference_two_action_text"/>
-      <item type="layout" name="car_ui_preference_two_action_text_borderless"/>
-      <item type="layout" name="car_ui_preference_widget_checkbox"/>
-      <item type="layout" name="car_ui_preference_widget_seekbar"/>
-      <item type="layout" name="car_ui_preference_widget_switch"/>
-      <item type="layout" name="car_ui_radio_button_preference_widget"/>
-      <item type="layout" name="car_ui_recycler_view"/>
-      <item type="layout" name="car_ui_recycler_view_item"/>
-      <item type="layout" name="car_ui_recyclerview_scrollbar"/>
-      <item type="layout" name="car_ui_seekbar_dialog"/>
-      <item type="layout" name="car_ui_toolbar"/>
-      <item type="layout" name="car_ui_toolbar_menu_item"/>
-      <item type="layout" name="car_ui_toolbar_menu_item_primary"/>
-      <item type="layout" name="car_ui_toolbar_search_view"/>
-      <item type="layout" name="car_ui_toolbar_tab_item"/>
-      <item type="layout" name="car_ui_toolbar_tab_item_flexible"/>
-      <item type="layout" name="car_ui_toolbar_tab_item_layout"/>
-      <item type="layout" name="car_ui_toolbar_tab_item_layout_flexible"/>
-      <item type="layout" name="car_ui_toolbar_two_row"/>
-      <item type="layout" name="car_ui_two_action_preference"/>
-      <item type="raw" name="car_ui_keep"/>
-      <item type="string" name="car_ui_alert_dialog_default_button"/>
-      <item type="string" name="car_ui_dialog_preference_negative"/>
-      <item type="string" name="car_ui_dialog_preference_positive"/>
-      <item type="string" name="car_ui_ellipsis"/>
-      <item type="string" name="car_ui_ime_wide_screen_system_property_name"/>
-      <item type="string" name="car_ui_installer_process_name"/>
-      <item type="string" name="car_ui_preference_switch_off"/>
-      <item type="string" name="car_ui_preference_switch_on"/>
-      <item type="string" name="car_ui_restricted_while_driving"/>
-      <item type="string" name="car_ui_scrollbar_component"/>
-      <item type="string" name="car_ui_scrollbar_page_down_button"/>
-      <item type="string" name="car_ui_scrollbar_page_up_button"/>
-      <item type="string" name="car_ui_scrolling_limited_message"/>
-      <item type="string" name="car_ui_shared_library_package_system_property_name"/>
-      <item type="string" name="car_ui_toolbar_default_search_hint"/>
-      <item type="string" name="car_ui_toolbar_menu_item_overflow_title"/>
-      <item type="string" name="car_ui_toolbar_menu_item_search_title"/>
-      <item type="string" name="car_ui_toolbar_menu_item_settings_title"/>
-      <item type="string" name="car_ui_toolbar_nav_icon_content_description"/>
-      <item type="style" name="CarUiPreferenceTheme"/>
-      <item type="style" name="Preference.CarUi"/>
-      <item type="style" name="Preference.CarUi.Category"/>
-      <item type="style" name="Preference.CarUi.CheckBoxPreference"/>
-      <item type="style" name="Preference.CarUi.DialogPreference"/>
-      <item type="style" name="Preference.CarUi.DialogPreference.EditTextPreference"/>
-      <item type="style" name="Preference.CarUi.DialogSeekBarPreference"/>
-      <item type="style" name="Preference.CarUi.DialogSeekBarPreference.LeftText"/>
-      <item type="style" name="Preference.CarUi.DialogSeekBarPreference.RightText"/>
-      <item type="style" name="Preference.CarUi.DialogSeekBarPreference.Seekbar"/>
-      <item type="style" name="Preference.CarUi.DialogSeekBarPreference.TopText"/>
-      <item type="style" name="Preference.CarUi.Divider"/>
-      <item type="style" name="Preference.CarUi.DropDown"/>
-      <item type="style" name="Preference.CarUi.Icon"/>
-      <item type="style" name="Preference.CarUi.Information"/>
-      <item type="style" name="Preference.CarUi.Preference"/>
-      <item type="style" name="Preference.CarUi.PreferenceScreen"/>
-      <item type="style" name="Preference.CarUi.SeekBarPreference"/>
-      <item type="style" name="Preference.CarUi.SwitchPreference"/>
-      <item type="style" name="PreferenceFragment.CarUi"/>
-      <item type="style" name="PreferenceFragmentList.CarUi"/>
-      <item type="style" name="TextAppearance.CarUi"/>
-      <item type="style" name="TextAppearance.CarUi.AlertDialog.Subtitle"/>
-      <item type="style" name="TextAppearance.CarUi.AlertDialog.Title"/>
-      <item type="style" name="TextAppearance.CarUi.Body1"/>
-      <item type="style" name="TextAppearance.CarUi.Body2"/>
-      <item type="style" name="TextAppearance.CarUi.Body3"/>
-      <item type="style" name="TextAppearance.CarUi.ListItem"/>
-      <item type="style" name="TextAppearance.CarUi.ListItem.Body"/>
-      <item type="style" name="TextAppearance.CarUi.ListItem.Header"/>
-      <item type="style" name="TextAppearance.CarUi.PreferenceCategoryTitle"/>
-      <item type="style" name="TextAppearance.CarUi.PreferenceEditTextDialogMessage"/>
-      <item type="style" name="TextAppearance.CarUi.PreferenceSummary"/>
-      <item type="style" name="TextAppearance.CarUi.PreferenceTitle"/>
-      <item type="style" name="TextAppearance.CarUi.Sub1"/>
-      <item type="style" name="TextAppearance.CarUi.Sub2"/>
-      <item type="style" name="TextAppearance.CarUi.Sub3"/>
-      <item type="style" name="TextAppearance.CarUi.Widget"/>
-      <item type="style" name="TextAppearance.CarUi.Widget.Toolbar"/>
-      <item type="style" name="TextAppearance.CarUi.Widget.Toolbar.Tab"/>
-      <item type="style" name="TextAppearance.CarUi.Widget.Toolbar.Tab.Selected"/>
-      <item type="style" name="TextAppearance.CarUi.Widget.Toolbar.Title"/>
-      <item type="style" name="Theme.CarUi"/>
-      <item type="style" name="Theme.CarUi.NoToolbar"/>
-      <item type="style" name="Theme.CarUi.WithToolbar"/>
-      <item type="style" name="Widget.CarUi"/>
-      <item type="style" name="Widget.CarUi.AlertDialog"/>
-      <item type="style" name="Widget.CarUi.AlertDialog.HeaderContainer"/>
-      <item type="style" name="Widget.CarUi.AlertDialog.Icon"/>
-      <item type="style" name="Widget.CarUi.AlertDialog.TitleContainer"/>
-      <item type="style" name="Widget.CarUi.Button"/>
-      <item type="style" name="Widget.CarUi.Button.Borderless.Colored"/>
-      <item type="style" name="Widget.CarUi.CarUiRecyclerView"/>
-      <item type="style" name="Widget.CarUi.SeekbarPreference"/>
-      <item type="style" name="Widget.CarUi.SeekbarPreference.Seekbar"/>
-      <item type="style" name="Widget.CarUi.Toolbar"/>
-      <item type="style" name="Widget.CarUi.Toolbar.BottomView"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Container"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Logo"/>
-      <item type="style" name="Widget.CarUi.Toolbar.LogoContainer"/>
-      <item type="style" name="Widget.CarUi.Toolbar.MenuItem"/>
-      <item type="style" name="Widget.CarUi.Toolbar.MenuItem.Container"/>
-      <item type="style" name="Widget.CarUi.Toolbar.MenuItem.IndividualContainer"/>
-      <item type="style" name="Widget.CarUi.Toolbar.NavIcon"/>
-      <item type="style" name="Widget.CarUi.Toolbar.NavIconContainer"/>
-      <item type="style" name="Widget.CarUi.Toolbar.ProgressBar"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Search.CloseIcon"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Search.EditText"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Search.SearchIcon"/>
-      <item type="style" name="Widget.CarUi.Toolbar.SeparatorView"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Subtitle"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Tab"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Tab.Container"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Tab.Icon"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Tab.Text"/>
-      <item type="style" name="Widget.CarUi.Toolbar.TextButton"/>
-      <item type="style" name="Widget.CarUi.Toolbar.TextButton.WithIcon"/>
-      <item type="style" name="Widget.CarUi.Toolbar.Title"/>
-    </policy>
-  </overlayable>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_app_styled_view_background.xml b/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_app_styled_view_background.xml
deleted file mode 100644
index d740109..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_app_styled_view_background.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-  <solid android:color="@color/car_ui_activity_background_color"/>
-  <stroke android:width="3dp" android:color="#B1BCBE" />
-  <corners android:radius="10dp"/>
-  <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
-</shape>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_app_styled_view_ripple.xml b/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_app_styled_view_ripple.xml
deleted file mode 100644
index fadd180..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_app_styled_view_ripple.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~
-  ~ Copyright (C) 2021 Google Inc.
-  ~
-  ~ 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.
-  ~
- -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-  <item android:state_focused="true" android:state_pressed="true">
-    <shape android:shape="oval">
-      <solid android:color="#8A94CBFF"/>
-      <stroke android:width="4dp"
-          android:color="#94CBFF"/>
-      <size android:width="48dp"
-          android:height="48dp"/>
-    </shape>
-  </item>
-  <item android:state_focused="true">
-    <shape android:shape="oval">
-      <solid android:color="#3D94CBFF"/>
-      <stroke android:width="8dp"
-          android:color="#94CBFF"/>
-      <size android:width="48dp"
-          android:height="48dp"/>
-    </shape>
-  </item>
-  <item>
-    <ripple android:color="#27ffffff">
-      <item android:id="@android:id/mask">
-        <shape android:shape="oval">
-          <solid android:color="#FFFFFF"/>
-        </shape>
-      </item>
-    </ripple>
-  </item>
-</selector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_button_ripple_background_private.xml b/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_button_ripple_background_private.xml
deleted file mode 100644
index 50369d9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_button_ripple_background_private.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="#27ffffff" />
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_ic_down_private.xml b/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_ic_down_private.xml
deleted file mode 100644
index 9a242e6..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_ic_down_private.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:pathData="M14.83,16.42L24,25.59l9.17,-9.17L36,19.25l-12,12 -12,-12z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_ic_up_private.xml b/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_ic_up_private.xml
deleted file mode 100644
index 09111a9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_ic_up_private.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:pathData="M14.83,30.83L24,21.66l9.17,9.17L36,28 24,16 12,28z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_scrollbar_thumb_private.xml b/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_scrollbar_thumb_private.xml
deleted file mode 100644
index 9efbb5e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/drawable/car_ui_recyclerview_scrollbar_thumb_private.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<shape
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="#99ffffff" />
-    <corners android:radius="100dp"/>
-</shape>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/layout-land/car_ui_app_styled_view.xml b/car-ui-lib/car-ui-lib/src/main/res-private/layout-land/car_ui_app_styled_view.xml
deleted file mode 100644
index 47daee0..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/layout-land/car_ui_app_styled_view.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:padding="0dp"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/car_ui_app_styled_view_background">
-    <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-    <com.android.car.ui.FocusArea
-        android:id="@+id/car_ui_focus_area"
-        android:layout_width="@dimen/car_ui_toolbar_first_row_height"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintRight_toLeftOf="@+id/car_ui_app_styled_content">
-        <FrameLayout
-            android:id="@+id/car_ui_app_styled_view_nav_icon_container"
-            android:layout_marginVertical="10dp"
-            android:layout_marginHorizontal="18dp"
-            android:layout_width="76dp"
-            android:layout_height="76dp"
-            android:layout_gravity="center"
-            app:layout_constraintHorizontal_bias="0.0"
-            android:background="@drawable/car_ui_app_styled_view_ripple">
-            <ImageView
-                android:id="@+id/car_ui_app_styled_view_icon_close"
-                android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
-                android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
-                android:tint="@color/car_ui_toolbar_nav_icon_color"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-        </FrameLayout>
-    </com.android.car.ui.FocusArea>
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/car_ui_app_styled_content"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:carUiSize="small"
-        android:layout_marginLeft="@dimen/car_ui_toolbar_first_row_height"
-        app:layout_constraintBottom_toBottomOf="parent"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_app_styled_view.xml b/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_app_styled_view.xml
deleted file mode 100644
index f544e1d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_app_styled_view.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:padding="20dp"
-    android:background="@drawable/car_ui_app_styled_view_background">
-
-    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
-         first focusable view in the window automatically. Adding a FocusParkingView to the window
-         can fix this issue, because it can take focus, and it is transparent and its default focus
-         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
-         -->
-    <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-    <com.android.car.ui.FocusArea
-        android:id="@+id/car_ui_focus_area"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/car_ui_toolbar_first_row_height"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintStart_toStartOf="parent">
-        <FrameLayout
-            android:id="@+id/car_ui_app_styled_view_nav_icon_container"
-            android:layout_marginVertical="10dp"
-            android:layout_marginHorizontal="18dp"
-            android:background="@drawable/car_ui_app_styled_view_ripple"
-            android:layout_width="@dimen/car_ui_toolbar_margin"
-            android:layout_height="match_parent"
-            app:layout_constraintHorizontal_bias="0.0">
-            <ImageView
-                android:id="@+id/car_ui_app_styled_view_icon_close"
-                android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
-                android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
-                android:tint="@color/car_ui_toolbar_nav_icon_color"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-        </FrameLayout>
-    </com.android.car.ui.FocusArea>
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/car_ui_app_styled_content"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        app:carUiSize="small"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/car_ui_focus_area"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_app_styled_view_item.xml b/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_app_styled_view_item.xml
deleted file mode 100644
index f202a65..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_app_styled_view_item.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-  <FrameLayout
-      android:id="@+id/car_ui_app_styled_item"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_base_layout_toolbar_legacy.xml b/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_base_layout_toolbar_legacy.xml
deleted file mode 100644
index f89f04e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_base_layout_toolbar_legacy.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<!-- This layout is used on P or earlier, to support OEMs that shipped
-     on P and only customized the non-baselayout version of the toolbar -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
-         first focusable view in the window automatically. Adding a FocusParkingView to the window
-         can fix this issue, because it can take focus, and it is transparent and its default focus
-         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
-         -->
-    <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-
-    <FrameLayout
-        android:id="@+id/car_ui_base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <FrameLayout
-        android:id="@+id/car_ui_toolbar"
-        android:tag="car_ui_top_inset"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toTopOf="parent">
-        <include layout="@layout/car_ui_toolbar"/>
-    </FrameLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_base_layout_toolbar_legacy_two_row.xml b/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_base_layout_toolbar_legacy_two_row.xml
deleted file mode 100644
index e02927d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_base_layout_toolbar_legacy_two_row.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<!-- This layout is used on P or earlier, to support OEMs that shipped
-     on P and only customized the non-baselayout version of the toolbar -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
-         first focusable view in the window automatically. Adding a FocusParkingView to the window
-         can fix this issue, because it can take focus, and it is transparent and its default focus
-         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
-         -->
-    <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-
-    <FrameLayout
-        android:id="@+id/car_ui_base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <FrameLayout
-        android:id="@+id/car_ui_toolbar"
-        android:tag="car_ui_top_inset"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toTopOf="parent">
-        <include layout="@layout/car_ui_toolbar_two_row"/>
-    </FrameLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_recycler_view_medium.xml b/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_recycler_view_medium.xml
deleted file mode 100644
index 2140275..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/layout/car_ui_recycler_view_medium.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <com.android.car.ui.recyclerview.CarUiRecyclerViewContainer
-        android:id="@+id/car_ui_recycler_view"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingLeft="112dp"
-        android:tag="carUiRecyclerView" />
-
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="left" >
-        <androidx.constraintlayout.widget.ConstraintLayout
-            xmlns:app="http://schemas.android.com/apk/res-auto"
-            android:layout_width="112dp"
-            android:layout_height="match_parent"
-            android:id="@+id/car_ui_scroll_bar"
-            android:gravity="center">
-
-            <ImageView
-                android:id="@+id/car_ui_scrollbar_page_up"
-                android:layout_width="76dp"
-                android:layout_height="76dp"
-                android:background="@drawable/car_ui_recyclerview_button_ripple_background_private"
-                android:contentDescription="Scroll up"
-                android:focusable="false"
-                android:hapticFeedbackEnabled="false"
-                android:src="@drawable/car_ui_recyclerview_ic_up_private"
-                android:scaleType="centerInside"
-                android:layout_marginTop="15dp"
-                app:layout_constraintTop_toTopOf="parent"
-                app:layout_constraintLeft_toLeftOf="parent"
-                app:layout_constraintRight_toRightOf="parent"/>
-
-            <!-- View height is dynamically calculated during layout. -->
-            <View
-                android:id="@+id/car_ui_scrollbar_thumb"
-                android:layout_width="7dp"
-                android:layout_height="0dp"
-                android:layout_gravity="center_horizontal"
-                android:background="@drawable/car_ui_recyclerview_scrollbar_thumb_private"
-                app:layout_constraintTop_toTopOf="@+id/car_ui_scrollbar_track"
-                app:layout_constraintBottom_toBottomOf="@+id/car_ui_scrollbar_track"
-                app:layout_constraintLeft_toLeftOf="parent"
-                app:layout_constraintRight_toRightOf="parent"/>
-
-            <View
-                android:id="@+id/car_ui_scrollbar_track"
-                android:layout_width="0dp"
-                android:layout_height="0dp"
-                android:layout_marginTop="16dp"
-                android:layout_marginBottom="16dp"
-                app:layout_constraintTop_toBottomOf="@+id/car_ui_scrollbar_page_up"
-                app:layout_constraintBottom_toTopOf="@+id/car_ui_scrollbar_page_down"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"/>
-
-            <ImageView
-                android:id="@+id/car_ui_scrollbar_page_down"
-                android:layout_width="76dp"
-                android:layout_height="76dp"
-                android:background="@drawable/car_ui_recyclerview_button_ripple_background_private"
-                android:contentDescription="Scroll down"
-                android:focusable="false"
-                android:hapticFeedbackEnabled="false"
-                android:src="@drawable/car_ui_recyclerview_ic_down_private"
-                android:scaleType="centerInside"
-                android:layout_marginBottom="15dp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintLeft_toLeftOf="parent"
-                app:layout_constraintRight_toRightOf="parent"/>
-        </androidx.constraintlayout.widget.ConstraintLayout>
-    </FrameLayout>
-</merge>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/values-port/dimens.xml b/car-ui-lib/car-ui-lib/src/main/res-private/values-port/dimens.xml
deleted file mode 100644
index b57c750..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/values-port/dimens.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-    <!-- height and width of the dialog modal.  -->
-    <dimen name="car_ui_app_styled_dialog_width_max">768dp</dimen>
-    <dimen name="car_ui_app_styled_dialog_height_max">1056dp</dimen>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res-private/values/dimens.xml b/car-ui-lib/car-ui-lib/src/main/res-private/values/dimens.xml
deleted file mode 100644
index f5b21df..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res-private/values/dimens.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-    <!-- height and width of the dialog modal.  -->
-    <dimen name="car_ui_app_styled_dialog_width_max">1334dp</dimen>
-    <dimen name="car_ui_app_styled_dialog_height_max">768dp</dimen>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_scrollbar_thumb.xml b/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_scrollbar_thumb.xml
deleted file mode 100644
index ae914ff..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_scrollbar_thumb.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-    Copyright (C) 2021 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<!-- Activated state is used to highlight recycler view scrollbar thumb when rotary scrolling. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true" android:color="@color/car_ui_rotary_focus_stroke_color" />
-    <item android:color="#99ffffff" />
-</selector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_text_color_secondary.xml b/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_text_color_secondary.xml
deleted file mode 100644
index 4c9f267..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_text_color_secondary.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<!-- Copy of ?android:attr/textColorSecondary (frameworks/base/res/res/color/text_color_secondary.xml)
-     but with a ux restricted state. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:alpha="?android:attr/secondaryContentAlpha"
-          android:color="?android:attr/colorForeground"/>
-</selector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_toolbar_menu_item_icon_color.xml b/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_toolbar_menu_item_icon_color.xml
deleted file mode 100644
index 2b68a84..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_toolbar_menu_item_icon_color.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<!-- The same as @color/car_ui_text_color_primary but with an activated state -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true"
-          android:color="?android:attr/colorBackground"/>
-    <item android:color="@color/car_ui_text_color_primary" />
-</selector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_add.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_add.xml
deleted file mode 100644
index 3e86db9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_add.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<!-- Used in Carboard's toolbar. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-<path
-    android:fillColor="?android:attr/colorForeground"
-    android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_arrow_back.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_arrow_back.xml
deleted file mode 100644
index 4ad49b2..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_arrow_back.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2018, The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:autoMirrored="true"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_chevron.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_chevron.xml
deleted file mode 100644
index 2d719fc..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_chevron.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="48dp"
-    android:height="48dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24">
-    <path
-        android:fillColor="@color/car_ui_text_color_primary"
-        android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_delete.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_delete.xml
deleted file mode 100644
index 81cae40..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_delete.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<!-- Used in Carboard's toolbar. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-<path
-    android:fillColor="?android:attr/colorForeground"
-    android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_edit.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_edit.xml
deleted file mode 100644
index e234233..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_edit.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<!-- Used in Carboard's toolbar. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-<path
-    android:fillColor="?android:attr/colorForeground"
-    android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_error.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_error.xml
deleted file mode 100644
index b0f4a34..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_error.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M15.73,3L8.27,3L3,8.27v7.46L8.27,21h7.46L21,15.73L21,8.27L15.73,3zM12,17.3c-0.72,0 -1.3,-0.58 -1.3,-1.3 0,-0.72 0.58,-1.3 1.3,-1.3 0.72,0 1.3,0.58 1.3,1.3 0,0.72 -0.58,1.3 -1.3,1.3zM13,13h-2L11,7h2v6z"
-        android:fillColor="#F00"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_lock.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_lock.xml
deleted file mode 100644
index d74b14a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_lock.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2018 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="44dp"
-    android:height="44dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0">
-    <path
-        android:fillColor="@color/car_ui_text_color_primary"
-        android:pathData="M36,16h-2v-4c0,-5.52 -4.48,-10 -10,-10S14,6.48 14,12v4h-2c-2.21,0 -4,1.79 -4,4v20c0,2.21 1.79,4 4,4h24c2.21,0 4,-1.79 4,-4L40,20c0,-2.21 -1.79,-4 -4,-4zM24,34c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4zM30.2,16L17.8,16v-4c0,-3.42 2.78,-6.2 6.2,-6.2 3.42,0 6.2,2.78 6.2,6.2v4z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_save.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_save.xml
deleted file mode 100644
index 8f45b8f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_save.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<!-- Used in Carboard's toolbar. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-<path
-    android:fillColor="?android:attr/colorForeground"
-    android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_search.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_search.xml
deleted file mode 100644
index cfa46d8..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_search.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="48dp"
-    android:height="48dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-    <path
-        android:fillColor="?android:attr/colorForeground"
-        android:pathData="M31 28h-1.59l-.55-.55C30.82 25.18 32 22.23 32 19c0-7.18-5.82-13-13-13S6 11.82 6
-19s5.82 13 13 13c3.23 0 6.18-1.18 8.45-3.13l.55 .55 V31l10 9.98L40.98 38 31
-28zm-12 0c-4.97 0-9-4.03-9-9s4.03-9 9-9 9 4.03 9 9-4.03 9-9 9z" />
-    <path
-        android:pathData="M0 0h48v48H0z" />
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml
deleted file mode 100644
index 9c11e71..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:state_pressed="true">
-        <shape android:shape="rectangle">
-            <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/>
-            <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width"
-                    android:color="@color/car_ui_rotary_focus_pressed_stroke_color"/>
-        </shape>
-    </item>
-    <item android:state_focused="true">
-        <shape android:shape="rectangle">
-            <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
-            <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
-                    android:color="@color/car_ui_rotary_focus_stroke_color"/>
-        </shape>
-    </item>
-    <item android:state_activated="true">
-        <shape android:shape="rectangle">
-            <solid android:color="?android:attr/colorControlHighlight"/>
-        </shape>
-    </item>
-    <item>
-        <ripple android:color="?android:attr/colorControlHighlight">
-            <item android:id="@android:id/mask">
-                <shape android:shape="rectangle">
-                    <solid android:color="?android:colorAccent"/>
-                </shape>
-            </item>
-        </ripple>
-    </item>
-</selector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_limiting_message_background.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_limiting_message_background.xml
deleted file mode 100644
index 02a8065..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_limiting_message_background.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <solid android:color="#282A2D"/>
-    <corners android:radius="96dp"/>
-</shape>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_ic_down.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_ic_down.xml
deleted file mode 100644
index 0943288..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_ic_down.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:pathData="M14.83,16.42L24,25.59l9.17,-9.17L36,19.25l-12,12 -12,-12z"
-        android:fillColor="@color/car_ui_scrollbar_arrow"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_ic_up.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_ic_up.xml
deleted file mode 100644
index 72abbc9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_ic_up.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:pathData="M14.83,30.83L24,21.66l9.17,9.17L36,28 24,16 12,28z"
-        android:fillColor="@color/car_ui_scrollbar_arrow"/>
-</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_toolbar_menu_item_icon_background.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_toolbar_menu_item_icon_background.xml
deleted file mode 100644
index 46171fd..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_toolbar_menu_item_icon_background.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~
-  ~ Copyright (C) 2019 Google Inc.
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="oval">
-    <size
-        android:width="@dimen/car_ui_toolbar_menu_item_icon_background_size"
-        android:height="@dimen/car_ui_toolbar_menu_item_icon_background_size"/>
-    <solid android:color="@color/car_ui_toolbar_menu_item_icon_background_color"/>
-</shape>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_alert_dialog_edit_text.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_alert_dialog_edit_text.xml
deleted file mode 100644
index 985b7d8..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_alert_dialog_edit_text.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
-    <com.android.car.ui.toolbar.CarUiEditText
-              android:id="@+id/textbox"
-              android:layout_width="match_parent"
-              android:layout_height="@dimen/car_ui_dialog_edittext_height"
-              android:layout_marginTop="@dimen/car_ui_dialog_edittext_margin_top"
-              android:layout_marginBottom="@dimen/car_ui_dialog_edittext_margin_bottom"
-              android:layout_marginStart="@dimen/car_ui_dialog_edittext_margin_start"
-              android:layout_marginEnd="@dimen/car_ui_dialog_edittext_margin_end"/>
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_base_layout.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_base_layout.xml
deleted file mode 100644
index cd73725..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_base_layout.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
-         first focusable view in the window automatically. Adding a FocusParkingView to the window
-         can fix this issue, because it can take focus, and it is transparent and its default focus
-         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
-         -->
-    <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-
-    <FrameLayout
-        android:id="@+id/car_ui_base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_base_layout_toolbar.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_base_layout_toolbar.xml
deleted file mode 100644
index 1c26e5d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_base_layout_toolbar.xml
+++ /dev/null
@@ -1,171 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:tag="CarUiBaseLayoutToolbar">
-
-    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
-         first focusable view in the window automatically. Adding a FocusParkingView to the window
-         can fix this issue, because it can take focus, and it is transparent and its default focus
-         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
-         -->
-    <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
-
-    <FrameLayout
-        android:id="@+id/car_ui_base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toTopOf="parent"/>
-
-    <com.android.car.ui.FocusArea
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/car_ui_toolbar_first_row_height">
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/car_ui_toolbar_background"
-            style="@style/Widget.CarUi.Toolbar.Container"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:tag="car_ui_top_inset"
-            app:layout_constraintTop_toTopOf="parent">
-            <com.android.car.ui.baselayout.ClickBlockingView
-                android:layout_width="0dp"
-                android:layout_height="0dp"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintTop_toTopOf="parent"
-                app:layout_constraintBottom_toBottomOf="parent"/>
-
-            <!-- The horizontal bias set to 0.0 here is so that when you set this view as GONE, it will
-                 be treated as if it's all the way to the left instead of centered in the margin -->
-            <FrameLayout
-                android:id="@+id/car_ui_toolbar_nav_icon_container"
-                style="@style/Widget.CarUi.Toolbar.NavIconContainer"
-                android:layout_width="@dimen/car_ui_toolbar_margin"
-                android:layout_height="0dp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintHorizontal_bias="0.0"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent">
-
-                <ImageView
-                    android:id="@+id/car_ui_toolbar_nav_icon"
-                    style="@style/Widget.CarUi.Toolbar.NavIcon"
-                    android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
-                    android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
-                    android:layout_gravity="center"
-                    android:scaleType="fitXY"/>
-
-                <ImageView
-                    android:id="@+id/car_ui_toolbar_logo"
-                    android:layout_width="@dimen/car_ui_toolbar_logo_size"
-                    android:layout_height="@dimen/car_ui_toolbar_logo_size"
-                    android:layout_gravity="center"
-                    android:scaleType="fitXY"/>
-            </FrameLayout>
-
-            <FrameLayout
-                android:id="@+id/car_ui_toolbar_title_logo_container"
-                style="@style/Widget.CarUi.Toolbar.LogoContainer"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toEndOf="@id/car_ui_toolbar_nav_icon_container"
-                app:layout_constraintTop_toTopOf="parent">
-
-                <ImageView
-                    android:id="@+id/car_ui_toolbar_title_logo"
-                    style="@style/Widget.CarUi.Toolbar.Logo"
-                    android:layout_width="@dimen/car_ui_toolbar_logo_size"
-                    android:layout_height="@dimen/car_ui_toolbar_logo_size"
-                    android:layout_gravity="center"
-                    android:scaleType="fitXY"/>
-            </FrameLayout>
-
-            <LinearLayout android:layout_height="wrap_content"
-                          android:layout_width="0dp"
-                          android:id="@+id/car_ui_toolbar_title_container"
-                          android:orientation="vertical"
-                          android:layout_marginStart="@dimen/car_ui_toolbar_title_margin_start"
-                          app:layout_goneMarginStart="@dimen/car_ui_toolbar_title_no_logo_margin_start"
-                          app:layout_constraintBottom_toBottomOf="parent"
-                          app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_menu_items_container"
-                          app:layout_constraintStart_toEndOf="@+id/car_ui_toolbar_title_logo_container"
-                          app:layout_constraintTop_toTopOf="parent">
-                <TextView android:id="@+id/car_ui_toolbar_title"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:singleLine="true"
-                          style="@style/Widget.CarUi.Toolbar.Title"/>
-                <TextView android:id="@+id/car_ui_toolbar_subtitle"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:visibility="gone"
-                          style="@style/Widget.CarUi.Toolbar.Subtitle"/>
-            </LinearLayout>
-
-            <com.android.car.ui.toolbar.TabLayout
-                android:id="@+id/car_ui_toolbar_tabs"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_menu_items_container"
-                app:layout_constraintHorizontal_bias="0.0"
-                app:layout_constraintStart_toEndOf="@+id/car_ui_toolbar_title_logo_container"
-                app:layout_constraintTop_toTopOf="parent"/>
-
-            <LinearLayout
-                android:id="@+id/car_ui_toolbar_menu_items_container"
-                style="@style/Widget.CarUi.Toolbar.MenuItem.Container"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:orientation="horizontal"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintTop_toTopOf="parent"/>
-
-            <FrameLayout
-                android:id="@+id/car_ui_toolbar_search_view_container"
-                android:layout_width="0dp"
-                android:layout_height="@dimen/car_ui_toolbar_search_height"
-                android:layout_marginStart="@dimen/car_ui_toolbar_title_margin_start"
-                app:layout_goneMarginStart="@dimen/car_ui_toolbar_title_no_logo_margin_start"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_menu_items_container"
-                app:layout_constraintStart_toEndOf="@+id/car_ui_toolbar_title_logo_container"
-                app:layout_constraintTop_toTopOf="parent"/>
-
-            <ProgressBar
-                android:id="@+id/car_ui_toolbar_progress_bar"
-                style="@style/Widget.CarUi.Toolbar.ProgressBar"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:indeterminate="true"
-                android:visibility="gone"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent"/>
-
-        </androidx.constraintlayout.widget.ConstraintLayout>
-    </com.android.car.ui.FocusArea>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_header_list_item.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_header_list_item.xml
deleted file mode 100644
index 6a81c96..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_header_list_item.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:background="@drawable/car_ui_list_header_background"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/car_ui_list_item_header_height">
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/car_ui_list_item_start_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_begin="@dimen/car_ui_list_item_header_start_inset" />
-
-    <TextView
-        android:id="@+id/car_ui_list_item_title"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/car_ui_header_list_item_text_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Header"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toTopOf="@+id/car_ui_list_item_body"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="@id/car_ui_list_item_start_guideline"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_chainStyle="packed" />
-
-    <TextView
-        android:id="@+id/car_ui_list_item_body"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/car_ui_list_item_text_no_icon_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="@id/car_ui_list_item_start_guideline"
-        app:layout_constraintTop_toBottomOf="@+id/car_ui_list_item_title" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml
deleted file mode 100644
index 9ea6697..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="horizontal">
-
-    <RelativeLayout
-        android:id="@+id/car_ui_ime_carboard_area"
-        android:layout_width="@dimen/car_ui_ime_wide_screen_keyboard_width"
-        android:layout_height="match_parent"
-        android:gravity="bottom"
-        android:paddingStart="@dimen/car_ui_ime_wide_screen_keyboard_area_padding_start"
-        android:paddingEnd="@dimen/car_ui_ime_wide_screen_keyboard_area_padding_end"
-        android:paddingBottom="@dimen/car_ui_ime_wide_screen_keyboard_area_padding_bottom"
-        android:layout_gravity="bottom"
-        android:background="@drawable/car_ui_ime_wide_screen_background">
-
-        <RelativeLayout
-            android:id="@id/car_ui_imeWideScreenInputArea"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/car_ui_ime_wide_screen_input_area_height"
-            android:layout_marginTop="@dimen/car_ui_ime_wide_screen_input_area_padding_top"
-            android:layout_alignParentTop="true">
-            <ImageView
-                android:id="@id/car_ui_closeKeyboard"
-                android:layout_width="@dimen/car_ui_primary_icon_size"
-                android:layout_height="@dimen/car_ui_primary_icon_size"
-                android:layout_centerVertical="true"
-                style="@style/Widget.CarUi.Toolbar.NavIcon"
-                android:layout_alignParentLeft="true"/>
-
-            <FrameLayout
-                android:id="@id/car_ui_fullscreenArea"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_centerVertical="true"
-                android:layout_toRightOf="@id/car_ui_closeKeyboard"
-                android:paddingLeft="@dimen/car_ui_ime_wide_screen_input_padding_start"
-                android:background="@drawable/car_ui_ime_wide_screen_input_area_background"
-                android:orientation="vertical">
-
-                <FrameLayout
-                    android:id="@id/car_ui_inputExtractEditTextContainer"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:layout_weight="1"
-                    android:scrollbars="vertical"
-                    android:gravity="left|center"
-                    android:backgroundTint="@drawable/car_ui_ime_wide_screen_input_area_tint_color"
-                    android:paddingEnd="@dimen/car_ui_ime_wide_screen_input_area_padding_end"
-                    android:minLines="1"
-                    android:inputType="text"/>
-
-                <RelativeLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:background="@android:color/transparent">
-                    <ImageView
-                        android:id="@id/car_ui_wideScreenExtractedTextIcon"
-                        android:layout_width="@dimen/car_ui_primary_icon_size"
-                        android:layout_height="@dimen/car_ui_primary_icon_size"
-                        android:gravity="center"
-                        android:layout_gravity="center"
-                        android:layout_alignParentLeft="true"
-                        android:layout_centerVertical="true"/>
-
-                    <ImageView
-                        android:id="@id/car_ui_wideScreenClearData"
-                        android:layout_width="@dimen/car_ui_primary_icon_size"
-                        android:layout_height="@dimen/car_ui_primary_icon_size"
-                        android:gravity="center"
-                        android:layout_gravity="center"
-                        android:background="@drawable/car_ui_icon_close"
-                        android:layout_alignParentRight="true"
-                        android:layout_centerVertical="true"/>
-
-                    <ImageView
-                        android:id="@id/car_ui_wideScreenError"
-                        android:layout_width="@dimen/car_ui_primary_icon_size"
-                        android:layout_height="@dimen/car_ui_primary_icon_size"
-                        android:gravity="center"
-                        android:layout_gravity="center"
-                        android:background="@drawable/car_ui_icon_error"
-                        android:layout_alignParentRight="true"
-                        android:layout_centerVertical="true"
-                        android:visibility="gone"/>
-                </RelativeLayout>
-
-            </FrameLayout>
-        </RelativeLayout>
-
-        <TextView
-            android:id="@id/car_ui_wideScreenErrorMessage"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_below="@id/car_ui_imeWideScreenInputArea"
-            android:paddingLeft="@dimen/car_ui_ime_wide_screen_error_text_padding_start"
-            android:textColor="@color/car_ui_ime_wide_screen_error_text_color"
-            android:visibility="gone"
-            android:textSize="@dimen/car_ui_ime_wide_screen_error_text_size"/>
-
-        <FrameLayout
-            android:id="@id/car_ui_wideScreenInputArea"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true">
-        </FrameLayout>
-    </RelativeLayout>
-
-    <View
-        android:layout_width="@dimen/car_ui_ime_wide_screen_divider_width"
-        android:layout_height="match_parent"
-        android:background="@color/car_ui_ime_wide_screen_divider_color"/>
-
-    <SurfaceView
-        android:id="@id/car_ui_ime_surface"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone"
-        android:focusable="false"
-        android:paddingTop="@dimen/car_ui_ime_wide_screen_input_area_padding_top"
-        android:paddingBottom="@dimen/car_ui_ime_wide_screen_keyboard_area_padding_bottom"
-        android:background="@drawable/car_ui_ime_wide_screen_content_area_background"/>
-
-    <RelativeLayout
-        android:id="@id/car_ui_contentAreaAutomotive"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone"
-        android:background="@drawable/car_ui_ime_wide_screen_no_content_background">
-        <com.android.car.ui.recyclerview.CarUiRecyclerView
-            android:id="@id/car_ui_wideScreenSearchResultList"
-            android:requiresFadingEdge="vertical"
-            android:paddingTop="@dimen/car_ui_ime_wide_screen_input_area_padding_top"
-            android:layout_width="match_parent"
-            android:visibility="gone"
-            android:layout_height="match_parent"/>
-        <TextView
-            android:id="@id/car_ui_wideScreenDescriptionTitle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_marginTop="@dimen/car_ui_ime_wide_screen_description_title_margin_top"
-            android:paddingLeft="@dimen/car_ui_ime_wide_screen_description_title_padding_left"
-            android:textColor="@color/car_ui_ime_wide_screen_description_title_color"
-            android:textSize="@dimen/car_ui_ime_wide_screen_description_title_text_size"
-            android:visibility="gone"/>
-        <TextView
-            android:id="@id/car_ui_wideScreenDescription"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/car_ui_wideScreenDescriptionTitle"
-            android:layout_alignParentLeft="true"
-            android:paddingLeft="@dimen/car_ui_ime_wide_screen_description_title_padding_left"
-            android:paddingTop="@dimen/car_ui_ime_wide_screen_description_padding_top"
-            android:textColor="@color/car_ui_ime_wide_screen_description_color"
-            android:textSize="@dimen/car_ui_ime_wide_screen_description_text_size"
-            android:visibility="gone"/>
-
-        <Button
-            android:id="@id/car_ui_inputExtractActionAutomotive"
-            android:layout_width="wrap_content"
-            android:layout_height="@dimen/car_ui_ime_wide_screen_action_button_height"
-            android:theme="@android:style/Theme.DeviceDefault"
-            android:textSize="@dimen/car_ui_ime_wide_screen_action_button_text_size"
-            android:layout_alignParentBottom="true"
-            android:visibility="gone"
-            android:layout_marginBottom="@dimen/car_ui_ime_wide_screen_action_button_margin_bottom"
-            android:layout_marginLeft="@dimen/car_ui_ime_wide_screen_action_button_margin_left"
-            android:layout_gravity="center"/>
-    </RelativeLayout>
-
-</LinearLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_item.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_item.xml
deleted file mode 100644
index 801f236..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_item.xml
+++ /dev/null
@@ -1,186 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:tag="carUiListItem"
-    android:minHeight="@dimen/car_ui_list_item_height">
-
-    <!-- The following touch interceptor views are sized to encompass the specific sub-sections of
-    the list item view to easily control the bounds of a background ripple effects. -->
-    <View
-        android:id="@+id/car_ui_list_item_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/car_ui_list_item_background"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <!-- This touch interceptor does not include the action container -->
-    <View
-        android:id="@+id/car_ui_list_item_reduced_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/car_ui_list_item_background"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/car_ui_list_item_start_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_begin="@dimen/car_ui_list_item_start_inset" />
-
-    <FrameLayout
-        android:id="@+id/car_ui_list_item_icon_container"
-        android:layout_width="@dimen/car_ui_list_item_icon_container_width"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="@+id/car_ui_list_item_start_guideline"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_icon"
-            android:layout_width="@dimen/car_ui_list_item_icon_size"
-            android:layout_height="@dimen/car_ui_list_item_icon_size"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_content_icon"
-            android:layout_width="@dimen/car_ui_list_item_content_icon_width"
-            android:layout_height="@dimen/car_ui_list_item_content_icon_height"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_avatar_icon"
-            android:background="@drawable/car_ui_list_item_avatar_icon_outline"
-            android:layout_width="@dimen/car_ui_list_item_avatar_icon_width"
-            android:layout_height="@dimen/car_ui_list_item_avatar_icon_height"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-    </FrameLayout>
-
-    <CarUiTextView
-        android:id="@+id/car_ui_list_item_title"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
-        android:singleLine="@bool/car_ui_list_item_single_line_title"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toTopOf="@+id/car_ui_list_item_body"
-        app:layout_constraintEnd_toStartOf="@+id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toEndOf="@+id/car_ui_list_item_icon_container"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_chainStyle="packed"
-        app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" />
-    <CarUiTextView
-        android:id="@+id/car_ui_list_item_body"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toEndOf="@+id/car_ui_list_item_icon_container"
-        app:layout_constraintTop_toBottomOf="@+id/car_ui_list_item_title"
-        app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" />
-
-    <!-- This touch interceptor is sized and positioned to encompass the action container   -->
-    <View
-        android:id="@+id/car_ui_list_item_action_container_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/car_ui_list_item_background"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintEnd_toEndOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toStartOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintTop_toTopOf="@id/car_ui_list_item_action_container" />
-
-    <FrameLayout
-        android:id="@+id/car_ui_list_item_action_container"
-        android:layout_width="wrap_content"
-        android:minWidth="@dimen/car_ui_list_item_icon_container_width"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="@+id/car_ui_list_item_end_guideline"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <View
-            android:id="@+id/car_ui_list_item_action_divider"
-            android:layout_width="@dimen/car_ui_list_item_action_divider_width"
-            android:layout_height="@dimen/car_ui_list_item_action_divider_height"
-            android:layout_gravity="start|center_vertical"
-            android:background="@drawable/car_ui_list_item_divider" />
-
-        <Switch
-            android:id="@+id/car_ui_list_item_switch_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <CheckBox
-            android:id="@+id/car_ui_list_item_checkbox_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <RadioButton
-            android:id="@+id/car_ui_list_item_radio_button_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_supplemental_icon"
-            android:layout_width="@dimen/car_ui_list_item_supplemental_icon_size"
-            android:layout_height="@dimen/car_ui_list_item_supplemental_icon_size"
-            android:layout_gravity="center"
-            android:scaleType="fitCenter" />
-    </FrameLayout>
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/car_ui_list_item_end_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_end="@dimen/car_ui_list_item_end_inset" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
-
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_item_compact.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_item_compact.xml
deleted file mode 100644
index 9d3c3a2..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_item_compact.xml
+++ /dev/null
@@ -1,186 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:tag="carUiListItem"
-    android:minHeight="@dimen/car_ui_list_item_height">
-
-    <!-- The following touch interceptor views are sized to encompass the specific sub-sections of
-    the list item view to easily control the bounds of a background ripple effects. -->
-    <View
-        android:id="@+id/car_ui_list_item_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/car_ui_list_item_background"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <!-- This touch interceptor does not include the action container -->
-    <View
-        android:id="@+id/car_ui_list_item_reduced_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/car_ui_list_item_background"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/car_ui_list_item_start_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_begin="@dimen/car_ui_list_item_start_inset" />
-
-    <FrameLayout
-        android:id="@+id/car_ui_list_item_icon_container"
-        android:layout_width="@dimen/car_ui_list_item_icon_container_width"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="@+id/car_ui_list_item_start_guideline"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_icon"
-            android:layout_width="@dimen/car_ui_list_item_icon_size"
-            android:layout_height="@dimen/car_ui_list_item_icon_size"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_content_icon"
-            android:layout_width="@dimen/car_ui_list_item_content_icon_width"
-            android:layout_height="@dimen/car_ui_list_item_content_icon_height"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_avatar_icon"
-            android:background="@drawable/car_ui_list_item_avatar_icon_outline"
-            android:layout_width="@dimen/car_ui_list_item_avatar_icon_width"
-            android:layout_height="@dimen/car_ui_list_item_avatar_icon_height"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-    </FrameLayout>
-
-    <CarUiTextView
-        android:id="@+id/car_ui_list_item_title"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
-        android:singleLine="@bool/car_ui_list_item_single_line_title"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toTopOf="@+id/car_ui_list_item_body"
-        app:layout_constraintEnd_toStartOf="@+id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toEndOf="@+id/car_ui_list_item_icon_container"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_chainStyle="packed"
-        app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" />
-    <CarUiTextView
-        android:id="@+id/car_ui_list_item_body"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toEndOf="@+id/car_ui_list_item_icon_container"
-        app:layout_constraintTop_toBottomOf="@+id/car_ui_list_item_title"
-        app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" />
-
-    <!-- This touch interceptor is sized and positioned to encompass the action container   -->
-    <View
-        android:id="@+id/car_ui_list_item_action_container_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/car_ui_list_item_background"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintEnd_toEndOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintStart_toStartOf="@id/car_ui_list_item_action_container"
-        app:layout_constraintTop_toTopOf="@id/car_ui_list_item_action_container" />
-
-    <FrameLayout
-        android:id="@+id/car_ui_list_item_action_container"
-        android:layout_width="wrap_content"
-        android:minWidth="@dimen/car_ui_list_item_icon_container_width"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="@+id/car_ui_list_item_end_guideline"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <View
-            android:id="@+id/car_ui_list_item_action_divider"
-            android:layout_width="@dimen/car_ui_list_item_action_divider_width"
-            android:layout_height="@dimen/car_ui_list_item_action_divider_height"
-            android:layout_gravity="start|center_vertical"
-            android:background="@drawable/car_ui_list_item_divider" />
-
-        <Switch
-            android:id="@+id/car_ui_list_item_switch_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <CheckBox
-            android:id="@+id/car_ui_list_item_checkbox_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <RadioButton
-            android:id="@+id/car_ui_list_item_radio_button_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <ImageView
-            android:id="@+id/car_ui_list_item_supplemental_icon"
-            android:layout_width="@dimen/car_ui_list_item_supplemental_icon_size"
-            android:layout_height="@dimen/car_ui_list_item_supplemental_icon_size"
-            android:layout_gravity="center"
-            android:scaleType="fitCenter" />
-    </FrameLayout>
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/car_ui_list_item_end_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_end="@dimen/car_ui_list_item_end_inset" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
-
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_limiting_message.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_limiting_message.xml
deleted file mode 100644
index a9f9b9b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_limiting_message.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="144dp"
-    android:gravity="center"
-    android:paddingTop="16dp"
-    android:paddingBottom="32dp"
->
-    <TextView
-        android:id="@+id/car_ui_list_limiting_message"
-        android:layout_width="wrap_content"
-        android:layout_height="96dp"
-        android:layout_gravity="center_horizontal"
-        android:gravity="center"
-        android:paddingStart="48dp"
-        android:paddingEnd="48dp"
-        android:drawableStart="@drawable/car_ui_icon_lock"
-        android:drawablePadding="24dp"
-        android:textColor="?android:attr/textColorPrimary"
-        android:textAllCaps="false"
-        android:singleLine="true"
-        android:background="@drawable/car_ui_list_limiting_message_background"
-    />
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_preference.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_preference.xml
deleted file mode 100644
index d56fb38..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_preference.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/car_ui_activity_background">
-
-    <com.android.car.ui.FocusArea
-        android:id="@+id/car_ui_focus_area"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-        <com.android.car.ui.recyclerview.CarUiRecyclerView
-            android:id="@+id/list"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:tag="carUiPreferenceRecyclerView"
-            app:enableDivider="true" />
-    </com.android.car.ui.FocusArea>
-
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference.xml
deleted file mode 100644
index ef60b83..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<com.android.car.ui.uxr.DrawableStateRelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?android:attr/selectableItemBackground"
-    android:clipToPadding="false"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:tag="carUiPreference"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart">
-
-    <com.android.car.ui.uxr.DrawableStateImageView
-        android:id="@android:id/icon"
-        android:layout_width="@dimen/car_ui_preference_icon_size"
-        android:layout_height="@dimen/car_ui_preference_icon_size"
-        android:layout_alignParentStart="true"
-        android:layout_centerVertical="true"
-        android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
-        android:layout_marginEnd="@dimen/car_ui_preference_icon_margin_end"
-        android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
-        android:scaleType="fitCenter"
-        style="@style/Preference.CarUi.Icon"/>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_centerVertical="true"
-        android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
-        android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
-        android:layout_toEndOf="@android:id/icon"
-        android:layout_toStartOf="@android:id/widget_frame"
-        android:orientation="vertical">
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/summary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"/>
-
-    </LinearLayout>
-
-    <!-- Preference should place its actual preference widget here. -->
-    <FrameLayout
-        android:id="@android:id/widget_frame"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_centerVertical="true"/>
-
-</com.android.car.ui.uxr.DrawableStateRelativeLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_dialog_edittext.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_dialog_edittext.xml
deleted file mode 100644
index 86474a9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_dialog_edittext.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginTop="@dimen/car_ui_preference_edit_text_dialog_margin_top"
-    android:layout_marginBottom="@dimen/car_ui_preference_edit_text_dialog_margin_bottom"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@android:id/message"
-        style="@style/TextAppearance.CarUi.PreferenceEditTextDialogMessage"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/car_ui_preference_edit_text_dialog_message_margin_bottom"
-        android:layout_marginStart="@dimen/car_ui_preference_edit_text_dialog_message_margin_start"
-        android:layout_marginEnd="@dimen/car_ui_preference_edit_text_dialog_message_margin_end"
-        android:visibility="gone"/>
-
-    <com.android.car.ui.toolbar.CarUiEditText
-        android:id="@android:id/edit"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="@dimen/car_ui_preference_edit_text_dialog_text_margin_end"
-        android:layout_marginStart="@dimen/car_ui_preference_edit_text_dialog_text_margin_start"/>
-
-</LinearLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_fragment.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_fragment.xml
deleted file mode 100644
index 53fc089..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_fragment.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/car_ui_activity_background">
-
-    <FrameLayout
-        android:id="@android:id/list_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-        <com.android.car.ui.FocusArea
-            android:id="@+id/car_ui_focus_area"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
-            <com.android.car.ui.recyclerview.CarUiRecyclerView
-                android:id="@+id/recycler_view"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:tag="carUiPreferenceRecyclerView"
-                app:enableDivider="true"/>
-        </com.android.car.ui.FocusArea>
-    </FrameLayout>
-</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_icon.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_icon.xml
deleted file mode 100644
index c5c4fee..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_icon.xml
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:tag="carUiPreference">
-
-    <com.android.car.ui.uxr.DrawableStateConstraintLayout
-        android:id="@+id/car_ui_first_action_container"
-        android:layout_height="0dp"
-        android:layout_width="0dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/car_ui_second_action_container"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-        <com.android.car.ui.uxr.DrawableStateImageView
-            style="@style/Preference.CarUi.Icon"
-            android:id="@android:id/icon"
-            android:layout_width="@dimen/car_ui_preference_icon_size"
-            android:layout_height="@dimen/car_ui_preference_icon_size"
-            android:scaleType="fitCenter"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toStartOf="parent"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/title"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toTopOf="@android:id/summary"
-            app:layout_constraintVertical_chainStyle="packed"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/summary"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"
-            android:maxLines="2"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@android:id/title"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </com.android.car.ui.uxr.DrawableStateConstraintLayout>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/car_ui_second_action_container"
-        android:layout_height="0dp"
-        android:layout_width="wrap_content"
-        app:layout_constraintStart_toEndOf="@id/car_ui_first_action_container"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-
-        <View
-            android:id="@+id/car_ui_divider"
-            android:layout_width="@dimen/car_ui_divider_width"
-            android:layout_height="0dp"
-            android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
-            android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/car_ui_secondary_action"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            style="@style/Preference.CarUi.Divider"/>
-
-        <com.android.car.ui.uxr.DrawableStateFrameLayout
-            android:id="@+id/car_ui_secondary_action"
-            android:layout_width="?android:attr/listPreferredItemHeightSmall"
-            android:layout_height="match_parent"
-            android:background="?android:attr/selectableItemBackground"
-            app:layout_constraintStart_toEndOf="@id/car_ui_divider"
-            app:layout_constraintEnd_toStartOf="@android:id/widget_frame"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent">
-            <com.android.car.ui.uxr.DrawableStateImageView
-                android:id="@+id/car_ui_secondary_action_concrete"
-                android:layout_width="48dp"
-                android:layout_height="48dp"
-                android:layout_gravity="center"
-                android:tintMode="src_in"
-                android:tint="@color/car_ui_text_color_primary"/>
-        </com.android.car.ui.uxr.DrawableStateFrameLayout>
-
-        <!-- The widget frame is required for androidx preferences, but we won't use it. -->
-        <FrameLayout
-            android:id="@android:id/widget_frame"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_switch.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_switch.xml
deleted file mode 100644
index 3d7f6fa..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_switch.xml
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:tag="carUiPreference">
-
-    <com.android.car.ui.uxr.DrawableStateConstraintLayout
-        android:id="@+id/car_ui_first_action_container"
-        android:layout_height="0dp"
-        android:layout_width="0dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/car_ui_second_action_container"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-        <com.android.car.ui.uxr.DrawableStateImageView
-            style="@style/Preference.CarUi.Icon"
-            android:id="@android:id/icon"
-            android:layout_width="@dimen/car_ui_preference_icon_size"
-            android:layout_height="@dimen/car_ui_preference_icon_size"
-            android:scaleType="fitCenter"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toStartOf="parent"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/title"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toTopOf="@android:id/summary"
-            app:layout_constraintVertical_chainStyle="packed"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/summary"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"
-            android:maxLines="2"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@android:id/title"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </com.android.car.ui.uxr.DrawableStateConstraintLayout>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/car_ui_second_action_container"
-        android:layout_height="0dp"
-        android:layout_width="wrap_content"
-        app:layout_constraintStart_toEndOf="@id/car_ui_first_action_container"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-
-        <View
-            android:id="@+id/car_ui_divider"
-            android:layout_width="@dimen/car_ui_divider_width"
-            android:layout_height="0dp"
-            android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
-            android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/car_ui_secondary_action"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            style="@style/Preference.CarUi.Divider"/>
-
-        <com.android.car.ui.uxr.DrawableStateFrameLayout
-            android:id="@+id/car_ui_secondary_action"
-            android:layout_width="?android:attr/listPreferredItemHeightSmall"
-            android:layout_height="match_parent"
-            android:background="?android:attr/selectableItemBackground"
-            app:layout_constraintStart_toEndOf="@id/car_ui_divider"
-            app:layout_constraintEnd_toStartOf="@android:id/widget_frame"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent">
-            <com.android.car.ui.uxr.DrawableStateSwitch
-                android:id="@+id/car_ui_secondary_action_concrete"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:clickable="false"
-                android:focusable="false"/>
-        </com.android.car.ui.uxr.DrawableStateFrameLayout>
-
-        <!-- The widget frame is required for androidx preferences, but we won't use it. -->
-        <FrameLayout
-            android:id="@android:id/widget_frame"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_text.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_text.xml
deleted file mode 100644
index 6f568c0..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_text.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:tag="carUiPreference">
-
-    <com.android.car.ui.uxr.DrawableStateConstraintLayout
-        android:id="@+id/car_ui_first_action_container"
-        android:layout_height="0dp"
-        android:layout_width="0dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/car_ui_second_action_container"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-        <com.android.car.ui.uxr.DrawableStateImageView
-            style="@style/Preference.CarUi.Icon"
-            android:id="@android:id/icon"
-            android:layout_width="@dimen/car_ui_preference_icon_size"
-            android:layout_height="@dimen/car_ui_preference_icon_size"
-            android:scaleType="fitCenter"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toStartOf="parent"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/title"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toTopOf="@android:id/summary"
-            app:layout_constraintVertical_chainStyle="packed"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/summary"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"
-            android:maxLines="2"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@android:id/title"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </com.android.car.ui.uxr.DrawableStateConstraintLayout>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/car_ui_second_action_container"
-        android:layout_height="0dp"
-        android:layout_width="wrap_content"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        app:layout_constraintStart_toEndOf="@id/car_ui_first_action_container"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-
-        <View
-            android:id="@+id/car_ui_divider"
-            android:layout_width="@dimen/car_ui_divider_width"
-            android:layout_height="0dp"
-            android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
-            android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
-            android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/car_ui_secondary_action"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            style="@style/Preference.CarUi.Divider"/>
-
-        <com.android.car.ui.uxr.DrawableStateButton
-            android:id="@+id/car_ui_secondary_action"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:layout_constraintStart_toEndOf="@id/car_ui_divider"
-            app:layout_constraintEnd_toStartOf="@android:id/widget_frame"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-
-        <!-- The widget frame is required for androidx preferences, but we won't use it. -->
-        <FrameLayout
-            android:id="@android:id/widget_frame"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_text_borderless.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_text_borderless.xml
deleted file mode 100644
index d329d98..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_two_action_text_borderless.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:tag="carUiPreference">
-
-    <com.android.car.ui.uxr.DrawableStateConstraintLayout
-        android:id="@+id/car_ui_first_action_container"
-        android:layout_height="0dp"
-        android:layout_width="0dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/car_ui_second_action_container"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-        <com.android.car.ui.uxr.DrawableStateImageView
-            style="@style/Preference.CarUi.Icon"
-            android:id="@android:id/icon"
-            android:layout_width="@dimen/car_ui_preference_icon_size"
-            android:layout_height="@dimen/car_ui_preference_icon_size"
-            android:scaleType="fitCenter"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toStartOf="parent"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/title"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toTopOf="@android:id/summary"
-            app:layout_constraintVertical_chainStyle="packed"/>
-
-        <com.android.car.ui.uxr.DrawableStateTextView
-            android:id="@android:id/summary"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/car_ui_preference_icon_margin_end"
-            app:layout_goneMarginStart="0dp"
-            android:textAlignment="viewStart"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"
-            android:maxLines="2"
-            app:layout_constraintStart_toEndOf="@android:id/icon"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@android:id/title"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </com.android.car.ui.uxr.DrawableStateConstraintLayout>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/car_ui_second_action_container"
-        android:layout_height="0dp"
-        android:layout_width="wrap_content"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        app:layout_constraintStart_toEndOf="@id/car_ui_first_action_container"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent">
-
-        <View
-            android:id="@+id/car_ui_divider"
-            android:layout_width="@dimen/car_ui_divider_width"
-            android:layout_height="0dp"
-            android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
-            android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
-            android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/car_ui_secondary_action"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            style="@style/Preference.CarUi.Divider"/>
-
-        <com.android.car.ui.uxr.DrawableStateButton
-            android:id="@+id/car_ui_secondary_action"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            style="?android:attr/borderlessButtonStyle"
-            app:layout_constraintStart_toEndOf="@id/car_ui_divider"
-            app:layout_constraintEnd_toStartOf="@android:id/widget_frame"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-
-        <!-- The widget frame is required for androidx preferences, but we won't use it. -->
-        <FrameLayout
-            android:id="@android:id/widget_frame"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recycler_view.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recycler_view.xml
deleted file mode 100644
index 6e12515..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recycler_view.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <com.android.car.ui.recyclerview.CarUiRecyclerViewContainer
-        android:id="@+id/car_ui_recycler_view"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingStart="@dimen/car_ui_scrollbar_margin"
-        android:paddingEnd="@dimen/car_ui_scrollbar_margin"
-        android:tag="carUiRecyclerView" />
-
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="left" >
-        <include layout="@layout/car_ui_recyclerview_scrollbar"/>
-    </FrameLayout>
-</merge>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recyclerview_scrollbar.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recyclerview_scrollbar.xml
deleted file mode 100644
index d5e626a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recyclerview_scrollbar.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="@dimen/car_ui_scrollbar_container_width"
-    android:layout_height="match_parent"
-    android:id="@+id/car_ui_scroll_bar"
-    android:gravity="center">
-
-    <ImageView
-        android:id="@+id/car_ui_scrollbar_page_up"
-        android:layout_width="@dimen/car_ui_scrollbar_button_size"
-        android:layout_height="@dimen/car_ui_scrollbar_button_size"
-        android:background="@drawable/car_ui_recyclerview_button_ripple_background"
-        android:contentDescription="@string/car_ui_scrollbar_page_up_button"
-        android:focusable="false"
-        android:hapticFeedbackEnabled="false"
-        android:src="@drawable/car_ui_recyclerview_ic_up"
-        android:scaleType="centerInside"
-        android:layout_marginTop="15dp"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"/>
-
-    <!-- View height is dynamically calculated during layout. -->
-    <View
-        android:id="@+id/car_ui_scrollbar_thumb"
-        android:layout_width="@dimen/car_ui_scrollbar_thumb_width"
-        android:layout_height="0dp"
-        android:layout_gravity="center_horizontal"
-        android:background="@drawable/car_ui_recyclerview_scrollbar_thumb"
-        app:layout_constraintTop_toTopOf="@+id/car_ui_scrollbar_track"
-        app:layout_constraintBottom_toBottomOf="@+id/car_ui_scrollbar_track"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"/>
-
-    <View
-        android:id="@+id/car_ui_scrollbar_track"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_marginTop="@dimen/car_ui_scrollbar_separator_margin"
-        android:layout_marginBottom="@dimen/car_ui_scrollbar_separator_margin"
-        app:layout_constraintTop_toBottomOf="@+id/car_ui_scrollbar_page_up"
-        app:layout_constraintBottom_toTopOf="@+id/car_ui_scrollbar_page_down"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
-
-    <ImageView
-        android:id="@+id/car_ui_scrollbar_page_down"
-        android:layout_width="@dimen/car_ui_scrollbar_button_size"
-        android:layout_height="@dimen/car_ui_scrollbar_button_size"
-        android:background="@drawable/car_ui_recyclerview_button_ripple_background"
-        android:contentDescription="@string/car_ui_scrollbar_page_down_button"
-        android:focusable="false"
-        android:hapticFeedbackEnabled="false"
-        android:src="@drawable/car_ui_recyclerview_ic_down"
-        android:scaleType="centerInside"
-        android:layout_marginBottom="15dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_search_view.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_search_view.xml
deleted file mode 100644
index 6a3d9ec..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_search_view.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<merge
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <com.android.car.ui.toolbar.CarUiEditText
-        android:id="@+id/car_ui_toolbar_search_bar"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        android:hint="@string/car_ui_toolbar_default_search_hint"
-        android:textColorHint="@color/car_ui_toolbar_search_hint_text_color"
-        android:inputType="text"
-        android:singleLine="true"
-        android:imeOptions="actionSearch"
-        style="@style/Widget.CarUi.Toolbar.Search.EditText"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
-
-    <!-- This constraintLayout is to provide a background for the ripples to draw on, so
-         they don't get drawn underneath the EditText's background -->
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@android:color/transparent">
-        <FrameLayout
-            android:layout_width="@dimen/car_ui_toolbar_search_search_icon_container_width"
-            android:layout_height="match_parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toStartOf="parent">
-            <ImageView
-                android:id="@+id/car_ui_toolbar_search_icon"
-                android:layout_width="@dimen/car_ui_toolbar_search_search_icon_size"
-                android:layout_height="@dimen/car_ui_toolbar_search_search_icon_size"
-                android:layout_gravity="center"
-                android:src="@drawable/car_ui_toolbar_search_search_icon"
-                android:scaleType="fitXY"
-                style="@style/Widget.CarUi.Toolbar.Search.SearchIcon"/>
-        </FrameLayout>
-
-        <FrameLayout
-            android:id="@+id/car_ui_toolbar_search_close"
-            android:layout_width="@dimen/car_ui_toolbar_search_close_icon_container_width"
-            android:layout_height="match_parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent">
-            <ImageView
-                android:layout_width="@dimen/car_ui_toolbar_search_close_icon_size"
-                android:layout_height="@dimen/car_ui_toolbar_search_close_icon_size"
-                android:layout_gravity="center"
-                android:src="@drawable/car_ui_toolbar_search_close_icon"
-                android:scaleType="fitXY"
-                style="@style/Widget.CarUi.Toolbar.Search.CloseIcon"/>
-        </FrameLayout>
-    </androidx.constraintlayout.widget.ConstraintLayout>
-</merge>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_two_action_preference.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_two_action_preference.xml
deleted file mode 100644
index 3f3ffb0..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_two_action_preference.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2018 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="@android:color/transparent"
-    android:gravity="center_vertical"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall">
-    <com.android.car.ui.uxr.DrawableStateLinearLayout
-        android:id="@+id/car_ui_preference_container_without_widget"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:background="?android:attr/selectableItemBackground"
-        android:clipToPadding="false"
-        android:gravity="start|center_vertical"
-        android:paddingBottom="@dimen/car_ui_preference_content_margin_bottom"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-        android:paddingTop="@dimen/car_ui_preference_content_margin_top">
-        <androidx.preference.internal.PreferenceImageView
-            android:id="@android:id/icon"
-            android:layout_width="@dimen/car_ui_preference_icon_size"
-            android:layout_height="@dimen/car_ui_preference_icon_size"
-            android:layout_marginEnd="@dimen/car_ui_preference_icon_margin_end"/>
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_centerVertical="true"
-            android:orientation="vertical">
-            <com.android.car.ui.uxr.DrawableStateTextView
-                android:id="@android:id/title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:ellipsize="end"
-                android:singleLine="true"
-                android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"/>
-            <com.android.car.ui.uxr.DrawableStateTextView
-                android:id="@android:id/summary"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"/>
-        </LinearLayout>
-    </com.android.car.ui.uxr.DrawableStateLinearLayout>
-    <LinearLayout
-        android:id="@+id/action_widget_container"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent">
-        <View
-            android:layout_width="@dimen/car_ui_divider_width"
-            android:layout_height="match_parent"
-            android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
-            android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
-            style="@style/Preference.CarUi.Divider"/>
-        <!-- Preference should place its actual preference widget here. -->
-        <com.android.car.ui.uxr.DrawableStateFrameLayout
-            android:id="@android:id/widget_frame"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:background="?android:attr/selectableItemBackground"
-            android:minWidth="?android:attr/listPreferredItemHeightSmall"
-            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-            android:paddingStart="?android:attr/listPreferredItemPaddingStart"/>
-    </LinearLayout>
-</LinearLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/raw/car_ui_keep.xml b/car-ui-lib/car-ui-lib/src/main/res/raw/car_ui_keep.xml
deleted file mode 100644
index fca5f28..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/raw/car_ui_keep.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources xmlns:tools="http://schemas.android.com/tools"
-    tools:keep="
-               @attr/CarUi*,
-               @attr/carUi*,
-               @attr/state_ux_restricted,
-               @attr/layout_optimizationLevel,
-               @attr/constraintSet,
-               @attr/barrierDirection,
-               @attr/constraint_referenced_ids,
-               @attr/chainUseRtl,
-               @attr/title,
-               @attr/layout_constraintGuide_begin,
-               @attr/layout_constraintGuide_end,
-               @attr/layout_constraintGuide_percent,
-               @attr/layout_constraintLeft_toLeftOf,
-               @attr/layout_constraintLeft_toRightOf,
-               @attr/layout_constraintRight_toLeftOf,
-               @attr/layout_constraintRight_toRightOf,
-               @attr/layout_constraintTop_toTopOf,
-               @attr/layout_constraintTop_toBottomOf,
-               @attr/layout_constraintBottom_toTopOf,
-               @attr/layout_constraintBottom_toBottomOf,
-               @attr/layout_constraintBaseline_toBaselineOf,
-               @attr/layout_constraintStart_toEndOf,
-               @attr/layout_constraintStart_toStartOf,
-               @attr/layout_constraintEnd_toStartOf,
-               @attr/layout_constraintEnd_toEndOf,
-               @attr/layout_goneMarginLeft,
-               @attr/layout_goneMarginTop,
-               @attr/layout_goneMarginRight,
-               @attr/layout_goneMarginBottom,
-               @attr/layout_goneMarginStart,
-               @attr/layout_goneMarginEnd,
-               @attr/layout_constraintHorizontal_bias,
-               @attr/layout_constraintVertical_bias,
-               @attr/layout_constraintWidth_default,
-               @attr/layout_constraintHeight_default,
-               @attr/layout_constraintWidth_min,
-               @attr/layout_constraintWidth_max,
-               @attr/layout_constraintWidth_percent,
-               @attr/layout_constraintHeight_min,
-               @attr/layout_constraintHeight_max,
-               @attr/layout_constraintHeight_percent,
-               @attr/layout_constraintLeft_creator,
-               @attr/layout_constraintTop_creator,
-               @attr/layout_constraintRight_creator,
-               @attr/layout_constraintBottom_creator,
-               @attr/layout_constraintBaseline_creator,
-               @attr/layout_constraintDimensionRatio,
-               @attr/layout_constraintHorizontal_weight,
-               @attr/layout_constraintVertical_weight,
-               @attr/layout_constraintHorizontal_chainStyle,
-               @attr/layout_constraintVertical_chainStyle,
-               @attr/layout_editor_absoluteX,
-               @attr/layout_editor_absoluteY,
-               @bool/car_ui_*,
-               @color/car_ui_*,
-               @dimen/car_ui_*,
-               @dimen/wrap_content,
-               @drawable/car_ui_*,
-               @font/car_ui_*,
-               @id/action_container,
-               @id/action_container_touch_interceptor,
-               @id/action_divider,
-               @id/action_widget_container,
-               @id/avatar_icon,
-               @id/body,
-               @id/car_ui_*,
-               @id/checkbox_widget,
-               @id/container,
-               @id/content_icon,
-               @id/icon,
-               @id/icon_container,
-               @id/list,
-               @id/nested_recycler_view_layout,
-               @id/radio_button,
-               @id/radio_button_widget,
-               @id/recycler_view,
-               @id/reduced_touch_interceptor,
-               @id/search,
-               @id/seek_bar,
-               @id/seek_bar_text_left,
-               @id/seek_bar_text_right,
-               @id/seek_bar_text_top,
-               @id/seekbar,
-               @id/seekbar_value,
-               @id/spinner,
-               @id/supplemental_icon,
-               @id/switch_widget,
-               @id/textbox,
-               @id/title,
-               @id/title_template,
-               @id/toolbar,
-               @id/touch_interceptor,
-               @integer/car_ui_*,
-               @layout/car_ui_*,
-               @raw/car_ui_*,
-               @string/car_ui_*,
-               @style/*CarUi*,
-                "
-  />
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-af/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-af/strings.xml
deleted file mode 100644
index 2c00927..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-af/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Soek …"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Rollees af"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Rollees op"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Terug"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Soek"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Instellings"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Oorloop"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Aan"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Af"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Maak toe"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Rollees word beperk terwyl jy bestuur"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Kenmerk is nie beskikbaar terwyl jy bestuur nie"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-am/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-am/strings.xml
deleted file mode 100644
index 0558e81..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-am/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ይፈልጉ…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"ወደ ታች ይሸብልሉ"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ወደ ላይ ይሸብልሉ"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ተመለስ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ፈልግ"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ቅንብሮች"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ትርፍ ፍሰት"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"አብራ"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ቅናሽ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"ዝጋ"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"እየነዱ ማሸብለል ተገድቧል"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"እየነዱ ሳለ ባህሪው አይገኝም"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ar/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ar/strings.xml
deleted file mode 100644
index 4879cb5..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ar/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"بحث…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"التمرير للأسفل"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"التمرير للأعلى"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"رجوع"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"بحث"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"إعدادات"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"القائمة الكاملة"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"مفعّل"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"غير مفعَّل"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"إغلاق"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"هناك حد أقصى للتمرير على الشاشة أثناء القيادة."</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"لا تتوفَّر هذه الميزة أثناء القيادة."</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-as/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-as/strings.xml
deleted file mode 100644
index 060f64e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-as/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"সন্ধান কৰক…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"তললৈ স্ক্ৰ’ল কৰক"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ওপৰলৈ স্ক্ৰ’ল কৰক"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"উভতি যাওক"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"সন্ধান কৰক"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ছেটিংসমূহ"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"অভাৰফ্ল’"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"অন আছে"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"অফ আছে"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"বন্ধ কৰক"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"গাড়ী চলাই থকা সময়ত স্ক্ৰ’ল কৰাটো সীমিত কৰা হৈছে"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"গাড়ী চলাই থকা সময়ত এই সুবিধাটো উপলব্ধ নহয়"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-az/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-az/strings.xml
deleted file mode 100644
index 9f0472e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-az/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Axtarış…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Aşağı sürüşdürün"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Yuxarı sürüşdürün"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Geri"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Axtarış"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Ayarlar"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Kənara çıxma"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Aktiv"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Deaktiv"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Qapadın"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Sürüşdürmə avtomobil idarə edərkən məhdudlaşdırılır"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funksiya avtomobil idarə edərkən əlçatan deyil"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-b+sr+Latn/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 2584a57..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Pretražite…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Pomerite nadole"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Pomerite nagore"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Nazad"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Pretraži"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Podešavanja"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Preklopni meni"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Uključeno"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Isključeno"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Zatvori"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Pomeranje je ograničeno tokom vožnje"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkcija nije dostupna tokom vožnje"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-be/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-be/strings.xml
deleted file mode 100644
index c66577d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-be/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Пошук…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Прагартаць уніз"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Прагартаць уверх"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Назад"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Пошук"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Налады"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Дадатковае меню"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Уключана"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Выключана"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Закрыць"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Функцыя прагортвання абмежаваная, калі аўтамабіль рухаецца"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Функцыя недаступная, калі аўтамабіль рухаецца"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-bg/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-bg/strings.xml
deleted file mode 100644
index 64d1e0a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-bg/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Търсете…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Превъртане надолу"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Превъртане нагоре"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Назад"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Търсене"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Настройки"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Препълване"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Вкл."</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Изкл."</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Затваряне"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Превъртането е ограничено при шофиране"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Функцията не е налице по време на шофиране"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-bn/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-bn/strings.xml
deleted file mode 100644
index 7f09486..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-bn/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"সার্চ করুন…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"নিচের দিকে স্ক্রল করুন"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"উপরের দিকে স্ক্রল করুন"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ফিরুন"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"সার্চ মেনু"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"সেটিংস"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ওভারফ্লো মেনু"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"চালু"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"বন্ধ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"বন্ধ করুন"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"গাড়ি চালানোর সময় স্ক্রলিং ফিচার সীমিতভাবে ব্যবহার করা যাবে"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"গাড়ি চালানোর সময় এই ফিচার কাজ করবে না"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-bs/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-bs/strings.xml
deleted file mode 100644
index 7295dac..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-bs/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Pretražite…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Klizanje prema dolje"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Klizanje prema gore"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Nazad"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Pretraživanje"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Postavke"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Preklopni meni"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Uključeno"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Isključeno"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Zatvori"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Klizanje je ograničeno tokom vožnje"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkcija nije dostupna tokom vožnje"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ca/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ca/strings.xml
deleted file mode 100644
index a19a663..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ca/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Cerca…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Desplaça cap avall"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Desplaça cap amunt"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Enrere"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Cerca"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Configuració"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Menú addicional"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Activat"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Desactivat"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Tanca"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"El desplaçament està limitat mentre condueixes"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Aquesta funció no està disponible mentre condueixes"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-cs/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-cs/strings.xml
deleted file mode 100644
index 16ad755..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-cs/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Vyhledat…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Posunout dolů"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Posunout nahoru"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Zpět"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Hledat"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Nastavení"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Rozbalovací nabídka"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Zap"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Vyp"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Zavřít"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Posouvání zobrazení je při řízení omezeno"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkce při řízení není dostupná"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-da/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-da/strings.xml
deleted file mode 100644
index 80d4a64..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-da/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Søg…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Rul ned"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Rul op"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Tilbage"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Søg"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Indstillinger"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overløb"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Til"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Fra"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Luk"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Rullefunktionen er begrænset under kørsel"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funktionen er ikke tilgængelig, mens du kører"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-de/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-de/strings.xml
deleted file mode 100644
index 8a76bd3..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-de/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Suchen…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Nach unten scrollen"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Nach oben scrollen"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Zurück"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Suchen"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Einstellungen"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Dreipunkt-Menü"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"An"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Aus"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Schließen"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scrollen während der Fahrt eingeschränkt"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funktion während der Fahrt nicht verfügbar"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-el/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-el/strings.xml
deleted file mode 100644
index 1819ec2..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-el/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Αναζήτηση…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Κύλιση προς τα κάτω"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Κύλιση προς τα επάνω"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Πίσω"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Αναζήτηση"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Ρυθμίσεις"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Υπερχείλιση"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Ενεργό"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Ανενεργή"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Κλείσιμο"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Η κύλιση είναι περιορισμένη κατά τη διάρκεια της οδήγησης."</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Η λειτουργία δεν διατίθεται κατά τη διάρκεια της οδήγησης."</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-en-rAU/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-en-rAU/strings.xml
deleted file mode 100644
index fb25c85..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Search…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Scroll down"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Scroll up"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Back"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Search"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Settings"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overflow"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"On"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Off"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Close"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scrolling limited while driving"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Feature not available while driving"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-en-rCA/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-en-rCA/strings.xml
deleted file mode 100644
index fb25c85..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Search…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Scroll down"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Scroll up"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Back"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Search"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Settings"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overflow"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"On"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Off"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Close"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scrolling limited while driving"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Feature not available while driving"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-en-rGB/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-en-rGB/strings.xml
deleted file mode 100644
index fb25c85..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Search…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Scroll down"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Scroll up"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Back"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Search"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Settings"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overflow"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"On"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Off"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Close"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scrolling limited while driving"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Feature not available while driving"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-en-rIN/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-en-rIN/strings.xml
deleted file mode 100644
index fb25c85..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Search…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Scroll down"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Scroll up"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Back"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Search"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Settings"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overflow"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"On"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Off"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Close"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scrolling limited while driving"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Feature not available while driving"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-en-rXC/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-en-rXC/strings.xml
deleted file mode 100644
index 82c6ca1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‎Search…‎‏‎‎‏‎"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎Scroll down‎‏‎‎‏‎"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎Scroll up‎‏‎‎‏‎"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‎Back‎‏‎‎‏‎"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎Search‎‏‎‎‏‎"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎Settings‎‏‎‎‏‎"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎Overflow‎‏‎‎‏‎"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎On‎‏‎‎‏‎"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎Off‎‏‎‎‏‎"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎Close‎‏‎‎‏‎"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎Scrolling limited while driving‎‏‎‎‏‎"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‎‎Feature not available while driving‎‏‎‎‏‎"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-es-rUS/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-es-rUS/strings.xml
deleted file mode 100644
index 4904ad4..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Buscar…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Desplazamiento hacia abajo"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Desplazamiento hacia arriba"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Atrás"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Buscar"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Configuración"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Ampliado"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Sí"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"No"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Cerrar"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"La función de desplazamiento se limita al conducir"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Esta función no está disponible mientras conduces"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-es/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-es/strings.xml
deleted file mode 100644
index 171134a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-es/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Realiza una búsqueda…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Desplazarse hacia abajo"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Desplazarse hacia arriba"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Atrás"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Buscar"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Ajustes"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Menú adicional"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Activado"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Desactivado"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Cerrar"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Desplazamiento limitado mientras conduces"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Función no disponible mientras conduces"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-et/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-et/strings.xml
deleted file mode 100644
index bb5092c..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-et/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Otsing …"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Keri alla"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Keri üles"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Tagasi"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Otsi"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Seaded"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Ületäide"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Sees"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Väljas"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Sule"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Kerimine on sõitmise ajal piiratud"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funktsioon pole sõidu ajal saadaval"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-eu/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-eu/strings.xml
deleted file mode 100644
index af4e757..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-eu/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Bilatu…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Egin behera"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Egin gora"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Atzera"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Bilaketa"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Ezarpenak"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Luzapena"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Aktibatuta"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Desaktibatuta"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Itxi"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Gora edo behera egiteko eginbidea mugatuta dago gidatu bitartean"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Eginbide hau ezin da erabili gidatu bitartean"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-fa/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-fa/strings.xml
deleted file mode 100644
index 1ddc1df..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-fa/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"جستجو…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"پیمایش به پایین"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"پیمایش به بالا"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"برگشت"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"جستجو"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"تنظیمات"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"لبریزشده"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"روشن"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"خاموش"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"بستن"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"پیمایش درحین رانندگی محدود شده است"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"این ویژگی هنگام رانندگی در دسترس نیست"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-fi/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-fi/strings.xml
deleted file mode 100644
index 31c1e62..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-fi/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Hae…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Vieritä alas"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Vieritä ylös"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Takaisin"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Haku"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Asetukset"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Ylivuoto"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Päällä"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Pois"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Sulje"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Vierittämistä rajoitettu ajon aikana"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Ominaisuus ei ole käytettävissä ajon aikana"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-fr-rCA/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-fr-rCA/strings.xml
deleted file mode 100644
index a894032..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Rechercher…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Faire défiler vers le bas"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Faire défiler vers le haut"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Retour"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Rechercher"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Paramètres"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Menu déroulant"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Activé"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Désactivé"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Fermer"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Le défilement de l\'écran est limité durant la conduite"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Cette fonctionnalité n\'est pas accessible durant la conduite"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-fr/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-fr/strings.xml
deleted file mode 100644
index 8776859..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-fr/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Rechercher…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Défiler vers le bas"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Défiler vers le haut"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Retour"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Rechercher"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Paramètres"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Menu à développer"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Activé"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Désactivé"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Fermer"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Défilement limité lorsque vous conduisez"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Fonctionnalité non disponible lorsque vous conduisez"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-gl/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-gl/strings.xml
deleted file mode 100644
index 7882edf..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-gl/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Busca…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Desprazarse cara abaixo"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Desprazarse cara arriba"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Atrás"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Buscar"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Configuración"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Elemento do menú adicional"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Si"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Non"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Pechar"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"O desprazamento está limitado mentres conduces"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Esta función non está dispoñible mentres conduces"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-gu/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-gu/strings.xml
deleted file mode 100644
index 25d6fbc..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-gu/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"શોધો…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"નીચે સ્ક્રોલ કરો"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ઉપર સ્ક્રોલ કરો"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"પાછળ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"શોધો"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"સેટિંગ"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ઓવરફ્લો"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ચાલુ"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"બંધ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"બંધ કરો"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ડ્રાઇવિંગ કરતી વખતે સ્ક્રોલ કરવું મર્યાદિત છે"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ડ્રાઇવિંગ કરતી વખતે આ સુવિધા ઉપલબ્ધ રહેશે નહીં"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-hi/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-hi/strings.xml
deleted file mode 100644
index 21aaf3c..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-hi/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"खोजें…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"नीचे की ओर स्क्रोल करें"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ऊपर की ओर स्क्रोल करें"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"वापस जाएं"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"खोजें"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"सेटिंग"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ओवरफ़्लो मेन्यू"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"चालू है"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"बंद है"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"बंद करें"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"गाड़ी चलाते समय इससे ज़्यादा स्क्रोल नहीं कर सकते"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"गाड़ी चलाते समय इस सुविधा का इस्तेमाल नहीं किया जा सकता"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-hr/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-hr/strings.xml
deleted file mode 100644
index 1bc74b5..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-hr/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Pretražite…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Pomak prema dolje"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Pomak prema gore"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Natrag"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Pretraži"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Postavke"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Dodatno"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Uključeno"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Isključeno"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Zatvori"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Pomicanje je ograničeno tijekom vožnje"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Značajka nije dostupna tijekom vožnje"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-hu/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-hu/strings.xml
deleted file mode 100644
index 912809b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-hu/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Keresés…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Görgetés lefelé"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Görgetés felfelé"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Vissza"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Keresés"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Beállítások"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"További elemeket tartalmazó menü"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Be"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Ki"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Bezárás"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Vezetés közben a görgetés korlátozott"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Vezetés közben nem áll rendelkezésre a funkció"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-hy/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-hy/strings.xml
deleted file mode 100644
index bed2d2c..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-hy/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Որոնում…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Ոլորել վար"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Ոլորել վեր"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Հետ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Որոնել"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Կարգավորումներ"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Լրացուցիչ ընտրացանկ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Միացված է"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Անջատված է"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Փակել"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Վարելու ընթացքում ոլորումը սահմանափակված է"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Վարելու ընթացքում գործառույթը հասանելի չէ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-in/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-in/strings.xml
deleted file mode 100644
index b3d7063..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-in/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Telusuri…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Scroll ke bawah"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Scroll ke atas"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Kembali"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Penelusuran"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Setelan"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Tambahan"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Aktif"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Nonaktif"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Tutup"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Men-scroll dibatasi saat mengemudi"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Fitur tidak tersedia saat mengemudi"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-is/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-is/strings.xml
deleted file mode 100644
index 61d2891..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-is/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Leita…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Fletta niður"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Fletta upp"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Til baka"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Leit"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Stillingar"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Yfirflæði"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Kveikt"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Slökkt"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Loka"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Fletting er takmörkuð meðan á akstri stendur"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Þessi eiginleiki er ekki í boði meðan á akstri stendur"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-it/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-it/strings.xml
deleted file mode 100644
index 2cb178a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-it/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Cerca…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Scorri verso il basso"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Scorri verso l\'alto"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Indietro"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Cerca"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Impostazioni"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Extra"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"On"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Off"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Chiudi"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scorrimento limitato durante la guida"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funzionalità non disponibile durante la guida"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-iw/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-iw/strings.xml
deleted file mode 100644
index 746dfbc..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-iw/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"חיפוש…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"גלילה למטה"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"גלילה למעלה"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"חזרה"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"חיפוש"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"הגדרות"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"אפשרויות נוספות"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"פועל"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"כבוי"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"סגירה"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"הגלילה מוגבלת בזמן הנהיגה"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"התכונה לא זמינה בזמן הנהיגה"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ja/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ja/strings.xml
deleted file mode 100644
index 7d8eac1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ja/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"検索…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"下にスクロール"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"上にスクロール"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"戻る"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"検索"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"設定"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"オーバーフロー"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ON"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"OFF"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"閉じる"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"運転中のスクロール操作は制限されています"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"この機能は運転中は利用できません"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ka/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ka/strings.xml
deleted file mode 100644
index 1350fe8..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ka/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ძიება…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"ქვემოთ გადაადგილება"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ზემოთ გადაადგილება"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"უკან"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ძიება"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"პარამეტრები"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"გადავსება"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ჩართულია"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"გამორთულია"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"დახურვა"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"გადაადგილება შეზღუდულია მანქანის მართვისას"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ფუნქცია მიუწვდომელია მანქანის მართვისას"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-kk/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-kk/strings.xml
deleted file mode 100644
index ab8a259..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-kk/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Іздеу…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Төмен айналдыру"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Жоғары айналдыру"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Артқа"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Іздеу"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Параметрлер"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Қосымша мәзір"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Қосулы"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Өшірулі"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Жабу"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Көлік жүргізу кезінде айналдыру мүмкіндігі шектеледі."</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Көлік жүргізу кезінде бұл функция жұмыс істемейді."</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-km/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-km/strings.xml
deleted file mode 100644
index 17d3293..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-km/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ស្វែងរក…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"រំកិលចុះក្រោម"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"រំកិល​​ឡើង​លើ"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ថយក្រោយ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ស្វែងរក"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ការកំណត់"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ម៉ឺនុយបន្ថែម"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"បើក"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"បិទ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"បិទ"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ការរំកិលបានកំណត់ ខណៈពេលកំពុង​បើកបរ"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"មិនអាច​ប្រើមុខងារ​នេះបានទេ ខណៈពេល​កំពុង​បើកបរ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-kn/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-kn/strings.xml
deleted file mode 100644
index 3d312d1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-kn/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ಹುಡುಕಿ…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"ಕೆಳಗೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ಮೇಲೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ಹಿಂದಕ್ಕೆ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ಹುಡುಕಾಟ"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ಓವರ್‌ಫ್ಲೋ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ಆನ್ ಆಗಿದೆ"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ಆಫ್ ಆಗಿದೆ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"ಮುಚ್ಚಿ"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ಡ್ರೈವ್ ಮಾಡುವಾಗ ಸ್ಕ್ರಾಲ್ ಮಾಡುವಿಕೆ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಸೀಮಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ಡ್ರೈವ್ ಮಾಡುವಾಗ ಈ ವೈಶಿಷ್ಟ್ಯ ಲಭ್ಯವಿಲ್ಲ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ko/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ko/strings.xml
deleted file mode 100644
index d992a45..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ko/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"검색…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"아래로 스크롤"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"위로 스크롤"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"뒤로"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"검색"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"설정"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"더보기"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"사용 설정됨"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"사용 중지됨"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"닫기"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"운전 중에는 스크롤이 제한됨"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"운전 중에 사용할 수 없는 기능입니다."</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ky/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ky/strings.xml
deleted file mode 100644
index 7340674..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ky/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Издөө…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Төмөн сыдыруу"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Жогору сыдыруу"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Артка"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Издөө"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Жөндөөлөр"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Кошумча меню"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Күйүк"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Өчүк"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Жабуу"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Унаа айдаганда сыдыруу чектелет"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Унаа айдаганда бул функция жеткиликтүү эмес"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-lo/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-lo/strings.xml
deleted file mode 100644
index 0422da3..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-lo/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ຊອກຫາ…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"ເລື່ອນລົງ"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ເລື່ອນຂຶ້ນ"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ກັບຄືນ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ຊອກຫາ"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ການຕັ້ງຄ່າ"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ລົ້ນ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ເປີດ"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ປິດ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"ປິດ"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ຈຳກັດການເລື່ອນໃນຂະນະທີ່ຂັບລົດ"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ຄຸນສົມບັດບໍ່ສາມາດໃຊ້ໄດ້ໃນເວລາຂັບລົດ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-lt/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-lt/strings.xml
deleted file mode 100644
index 09539cc..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-lt/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Ieškoti…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Slinkti žemyn"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Slinkti aukštyn"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Atgal"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Paieška"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Nustatymai"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Perpildymas"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Įjungta"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Išjungta"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Uždaryti"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Slinkimas apribotas vairuojant"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkcija nepasiekiama vairuojant"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-lv/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-lv/strings.xml
deleted file mode 100644
index 1df9318..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-lv/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Meklēt…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Ritināt uz leju"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Ritināt uz augšu"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Atpakaļ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Meklēšana"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Iestatījumi"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Pārpilde"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Ieslēgta"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Izslēgta"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Aizvērt"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Ritināšana ir ierobežota braukšanas laikā."</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkcija nav pieejama braukšanas laikā."</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-mk/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-mk/strings.xml
deleted file mode 100644
index 413e340..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-mk/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Пребарувајте…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Оди надолу"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Оди нагоре"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Назад"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Пребарување"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Поставки"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Прелевање"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Вклучено"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Исклучено"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Затвори"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Лизгањето е ограничено при возење"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Функцијата не е достапна при возење"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ml/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ml/strings.xml
deleted file mode 100644
index f588c60..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ml/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"തിരയുക…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"താഴോട്ട് സ്‌ക്രോൾ ചെയ്യുക"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"മുകളിലോട്ട് സ്‌ക്രോൾ ചെയ്യുക"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"മടങ്ങുക"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"തിരയുക"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ക്രമീകരണം"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ഓവർഫ്ലോ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ഓണാണ്"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ഓഫാണ്"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"അടയ്‌ക്കുക"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ഡ്രൈവ് ചെയ്യുമ്പോൾ സ്ക്രോൾ ചെയ്യൽ പരിമിതപ്പെടുത്തിയിരിക്കുന്നു"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ഡ്രൈവ് ചെയ്യുമ്പോൾ ഫീച്ചർ ലഭ്യമല്ല"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-mn/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-mn/strings.xml
deleted file mode 100644
index db34cd7..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-mn/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Хайх..."</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Доош гүйлгэх"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Дээш гүйлгэх"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Буцах"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Хайлт"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Тохиргоо"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Халих"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Асаалттай"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Унтраалттай"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Хаах"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Жолоо барьж байх үед гүйлгэхийг хязгаарласан"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Жолоо барьж байх үед онцлог боломжгүй"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-mr/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-mr/strings.xml
deleted file mode 100644
index c8f7a42..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-mr/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"शोधा…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"खाली स्क्रोल करा"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"वर स्क्रोल करा"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"मागे जा"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Search"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"सेटिंग्ज"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ओव्हरफ्लो"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"सुरू आहे"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"बंद आहे"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"बंद करा"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ड्राइव्ह करताना स्क्रोलिंग मर्यादित केली आहे"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ड्राइव्ह करताना वैशिष्ट्य उपलब्ध नाही"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ms/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ms/strings.xml
deleted file mode 100644
index 7ea4fbb..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ms/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Cari…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Tatal ke bawah"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Tatal ke atas"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Kembali"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Cari"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Tetapan"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Limpahan"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Hidup"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Mati"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Tutup"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Penatalan terhad semasa memandu"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Ciri tidak tersedia semasa anda memandu"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-my/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-my/strings.xml
deleted file mode 100644
index 55f37b1..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-my/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ရှာဖွေရန်…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"အောက်သို့ လှိမ့်ရန်"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"အပေါ်သို့ လှိမ့်ရန်"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"နောက်သို့"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ရှာဖွေခြင်း"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ဆက်တင်များ"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"အပို"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ဖွင့်ထားသည်"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ပိတ်ထားသည်"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"ပိတ်ရန်"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ယာဉ်မောင်းနေစဉ် အပေါ်အောက်ရွှေ့ခြင်းကို ကန့်သတ်ထားသည်"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ကားမောင်းနေစဉ် ဝန်ဆောင်မှု မရနိုင်ပါ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-nb/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-nb/strings.xml
deleted file mode 100644
index d490393..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-nb/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Søk"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Rull ned"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Rull opp"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Tilbake"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Søk"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Innstillinger"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overflyt"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"På"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Av"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Lukk"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Rullefunksjonen er begrenset mens du kjører"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funksjonen er ikke tilgjengelig når du kjører"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ne/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ne/strings.xml
deleted file mode 100644
index 90124de..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ne/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"खोज्नुहोस्…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"तलतिर स्क्रोल गर्नुहोस्"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"माथितिर स्क्रोल गर्नु…"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"पछाडि"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"खोज्नुहोस्"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"सेटिङ"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ओभरफ्लो"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"सुचारू छ"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"बन्द छ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"बन्द गर्नुहोस्"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"सवारी साधन चलाइरहेका बेला योभन्दा बढी स्क्रोल गर्न पाइँदैन"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"सवारी साधन चलाइरहेका बेला यो सुविधा उपलब्ध हुँदैन"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-nl/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-nl/strings.xml
deleted file mode 100644
index fe36ab0..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-nl/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Zoeken…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Omlaag scrollen"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Omhoog scrollen"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Terug"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Zoeken"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Instellingen"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overloop"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Aan"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Uit"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Sluiten"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scrollen is beperkt tijdens het rijden"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Functie niet beschikbaar tijdens het rijden"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-or/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-or/strings.xml
deleted file mode 100644
index d84ae51..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-or/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ସନ୍ଧାନ କରନ୍ତୁ…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"ତଳକୁ ସ୍କ୍ରୋଲ୍ କରନ୍ତୁ"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ଉପରକୁ ସ୍କ୍ରୋଲ୍ କରନ୍ତୁ"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ପଛକୁ ଫେରନ୍ତୁ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ସେଟିଂସ୍"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ଓଭରଫ୍ଲୋ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ଚାଲୁ ଅଛି"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ବନ୍ଦ ଅଛି"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"ବନ୍ଦ କରନ୍ତୁ"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ଗାଡ଼ି ଚଲାଇବା ସମୟରେ ସ୍କ୍ରୋଲିଂ ସୀମିତ ଅଟେ"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ଗାଡ଼ି ଚଲାଇବା ସମୟରେ ଫିଚର୍ ଉପଲବ୍ଧ ହେବ ନାହିଁ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-pa/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-pa/strings.xml
deleted file mode 100644
index 576c6d4..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-pa/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ਖੋਜ…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"ਹੇਠਾਂ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ਉੱਪਰ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ਪਿੱਛੇ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ਖੋਜ"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ਸੈਟਿੰਗਾਂ"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ਓਵਰਫ਼ਲੋ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ਚਾਲੂ"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ਬੰਦ"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"ਬੰਦ ਕਰੋ"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ਚਲਦੀ ਗੱਡੀ ਵਿੱਚ ਸਕ੍ਰੋਲ ਕਰਨ ਨੂੰ ਸੀਮਤ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ਚੱਲਦੀ ਗੱਡੀ ਵਿੱਚ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-pl/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-pl/strings.xml
deleted file mode 100644
index 85df36d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-pl/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Szukaj…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Przewiń w dół"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Przewiń w górę"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Wstecz"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Szukaj"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Ustawienia"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Rozszerzone menu"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Wł."</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Wył."</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Zamknij"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Podczas jazdy można przewijać tylko w ograniczonym zakresie"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkcja niedostępna podczas jazdy"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-port/bools.xml b/car-ui-lib/car-ui-lib/src/main/res/values-port/bools.xml
deleted file mode 100644
index 136b3e9..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-port/bools.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<resources>
-   <!-- Toolbar -->
-
-   <!-- Normally no resources should live in any other resource folder than default configuration. -->
-   <!-- Because OEMs will have to always add them to their RROs. -->
-   <!-- But we can't remove this resource from -port folder, because it was used as part of an earlier release -->
-   <!-- Whether tabs should use flex layout or not -->
-   <bool name="car_ui_toolbar_tab_flexible_layout">true</bool>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-pt-rPT/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-pt-rPT/strings.xml
deleted file mode 100644
index ad969e8..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Pesquisar…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Deslocar para baixo"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Deslocar para cima"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Anterior"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Pesquisar"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Definições"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Menu adicional"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Ativado"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Desativado"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Fechar"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Deslocamento limitado durante a condução"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funcionalidade não disponível durante a condução."</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-pt/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-pt/strings.xml
deleted file mode 100644
index 98a3746..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-pt/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Pesquisar…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Rolar para baixo"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Rolar para cima"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Voltar"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Pesquisa"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Configurações"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Menu flutuante"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Ativada"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Desativada"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Fechar"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"O recurso de rolagem fica limitado enquanto você dirige"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Recurso indisponível enquanto você dirige"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ro/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ro/strings.xml
deleted file mode 100644
index 3433253..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ro/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Căutați…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Derulați în jos"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Derulați în sus"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Înapoi"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Căutați"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Setări"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Suplimentar"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Activat"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Dezactivat"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Închideți"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Derularea este restricționată în timp ce conduceți"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funcția nu este disponibilă când conduceți"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ru/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ru/strings.xml
deleted file mode 100644
index 50c7efd..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ru/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Поиск…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Прокрутить вниз"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Прокрутить вверх"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Назад"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Поиск"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Настройки"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Дополнительное меню"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Включено"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Выключено"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Закрыть"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Функция прокручивания ограничена во время вождения."</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Функция недоступна во время вождения."</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-si/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-si/strings.xml
deleted file mode 100644
index 3693869..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-si/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"සොයන්න…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"පහළට අනුචලනය කරන්න"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"ඉහළට අනුචලනය කරන්න"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"ආපසු"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"සෙවීම"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"සැකසීම්"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ඉතිරියනය"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ක්‍රියාත්මකයි"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ක්‍රියාවිරහිතයි"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"වසන්න"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"රිය පදවන අතරතුර සීමිත අනුචලනය"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"රිය පදවන අතරේ විශේෂාංගය නොමැත"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-sk/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-sk/strings.xml
deleted file mode 100644
index a9c0565..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-sk/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Vyhľadať…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Posunúť nadol"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Posunúť nahor"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Späť"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Hľadať"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Nastavenia"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Rozšírená ponuka"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Zap."</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Vyp."</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Zavrieť"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Posúvanie zobrazenia je počas jazdy obmedzené"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkcia nie je k dispozícii počas jazdy"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-sl/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-sl/strings.xml
deleted file mode 100644
index ac0940f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-sl/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Iskanje …"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Pomik navzdol"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Pomik navzgor"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Nazaj"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Išči"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Nastavitve"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Element menija z dodatnimi elementi"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Vklopljeno"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Izklopljeno"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Zapri"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Pomikanje je med vožnjo omejeno"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funkcija med vožnjo ni na voljo"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-sq/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-sq/strings.xml
deleted file mode 100644
index 9208197..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-sq/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Kërko…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Lëviz poshtë"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Lëviz lart"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Pas"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Kërko"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Cilësimet"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Tejkalo"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Aktiv"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Joaktiv"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Mbyll"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Lëvizja është e kufizuar gjatë drejtimit të makinës"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Veçoria nuk ofrohet gjatë drejtimit të makinës"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-sr/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-sr/strings.xml
deleted file mode 100644
index 6a6fb9b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-sr/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Претражите…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Померите надоле"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Померите нагоре"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Назад"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Претражи"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Подешавања"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Преклопни мени"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Укључено"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Искључено"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Затвори"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Померање је ограничено током вожње"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Функција није доступна током вожње"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-sv/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-sv/strings.xml
deleted file mode 100644
index e14b299..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-sv/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Sök …"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Scrolla nedåt"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Scrolla uppåt"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Tillbaka"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Sök"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Inställningar"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Fler menyalternativ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"På"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Av"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Stäng"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Scrollning begränsas när du kör"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Funktionen är inte tillgänglig när du kör"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-sw/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-sw/strings.xml
deleted file mode 100644
index 3d6ed8a..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-sw/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Tafuta…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Sogeza chini"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Sogeza juu"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Nyuma"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Tafuta"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Mipangilio"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Vipengee vya ziada"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Imewashwa"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Imezimwa"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Funga"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Umedhibitiwa kusogeza unapoendesha gari"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Kipengele hakipatikani unapoendesha gari"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ta/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ta/strings.xml
deleted file mode 100644
index abd4b98..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ta/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"தேடுக…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"கீழே செல்லும்"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"மேலே செல்லும்"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"பின்செல்வதற்கான பட்டன்"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"தேடு"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"அமைப்புகள்"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"ஓவர்ஃப்லோ"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ஆன்"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ஆஃப்"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"மூடுக"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"வாகனம் ஓட்டிக் கொண்டிருப்பதனால் இதற்குமேல் ஸ்க்ரோல் செய்ய முடியாது"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"வாகனம் ஓட்டும்போது இந்த அம்சத்தைப் பயன்படுத்த இயலாது"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-te/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-te/strings.xml
deleted file mode 100644
index e3422b8..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-te/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"వెతకండి…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"కిందికి స్క్రోల్ చేయండి"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"పైకి స్క్రోల్ చేయండి"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"వెనుకకు"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"శోధన"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"సెట్టింగ్‌లు"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"అతివ్యాప్తి అంశాలు"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"ఆన్‌లో ఉంది"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ఆఫ్‌లో ఉంది"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"మూసివేయండి"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"డ్రైవింగ్ చేస్తున్నప్పుడు స్క్రోలింగ్ పరిమితంగా ఉంటుంది"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"డ్రైవింగ్ చేస్తున్నప్పుడు ఈ ఫీచర్ అందుబాటులో ఉండదు"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-th/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-th/strings.xml
deleted file mode 100644
index 837ff9c..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-th/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"ค้นหา…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"เลื่อนลง"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"เลื่อนขึ้น"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"กลับ"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"ค้นหา"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"การตั้งค่า"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"รายการเพิ่มเติม"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"เปิด"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"ปิด"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"ปิด"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"การเลื่อนถูกจำกัดไม่ให้ใช้งานขณะขับรถ"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ฟีเจอร์ไม่พร้อมใช้งานขณะขับรถ"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-tl/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-tl/strings.xml
deleted file mode 100644
index 3a8e981..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-tl/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Maghanap…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Mag-scroll pababa"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Mag-scroll pataas"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Bumalik"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Paghahanap"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Mga Setting"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Overflow"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"I-on"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"I-off"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Isara"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Limitado ang pag-scroll habang nagmamaneho"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Hindi available ang feature habang nagmamaneho"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-tr/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-tr/strings.xml
deleted file mode 100644
index f9e923f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-tr/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Ara…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Aşağı kaydır"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Yukarı kaydır"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Geri"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Ara"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Ayarlar"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Taşma"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Açık"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Kapalı"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Kapat"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Sürüş sırasında ekran kaydırma işlevi sınırlandırılmıştır"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Sürüş sırasında bu özellik kullanılamaz"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-uk/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-uk/strings.xml
deleted file mode 100644
index 0ecec7e..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-uk/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Пошук…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Прокрутити вниз"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Прокрутити вгору"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Назад"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Пошук"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Налаштування"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Додаткове меню"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Увімкнено"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Вимкнено"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Закрити"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Прокручування обмежено під час водіння"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Функція недоступна під час руху автомобіля"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-ur/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-ur/strings.xml
deleted file mode 100644
index 23b9033..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-ur/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"تلاش کریں…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"نیچے اسکرول کریں"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"اوپر اسکرول کریں"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"پیچھے"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"تلاش کریں"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"ترتیبات"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"اوورفلو"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"آن ہے"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"آف ہے"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"بند کریں"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"ڈرائیونگ کے دوران اسکرولنگ محدود ہے"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"ڈرائیونگ کے دوران یہ خصوصیت دستیاب نہیں ہے"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-uz/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-uz/strings.xml
deleted file mode 100644
index 9735f60..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-uz/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Qidirish…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Pastga surish"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Tepaga surish"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Orqaga"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Qidiruv"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Sozlamalar"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Kengaytirilgan"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Yoniq"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Yoqilmagan"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Yopish"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Avtomobilda harakatlanayotganda aylantirish funksiyasi cheklangan"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Avtomobilda harakatlanayotganda bu funksiya ishlamaydi"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-vi/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-vi/strings.xml
deleted file mode 100644
index d0ebb04..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-vi/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Tìm kiếm…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Cuộn xuống"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Cuộn lên"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Quay lại"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Tìm kiếm"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Cài đặt"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Trình đơn mục bổ sung"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Đang bật"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Đang tắt"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Đóng"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Tính năng cuộn bị hạn chế khi đang lái xe"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Bạn không sử dụng được tính năng này khi đang lái xe"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-zh-rCN/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 7c5a5b0..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"搜索…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"向下滚动"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"向上滚动"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"返回"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"搜索"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"设置"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"溢出菜单"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"开启"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"关闭"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"关闭"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"驾车时滚动操作受限"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"驾车时无法使用此功能"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-zh-rHK/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 2bd14e7..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"搜尋…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"向下捲動"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"向上捲動"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"返回"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"搜尋"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"設定"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"展開式選單"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"已開啟"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"已關閉"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"關閉"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"捲動功能在駕駛時受限制"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"無法在駕駛時使用此功能"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-zh-rTW/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 1fc26f4..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"搜尋…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"向下捲動"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"向上捲動"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"返回"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"搜尋"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"設定"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"溢位"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"開啟"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"關閉"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"關閉"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"系統會限制開車時的捲動操作"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"開車時無法使用這項功能"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values-zu/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values-zu/strings.xml
deleted file mode 100644
index 8955377..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values-zu/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_ui_toolbar_default_search_hint" msgid="8339474149462104372">"Sesha…"</string>
-    <string name="car_ui_scrollbar_page_down_button" msgid="746830252244551947">"Skrolela phansi"</string>
-    <string name="car_ui_scrollbar_page_up_button" msgid="965431866383176249">"Skrolela phezulu"</string>
-    <string name="car_ui_toolbar_nav_icon_content_description" msgid="6116610935599234725">"Emuva"</string>
-    <string name="car_ui_toolbar_menu_item_search_title" msgid="2988075382498202155">"Sesha"</string>
-    <string name="car_ui_toolbar_menu_item_settings_title" msgid="5206858558664840197">"Izilungiselelo"</string>
-    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="9132512843297732890">"Ukuphuphuma"</string>
-    <string name="car_ui_preference_switch_on" msgid="2091385466752081649">"Vuliwe"</string>
-    <string name="car_ui_preference_switch_off" msgid="511096411523593697">"Valiwe"</string>
-    <string name="car_ui_alert_dialog_default_button" msgid="399078418913970003">"Vala"</string>
-    <string name="car_ui_scrolling_limited_message" msgid="5978003166159186378">"Ukuskrola kukhawulelwe uma ushayela"</string>
-    <string name="car_ui_restricted_while_driving" msgid="7490306547860308268">"Isici asitholakali ngenkathi ushayela"</string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/attrs.xml b/car-ui-lib/car-ui-lib/src/main/res/values/attrs.xml
deleted file mode 100644
index adb1d56..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,188 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-    <!-- Global theme options for CarUi -->
-    <declare-styleable name="CarUi">
-        <!-- When set to true, the window decor will contain an OEM-customizable layout -->
-        <attr name="carUiBaseLayout" format="boolean"/>
-        <!-- When set to true, a CarUi Toolbar will be provided in the window decor -->
-        <attr name="carUiToolbar" format="boolean"/>
-    </declare-styleable>
-
-    <declare-styleable name="CarUiToolbar">
-        <!-- Title of the toolbar, only displayed in certain conditions -->
-        <attr name="title" format="string"/>
-        <!-- Logo drawable for the toolbar. Appears when there's no back/close button shown -->
-        <attr name="logo" format="reference"/>
-        <!-- Hint for the search bar in the toolbar -->
-        <attr name="searchHint" format="string"/>
-        <!-- Whether or not to show the MenuItems while searching. Default false. -->
-        <attr name="showMenuItemsWhileSearching" format="boolean"/>
-        <!-- Initial state of the toolbar. See the Toolbar.State enum for more information -->
-        <attr name="car_ui_state" format="enum">
-            <enum name="home" value="0"/>
-            <enum name="subpage" value="1"/>
-            <enum name="search" value="2"/>
-        </attr>
-        <!-- Whether or not the toolbar should have a background. Default true. -->
-        <attr name="showBackground" format="boolean"/>
-        <!-- Mode of the navigation button See the Toolbar.NavButtonMode enum for more information -->
-        <attr name="car_ui_navButtonMode" format="enum">
-            <enum name="back" value="0"/>
-            <enum name="close" value="1"/>
-            <enum name="down" value="2"/>
-        </attr>
-        <!-- XML resource of MenuItems. See Toolbar.setMenuItems(int) for more information. -->
-        <attr name="menuItems" format="reference"/>
-        <!-- Whether or not to show tabs in the SUBPAGE state. Default false -->
-        <attr name="showTabsInSubpage" format="boolean"/>
-    </declare-styleable>
-
-    <declare-styleable name="CarUiToolbarMenuItem">
-        <!-- Id of MenuItem, used to differentiate them -->
-        <attr name="id" format="reference"/>
-        <!-- Show/hide the MenuItem -->
-        <attr name="visible" format="boolean"/>
-        <!-- Set this to true to make a search MenuItem. This will override every other property except id, visible, and onclick. -->
-        <attr name="search" format="boolean"/>
-        <!-- Set this to true to make a settings MenuItem. This will override every other property except id, visible, and onclick. -->
-        <attr name="settings" format="boolean"/>
-        <!-- Title -->
-        <attr name="title"/>
-        <!-- Icon -->
-        <attr name="icon" format="reference"/>
-        <!-- True to tint the icon to a consistent color. Default true, all the other booleans default to false -->
-        <attr name="tinted" format="boolean"/>
-        <!-- Show both the icon and title at the same time -->
-        <attr name="showIconAndTitle" format="boolean"/>
-        <!-- True if this MenuItem should be a switch -->
-        <attr name="checkable" format="boolean"/>
-        <!-- Whether the switch should be checked or not. Setting this implies checkable=true -->
-        <attr name="checked" format="boolean"/>
-        <!-- True if this MenuItem should be activatable, in which case it will visually toggle states when clicked -->
-        <attr name="activatable" format="boolean"/>
-        <!-- Whether the MenuItem starts activated. Setting this implies activatable=true -->
-        <attr name="activated" format="boolean"/>
-        <!-- How to display the MenuItem. "always" means always show it on the toolbar, "never" means never show it on the toolbar and instead show it in the overflow menu -->
-        <attr name="displayBehavior" format="enum">
-            <enum name="always" value="0"/>
-            <enum name="never" value="1"/>
-        </attr>
-        <!-- Ux restrictions required to interact with this MenuItem -->
-        <attr name="uxRestrictions">
-            <!-- Values are copied from android.car.drivingstate.CarUxRestrictions. Note:
-            UX_RESTRICTIONS_BASELINE is not allowed here because it's useless and confusing. -->
-            <flag name="UX_RESTRICTIONS_NO_DIALPAD" value="1"/>
-            <flag name="UX_RESTRICTIONS_NO_FILTERING" value="2"/>
-            <flag name="UX_RESTRICTIONS_LIMIT_STRING_LENGTH" value="4"/>
-            <flag name="UX_RESTRICTIONS_NO_KEYBOARD" value="8"/>
-            <flag name="UX_RESTRICTIONS_NO_VIDEO" value="16"/>
-            <flag name="UX_RESTRICTIONS_LIMIT_CONTENT" value="32"/>
-            <flag name="UX_RESTRICTIONS_NO_SETUP" value="64"/>
-            <flag name="UX_RESTRICTIONS_NO_TEXT_MESSAGE" value="128"/>
-            <flag name="UX_RESTRICTIONS_NO_VOICE_TRANSCRIPTION" value="256"/>
-            <flag name="UX_RESTRICTIONS_FULLY_RESTRICTED" value="511"/>
-        </attr>
-        <!-- The name of a method that takes a MenuItem as an argument in you'r toolbar's Activity. Will be called when the MenuItem is clicked -->
-        <attr name="onClick" format="string"/>
-    </declare-styleable>
-
-    <!-- Theme attribute to specifying a default style for all CarUiToolbars -->
-    <attr name="CarUiToolbarStyle" format="reference"/>
-
-    <declare-styleable name="CarUiRecyclerView">
-        <!-- Whether to enable the dividers or not. Linear and grid layout uses
-        car_ui_recyclerview_divider.xml and car_ui_divider.xml drawables
-        respectively for styling dividers. -->
-        <attr name="enableDivider" format="boolean" />
-
-        <!-- Whether to enable rotary scrolling. Disabled by default. With rotary scrolling enabled,
-        rotating the rotary controller will scroll rather than moving the focus when moving the
-        focus would cause a lot of scrolling. Rotary scrolling should be enabled when the recycler
-        view contains content which the user may want to see but can't interact with, either alone
-        or along with interactive (focusable) content. -->
-        <attr name="rotaryScrollEnabled" format="boolean" />
-
-        <!-- Number of columns in a grid layout. -->
-        <attr name="numOfColumns" format="integer" />
-
-        <!-- car ui recycler view layout. -->
-        <attr name="layoutStyle" format="enum">
-            <!-- linear layout -->
-            <enum name="linear" value="0" />
-            <!-- grid layout -->
-            <enum name="grid" value="1" />
-        </attr>
-
-        <!-- car ui recycler view size. -->
-        <attr name="carUiSize" format="enum">
-            <enum name="small" value="0" />
-            <enum name="medium" value="1" />
-            <enum name="large" value="2" />
-        </attr>
-
-        <!-- car ui recyclerview orientation -->
-        <attr name="android:orientation" />
-        <!-- car ui recyclerview layout reversed -->
-        <attr name="reverseLayout" format="boolean" />
-    </declare-styleable>
-
-    <declare-styleable name="CarUiPreference">
-        <!-- Toggle for showing chevron -->
-        <attr name="showChevron" format="boolean" />
-        <!-- Display this preference as ux restricted. -->
-        <attr name="car_ui_ux_restricted" format="boolean" />
-    </declare-styleable>
-
-    <declare-styleable name="CarUiTwoActionPreference">
-        <!-- Determines if the secondary action is initially shown -->
-        <attr name="actionShown" format="boolean"/>
-        <!-- Determines if the secondary action is initially enabled -->
-        <attr name="actionEnabled" format="boolean"/>
-    </declare-styleable>
-
-    <declare-styleable name="CarUiTwoActionBasePreference">
-        <!-- All of these are disallowed -->
-        <attr name="layout" format="reference"/>
-        <attr name="android:layout" format="reference"/>
-        <attr name="widgetLayout" format="reference"/>
-        <attr name="android:widgetLayout" format="reference"/>
-    </declare-styleable>
-
-    <declare-styleable name="CarUiTwoActionTextPreference">
-        <attr name="secondaryActionStyle" format="enum">
-            <enum name="bordered" value="0"/>
-            <enum name="borderless" value="1"/>
-        </attr>
-        <attr name="secondaryActionText" format="string"/>
-    </declare-styleable>
-
-    <declare-styleable name="CarUiTwoActionIconPreference">
-        <attr name="secondaryActionIcon" format="reference"/>
-    </declare-styleable>
-
-    <!-- Adding AndroidX attr here, because it doesn't compile on google3 -->
-    <attr name="preferenceStyle" format="reference"/>
-
-    <!-- Theme attribute to specify a default style for all CarUiPreferences -->
-    <attr name="carUiPreferenceStyle" format="reference" />
-
-    <!-- Theme attribute to specify a default style for all CarUiRecyclerViews -->
-    <attr name="carUiRecyclerViewStyle" format="reference" />
-
-    <attr name="state_ux_restricted" format="boolean" />
-
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/bools.xml b/car-ui-lib/car-ui-lib/src/main/res/values/bools.xml
deleted file mode 100644
index 0b4d62b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/bools.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
-    <!-- Toolbar -->
-
-    <!-- Whether tabs should use flex layout or not -->
-    <bool name="car_ui_toolbar_tab_flexible_layout">false</bool>
-    <!-- Whether the space for nav icon should be reserved, even if the nav icon is not visible -->
-    <bool name="car_ui_toolbar_nav_icon_reserve_space">true</bool>
-    <!-- Whether the logo (if provided) should be used in place of the nav icon when nav icon is
-         not visible -->
-    <bool name="car_ui_toolbar_logo_fills_nav_icon_space">true</bool>
-    <!-- Whether logo should be displayed. If set to false, logo won't be shown even if provided -->
-    <bool name="car_ui_toolbar_show_logo">true</bool>
-    <!-- Whether tabs should be displayed on a second row, or they should be placed in the first
-         row, replacing the title -->
-    <bool name="car_ui_toolbar_tabs_on_second_row">false</bool>
-
-    <bool name="car_ui_toolbar_menuitem_individual_click_listeners">false</bool>
-
-    <!-- CarUiRecyclerView -->
-
-    <!-- Whether to display the Scroll Bar or not. Defaults to true. If this is set to false,
-         the CarUiRecyclerView will behave exactly like the RecyclerView. -->
-    <bool name="car_ui_scrollbar_enable">true</bool>
-
-    <!-- Preferences -->
-
-    <!-- Whether list, edit, dropdown and intent preferences should show a chevron or not -->
-    <bool name="car_ui_preference_show_chevron">false</bool>
-    <!-- whether list preference should be shown in full screen or as a dialog -->
-    <bool name="car_ui_preference_list_show_full_screen">true</bool>
-    <!-- Whether list and multi-select preference selection changes should propagate instantly -->
-    <bool name="car_ui_preference_list_instant_change_callback">false</bool>
-
-    <!-- List items -->
-
-    <bool name="car_ui_list_item_single_line_title">false</bool>
-
-    <!--  Whether to log the escrow components check automatically for all the activities or not.  -->
-    <bool name="car_ui_escrow_check_components_automatically">false</bool>
-
-    <!-- Whether or not to allow application to hide the content area in IME wide screen.  -->
-    <bool name="car_ui_ime_wide_screen_allow_app_hide_content_area">true</bool>
-
-    <!-- Whether IME is aligned left or not(which means its on right). This value will be used by
-         the applications not using car-ui-lib components and are hiding the content area. -->
-    <bool name="car_ui_ime_wide_screen_aligned_left">true</bool>
-
-    <!-- If there is no positive/negative/neutral button, should we add one that says "dismiss"? -->
-    <bool name="car_ui_alert_dialog_force_dismiss_button">true</bool>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/colors.xml b/car-ui-lib/car-ui-lib/src/main/res/values/colors.xml
deleted file mode 100644
index bf6811b..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <!-- General -->
-
-    <!-- Background color to use on full screen activities -->
-    <color name="car_ui_activity_background_color">#000000</color>
-    <!-- The ripple color. -->
-    <color name="car_ui_ripple_color">#27ffffff</color>
-
-    <!-- Toolbar -->
-
-    <!-- Color used on the navigation icon -->
-    <color name="car_ui_toolbar_nav_icon_color">@color/car_ui_text_color_primary</color>
-    <!-- Text color applied to the hint displayed inside the search box -->
-    <color name="car_ui_toolbar_search_hint_text_color">@color/car_ui_text_color_hint</color>
-    <!-- Tab selected color -->
-    <color name="car_ui_toolbar_tab_selected_color">@color/car_ui_text_color_primary</color>
-    <!-- Tab normal color -->
-    <color name="car_ui_toolbar_tab_unselected_color">@color/car_ui_text_color_secondary</color>
-
-    <!-- Recycler View  -->
-
-    <!-- Color of the scroll bar indicator in the CarUiRecyclerView. -->
-    <color name="car_ui_scrollbar_arrow">#FFFFFF</color>
-
-    <!-- Color of the divider views between CarUiRecyclerView items -->
-    <color name="car_ui_recyclerview_divider_color">@android:color/transparent</color>
-
-    <!-- Preferences -->
-
-    <color name="car_ui_preference_icon_color">@color/car_ui_text_color_primary</color>
-    <color name="car_ui_preference_two_action_divider_color">#75ffffff</color>
-
-    <!-- IME wide screen -->
-
-    <color name="car_ui_ime_wide_screen_error_text_color">#F00</color>
-    <color name="car_ui_ime_wide_screen_divider_color">#2E3134</color>
-    <color name="car_ui_ime_wide_screen_description_title_color">#FFF</color>
-    <color name="car_ui_ime_wide_screen_description_color">#FFF</color>
-    <color name="car_ui_ime_wide_screen_search_item_title_color">#FFF</color>
-    <color name="car_ui_ime_wide_screen_search_item_sub_title_color">#FFF</color>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/dimens.xml b/car-ui-lib/car-ui-lib/src/main/res/values/dimens.xml
deleted file mode 100644
index f0c536d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,247 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-    <!-- General resources -->
-
-    <dimen name="car_ui_touch_target_size">76dp</dimen>
-    <dimen name="car_ui_touch_target_width">@dimen/car_ui_touch_target_size</dimen>
-    <dimen name="car_ui_touch_target_height">@dimen/car_ui_touch_target_size</dimen>
-
-    <dimen name="car_ui_primary_icon_size">44dp</dimen>
-
-    <!-- Horizontal margin between screen content and display border. In reference
-     implementation, this value matches the CarUiRecyclerView scrollbar width -->
-    <dimen name="car_ui_margin">112dp</dimen>
-
-    <!-- Paddings -->
-    <dimen name="car_ui_padding_0">4dp</dimen>
-    <dimen name="car_ui_padding_1">8dp</dimen>
-    <dimen name="car_ui_padding_2">12dp</dimen>
-    <dimen name="car_ui_padding_3">16dp</dimen>
-    <dimen name="car_ui_padding_4">24dp</dimen>
-    <dimen name="car_ui_padding_5">32dp</dimen>
-    <dimen name="car_ui_padding_6">48dp</dimen>
-    <dimen name="car_ui_padding_7">64dp</dimen>
-    <dimen name="car_ui_padding_8">96dp</dimen>
-
-    <!-- Type Sizings -->
-    <dimen name="car_ui_body1_size">32sp</dimen>
-    <dimen name="car_ui_body2_size">28sp</dimen>
-    <dimen name="car_ui_body3_size">24sp</dimen>
-    <dimen name="car_ui_sub1_size">22sp</dimen>
-    <dimen name="car_ui_sub2_size">20sp</dimen>
-    <dimen name="car_ui_sub3_size">18sp</dimen>
-
-    <!-- Tabs -->
-
-    <!-- Exact size of the tab textbox. Use @dimen/wrap_content if this must be flexible -->
-    <dimen name="car_ui_toolbar_tab_text_width">135dp</dimen>
-    <!-- Horizontal padding between tabs -->
-    <dimen name="car_ui_toolbar_tab_padding_x">12dp</dimen>
-    <!-- Tab icon width (if icons are enabled) -->
-    <dimen name="car_ui_toolbar_tab_icon_width">36dp</dimen>
-    <!-- Tab icon height (if icons are enabled) -->
-    <dimen name="car_ui_toolbar_tab_icon_height">36dp</dimen>
-
-    <!-- Toolbar -->
-
-    <!-- Default height for both toolbar rows. See car_ui_toolbar_first_row_height and
-     car_ui_toolbar_second_row_height -->
-    <dimen name="car_ui_toolbar_row_height">96dp</dimen>
-    <!-- Height of the top toolbar row. This can be customized independently. -->
-    <dimen name="car_ui_toolbar_first_row_height">@dimen/car_ui_toolbar_row_height</dimen>
-    <!-- Height of the bottom toolbar row (if the toolbar is used in two-rows mode. -->
-    <dimen name="car_ui_toolbar_second_row_height">@dimen/car_ui_toolbar_row_height</dimen>
-    <!-- Padding on the toolbar start (e.g.: distance between the container start and the start of
-    nav icon or logo) -->
-    <dimen name="car_ui_toolbar_start_inset">0dp</dimen>
-    <!-- End padding (e.g.: distance between the container end and the end of the menu items) -->
-    <dimen name="car_ui_toolbar_end_inset">0dp</dimen>
-    <!-- Top padding -->
-    <dimen name="car_ui_toolbar_top_inset">0dp</dimen>
-    <!-- Bottom padding -->
-    <dimen name="car_ui_toolbar_bottom_inset">0dp</dimen>
-    <!-- Toolbar title/tabs start margin. Toolbar navigation icon (or logo if no navigation icon is
-    used) will be centered in this space, and the title will start from here -->
-    <dimen name="car_ui_toolbar_margin">@dimen/car_ui_margin</dimen>
-    <!-- Navigation icon -->
-    <dimen name="car_ui_toolbar_nav_icon_size">@dimen/car_ui_primary_icon_size</dimen>
-    <!-- Logo -->
-    <dimen name="car_ui_toolbar_logo_size">@dimen/car_ui_primary_icon_size</dimen>
-    <!-- Margin between the logo and the title, when both logo and navigation icons are used -->
-    <dimen name="car_ui_toolbar_title_logo_padding">0dp</dimen>
-    <!-- Margin at the start of the title -->
-    <dimen name="car_ui_toolbar_title_margin_start">@dimen/car_ui_padding_3</dimen>
-    <!-- Margin at the start of the title when there is no logo present -->
-    <dimen name="car_ui_toolbar_title_no_logo_margin_start">0dp</dimen>
-    <!-- Space at the end and in between menu items -->
-    <dimen name="car_ui_toolbar_menu_item_margin">@dimen/car_ui_padding_3</dimen>
-    <!-- Ripple effect radius for icon menu items -->
-    <dimen name="car_ui_toolbar_menu_item_icon_ripple_radius">48dp</dimen>
-    <!-- Icon size for icon menu items -->
-    <dimen name="car_ui_toolbar_menu_item_icon_size">@dimen/car_ui_primary_icon_size</dimen>
-    <!-- Icon background size for icon menu items -->
-    <dimen name="car_ui_toolbar_menu_item_icon_background_size">54dp</dimen>
-    <!-- Height of the decoration view between the two rows of the toolbar (or below the toolbar
-    if this is a single row one -->
-    <!-- can't use 0dp for layout_height or the constraintlayout effect kicks in -->
-    <dimen name="car_ui_toolbar_separator_height">0.1dp</dimen>
-    <!-- Height of the decoration view below the toolbar -->
-    <!-- can't use 0dp for layout_height or the constraintlayout effect kicks in -->
-    <dimen name="car_ui_toolbar_bottom_view_height">0.1dp</dimen>
-    <!-- Height of the search box -->
-    <dimen name="car_ui_toolbar_search_height">0dp</dimen>
-    <!-- Space before the text search area, where the search icon is located -->
-    <dimen name="car_ui_toolbar_search_search_icon_container_width">@dimen/car_ui_touch_target_width</dimen>
-    <!-- Space after the text search area, where the cancel icon is located -->
-    <dimen name="car_ui_toolbar_search_close_icon_container_width">@dimen/car_ui_touch_target_width</dimen>
-    <!-- Size of the search icon inside the search box -->
-    <dimen name="car_ui_toolbar_search_search_icon_size">@dimen/car_ui_primary_icon_size</dimen>
-    <!-- Size of the close icon inside the search box -->
-    <dimen name="car_ui_toolbar_search_close_icon_size">@dimen/car_ui_primary_icon_size</dimen>
-
-    <!-- Internal artifacts. Do not overlay -->
-    <item name="wrap_content" format="integer" type="dimen">-2</item>
-
-    <!-- CarUiRecyclerView -->
-
-    <dimen name="car_ui_recyclerview_divider_height">0dp</dimen>
-    <dimen name="car_ui_recyclerview_divider_start_margin">0dp</dimen>
-    <dimen name="car_ui_recyclerview_divider_end_margin">0dp</dimen>
-    <dimen name="car_ui_recyclerview_divider_top_margin">0dp</dimen>
-    <dimen name="car_ui_recyclerview_divider_bottom_margin">0dp</dimen>
-
-    <!-- CarUiRecyclerView default scrollbar -->
-
-    <dimen name="car_ui_scrollbar_container_width">@dimen/car_ui_margin</dimen>
-    <dimen name="car_ui_scrollbar_button_size">@dimen/car_ui_touch_target_width</dimen>
-    <dimen name="car_ui_scrollbar_thumb_width">7dp</dimen>
-    <dimen name="car_ui_scrollbar_min_thumb_height">56dp</dimen>
-    <dimen name="car_ui_scrollbar_separator_margin">16dp</dimen>
-    <dimen name="car_ui_scrollbar_margin">@dimen/car_ui_margin</dimen>
-    <dimen name="car_ui_scrollbar_thumb_radius">100dp</dimen>
-
-    <item name="car_ui_button_disabled_alpha" format="float" type="dimen">0.2</item>
-    <item name="car_ui_scrollbar_milliseconds_per_inch" format="float" type="dimen">150.0</item>
-    <item name="car_ui_scrollbar_deceleration_times_divisor" format="float" type="dimen">0.45</item>
-    <item name="car_ui_scrollbar_decelerate_interpolator_factor" format="float" type="dimen">1.8</item>
-
-    <dimen name="car_ui_scrollbar_padding_top">0dp</dimen>
-    <dimen name="car_ui_scrollbar_padding_bottom">0dp</dimen>
-
-    <!-- Preferences -->
-
-    <dimen name="car_ui_divider_width">1dp</dimen>
-
-    <dimen name="car_ui_preference_content_margin_top">16dp</dimen>
-    <dimen name="car_ui_preference_content_margin_bottom">16dp</dimen>
-    <dimen name="car_ui_preference_icon_size">44dp</dimen>
-    <dimen name="car_ui_preference_icon_margin_end">16dp</dimen>
-
-    <dimen name="car_ui_preference_category_min_height">76dp</dimen>
-    <dimen name="car_ui_preference_category_icon_size">44dp</dimen>
-    <dimen name="car_ui_preference_category_icon_margin_end">16dp</dimen>
-
-    <dimen name="car_ui_preference_dropdown_padding_start">112dp</dimen>
-
-    <dimen name="car_ui_preference_edit_text_dialog_margin_top">32dp</dimen>
-    <dimen name="car_ui_preference_edit_text_dialog_margin_bottom">32dp</dimen>
-    <dimen name="car_ui_preference_edit_text_dialog_message_margin_bottom">32dp</dimen>
-    <dimen name="car_ui_preference_edit_text_dialog_message_margin_start">24dp</dimen>
-    <dimen name="car_ui_preference_edit_text_dialog_message_margin_end">24dp</dimen>
-    <dimen name="car_ui_preference_edit_text_dialog_text_margin_start">24dp</dimen>
-    <dimen name="car_ui_preference_edit_text_dialog_text_margin_end">24dp</dimen>
-
-    <!-- Alert dialog   -->
-
-    <dimen name="car_ui_dialog_edittext_height">50dp</dimen>
-    <dimen name="car_ui_dialog_edittext_margin_top">10dp</dimen>
-    <dimen name="car_ui_dialog_edittext_margin_bottom">10dp</dimen>
-    <dimen name="car_ui_dialog_edittext_margin_start">22dp</dimen>
-    <dimen name="car_ui_dialog_edittext_margin_end">22dp</dimen>
-    <dimen name="car_ui_dialog_icon_size">56dp</dimen>
-    <dimen name="car_ui_dialog_title_margin">24dp</dimen>
-
-    <!-- List item  -->
-
-    <dimen name="car_ui_list_item_height">116dp</dimen>
-    <dimen name="car_ui_list_item_header_height">76dp</dimen>
-    <dimen name="car_ui_list_item_header_start_inset">0dp</dimen>
-    <dimen name="car_ui_list_item_start_inset">0dp</dimen>
-    <dimen name="car_ui_list_item_end_inset">0dp</dimen>
-    <dimen name="car_ui_header_list_item_text_start_margin">0dp</dimen>
-    <dimen name="car_ui_list_item_text_start_margin">24dp</dimen>
-    <dimen name="car_ui_list_item_text_no_icon_start_margin">24dp</dimen>
-
-    <!-- List item icons  -->
-
-    <dimen name="car_ui_list_item_icon_size">@dimen/car_ui_primary_icon_size</dimen>
-    <dimen name="car_ui_list_item_content_icon_width">@dimen/car_ui_list_item_icon_container_width</dimen>
-    <dimen name="car_ui_list_item_content_icon_height">@dimen/car_ui_list_item_icon_container_width</dimen>
-    <dimen name="car_ui_list_item_avatar_icon_width">@dimen/car_ui_primary_icon_size</dimen>
-    <dimen name="car_ui_list_item_avatar_icon_height">@dimen/car_ui_primary_icon_size</dimen>
-    <dimen name="car_ui_list_item_supplemental_icon_size">@dimen/car_ui_primary_icon_size</dimen>
-    <dimen name="car_ui_list_item_icon_container_width">112dp</dimen>
-    <dimen name="car_ui_list_item_action_divider_width">1dp</dimen>
-    <dimen name="car_ui_list_item_action_divider_height">60dp</dimen>
-
-    <!-- IME wide screen -->
-    <dimen name="car_ui_ime_wide_screen_keyboard_width">1250dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_keyboard_area_padding_start">36dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_keyboard_area_padding_end">36dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_keyboard_area_padding_bottom">40dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_input_area_height">96dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_input_area_padding_top">56dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_input_padding_start">36dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_input_edit_text_padding_left">68dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_input_edit_text_padding_right">0dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_input_edit_text_size">68dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_error_text_padding_start">68dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_error_text_size">24dp</dimen>
-
-    <dimen name="car_ui_ime_wide_screen_divider_width">5dp</dimen>
-
-    <dimen name="car_ui_ime_wide_screen_recycler_view_padding_top">100dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_description_title_margin_top">190dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_description_title_padding_left">36dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_description_title_text_size">44dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_description_text_size">32dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_description_padding_top">16dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_action_button_text_size">32dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_action_button_margin_bottom">40dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_action_button_margin_left">36dp</dimen>
-    <dimen name="car_ui_ime_wide_screen_action_button_height">88dp</dimen>
-
-    <dimen name="car_ui_ime_wide_search_item_icon_size">116dp</dimen>
-    <dimen name="car_ui_ime_wide_search_item_title_text_size">32dp</dimen>
-    <dimen name="car_ui_ime_wide_search_item_title_padding_left">24dp</dimen>
-    <dimen name="car_ui_ime_wide_search_item_title_padding_top">22dp</dimen>
-    <dimen name="car_ui_ime_wide_search_item_sub_title_padding_left">24dp</dimen>
-    <dimen name="car_ui_ime_wide_search_item_sub_title_padding_top">22dp</dimen>
-    <dimen name="car_ui_ime_wide_search_item_sub_title_text_size">24dp</dimen>
-    <dimen name="car_ui_ime_wide_search_item_secondary_image_padding_left">36dp</dimen>
-
-    <!-- Padding towards the end of the input field. We have an overlay on top
-     of input text field that displays the clear and the error icon. This
-     padding is needed so that the icon does not overlap the input field. The
-     padding is calculated by 24dp + car_ui_primary_icon_size (44dp). -->
-    <dimen name="car_ui_ime_wide_screen_input_area_padding_end">68dp</dimen>
-
-    <dimen name="car_ui_app_styled_dialog_width">0dp</dimen>
-    <dimen name="car_ui_app_styled_dialog_height">0dp</dimen>
-    <dimen name="car_ui_app_styled_dialog_position_x">0dp</dimen>
-    <dimen name="car_ui_app_styled_dialog_position_y">0dp</dimen>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/drawables.xml b/car-ui-lib/car-ui-lib/src/main/res/values/drawables.xml
deleted file mode 100644
index ea5a45d..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/drawables.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <!-- General -->
-
-    <!-- Background drawable to use on full screen activities -->
-    <drawable name="car_ui_activity_background">@color/car_ui_activity_background_color</drawable>
-
-    <!-- Toolbar -->
-
-    <!-- Toolbar background color -->
-    <drawable name="car_ui_toolbar_background">#E0000000</drawable>
-    <!-- Search icon shown inside the search box in the toolbar -->
-    <drawable name="car_ui_toolbar_search_search_icon">@drawable/car_ui_icon_search</drawable>
-    <!-- Icon used for clearing the search box in toolbar -->
-    <drawable name="car_ui_toolbar_search_close_icon">@drawable/car_ui_icon_close</drawable>
-    <!-- Icon used for nav when the toolbar is in search state   -->
-    <drawable name="car_ui_icon_search_nav_icon">@drawable/car_ui_icon_arrow_back</drawable>
-
-    <!-- Preferences -->
-
-    <!-- Overlayable drawable to use for the preference chevron when preference is enabled -->
-    <item name="car_ui_preference_icon_chevron_enabled" type="drawable">@drawable/car_ui_icon_chevron</item>
-    <!-- Overlayable drawable to use for the preference chevron when preference is disabled -->
-    <item name="car_ui_preference_icon_chevron_disabled" type="drawable">@android:color/transparent</item>
-
-    <!-- IME wide screen -->
-
-    <!--  Background of the entire area other than content area which is
-          input text box and keyboard.  -->
-    <drawable name="car_ui_ime_wide_screen_background">#000</drawable>
-
-    <!--  Background of the content area.  -->
-    <drawable name="car_ui_ime_wide_screen_content_area_background">#000</drawable>
-
-    <!--  Background of the content area when there is no content.  -->
-    <drawable name="car_ui_ime_wide_screen_no_content_background">#cc000000</drawable>
-
-    <!--  Background of the input area.  -->
-    <drawable name="car_ui_ime_wide_screen_input_area_background">#000</drawable>
-
-    <!--  Tint color of input area in wide screen with error string.  -->
-    <drawable name="car_ui_ime_wide_screen_input_area_tint_error_color">#f00</drawable>
-
-    <!--  Tint color of input area in wide screen.  -->
-    <drawable name="car_ui_ime_wide_screen_input_area_tint_color">#f5f5f5</drawable>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/ids.xml b/car-ui-lib/car-ui-lib/src/main/res/values/ids.xml
deleted file mode 100644
index b393c28..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/ids.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-    <!-- Id used for the search button when using Toolbar.createSearch() method -->
-    <item name="search" type="id"/>
-
-    <!-- Id used as a tag on views to store their CarUi component objects. -->
-    <item type="id" name="car_ui_component_reference"/>
-
-    <!-- WideScreen Keyboard IDs-->
-    <item type="id" name="car_ui_wideScreenInputArea"/>
-    <item type="id" name="car_ui_imeWideScreenInputArea"/>
-    <item type="id" name="car_ui_closeKeyboard"/>
-    <item type="id" name="car_ui_ime_surface"/>
-    <item type="id" name="car_ui_fullscreenArea"/>
-    <item type="id" name="car_ui_wideScreenErrorMessage"/>
-    <item type="id" name="car_ui_contentAreaAutomotive"/>
-    <item type="id" name="car_ui_wideScreenSearchResultList"/>
-    <item type="id" name="car_ui_wideScreenDescriptionTitle"/>
-    <item type="id" name="car_ui_wideScreenDescription"/>
-    <item type="id" name="car_ui_inputExtractActionAutomotive"/>
-    <item type="id" name="car_ui_wideScreenExtractedTextIcon"/>
-    <item type="id" name="car_ui_wideScreenClearData"/>
-    <item type="id" name="car_ui_wideScreenError"/>
-    <item type="id" name="car_ui_inputExtractEditTextContainer"/>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/integers.xml b/car-ui-lib/car-ui-lib/src/main/res/values/integers.xml
deleted file mode 100644
index 332dc76..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/integers.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
-    <!-- Default max string length -->
-    <integer name="car_ui_default_max_string_length">120</integer>
-    <integer name="car_ui_scrollbar_longpress_initial_delay">1000</integer>
-    <integer name="car_ui_scrollbar_longpress_repeat_interval">100</integer>
-
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/strings.xml b/car-ui-lib/car-ui-lib/src/main/res/values/strings.xml
deleted file mode 100644
index defba5f..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<resources>
-    <!--
-    Configuration for a default scrollbar for the CarUiRecyclerView. This component must inherit
-    abstract class ScrollBar. If the ScrollBar is enabled, the component will be initialized from
-    CarUiRecyclerView#createScrollBarFromConfig(). If no component is provided,
-    {@link DefaultScrollbar} class will be used.
-    -->
-    <string name="car_ui_scrollbar_component" translatable="false"/>
-    <!-- Search hint, displayed inside the search box [CHAR LIMIT=50] -->
-    <string name="car_ui_toolbar_default_search_hint">Search&#8230;</string>
-    <!-- CarUxRestrictions Utility -->
-    <string name="car_ui_ellipsis" translatable="false">&#8230;</string>
-    <!-- Content description for car ui recycler view scroll bar down arrow [CHAR LIMIT=30] -->
-    <string name="car_ui_scrollbar_page_down_button">Scroll down</string>
-    <!-- Content description for car ui recycler view scroll bar up arrow [CHAR LIMIT=30] -->
-    <string name="car_ui_scrollbar_page_up_button">Scroll up</string>
-    <!-- The content description on the toolbar back button -->
-    <string name="car_ui_toolbar_nav_icon_content_description">Back</string>
-    <!-- Title of the search menu item. Will be displayed if the button is in the overflow menu. [CHAR_LIMIT=50] -->
-    <string name="car_ui_toolbar_menu_item_search_title">Search</string>
-    <!-- Title of the settings menu item. Will be displayed if the button is in the overflow menu. [CHAR_LIMIT=50] -->
-    <string name="car_ui_toolbar_menu_item_settings_title">Settings</string>
-    <!-- Title of the overflow menu item. Only used for content descriptions. [CHAR_LIMIT=50] -->
-    <string name="car_ui_toolbar_menu_item_overflow_title">Overflow</string>
-
-    <!-- Positive option for a preference dialog. [CHAR_LIMIT=30] -->
-    <string name="car_ui_dialog_preference_positive" translatable="false">@android:string/ok
-    </string>
-    <!-- Negative option for a preference dialog. [CHAR_LIMIT=30] -->
-    <string name="car_ui_dialog_preference_negative" translatable="false">@android:string/cancel
-    </string>
-    <!-- Text to show when a preference switch is on. [CHAR_LIMIT=30] -->
-    <string name="car_ui_preference_switch_on">On</string>
-    <!-- Text to show when a preference switch is off. [CHAR_LIMIT=30] -->
-    <string name="car_ui_preference_switch_off">Off</string>
-
-    <!-- Text to show when no button is provided and a default button is used. -->
-    <string name="car_ui_alert_dialog_default_button">Close</string>
-
-    <!-- Shown at the bottom of a content limited list when user has scrolled past the limit while driving -->
-    <string name="car_ui_scrolling_limited_message">Scrolling limited while driving</string>
-
-    <!-- Shown in a toast when the user attempts to do something distracting while driving [CHAR_LIMIT=200] -->
-    <string name="car_ui_restricted_while_driving">Feature not available while driving</string>
-
-    <!-- Mostly used for GMSCore, this attribute is used to launch CarUiInstaller in a process -->
-    <!-- that can register to Application.ActivityLifecycleCallbacks. -->
-    <!-- Clients should override this value instead of changing the process name -->
-    <!-- from manifest file. -->
-    <string name="car_ui_installer_process_name" translatable="false"></string>
-
-    <!--
-    List of packages allowed to hide the content area in wide screen mode when
-    bool/car_ui_ime_wide_screen_allow_app_hide_content_area is set to false. Each package name
-    should be separated by a ",". For example, "com.package1,com.package2,com.package3" will allow
-    packages "com.package1", "com.package2" and "com.package3" to hide the content area.
-    -->
-    <string-array name="car_ui_ime_wide_screen_allowed_package_list" translatable="false">
-    </string-array>
-
-    <!-- Name of system property used to determine when wide screen mode is used. -->
-    <string name="car_ui_ime_wide_screen_system_property_name" translatable="false">
-        ro.build.automotive.ime.wide_screen.enabled
-    </string>
-
-    <!-- Name of system property used that contains the package name of the CarUi shared library. -->
-    <string name="car_ui_shared_library_package_system_property_name" translatable="false">
-        ro.build.automotive.car.ui.shared.library.package.name
-    </string>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/styles.xml b/car-ui-lib/car-ui-lib/src/main/res/values/styles.xml
deleted file mode 100644
index b8a0e51..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,317 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <!-- Styles for CarUi tab view -->
-
-    <style name="Widget.CarUi" parent="android:Widget.DeviceDefault"/>
-
-    <style name="Widget.CarUi.Button.Borderless.Colored"
-           parent="android:Widget.DeviceDefault.Button.Borderless.Colored"/>
-
-    <style name="Widget.CarUi.Button" parent="android:Widget.DeviceDefault.Button"/>
-
-    <style name="Widget.CarUi.Toolbar"/>
-
-    <style name="Widget.CarUi.SeekbarPreference"/>
-
-    <style name="Widget.CarUi.Toolbar.Container"/>
-
-    <style name="Widget.CarUi.Toolbar.NavIconContainer"/>
-
-    <style name="Widget.CarUi.Toolbar.Logo"/>
-
-    <style name="Widget.CarUi.Toolbar.LogoContainer">
-        <item name="android:paddingEnd">@dimen/car_ui_toolbar_title_logo_padding</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.ProgressBar"
-           parent="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"/>
-
-    <style name="Widget.CarUi.Toolbar.NavIcon">
-        <item name="android:tint">@color/car_ui_toolbar_nav_icon_color</item>
-        <item name="android:src">@drawable/car_ui_icon_arrow_back</item>
-        <item name="android:background">@drawable/car_ui_toolbar_menu_item_icon_ripple</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.Title">
-        <item name="android:textAppearance">@style/TextAppearance.CarUi.Widget.Toolbar.Title</item>
-        <item name="android:textAlignment">viewStart</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.Subtitle">
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:textAlignment">viewStart</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.TextButton" parent="Widget.CarUi.Button.Borderless.Colored">
-        <item name="android:drawableTint">@color/car_ui_toolbar_menu_item_icon_color</item>
-        <item name="android:drawablePadding">10dp</item>
-        <item name="android:maxWidth">350dp</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.TextButton.WithIcon">
-        <item name="android:textColor">@color/car_ui_toolbar_menu_item_icon_color</item>
-    </style>
-
-    <!-- Style applied to the seekbar widget within the seekbar preference -->
-    <style name="Widget.CarUi.SeekbarPreference.Seekbar">
-        <item name="android:background">@null</item>
-        <item name="android:clickable">false</item>
-        <item name="android:focusable">false</item>
-    </style>
-
-    <!-- Style applied to the decoration view between toolbar rows -->
-    <style name="Widget.CarUi.Toolbar.SeparatorView">
-        <item name="android:height">0.01dp</item>
-        <item name="android:background">@android:color/transparent</item>
-    </style>
-
-    <!-- Style applied to the decoration view below the toolbar -->
-    <style name="Widget.CarUi.Toolbar.BottomView">
-        <item name="android:height">0.01dp</item>
-        <item name="android:background">@android:color/transparent</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.MenuItem"/>
-
-    <style name="Widget.CarUi.Toolbar.MenuItem.Container">
-        <item name="android:divider">@drawable/car_ui_toolbar_menu_item_divider</item>
-        <item name="android:showDividers">beginning|middle|end</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.MenuItem.IndividualContainer">
-        <item name="android:minHeight">@dimen/car_ui_touch_target_height</item>
-        <item name="android:minWidth">@dimen/car_ui_touch_target_width</item>
-        <item name="android:layout_gravity">center_vertical</item>
-    </style>
-
-    <!-- Style applied to the edit box inside the toolbar search area -->
-    <style name="Widget.CarUi.Toolbar.Search.EditText"
-        parent="android:Widget.DeviceDefault.EditText">
-        <item name="android:textColor">@color/car_ui_text_color_primary</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.Search.SearchIcon" parent="Widget.CarUi.Toolbar"/>
-
-    <style name="Widget.CarUi.Toolbar.Search.CloseIcon" parent="Widget.CarUi.Toolbar">
-        <item name="android:background">@drawable/car_ui_toolbar_menu_item_icon_ripple</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.Tab"/>
-
-    <style name="Widget.CarUi.Toolbar.Tab.Container">
-        <item name="android:orientation">vertical</item>
-        <item name="android:paddingStart">@dimen/car_ui_toolbar_tab_padding_x</item>
-        <item name="android:paddingEnd">@dimen/car_ui_toolbar_tab_padding_x</item>
-        <item name="android:gravity">center</item>
-        <item name="android:background">?android:attr/selectableItemBackground</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.Tab.Icon">
-        <item name="android:scaleType">fitCenter</item>
-        <item name="android:tint">@color/car_ui_toolbar_tab_item_selector</item>
-        <item name="android:tintMode">src_in</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.Tab.Text">
-        <item name="android:singleLine">true</item>
-        <item name="android:gravity">center</item>
-        <item name="android:textAppearance">@style/TextAppearance.CarUi.Widget.Toolbar.Tab</item>
-    </style>
-
-    <style name="Widget.CarUi.CarUiRecyclerView">
-        <item name="android:scrollbars">vertical</item>
-    </style>
-
-    <style name="Widget.CarUi.AlertDialog"/>
-
-    <style name="Widget.CarUi.AlertDialog.HeaderContainer">
-        <item name="android:orientation">horizontal</item>
-        <item name="android:gravity">center_vertical|start</item>
-        <item name="android:paddingTop">18dp</item>
-        <item name="android:paddingBottom">18dp</item>
-    </style>
-
-    <style name="Widget.CarUi.AlertDialog.TitleContainer">
-        <item name="android:layout_marginStart">@dimen/car_ui_dialog_title_margin</item>
-        <item name="android:layout_marginEnd">@dimen/car_ui_dialog_title_margin</item>
-        <item name="android:orientation">vertical</item>
-    </style>
-
-    <style name="Widget.CarUi.AlertDialog.Icon">
-        <item name="android:layout_marginStart">@dimen/car_ui_dialog_title_margin</item>
-        <item name="android:scaleType">fitCenter</item>
-    </style>
-
-    <!-- Preference Styles -->
-
-    <style name="Preference.CarUi">
-        <item name="allowDividerBelow">false</item>
-        <item name="allowDividerAbove">false</item>
-        <item name="android:layout">@layout/car_ui_preference</item>
-    </style>
-
-    <style name="Preference.CarUi.Category">
-        <item name="android:layout">@layout/car_ui_preference_category</item>
-        <!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
-        <item name="android:shouldDisableView">false</item>
-        <item name="android:selectable">false</item>
-    </style>
-
-    <style name="Preference.CarUi.CheckBoxPreference">
-        <item name="android:widgetLayout">@layout/car_ui_preference_widget_checkbox</item>
-    </style>
-
-    <style name="Preference.CarUi.DialogPreference">
-        <item name="android:positiveButtonText">@string/car_ui_dialog_preference_positive</item>
-        <item name="android:negativeButtonText">@string/car_ui_dialog_preference_negative</item>
-    </style>
-
-    <style name="Preference.CarUi.DialogPreference.EditTextPreference">
-        <item name="android:dialogLayout">@layout/car_ui_preference_dialog_edittext</item>
-    </style>
-
-    <style name="Preference.CarUi.Divider">
-        <item name="android:background">@color/car_ui_preference_two_action_divider_color</item>
-    </style>
-
-    <style name="Preference.CarUi.DropDown">
-        <item name="android:layout">@layout/car_ui_preference_dropdown</item>
-    </style>
-
-    <style name="Preference.CarUi.Icon"/>
-
-    <style name="Preference.CarUi.Information">
-        <item name="android:enabled">false</item>
-        <item name="android:shouldDisableView">false</item>
-    </style>
-
-    <style name="Preference.CarUi.Preference"/>
-
-    <style name="Preference.CarUi.PreferenceScreen"/>
-
-    <style name="Preference.CarUi.SeekBarPreference">
-        <item name="android:layout">@layout/car_ui_preference_widget_seekbar</item>
-        <item name="adjustable">true</item>
-        <item name="showSeekBarValue">false</item>
-    </style>
-
-    <style name="Preference.CarUi.DialogSeekBarPreference"/>
-
-    <style name="Preference.CarUi.DialogSeekBarPreference.Seekbar"/>
-
-    <style name="Preference.CarUi.DialogSeekBarPreference.TopText"/>
-    <style name="Preference.CarUi.DialogSeekBarPreference.RightText"/>
-    <style name="Preference.CarUi.DialogSeekBarPreference.LeftText"/>
-
-    <style name="Preference.CarUi.SwitchPreference">
-        <item name="android:widgetLayout">@layout/car_ui_preference_widget_switch</item>
-        <item name="android:switchTextOn">@string/car_ui_preference_switch_on</item>
-        <item name="android:switchTextOff">@string/car_ui_preference_switch_off</item>
-    </style>
-
-    <style name="PreferenceFragment.CarUi">
-        <item name="android:divider">?android:attr/listDivider</item>
-        <!-- TODO(b/150230923) change this to car_ui_preference_fragment -->
-        <item name="android:layout">@layout/car_ui_preference_fragment</item>
-    </style>
-
-    <style name="PreferenceFragmentList.CarUi">
-        <item name="android:paddingTop">0dp</item>
-        <item name="android:paddingBottom">0dp</item>
-        <item name="android:paddingLeft">0dp</item>
-        <item name="android:paddingStart">0dp</item>
-        <item name="android:paddingRight">0dp</item>
-        <item name="android:paddingEnd">0dp</item>
-    </style>
-
-    <!-- TextAppearance -->
-
-    <style name="TextAppearance.CarUi" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textColor">@color/car_ui_text_color_primary</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Body1">
-        <item name="android:textSize">@dimen/car_ui_body1_size</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Body2">
-        <item name="android:textSize">@dimen/car_ui_body2_size</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Body3">
-        <item name="android:textSize">@dimen/car_ui_body3_size</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Sub1">
-        <item name="android:textSize">@dimen/car_ui_sub1_size</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Sub2">
-        <item name="android:textSize">@dimen/car_ui_sub2_size</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Sub3">
-        <item name="android:textSize">@dimen/car_ui_sub3_size</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.PreferenceCategoryTitle" parent="TextAppearance.CarUi.Body3">
-        <item name="android:fontFamily">sans-serif-medium</item>
-        <item name="android:textColor">@color/car_ui_color_accent</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.PreferenceSummary" parent="TextAppearance.CarUi.Body3">
-        <item name="android:textColor">@color/car_ui_text_color_secondary</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.PreferenceTitle" parent="TextAppearance.CarUi.Body1"/>
-
-    <style name="TextAppearance.CarUi.PreferenceEditTextDialogMessage" parent="TextAppearance.CarUi.Body3"/>
-
-    <style name="TextAppearance.CarUi.AlertDialog.Title" parent="TextAppearance.CarUi.Body3"/>
-    <style name="TextAppearance.CarUi.AlertDialog.Subtitle" parent="TextAppearance.CarUi.Sub3"/>
-
-    <style name="TextAppearance.CarUi.Widget" parent="android:TextAppearance.DeviceDefault.Widget"/>
-
-    <style name="TextAppearance.CarUi.Widget.Toolbar"/>
-
-    <style name="TextAppearance.CarUi.Widget.Toolbar.Title" parent="TextAppearance.CarUi.Body1">
-        <item name="android:singleLine">true</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Widget.Toolbar.Tab" parent="TextAppearance.CarUi.Body3">
-        <item name="android:textColor">@color/car_ui_toolbar_tab_item_selector</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textFontWeight">400</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Widget.Toolbar.Tab.Selected">
-        <item name="android:textFontWeight">500</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.ListItem.Header" parent="TextAppearance.CarUi.Body3">
-        <item name="android:fontFamily">sans-serif-medium</item>
-        <item name="android:textColor">@color/car_ui_color_accent</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.ListItem" parent="TextAppearance.CarUi.Body1"/>
-
-    <style name="TextAppearance.CarUi.ListItem.Body" parent="TextAppearance.CarUi.Body3">
-        <item name="android:textColor">@color/car_ui_text_color_secondary</item>
-    </style>
-
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/themes.xml b/car-ui-lib/car-ui-lib/src/main/res/values/themes.xml
deleted file mode 100644
index fbca1d7..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,244 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- TODO: for internal TODOs, expand theme/style to leaf resources as necessary -->
-    <style name="Theme.CarUi" parent="@android:style/Theme.DeviceDefault.NoActionBar">
-        <item name="viewInflaterClass">com.android.car.ui.CarUiLayoutInflaterFactory</item>
-
-        <!-- TODO(b/150230923) change to true when other apps are ready -->
-        <item name="carUiBaseLayout">false</item>
-        <item name="carUiToolbar">false</item>
-
-        <!-- Attributes from: Base.V7.Theme.AppCompat -->
-
-        <item name="windowNoTitle">true</item>
-        <item name="windowActionBar">false</item>
-        <item name="windowActionBarOverlay">false</item>
-        <item name="windowActionModeOverlay">false</item>
-        <item name="actionBarPopupTheme">@null</item>
-
-        <item name="colorBackgroundFloating">?android:attr/colorBackgroundFloating</item>
-
-        <!-- Used by MediaRouter -->
-        <item name="isLightTheme">false</item>
-
-        <item name="selectableItemBackground">?android:attr/selectableItemBackground</item>
-        <item name="selectableItemBackgroundBorderless">?android:attr/selectableItemBackgroundBorderless</item>
-        <item name="android:borderlessButtonStyle">@style/Widget.CarUi.Button.Borderless.Colored</item>
-        <item name="borderlessButtonStyle">?android:attr/borderlessButtonStyle</item>
-        <item name="homeAsUpIndicator">?android:attr/homeAsUpIndicator</item>
-
-        <item name="dividerVertical">?android:attr/dividerVertical</item>
-        <item name="dividerHorizontal">?android:attr/dividerHorizontal</item>
-
-        <!-- Action Bar Styles -->
-        <item name="actionBarTabStyle">?android:attr/actionBarTabStyle</item>
-        <item name="actionBarTabBarStyle">?android:attr/actionBarTabBarStyle</item>
-        <item name="actionBarTabTextStyle">?android:attr/actionBarTabTextStyle</item>
-        <item name="actionButtonStyle">?android:attr/actionButtonStyle</item>
-        <item name="actionOverflowButtonStyle">?android:attr/actionOverflowButtonStyle</item>
-        <item name="actionOverflowMenuStyle">?android:attr/actionOverflowMenuStyle</item>
-        <item name="actionBarStyle">?android:attr/actionBarStyle</item>
-        <item name="actionBarSplitStyle">?android:attr/actionBarSplitStyle</item>
-        <item name="actionBarWidgetTheme">?android:attr/actionBarWidgetTheme</item>
-        <item name="actionBarTheme">?android:attr/actionBarTheme</item>
-        <item name="actionBarSize">?android:attr/actionBarSize</item>
-        <item name="actionBarDivider">?android:attr/actionBarDivider</item>
-        <item name="actionBarItemBackground">?android:attr/actionBarItemBackground</item>
-        <item name="actionMenuTextAppearance">?android:attr/actionMenuTextAppearance</item>
-        <item name="actionMenuTextColor">?android:attr/actionMenuTextColor</item>
-
-        <!-- Dropdown Spinner Attributes -->
-        <item name="actionDropDownStyle">?android:attr/actionDropDownStyle</item>
-
-        <!-- Action Mode -->
-        <item name="actionModeStyle">?android:attr/actionModeStyle</item>
-        <item name="actionModeBackground">?android:attr/actionModeBackground</item>
-        <item name="actionModeSplitBackground">?android:attr/actionModeSplitBackground</item>
-        <item name="actionModeCloseDrawable">?android:attr/actionModeCloseDrawable</item>
-        <item name="actionModeCloseButtonStyle">?android:attr/actionModeCloseButtonStyle</item>
-
-        <item name="actionModeCutDrawable">?android:attr/actionModeCutDrawable</item>
-        <item name="actionModeCopyDrawable">?android:attr/actionModeCopyDrawable</item>
-        <item name="actionModePasteDrawable">?android:attr/actionModePasteDrawable</item>
-        <item name="actionModeSelectAllDrawable">?android:attr/actionModeSelectAllDrawable</item>
-        <item name="actionModeShareDrawable">?android:attr/actionModeShareDrawable</item>
-
-        <!-- Panel attributes -->
-        <!-- TODO: panelMenuListWidth -->
-        <item name="panelMenuListWidth">@dimen/abc_panel_menu_list_width</item>
-        <!-- TODO: panelMenuListTheme -->
-        <item name="panelMenuListTheme">@style/Theme.AppCompat.CompactMenu</item>
-        <item name="panelBackground">?android:attr/panelBackground</item>
-        <item name="listChoiceBackgroundIndicator">?android:attr/listChoiceBackgroundIndicator</item>
-
-        <!-- List attributes -->
-        <item name="textAppearanceListItem">?android:attr/textAppearanceListItem</item>
-        <item name="textAppearanceListItemSmall">?android:attr/textAppearanceListItemSmall</item>
-        <item name="textAppearanceListItemSecondary">?android:attr/textAppearanceListItemSecondary</item>
-        <item name="listPreferredItemHeight">?android:attr/listPreferredItemHeight</item>
-        <item name="listPreferredItemHeightSmall">?android:attr/listPreferredItemHeightSmall</item>
-        <item name="listPreferredItemHeightLarge">?android:attr/listPreferredItemHeightLarge</item>
-        <item name="listPreferredItemPaddingLeft">?android:attr/listPreferredItemPaddingLeft</item>
-        <item name="listPreferredItemPaddingRight">?android:attr/listPreferredItemPaddingRight</item>
-
-        <!-- Spinner styles -->
-        <item name="spinnerStyle">?android:attr/spinnerStyle</item>
-
-        <!-- Required for use of support_simple_spinner_dropdown_item.xml -->
-        <item name="spinnerDropDownItemStyle">?android:attr/spinnerDropDownItemStyle</item>
-        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
-
-        <!-- Popup Menu styles -->
-        <item name="popupMenuStyle">?android:attr/popupMenuStyle</item>
-        <item name="textAppearanceLargePopupMenu">?android:attr/textAppearanceLargePopupMenu</item>
-        <item name="textAppearanceSmallPopupMenu">?android:attr/textAppearanceSmallPopupMenu</item>
-        <item name="textAppearancePopupMenuHeader">?android:attr/textAppearancePopupMenuHeader</item>
-        <item name="listPopupWindowStyle">?android:attr/listPopupWindowStyle</item>
-        <item name="dropDownListViewStyle">?android:attr/dropDownListViewStyle</item>
-        <item name="listMenuViewStyle">?android:attr/listMenuViewStyle</item>
-
-        <!-- SearchView attributes -->
-        <item name="searchViewStyle">?android:attr/searchViewStyle</item>
-        <!-- TODO: textColorSearchUrl -->
-        <item name="textColorSearchUrl">@color/abc_search_url_text</item>
-        <item name="textAppearanceSearchResultTitle">?android:attr/textAppearanceSearchResultTitle</item>
-        <item name="textAppearanceSearchResultSubtitle">?android:attr/textAppearanceSearchResultSubtitle</item>
-
-        <!-- ShareActionProvider attributes -->
-        <!-- TODO: activityChooserViewStyle -->
-        <item name="activityChooserViewStyle">@style/Widget.AppCompat.ActivityChooserView</item>
-
-        <!-- Toolbar styles -->
-        <item name="toolbarStyle">?android:attr/toolbarStyle</item>
-        <!-- TODO: toolbarNavigationButtonStyle -->
-        <item name="toolbarNavigationButtonStyle">@style/Widget.AppCompat.Toolbar.Button.Navigation</item>
-
-        <item name="editTextStyle">?android:attr/editTextStyle</item>
-        <item name="editTextBackground">?android:attr/editTextBackground</item>
-        <item name="editTextColor">?android:attr/editTextColor</item>
-        <item name="autoCompleteTextViewStyle">?android:attr/autoCompleteTextViewStyle</item>
-
-        <!-- Color palette -->
-        <item name="colorPrimaryDark">?android:attr/colorPrimaryDark</item>
-        <item name="colorPrimary">?android:attr/colorPrimary</item>
-        <item name="colorAccent">?android:attr/colorAccent</item>
-
-        <item name="colorControlNormal">?android:attr/colorControlNormal</item>
-        <item name="colorControlActivated">?android:attr/colorControlActivated</item>
-        <item name="colorControlHighlight">?android:attr/colorControlHighlight</item>
-        <item name="colorButtonNormal">?android:attr/colorButtonNormal</item>
-        <!-- TODO: colorSwitchThumbNormal -->
-        <item name="colorSwitchThumbNormal">@color/switch_thumb_material_dark</item>
-        <item name="controlBackground">?attr/selectableItemBackgroundBorderless</item>
-
-        <!-- TODO: drawerArrowStyle -->
-        <item name="drawerArrowStyle">@style/Widget.AppCompat.DrawerArrowToggle</item>
-
-        <item name="checkboxStyle">?android:attr/checkboxStyle</item>
-        <item name="radioButtonStyle">?android:attr/radioButtonStyle</item>
-        <item name="switchStyle">?android:attr/switchStyle</item>
-
-        <item name="ratingBarStyle">?android:attr/ratingBarStyle</item>
-        <item name="ratingBarStyleIndicator">?android:attr/ratingBarStyleIndicator</item>
-        <item name="ratingBarStyleSmall">?android:attr/ratingBarStyleSmall</item>
-        <item name="seekBarStyle">?android:attr/seekBarStyle</item>
-
-        <!-- Button styles -->
-        <item name="android:buttonStyle">@style/Widget.CarUi.Button</item>
-        <item name="buttonStyle">?android:attr/buttonStyle</item>
-        <item name="buttonStyleSmall">?android:attr/buttonStyleSmall</item>
-
-        <item name="imageButtonStyle">?android:attr/imageButtonStyle</item>
-
-        <item name="buttonBarStyle">?android:attr/buttonBarStyle</item>
-        <item name="buttonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
-        <item name="buttonBarPositiveButtonStyle">?android:attr/buttonBarPositiveButtonStyle</item>
-        <item name="buttonBarNegativeButtonStyle">?android:attr/buttonBarNegativeButtonStyle</item>
-        <item name="buttonBarNeutralButtonStyle">?android:attr/buttonBarNeutralButtonStyle</item>
-
-        <!-- Dialog attributes -->
-        <item name="dialogTheme">?android:attr/dialogTheme</item>
-        <item name="dialogPreferredPadding">?android:attr/dialogPreferredPadding</item>
-        <item name="dialogCornerRadius">?android:attr/dialogCornerRadius</item>
-
-        <item name="alertDialogTheme">?android:attr/alertDialogTheme</item>
-        <item name="alertDialogStyle">?android:attr/alertDialogStyle</item>
-        <item name="alertDialogCenterButtons">false</item>
-        <item name="textColorAlertDialogListItem">?android:attr/textColorAlertDialogListItem</item>
-        <item name="listDividerAlertDialog">?android:attr/listDividerAlertDialog</item>
-
-        <!-- Define these here; ContextThemeWrappers around themes that define them should
-             always clear these values. -->
-        <item name="windowFixedWidthMajor">@null</item>
-        <item name="windowFixedWidthMinor">@null</item>
-        <item name="windowFixedHeightMajor">@null</item>
-        <item name="windowFixedHeightMinor">@null</item>
-
-        <!-- Tooltip attributes -->
-        <!-- TODO: tooltipFrameBackground -->
-        <item name="tooltipFrameBackground">@drawable/tooltip_frame_light</item>
-        <!-- TODO: tooltipForegroundColor -->
-        <item name="tooltipForegroundColor">@color/foreground_material_light</item>
-
-        <item name="colorError">?android:attr/colorError</item>
-
-        <!-- Attributes from: Platform.AppCompat -->
-
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowActionBar">false</item>
-
-        <item name="listChoiceIndicatorSingleAnimated">?android:attr/listChoiceIndicatorSingle</item>
-        <item name="listChoiceIndicatorMultipleAnimated">?android:attr/listChoiceIndicatorMultiple</item>
-
-        <item name="preferenceTheme">@style/CarUiPreferenceTheme</item>
-
-        <!-- Used by CarUiRecyclerView -->
-        <item name="carUiRecyclerViewStyle">@style/Widget.CarUi.CarUiRecyclerView</item>
-
-        <!-- textAppearance -->
-        <item name="android:textAppearance">@style/TextAppearance.CarUi</item>
-        <!--@color/transparent does not completely remove highlight  -->
-        <item name="android:textColorHighlight">#00FFFFFF</item>
-    </style>
-
-    <!-- TODO(b/150230923) remove this when other apps are ready -->
-    <style name="Theme.CarUi.WithToolbar">
-        <item name="carUiBaseLayout">true</item>
-        <item name="carUiToolbar">true</item>
-    </style>
-
-    <style name="Theme.CarUi.NoToolbar">
-        <item name="carUiBaseLayout">true</item>
-        <item name="carUiToolbar">false</item>
-    </style>
-
-    <style name="CarUiPreferenceTheme">
-        <item name="checkBoxPreferenceStyle">@style/Preference.CarUi.CheckBoxPreference</item>
-        <item name="dialogPreferenceStyle">@style/Preference.CarUi.DialogPreference</item>
-        <item name="dropdownPreferenceStyle">@style/Preference.CarUi.DropDown</item>
-        <item name="editTextPreferenceStyle">@style/Preference.CarUi.DialogPreference.EditTextPreference</item>
-        <item name="preferenceCategoryStyle">@style/Preference.CarUi.Category</item>
-        <item name="preferenceFragmentCompatStyle">@style/PreferenceFragment.CarUi</item>
-        <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList.CarUi</item>
-        <item name="preferenceFragmentStyle">@style/PreferenceFragment.CarUi</item>
-        <item name="preferenceScreenStyle">@style/Preference.CarUi.PreferenceScreen</item>
-        <item name="preferenceStyle">@style/Preference.CarUi</item>
-        <item name="seekBarPreferenceStyle">@style/Preference.CarUi.SeekBarPreference</item>
-        <item name="switchPreferenceStyle">@style/Preference.CarUi.SwitchPreference</item>
-    </style>
-
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/values.xml b/car-ui-lib/car-ui-lib/src/main/res/values/values.xml
deleted file mode 100644
index 35f033c..0000000
--- a/car-ui-lib/car-ui-lib/src/main/res/values/values.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<resources>
-    <!-- Toolbar -->
-
-    <!-- Layout to be used for toolbar tabs -->
-    <layout name="car_ui_toolbar_tab_item_layout">@layout/car_ui_toolbar_tab_item</layout>
-    <layout name="car_ui_toolbar_tab_item_layout_flexible">@layout/car_ui_toolbar_tab_item_flexible</layout>
-    <layout name="car_ui_toolbar_menu_item_primary">@layout/car_ui_toolbar_menu_item</layout>
-</resources>
diff --git a/car-ui-lib/documentation/images/android_project_view.png b/car-ui-lib/documentation/images/android_project_view.png
deleted file mode 100644
index 9b82bc2..0000000
--- a/car-ui-lib/documentation/images/android_project_view.png
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/documentation/images/launch_paintbooth.png b/car-ui-lib/documentation/images/launch_paintbooth.png
deleted file mode 100644
index ba901b6..0000000
--- a/car-ui-lib/documentation/images/launch_paintbooth.png
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/documentation/images/navigating_to_car_ui_lib.png b/car-ui-lib/documentation/images/navigating_to_car_ui_lib.png
deleted file mode 100644
index 4897ad6..0000000
--- a/car-ui-lib/documentation/images/navigating_to_car_ui_lib.png
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/documentation/images/open_existing_android_studio_project.png b/car-ui-lib/documentation/images/open_existing_android_studio_project.png
deleted file mode 100644
index 29c2f96..0000000
--- a/car-ui-lib/documentation/images/open_existing_android_studio_project.png
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/documentation/images/running_tests.png b/car-ui-lib/documentation/images/running_tests.png
deleted file mode 100644
index 796bf3a..0000000
--- a/car-ui-lib/documentation/images/running_tests.png
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/documentation/images/shared_library_setup.png b/car-ui-lib/documentation/images/shared_library_setup.png
deleted file mode 100644
index 8aac255..0000000
--- a/car-ui-lib/documentation/images/shared_library_setup.png
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/generate_rros.mk b/car-ui-lib/generate_rros.mk
index 63c69fd..4f67520 100644
--- a/car-ui-lib/generate_rros.mk
+++ b/car-ui-lib/generate_rros.mk
@@ -21,13 +21,10 @@
 define generate-rro
   include $$(CLEAR_VARS)
 
-  rro_package_name := $(subst .,-,$(2))-$(subst .,-,$(1))
-  manifest_file := $(4)
+  rro_package_name := $(2)-$(subst .,-,$(1))
   LOCAL_RESOURCE_DIR := $(3)
   LOCAL_RRO_THEME := $$(rro_package_name)
   LOCAL_PACKAGE_NAME := $$(rro_package_name)
-  LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-  LOCAL_LICENSE_CONDITIONS := notice
   LOCAL_CERTIFICATE := platform
   LOCAL_SDK_VERSION := current
   LOCAL_USE_AAPT2 := true
@@ -37,7 +34,7 @@
   LOCAL_AAPT_FLAGS := --no-resource-deduping
 
   gen := $$(call intermediates-dir-for,ETC,$$(rro_package_name))/AndroidManifest.xml
-  $$(gen): $$(manifest_file)
+  $$(gen): $(LOCAL_PATH)/AndroidManifest.xml
 	@echo Generate $$@
 	$$(hide) mkdir -p $$(dir $$@)
 	$$(hide) sed -e "s/{{TARGET_PACKAGE_NAME}}/$(1)/" \
@@ -47,17 +44,11 @@
   include $$(BUILD_RRO_PACKAGE)
 endef
 
-ifndef CAR_UI_RRO_MANIFEST_FILE
-CAR_UI_RRO_MANIFEST_FILE = $(LOCAL_PATH)/AndroidManifest.xml
-endif
-
 $(foreach t,\
   $(CAR_UI_RRO_TARGETS),\
-  $(eval $(call generate-rro,$(t),$(CAR_UI_RRO_SET_NAME),$(CAR_UI_RESOURCE_DIR),$(CAR_UI_RRO_MANIFEST_FILE))) \
-  )
+  $(eval $(call generate-rro,$(t),$(CAR_UI_RRO_SET_NAME),$(CAR_UI_RESOURCE_DIR))))
 
 # Clear variables
 CAR_UI_RRO_SET_NAME :=
-CAR_UI_RRO_MANIFEST_FILE :=
 CAR_UI_RESOURCE_DIR :=
 CAR_UI_RRO_TARGETS :=
diff --git a/car-ui-lib/gradlew b/car-ui-lib/gradlew
index fbd7c51..cccdd3d 100755
--- a/car-ui-lib/gradlew
+++ b/car-ui-lib/gradlew
@@ -1,21 +1,5 @@
 #!/usr/bin/env sh
 
-#
-# Copyright 2015 the original author or authors.
-#
-# 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
-#
-#      https://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.
-#
-
 ##############################################################################
 ##
 ##  Gradle start up script for UN*X
@@ -44,7 +28,7 @@
 APP_BASE_NAME=`basename "$0"`
 
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+DEFAULT_JVM_OPTS=""
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD="maximum"
@@ -82,7 +66,6 @@
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
-
 # Determine the Java command to use to start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -126,11 +109,10 @@
     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
 fi
 
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-    
     JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
@@ -156,19 +138,19 @@
         else
             eval `echo args$i`="\"$arg\""
         fi
-        i=`expr $i + 1`
+        i=$((i+1))
     done
     case $i in
-        0) set -- ;;
-        1) set -- "$args0" ;;
-        2) set -- "$args0" "$args1" ;;
-        3) set -- "$args0" "$args1" "$args2" ;;
-        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
     esac
 fi
 
@@ -177,9 +159,14 @@
     for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
     echo " "
 }
-APP_ARGS=`save "$@"`
+APP_ARGS=$(save "$@")
 
 # Collect all arguments for the java command, following the shell quoting and substitution rules
 eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
 
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
 exec "$JAVACMD" "$@"
diff --git a/car-ui-lib/gradlew.bat b/car-ui-lib/gradlew.bat
index a9f778a..e95643d 100644
--- a/car-ui-lib/gradlew.bat
+++ b/car-ui-lib/gradlew.bat
@@ -1,19 +1,3 @@
-@rem

-@rem Copyright 2015 the original author or authors.

-@rem

-@rem Licensed under the Apache License, Version 2.0 (the "License");

-@rem you may not use this file except in compliance with the License.

-@rem You may obtain a copy of the License at

-@rem

-@rem      https://www.apache.org/licenses/LICENSE-2.0

-@rem

-@rem Unless required by applicable law or agreed to in writing, software

-@rem distributed under the License is distributed on an "AS IS" BASIS,

-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-@rem See the License for the specific language governing permissions and

-@rem limitations under the License.

-@rem

-

 @if "%DEBUG%" == "" @echo off

 @rem ##########################################################################

 @rem

@@ -29,11 +13,8 @@
 set APP_BASE_NAME=%~n0

 set APP_HOME=%DIRNAME%

 

-@rem Resolve any "." and ".." in APP_HOME to make it shorter.

-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

-

 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

+set DEFAULT_JVM_OPTS=

 

 @rem Find java.exe

 if defined JAVA_HOME goto findJavaFromJavaHome

@@ -84,7 +65,6 @@
 

 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

 

-

 @rem Execute Gradle

 "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

 

diff --git a/car-ui-lib/oem-apis/Android.bp b/car-ui-lib/oem-apis/Android.bp
deleted file mode 100644
index e6bd2ca..0000000
--- a/car-ui-lib/oem-apis/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_library {
-    name: "car-ui-lib-oem-apis",
-
-    min_sdk_version: "28",
-    target_sdk_version: "30",
-    sdk_version: "current",
-
-    manifest: "src/main/AndroidManifest.xml",
-    srcs: ["src/main/java/**/*.java"],
-
-    optimize: {
-        enabled: false,
-    },
-
-    apex_available: [
-        "com.android.permission",
-        "//apex_available:platform",
-    ],
-}
diff --git a/car-ui-lib/oem-apis/README.md b/car-ui-lib/oem-apis/README.md
deleted file mode 100644
index 40d4b42..0000000
--- a/car-ui-lib/oem-apis/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Car-ui-lib OEM APIs
-
-```
-#############################################
-#                  WARNING                  #
-#############################################
-# The OEM APIs as they appear on this       #
-# branch of android are not finalized!      #
-# If a shared library is built using them,  #
-# it will cause apps to crash!              #
-#                                           #
-# Please get the OEM APIs from a later      #
-# branch of android instead.                #
-#############################################
-```
-
-These APIs allow OEMs to build a shared library for
-car-ui-lib that can supply custom implementations
-of car-ui-lib components. See
-SharedLibraryFactorySingleton for information
-on the entrypoint to the shared library.
diff --git a/car-ui-lib/oem-apis/build.gradle b/car-ui-lib/oem-apis/build.gradle
deleted file mode 100644
index 36f1047..0000000
--- a/car-ui-lib/oem-apis/build.gradle
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Library-level build file
-
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 30
-
-    defaultConfig {
-        minSdkVersion 28
-        targetSdkVersion 30
-        versionCode 1
-        versionName "1.0"
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
-    }
-
-    testOptions {
-        unitTests {
-            includeAndroidResources = true
-        }
-    }
-}
-
-dependencies {
-}
diff --git a/car-ui-lib/oem-apis/src/main/AndroidManifest.xml b/car-ui-lib/oem-apis/src/main/AndroidManifest.xml
deleted file mode 100644
index 4c48aee..0000000
--- a/car-ui-lib/oem-apis/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="should.not.matter.because.sta_tic.library">
-</manifest>
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/FocusAreaOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/FocusAreaOEMV1.java
deleted file mode 100644
index 017ec41..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/FocusAreaOEMV1.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis;
-
-import android.view.View;
-import android.widget.LinearLayout;
-
-/**
- * The OEM interface for a FocusArea. Unlike most components, the FocusArea has it's implementation
- * in the static library, and this interface is to give the shared library access to it. The
- * shared library is not expected to implement this interface.
- * <p>
- * See {@link SharedLibraryFactoryOEMV1#setRotaryFactories}
- */
-public interface FocusAreaOEMV1 {
-
-    /**
-     * Sets the padding (in pixels) of the FocusArea highlight.
-     * <p>
-     * It doesn't affect other values, such as the paddings on its child views.
-     */
-    void setHighlightPadding(int left, int top, int right, int bottom);
-
-    /**
-     * Sets the offset (in pixels) of the FocusArea's bounds.
-     * <p>
-     * It only affects the perceived bounds for the purposes of finding the nudge target. It doesn't
-     * affect the FocusArea's view bounds or highlight bounds. The offset should only be used when
-     * FocusAreas are overlapping and nudge interaction is ambiguous.
-     */
-    void setBoundsOffset(int left, int top, int right, int bottom);
-
-    /**
-     * Sets whether wrap-around is enabled for this FocusArea. Wrap-around being enabled means
-     * that when you try to move focus to the right from the rightmost view, the focus will
-     * wrap around to the leftmost view.
-     */
-    void setWrapAround(boolean wrapAround);
-
-    /** Sets the default focus view in this FocusArea. */
-    void setDefaultFocus(View defaultFocus);
-
-    /**
-     * Sets the nudge shortcut for the given {@code direction}. Removes the nudge shortcut if {@code
-     * view} is {@code null}.
-     */
-    void setNudgeShortcut(int direction, View view);
-
-    /**
-     * Gets the underlying view that this object represents. This is just for adding the view
-     * to the rest of the view hierarchy; no methods that change the appearance/behavior of the
-     * view should be called on it.
-     */
-    LinearLayout getView();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/FocusParkingViewOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/FocusParkingViewOEMV1.java
deleted file mode 100644
index f6ec374..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/FocusParkingViewOEMV1.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis;
-
-import android.view.View;
-
-/**
- * The OEM interface for a FocusParkingView. Unlike most components, the FocusParkingView has it's
- * implementation in the static library, and this interface is to give the shared library access to
- * it. The shared library is not expected to implement this interface.
- * <p>
- * See {@link SharedLibraryFactoryOEMV1#setRotaryFactories}
- */
-public interface FocusParkingViewOEMV1 {
-
-    /**
-     * Sets whether this view should restore focus when the framework wants to focus this view. When
-     * set to false, this view allows itself to be focused instead. This should be set to false for
-     * the {@code FocusParkingView} in a {@code TaskView}. The default value is true.
-     */
-    void setShouldRestoreFocus(boolean shouldRestoreFocus);
-
-    /**
-     * Gets the underlying view that this object represents. This is just for adding the view
-     * to the rest of the view hierarchy; no methods that change the appearance/behavior of the
-     * view should be called on it.
-     * <p>
-     * This should be the first focusable view in the view hierarchy, but other than that
-     * the position/size doesn't matter. It's recommended to use wrap_content as both the width
-     * and height in the LayoutParams.
-     */
-    View getView();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/InsetsOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/InsetsOEMV1.java
deleted file mode 100644
index 0e501d6..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/InsetsOEMV1.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis;
-
-import java.util.Objects;
-
-/**
- * Represents insets in the base layout. {@link com.android.car.ui.baselayout.Insets} for more
- * information.
- */
-public final class InsetsOEMV1 {
-    private final int mLeft;
-    private final int mRight;
-    private final int mTop;
-    private final int mBottom;
-
-    public InsetsOEMV1() {
-        mLeft = mRight = mTop = mBottom = 0;
-    }
-
-    public InsetsOEMV1(int left, int top, int right, int bottom) {
-        mLeft = left;
-        mRight = right;
-        mTop = top;
-        mBottom = bottom;
-    }
-
-    public int getLeft() {
-        return mLeft;
-    }
-
-    public int getRight() {
-        return mRight;
-    }
-
-    public int getTop() {
-        return mTop;
-    }
-
-    public int getBottom() {
-        return mBottom;
-    }
-
-    @Override
-    public String toString() {
-        return "{ left: " + mLeft + ", right: " + mRight
-                + ", top: " + mTop + ", bottom: " + mBottom + " }";
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        InsetsOEMV1 insets = (InsetsOEMV1) o;
-        return mLeft == insets.mLeft
-                && mRight == insets.mRight
-                && mTop == insets.mTop
-                && mBottom == insets.mBottom;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mLeft, mRight, mTop, mBottom);
-    }
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/SharedLibraryFactoryOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/SharedLibraryFactoryOEMV1.java
deleted file mode 100644
index db45204..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/SharedLibraryFactoryOEMV1.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis;
-
-import android.content.Context;
-import android.view.View;
-
-import com.android.car.ui.sharedlibrary.oemapis.appstyledview.AppStyledViewControllerOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewAttributesOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ViewHolderOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1;
-
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * This interface contains methods to create customizable carui components.
- * <p>
- * It returns them as their OEM-versioned interfaces (i.e. ToolbarControllerOEMV1) and is versioned
- * itself so that no additional reflection or casting is necessary once the SharedLibraryFactory has
- * been created.
- * <p>
- * Multiple of these can be provided via {@link SharedLibraryVersionProviderOEMV1} to allow shared
- * libraries to provide an old implementation for old apps, and a newer implementation for newer
- * apps.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public interface SharedLibraryFactoryOEMV1 {
-
-    /**
-     * Gives the shared library access to two factories that will create FocusParkingViews and
-     * FocusAreas. These views have their implementation in the static car-ui-lib.
-     * <p>
-     * When {@link #installBaseLayoutAround} creates a base layout, it should include a
-     * FocusParkingView for rotary to work properly. If the base layout has a toolbar, it should
-     * also be wrapped in a FocusArea.
-     *
-     * @param focusParkingViewFactory a function that will infinitely return new instances of
-     *                                FocusParkingView
-     * @param focusAreaFactory        a function that will infinitely return new instances of
-     *                                FocusArea
-     */
-    void setRotaryFactories(
-            Function<Context, FocusParkingViewOEMV1> focusParkingViewFactory,
-            Function<Context, FocusAreaOEMV1> focusAreaFactory);
-
-    /**
-     * Creates the base layout, and optionally the toolbar.
-     *
-     * @param contentView           The view to install the base layout around.
-     * @param insetsChangedListener A method to call when the insets change.
-     * @param toolbarEnabled        Whether or not to add a toolbar to the base layout.
-     * @param fullscreen            Whether or not this base layout / toolbar is taking up the whole
-     *                              screen. This can be used to decide whether or not to add
-     *                              decorations around the edge of it.
-     * @return A {@link ToolbarControllerOEMV1} or null if {@code toolbarEnabled} was false.
-     */
-    ToolbarControllerOEMV1 installBaseLayoutAround(
-            View contentView,
-            Consumer<InsetsOEMV1> insetsChangedListener,
-            boolean toolbarEnabled,
-            boolean fullscreen);
-
-    /**
-     * If implementation of the library would like to opt out of controlling the base layout and
-     * subsequently the toolbar they can do so by returning false from this method.
-     *
-     * @return false if {@link #installBaseLayoutAround} should not be called for this library
-     */
-    boolean customizesBaseLayout();
-
-    /**
-     * Creates a app styled view.
-     *
-     * @return the view used for app styled view.
-     */
-    AppStyledViewControllerOEMV1 createAppStyledView();
-
-    /**
-     * Creates an instance of CarUiRecyclerView
-     *
-     * @param context The visual context to create views with.
-     * @param attrs   An object containing initial attributes for the button.
-     */
-    RecyclerViewOEMV1 createRecyclerView(Context context, RecyclerViewAttributesOEMV1 attrs);
-
-    /**
-     * Creates an instance of list item adapter
-     */
-    AdapterOEMV1<? extends ViewHolderOEMV1> createListItemAdapter(List<ListItemOEMV1> items);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/SharedLibraryVersionProviderOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/SharedLibraryVersionProviderOEMV1.java
deleted file mode 100644
index 4b01d63..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/SharedLibraryVersionProviderOEMV1.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis;
-
-import android.content.Context;
-
-/**
- * An interface for objects that support providing a list a supported versions of
- * {@link SharedLibraryFactoryOEMV1} to the app. See {@link #getSharedLibraryFactory(int)}}
- * for more information.
- */
-public interface SharedLibraryVersionProviderOEMV1 {
-    /**
-     * Returns an object that implements {@link SharedLibraryFactoryOEMV1} or a later version.
-     *
-     * OEMs should aim to return the highest version of the factory possible that is <=
-     * {@code maxVersion}. If the shared library is not able to provide that version,
-     * it may return null, in which case car-ui-lib will fall back to it's static,
-     * uncustomized implementation.
-     *
-     * The shared library may also choose to return different SharedLibraryFactories based on
-     * certain conditions, like what type of device this is, or what app it's being used in.
-     * (The app can be discovered via {@link android.app.Application#getProcessName()}
-     *
-     * @param maxVersion The maximum version of {@link SharedLibraryFactoryOEMV1} supported by the
-     *                   app.
-     * @param context The shared library's context. It uses the shared library's classloader,
-     *                so layout inflaters created from it can use views defined in the shared lib.
-     * @param packageName The package name of the app creating the shared library. Can be used
-     *                    to provide per-app customizations.
-     *
-     * @return An object implementing {@link SharedLibraryFactoryOEMV1} for a version <=
-     *         {@code maxVersion}.
-     */
-    Object getSharedLibraryFactory(int maxVersion, Context context, String packageName);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/appstyledview/AppStyledViewControllerOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/appstyledview/AppStyledViewControllerOEMV1.java
deleted file mode 100644
index 0aed7e0..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/appstyledview/AppStyledViewControllerOEMV1.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.sharedlibrary.oemapis.appstyledview;
-
-import android.view.View;
-import android.view.WindowManager;
-
-/** The OEM interface for a AppStyledView. */
-public interface AppStyledViewControllerOEMV1 {
-
-    /**
-     * Creates a app styled view.
-     *
-     * @param content app content view.
-     * @return the view used for app styled view.
-     */
-    View getAppStyledView(View content);
-
-    /**
-     * Sets a {@link Runnable} to be called whenever the close icon is clicked.
-     */
-    void setOnCloseClickListener(Runnable listener);
-
-    /**
-     * Sets the nav icon to be used.
-     */
-    void setNavIcon(int navIcon);
-
-    /**
-     * Returns the layout params for the AppStyledView dialog
-     */
-    WindowManager.LayoutParams getDialogWindowLayoutParam(WindowManager.LayoutParams params);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/AdapterDataObserverOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/AdapterDataObserverOEMV1.java
deleted file mode 100644
index 628bb74..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/AdapterDataObserverOEMV1.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-/**
- * {@link androidx.recyclerview.widget.RecyclerView.Adapter#registerAdapterDataObserver}
- */
-public interface AdapterDataObserverOEMV1 {
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.AdapterDataObserver#onChanged()} */
-    void onChanged();
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.AdapterDataObserver#onItemRangeChanged(int, int)} */
-    void onItemRangeChanged(int positionStart, int itemCount);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.AdapterDataObserver#onItemRangeChanged(int, int, Object)} */
-    void onItemRangeChanged(int positionStart, int itemCount, Object payload);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.AdapterDataObserver#onItemRangeInserted(int, int)} */
-    void onItemRangeInserted(int positionStart, int itemCount);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.AdapterDataObserver#onItemRangeRemoved(int, int)} */
-    void onItemRangeRemoved(int positionStart, int itemCount);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.AdapterDataObserver#onItemRangeMoved(int, int, int)} */
-    void onItemMoved(int fromPosition, int toPosition);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.AdapterDataObserver#onStateRestorationPolicyChanged()} */
-    void onStateRestorationPolicyChanged();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/AdapterOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/AdapterOEMV1.java
deleted file mode 100644
index 2e4156e..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/AdapterOEMV1.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * See {@link androidx.recyclerview.widget.RecyclerView.Adapter}
- *
- * @param <V> A class that extends ViewHolder that will be used by the adapter.
- */
-public interface AdapterOEMV1<V extends ViewHolderOEMV1> {
-
-    int ALLOW = 0;
-    int PREVENT_WHEN_EMPTY = 1;
-    int PREVENT = 2;
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#getItemCount()} */
-    int getItemCount();
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#getItemId(int)} */
-    long getItemId(int position);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#getItemViewType(int)} */
-    int getItemViewType(int position);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#getStateRestorationPolicy()} */
-    int getStateRestorationPolicyInt();
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#onAttachedToRecyclerView} */
-    void onAttachedToRecyclerView(RecyclerViewOEMV1 recyclerView);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#bindViewHolder} */
-    void bindViewHolder(V holder, int position);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#createViewHolder} */
-    V createViewHolder(ViewGroup parent, int viewType);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#onDetachedFromRecyclerView} */
-    void onDetachedFromRecyclerView(RecyclerViewOEMV1 recyclerView);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#onFailedToRecycleView} */
-    boolean onFailedToRecycleView(V holder);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#onViewAttachedToWindow} */
-    void onViewAttachedToWindow(V holder);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#onViewDetachedFromWindow} */
-    void onViewDetachedFromWindow(V holder);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#onViewRecycled} */
-    void onViewRecycled(V holder);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#registerAdapterDataObserver} */
-    void registerAdapterDataObserver(AdapterDataObserverOEMV1 observer);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#unregisterAdapterDataObserver} */
-    void unregisterAdapterDataObserver(AdapterDataObserverOEMV1 observer);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.Adapter#hasStableIds} */
-    boolean hasStableIds();
-
-    /**
-     * Sets the wrapping recyclerview
-     * @param recyclerview the wrapping recyclerview
-     */
-    void setRecyclerView(View recyclerview);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ContentListItemOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ContentListItemOEMV1.java
deleted file mode 100644
index e672b4f..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ContentListItemOEMV1.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-import android.graphics.drawable.Drawable;
-import android.text.SpannableString;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * The OEM interface for content list item.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public final class ContentListItemOEMV1 implements ListItemOEMV1 {
-    public enum IconType {
-        /**
-         * For an icon type of CONTENT, the primary icon is a larger than {@code STANDARD}.
-         */
-        CONTENT,
-        /**
-         * For an icon type of STANDARD, the primary icon is the standard size.
-         */
-        STANDARD,
-        /**
-         * For an icon type of AVATAR, the primary icon is masked to provide an icon with a modified
-         * shape.
-         */
-        AVATAR
-    }
-
-    /**
-     * Enum of secondary action types of a list item.
-     */
-    public enum Action {
-        /**
-         * For an action value of NONE, no action element is shown for a list item.
-         */
-        NONE,
-        /**
-         * For an action value of SWITCH, a switch is shown for the action element of the list
-         * item.
-         */
-        SWITCH,
-        /**
-         * For an action value of CHECK_BOX, a checkbox is shown for the action element of the list
-         * item.
-         */
-        CHECK_BOX,
-        /**
-         * For an action value of RADIO_BUTTON, a radio button is shown for the action element of
-         * the list item.
-         */
-        RADIO_BUTTON,
-        /**
-         * For an action value of ICON, an icon is shown for the action element of the list item.
-         */
-        ICON,
-        /**
-         * For an action value CHEVRON, a chevron is shown for the action element of the list item.
-         */
-        CHEVRON
-    }
-
-    private final Action mAction;
-    private final SpannableString mTitle;
-    private final List<SpannableString> mBody;
-    private final Drawable mIcon;
-    private final IconType mPrimaryIconType;
-    private final Drawable mSupplementalIcon;
-    private boolean mIsChecked;
-    private final boolean mIsEnabled;
-    private final boolean mIsActivated;
-    private final boolean mIsActionDividerVisible;
-    private final Consumer<ContentListItemOEMV1> mOnClickListener;
-    private final Consumer<ContentListItemOEMV1> mOnCheckedChangeListener;
-    private final Consumer<ContentListItemOEMV1> mSupplementalIconOnClickListener;
-
-    ContentListItemOEMV1(Builder builder) {
-        mAction = builder.mAction;
-        mTitle = builder.mTitle;
-        mBody = builder.mBody;
-        mIcon = builder.mIcon;
-        mPrimaryIconType = builder.mPrimaryIconType;
-        mSupplementalIcon = builder.mSupplementalIcon;
-        mIsChecked = builder.mIsChecked;
-        mIsEnabled = builder.mIsEnabled;
-        mIsActivated = builder.mIsActivated;
-        mIsActionDividerVisible = builder.mIsActionDividerVisible;
-        mOnClickListener = builder.mOnClickListener;
-        mOnCheckedChangeListener = builder.mOnCheckedChangeListener;
-        mSupplementalIconOnClickListener = builder.mSupplementalIconOnClickListener;
-    }
-
-    /**
-     * Returns the title of the item.
-     */
-    public SpannableString getTitle() {
-        return mTitle;
-    }
-
-    /**
-     * Returns the body of the item.
-     */
-    public List<SpannableString> getBody() {
-        return mBody;
-    }
-
-    /**
-     * Returns the icon of the item.
-     */
-    public Drawable getIcon() {
-        return mIcon;
-    }
-
-    /**
-     * Returns the primary icon type for the item.
-     */
-    public IconType getPrimaryIconType() {
-        return mPrimaryIconType;
-    }
-
-    /**
-     * Returns {@code true} if the item is activated.
-     */
-    public boolean isActivated() {
-        return mIsActivated;
-    }
-
-    /**
-     * Returns {@code true} if the item is enabled.
-     */
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    /**
-     * Returns {@code true} if the item is checked. Will always return {@code false} when the action
-     * type for the item is {@code Action.NONE}.
-     */
-    public boolean isChecked() {
-        return mIsChecked;
-    }
-
-    /**
-     * Returns {@code true} if the action divider is visible.
-     */
-    public boolean isActionDividerVisible() {
-        return mIsActionDividerVisible;
-    }
-
-    /**
-     * Returns the action type for the item.
-     */
-    public Action getAction() {
-        return mAction;
-    }
-
-    /**
-     * Returns the supplemental icon for the item.
-     */
-    public Drawable getSupplementalIcon() {
-        return mSupplementalIcon;
-    }
-
-    /**
-     * Returns the click listener registered for the supplemental icon on this item.
-     */
-    public Consumer<ContentListItemOEMV1> getSupplementalIconOnClickListener() {
-        return mSupplementalIconOnClickListener;
-    }
-
-    /**
-     * Returns the click listener registered for this item.
-     */
-    public Consumer<ContentListItemOEMV1> getOnClickListener() {
-        return mOnClickListener;
-    }
-
-    /**
-     * Returns the checked change listener registered for this item.
-     */
-    public Consumer<ContentListItemOEMV1> getOnCheckedChangeListener() {
-        return mOnCheckedChangeListener;
-    }
-
-    /**
-     * Sets the checked state of the item.
-     *
-     * @param checked the checked state for the item.
-     */
-    public void setChecked(boolean checked) {
-        if (checked == mIsChecked) {
-            return;
-        }
-
-        // Checked state can only be set when action type is checkbox, radio button or switch.
-        if (mAction == Action.CHECK_BOX || mAction == Action.SWITCH
-                || mAction == Action.RADIO_BUTTON) {
-            mIsChecked = checked;
-
-            if (mOnCheckedChangeListener != null) {
-                mOnCheckedChangeListener.accept(this);
-            }
-        }
-    }
-
-    /**
-     * A builder of {@link ContentListItemOEMV1}.
-     */
-    public static final class Builder {
-        private final Action mAction;
-        private SpannableString mTitle;
-        private List<SpannableString> mBody;
-        private Drawable mIcon;
-        private IconType mPrimaryIconType = IconType.STANDARD;
-        private Drawable mSupplementalIcon;
-        private boolean mIsChecked = false;
-        private boolean mIsEnabled = true;
-        private boolean mIsActivated = false;
-        private boolean mIsActionDividerVisible;
-        private Consumer<ContentListItemOEMV1> mOnClickListener;
-        private Consumer<ContentListItemOEMV1> mOnCheckedChangeListener;
-        private Consumer<ContentListItemOEMV1> mSupplementalIconOnClickListener;
-
-        /**
-         * Returns a new instance of a {@link Builder}.
-         */
-        public Builder(Action action) {
-            mAction = action;
-        }
-
-        /**
-         * Sets the title of the item.
-         *
-         * @param text text to display as title
-         */
-        public Builder setTitle(SpannableString text) {
-            mTitle = text;
-            return this;
-        }
-
-        /**
-         * Sets the body of the item.
-         *
-         * @param text text to display as body text.
-         */
-        public Builder setBody(SpannableString text) {
-            mBody = Collections.singletonList(text);
-            return this;
-        }
-
-        /**
-         * Sets the body of the item.
-         *
-         * @param textList list of text to display as body text. Each {@link SpannableString} in the
-         *                list will be rendered on a new line, separated by a line break.
-         */
-        public Builder setBody(List<SpannableString> textList) {
-            mBody = textList;
-            return this;
-        }
-
-        /**
-         * Sets the icon of the item.
-         *
-         * @param icon the icon to display.
-         * @param type the icon type for the item.
-         */
-        public Builder setIcon(Drawable icon, IconType type) {
-            mIcon = icon;
-            mPrimaryIconType = type;
-            return this;
-        }
-
-        /**
-         * Sets the activated state of the item.
-         *
-         * @param activated the activated state for the item.
-         */
-        public Builder setActivated(boolean activated) {
-            mIsActivated = activated;
-            return this;
-        }
-
-        /**
-         * Sets the enabled state of the item.
-         *
-         * @param enabled the enabled state for the item.
-         */
-        public Builder setEnabled(boolean enabled) {
-            mIsEnabled = enabled;
-            return this;
-        }
-
-        /**
-         * Sets the checked state of the item.
-         *
-         * @param checked the checked state for the item.
-         */
-        public Builder setChecked(boolean checked) {
-            mIsChecked = checked;
-            return this;
-        }
-
-        /**
-         * Sets the visibility of the action divider.
-         *
-         * @param visible visibility of the action divider.
-         */
-        public Builder setActionDividerVisible(boolean visible) {
-            mIsActionDividerVisible = visible;
-            return this;
-        }
-
-        /**
-         * Sets supplemental icon to be displayed in a list item.
-         *
-         * @param icon the Drawable to set as the icon, or null to clear the content.
-         */
-        public Builder setSupplementalIcon(Drawable icon) {
-            return setSupplementalIcon(icon, null);
-        }
-
-        /**
-         * Sets supplemental icon to be displayed in a list item.
-         *
-         * @param icon     the Drawable to set as the icon, or null to clear the content.
-         * @param listener the callback that is invoked when the icon is clicked.
-         */
-        public Builder setSupplementalIcon(Drawable icon, Consumer<ContentListItemOEMV1> listener) {
-            if (mAction != Action.ICON) {
-                throw new IllegalStateException(
-                        "Cannot set supplemental icon on list item that does not have an action of "
-                                + "type ICON");
-            }
-
-            mSupplementalIcon = icon;
-            mSupplementalIconOnClickListener = listener;
-            return this;
-        }
-
-        /**
-         * Registers a callback to be invoked when the item is clicked.
-         *
-         * @param listener callback to be invoked when item is clicked.
-         */
-        public void setOnItemClickedListener(Consumer<ContentListItemOEMV1> listener) {
-            mOnClickListener = listener;
-        }
-
-        /**
-         * Registers a callback to be invoked when the checked state of list item changes.
-         *
-         * <p>Checked state changes can take place when the action type is {@code Action.SWITCH} or
-         * {@code Action.CHECK_BOX}.
-         *
-         * @param listener callback to be invoked when the checked state shown in the UI changes.
-         */
-        public Builder setOnCheckedChangeListener(Consumer<ContentListItemOEMV1> listener) {
-            mOnCheckedChangeListener = listener;
-            return this;
-        }
-
-        /**
-         * Returns a {@link ContentListItemOEMV1} for this {@link Builder}.
-         */
-        public ContentListItemOEMV1 build() {
-            return new ContentListItemOEMV1(this);
-        }
-    }
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/HeaderListItemOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/HeaderListItemOEMV1.java
deleted file mode 100644
index dc7c6f5..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/HeaderListItemOEMV1.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-import android.text.SpannableString;
-
-/**
- * The OEM interface for header list item.
- */
-public final class HeaderListItemOEMV1 implements ListItemOEMV1 {
-    private final SpannableString mTitle;
-    private final SpannableString mBody;
-
-    HeaderListItemOEMV1(Builder builder) {
-        mTitle = builder.mTitle;
-        mBody = builder.mBody;
-    }
-
-    /**
-     * Returns the title text for the header.
-     */
-    public SpannableString getTitle() {
-        return mTitle;
-    }
-
-    /**
-     * Returns the body text for the header.
-     */
-    public SpannableString getBody() {
-        return mBody;
-    }
-
-    /**
-     * A builder of {@link HeaderListItemOEMV1}.
-     */
-    public static final class Builder {
-        private final SpannableString mTitle;
-        private SpannableString mBody;
-
-        /**
-         * Returns a new instance of a {@link Builder}.
-         *
-         * @param title text to display as title
-         */
-        public Builder(SpannableString title) {
-            mTitle = title;
-        }
-
-        /**
-         * Sets the body of the item.
-         *
-         * @param body text to display as body text.
-         */
-        public Builder setBody(SpannableString body) {
-            mBody = body;
-            return this;
-        }
-
-        /**
-         * Returns a {@link HeaderListItemOEMV1} for this {@link ContentListItemOEMV1.Builder}.
-         */
-        public HeaderListItemOEMV1 build() {
-            return new HeaderListItemOEMV1(this);
-        }
-    }
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/LayoutStyleOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/LayoutStyleOEMV1.java
deleted file mode 100644
index 54895e1..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/LayoutStyleOEMV1.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-/**
- * Class for storing recyclerview layout style informatioon.
- */
-public interface LayoutStyleOEMV1 {
-
-    int LAYOUT_TYPE_LINEAR = 0;
-    int LAYOUT_TYPE_GRID = 1;
-
-    int ORIENTATION_HORIZONTAL = 0;
-    int ORIENTATION_VERTICAL = 1;
-
-    /** Returns number of recyclerview spans */
-    int getSpanCount();
-
-    /** Returns LAYOUT_TYPE_LINEAR vs LAYOUT_TYPE_GRID */
-    int getLayoutType();
-
-    /** Returns layout direction 0 for VERTICAL, 1 for HORIZONTAL */
-    int getOrientation();
-
-    /** Returns true if layout is reversed */
-    boolean getReverseLayout();
-
-    /** Returns a wrapper {@link androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup} */
-    SpanSizeLookupOEMV1 getSpanSizeLookup();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ListItemOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ListItemOEMV1.java
deleted file mode 100644
index 649d8a5..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ListItemOEMV1.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-/**
- * The OEM interface for a list item.
- */
-public interface ListItemOEMV1 {
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/OnScrollListenerOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/OnScrollListenerOEMV1.java
deleted file mode 100644
index 3ebec25..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/OnScrollListenerOEMV1.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-/** See {@link androidx.recyclerview.widget.RecyclerView.OnScrollListener} */
-public interface OnScrollListenerOEMV1 {
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.OnScrollListener#onScrollStateChanged} */
-    void onScrollStateChanged(RecyclerViewOEMV1 recyclerView, int newState);
-
-    /** See {@link androidx.recyclerview.widget.RecyclerView.OnScrollListener#onScrolled} */
-    void onScrolled(RecyclerViewOEMV1 recyclerView, int dx, int dy);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/RecyclerViewAttributesOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/RecyclerViewAttributesOEMV1.java
deleted file mode 100644
index bf7c2bf..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/RecyclerViewAttributesOEMV1.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-/**
- * Set of attributes passed from UI/layout to the oem implementation
- */
-public interface RecyclerViewAttributesOEMV1 {
-
-    int SIZE_SMALL = 0;
-    int SIZE_MEDIUM = 1;
-    int SIZE_LARGE = 2;
-
-    /** Returns if rotary scroll is enabled */
-    boolean isRotaryScrollEnabled();
-
-    /** Describes the expected relative size of the
-     * {@link androidx.recyclerview.widget.RecyclerView}. The list may be rendered differently for
-     * each expected size.
-     */
-    int getSize();
-
-    /** Returns information regarding the layout style */
-    LayoutStyleOEMV1 getLayoutStyle();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/RecyclerViewOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/RecyclerViewOEMV1.java
deleted file mode 100644
index a37be2c..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/RecyclerViewOEMV1.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-import android.view.View;
-
-/**
- * {@link androidx.recyclerview.widget.RecyclerView}
- */
-public interface RecyclerViewOEMV1 {
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#setAdapter(Adapter)} */
-    void setAdapter(AdapterOEMV1 adapter);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#addOnScrollListener} */
-    void addOnScrollListener(OnScrollListenerOEMV1 listener);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#removeOnScrollListener} */
-    void removeOnScrollListener(OnScrollListenerOEMV1 listener);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#clearOnScrollListeners()} */
-    void clearOnScrollListeners();
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#scrollToPosition(int)} */
-    void scrollToPosition(int position);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#smoothScrollBy(int, int)} */
-    void smoothScrollBy(int dx, int dy);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#smoothScrollToPosition(int)} */
-    void smoothScrollToPosition(int position);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#setHasFixedSize(boolean)} */
-    void setHasFixedSize(boolean hasFixedSize);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#hasFixedSize()} */
-    boolean hasFixedSize();
-
-    /**
-     * set {@link LayoutStyleOEMV1}. This is the replacement for
-     * {@link androidx.recyclerview.widget.RecyclerView.LayoutManager}
-     */
-    void setLayoutStyle(LayoutStyleOEMV1 layoutStyle);
-
-    /**
-     * Returns the view that will be displayed on the screen.
-     */
-    View getView();
-
-    /** {@link android.view.View#setPadding(int, int, int, int)} */
-    void setPadding(int left, int top, int right, int bottom);
-
-    /** {@link android.view.View#setPaddingRelative(int, int, int, int)} */
-    void setPaddingRelative(int start, int top, int end, int bottom);
-
-    /** {@link androidx.recyclerview.widget.RecyclerView#setClipToPadding(boolean)} */
-    void setClipToPadding(boolean clipToPadding);
-
-    /**
-     * Return's the container which contains the scrollbar and this RecyclerView.
-     */
-    View getContainer();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/SpanSizeLookupOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/SpanSizeLookupOEMV1.java
deleted file mode 100644
index a6e10f7..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/SpanSizeLookupOEMV1.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-/**
- * {@link androidx.recyclerview.widget.GridLayoutManager#setSpanSizeLookup}
- */
-public interface SpanSizeLookupOEMV1 {
-
-    /** {@link androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup#getSpanSize} */
-    int getSpanSize(int position);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ViewHolderOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ViewHolderOEMV1.java
deleted file mode 100644
index 8226657..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/recyclerview/ViewHolderOEMV1.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.recyclerview;
-
-import android.view.View;
-
-/** {@link androidx.recyclerview.widget.RecyclerView.ViewHolder} */
-public interface ViewHolderOEMV1 {
-
-    /** {@link androidx.recyclerview.widget.RecyclerView.ViewHolder#isRecyclable()} */
-    boolean isRecyclable();
-
-    /**
-     * Returns the ItemView for each element in the recyclerview.
-     */
-    View getItemView();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ImeSearchInterfaceOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ImeSearchInterfaceOEMV1.java
deleted file mode 100644
index 44e3ddf..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ImeSearchInterfaceOEMV1.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary.oemapis.toolbar;
-
-import android.os.Bundle;
-import android.widget.TextView;
-
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-/**
- * This is an interface (as in "bridge") between the static lib and the shared lib, so that
- * the static lib can handle showing search results inside the IME.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public interface ImeSearchInterfaceOEMV1 {
-    /**
-     * Sets a consumer that should be called when the search TextView is ready.
-     * <p>
-     * This is for the widescreen IME functionality, which is implemented in the static lib. If
-     * this implementation of a Toolbar does not need widescreen IME functionality,
-     * this method may return null.
-     *
-     * @see #setOnPrivateImeCommandListener
-     */
-    void setSearchTextViewConsumer(Consumer<TextView> textViewConsumer);
-
-    /**
-     * Sets a listener to be called when the TextView supplied to the consumer set in
-     * {@link #setSearchTextViewConsumer} receives a
-     * {@link TextView#onPrivateIMECommand(String, Bundle)} call.
-     * <p>
-     * This is for the widescreen IME functionality, which is implemented in the static lib. If
-     * this implementation of a Toolbar does not need widescreen IME functionality,
-     * this method may do nothing.
-     *
-     * @see #setSearchTextViewConsumer
-     */
-    void setOnPrivateImeCommandListener(BiConsumer<String, Bundle> onPrivateImeCommandListener);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/MenuItemOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/MenuItemOEMV1.java
deleted file mode 100644
index 2fb99b9..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/MenuItemOEMV1.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.sharedlibrary.oemapis.toolbar;
-
-import android.graphics.drawable.Drawable;
-
-import java.util.function.Consumer;
-
-/** The OEM interface of a MenuItem, which is a button in the toolbar */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public interface MenuItemOEMV1 {
-
-    /** Sets a listener that will be called when any property of the MenuItem changes */
-    void setUpdateListener(Consumer<MenuItemOEMV1> listener);
-
-    /**
-     * Triggers the MenuItem being clicked. This will toggle it's activated/checked state
-     * if it supports those, and also call it's onClickListener.
-     */
-    void performClick();
-
-    /** Gets the id, which is purely for the client to distinguish MenuItems with. */
-    int getId();
-
-    /** Returns whether the MenuItem is enabled */
-    boolean isEnabled();
-
-    /** Returns whether the MenuItem is checkable. If it is, it will be displayed as a switch. */
-    boolean isCheckable();
-
-    /**
-     * Returns whether the MenuItem is currently checked. Only valid if {@link #isCheckable()}
-     * is true.
-     */
-    boolean isChecked();
-
-    /** Whether or not to tint the Icon to match the theme of the toolbar */
-    boolean isTinted();
-
-    /** Returns whether or not the MenuItem is visible */
-    boolean isVisible();
-
-    /**
-     * Returns whether the MenuItem is activatable. If it is, it's every click will toggle
-     * the MenuItem's View to appear activated or not.
-     */
-    boolean isActivatable();
-
-    /** Returns whether or not this view is selected. Toggles after every click */
-    boolean isActivated();
-
-    /** Gets the title of this MenuItem. */
-    String getTitle();
-
-    /**
-     * Returns if this MenuItem is restricted due to the current driving restrictions and driving
-     * state. It should be displayed visually distinctly to indicate that.
-     */
-    boolean isRestricted();
-
-    /**
-     * Returns if both the icon and title should be shown. If not, and they're both provided,
-     * only the icon will be shown and the title will be used as a content description.
-     */
-    boolean isShowingIconAndTitle();
-
-    /**
-     * Returns if the MenuItem should do something when clicked. This can be used to forgo
-     * setting an onClickListener on it's View when it's not clickable.
-     */
-    boolean isClickable();
-
-    /** Always show the MenuItem on the toolbar */
-    int DISPLAY_BEHAVIOR_ALWAYS = 0;
-    /** Show the MenuItem in the toolbar if there's space, otherwise show it in the overflow menu */
-    int DISPLAY_BEHAVIOR_IF_ROOM = 1;
-    /** Never show the MenuItem on the toolbar, always put it in an overflow menu */
-    int DISPLAY_BEHAVIOR_NEVER = 2;
-
-    /**
-     * Gets the current display behavior.
-     *
-     * See {@link #DISPLAY_BEHAVIOR_ALWAYS}, {@link #DISPLAY_BEHAVIOR_IF_ROOM}, and
-     * {@link #DISPLAY_BEHAVIOR_NEVER}.
-     */
-    int getDisplayBehavior();
-
-    /** Gets the current Icon */
-    Drawable getIcon();
-
-    /**
-     * Returns if this MenuItem is a primary one, which should be visually different.
-     *
-     * This value will not change, even after an update was triggered.
-     */
-    boolean isPrimary();
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ProgressBarControllerOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ProgressBarControllerOEMV1.java
deleted file mode 100644
index 3d76209..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ProgressBarControllerOEMV1.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.sharedlibrary.oemapis.toolbar;
-
-/**
- * Interface for a Progress Bar. It's methods are a subset of the methods of
- * {@link android.widget.ProgressBar}. This is so that an application doesn't
- * have access to customize the {@link android.widget.ProgressBar} or other
- * views in it's hierarchy in ways that were not intended.
- */
-public interface ProgressBarControllerOEMV1 {
-    /** Shows/hides the progress bar */
-    void setVisible(boolean visible);
-    /** Equivalent to {@link android.widget.ProgressBar#setIndeterminate(boolean)} */
-    void setIndeterminate(boolean indeterminate);
-    /** Equivalent to {@link android.widget.ProgressBar#setMax(int)} */
-    void setMax(int max);
-    /** Equivalent to {@link android.widget.ProgressBar#setMin(int)} */
-    void setMin(int min);
-    /** Equivalent to {@link android.widget.ProgressBar#setProgress(int)} */
-    void setProgress(int progress);
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/TabOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/TabOEMV1.java
deleted file mode 100644
index d175aca..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/TabOEMV1.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.sharedlibrary.oemapis.toolbar;
-
-import android.graphics.drawable.Drawable;
-
-/** Interface representing a toolbar tab */
-public final class TabOEMV1 {
-    private final String mTitle;
-    private final Drawable mIcon;
-    private final Runnable mOnSelectedListener;
-    private final boolean mTinted;
-
-    private TabOEMV1(Builder builder) {
-        mTitle = builder.mTitle;
-        mIcon = builder.mIcon;
-        mOnSelectedListener = builder.mOnSelectedListener;
-        mTinted = builder.mTinted;
-    }
-
-    /** Constructs a new {@link Builder} to build a tab with */
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /** Gets the title of the tab */
-    public String getTitle() {
-        return mTitle;
-    }
-
-    /** Gets the icon of the tab. The icon may be tinted to match the theme of the toolbar */
-    public Drawable getIcon() {
-        return mIcon;
-    }
-
-    /** Gets the function to call when the tab is selected */
-    public Runnable getOnSelectedListener() {
-        return mOnSelectedListener;
-    }
-
-    /**
-     * Returns if the icon should be tinted to match the style of the toolbar.
-     * Most of the time this will be true. If not, then the original colors of the drawable
-     * should be shown.
-     */
-    public boolean isTinted() {
-        return mTinted;
-    }
-
-    /** Builder for {@link TabOEMV1} */
-    public static class Builder {
-        private String mTitle = null;
-        private Drawable mIcon = null;
-        private Runnable mOnSelectedListener = null;
-        private boolean mTinted = true;
-
-        private Builder() {
-        }
-
-        /** Sets the tab's text */
-        public Builder setTitle(String title) {
-            mTitle = title;
-            return this;
-        }
-
-        /** Sets the tab's icon */
-        public Builder setIcon(Drawable icon) {
-            mIcon = icon;
-            return this;
-        }
-
-        /** Sets a listener that is called when the tab is selected */
-        public Builder setOnSelectedListener(Runnable callback) {
-            mOnSelectedListener = callback;
-            return this;
-        }
-
-        /** See {@link TabOEMV1#isTinted} */
-        public Builder setTinted(boolean tinted) {
-            mTinted = tinted;
-            return this;
-        }
-
-        /** Builds the final {@link TabOEMV1} */
-        public TabOEMV1 build() {
-            return new TabOEMV1(this);
-        }
-    }
-}
diff --git a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ToolbarControllerOEMV1.java b/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ToolbarControllerOEMV1.java
deleted file mode 100644
index d50382c..0000000
--- a/car-ui-lib/oem-apis/src/main/java/com/android/car/ui/sharedlibrary/oemapis/toolbar/ToolbarControllerOEMV1.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.sharedlibrary.oemapis.toolbar;
-
-import android.graphics.drawable.Drawable;
-
-import java.util.List;
-import java.util.function.Consumer;
-
-/** The OEM interface for a Toolbar. */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public interface ToolbarControllerOEMV1 {
-
-    /**
-     * Sets the title of the toolbar to a String.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    void setTitle(String title);
-
-    /**
-     * Sets the subtitle of the toolbar to a String.
-     *
-     * <p>The title may not always be shown, for example with one row layout with tabs.
-     */
-    void setSubtitle(String title);
-
-    /**
-     * Sets the tab to be shown. The implementation must copy the list once it's passed in,
-     * or else the list could be modified from the app when the toolbar wasn't expecting it.
-     *
-     * @param tabs Nullable. Must not be mutated. List of tabs to show.
-     * @param selectedTab The index of the tab that is initially selected.
-     */
-    void setTabs(List<? extends TabOEMV1> tabs, int selectedTab);
-
-    /**
-     * Selects a tab added to this toolbar. See
-     * {@link #setTabs(List, int)}. The tab's callback should also be called if {@code sendCallback}
-     * is true.
-     */
-    void selectTab(int position, boolean sendCallback);
-
-    /**
-     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
-     * will be displayed next to the title.
-     */
-    void setLogo(Drawable drawable);
-
-    /** Sets the hint for the search bar. */
-    void setSearchHint(String hint);
-
-    /**
-     * Sets the icon to display in the search box.
-     *
-     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
-     * a similar place.
-     */
-    void setSearchIcon(Drawable d);
-
-    /**
-     * Sets the search query.
-     */
-    void setSearchQuery(String query);
-
-    int SEARCH_MODE_DISABLED = 0;
-    int SEARCH_MODE_SEARCH = 1;
-    int SEARCH_MODE_EDIT = 2;
-
-    /**
-     * Sets the search mode, which is whether or not to display the search bar and how it should
-     * look.
-     */
-    void setSearchMode(int searchMode);
-
-    /**
-     * Gets a {@link ImeSearchInterfaceOEMV1}, which contains methods for interfacing
-     * with the static library to support showing search results in the IME. It should return
-     * the same object every time it's called. It may return null if this feature is not supported.
-     */
-    ImeSearchInterfaceOEMV1 getImeSearchInterface();
-
-    /** Don't show the nav button */
-    int NAV_BUTTON_MODE_DISABLED = 0;
-    /** Display the nav button as a back button */
-    int NAV_BUTTON_MODE_BACK = 1;
-    /** Display the nav button as a close button */
-    int NAV_BUTTON_MODE_CLOSE = 2;
-    /**
-     * Display the nav button as a "down" button.
-     * This indicates that pressing it will slide a panel down to close it.
-     */
-    int NAV_BUTTON_MODE_DOWN = 3;
-
-    /**
-     * Sets the nav button mode, which is a certain style to display the nav button in.
-     * These styles are all purely visual, and don't affect the behavior of clicking
-     * the nav button.
-     *
-     * See {@link #NAV_BUTTON_MODE_DISABLED}, {@link #NAV_BUTTON_MODE_BACK},
-     * {@link #NAV_BUTTON_MODE_CLOSE}, and {@link #NAV_BUTTON_MODE_DOWN}.
-     */
-    void setNavButtonMode(int mode);
-
-    /**
-     * Sets the {@link MenuItemOEMV1 Menuitems} to display.
-     */
-    void setMenuItems(List<? extends MenuItemOEMV1> items);
-
-    /**
-     * Sets a {@link Consumer<String>} to be called whenever the text in the search box
-     * changes.
-     *
-     * Must accept {@code null} to unset the listener.
-     */
-    void setSearchListener(Consumer<String> listener);
-
-    /**
-     * Sets a {@link Runnable} to be called whenever the user indicates that they're done searching.
-     * This can be by clicking the search/enter button on the keyboard, or a custom button
-     * on the toolbar.
-     *
-     * Must accept {@code null} to unset the listener.
-     */
-    void setSearchCompletedListener(Runnable listener);
-
-    /**
-     * Sets a {@link Runnable} to be called whenever the back button is pressed.
-     *
-     * Must accept {@code null} to unset the listener.
-     */
-    void setBackListener(Runnable listener);
-
-    /** Gets a {@link ProgressBarControllerOEMV1 ProgressBarController} */
-    ProgressBarControllerOEMV1 getProgressBar();
-}
diff --git a/car-ui-lib/paintbooth/build.gradle b/car-ui-lib/paintbooth/build.gradle
deleted file mode 100644
index eba3fbe..0000000
--- a/car-ui-lib/paintbooth/build.gradle
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion 30
-    defaultConfig {
-        applicationId "com.android.car.ui.paintbooth"
-        minSdkVersion 28
-        targetSdkVersion 30
-        versionCode 1
-        versionName "1.0"
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
-    }
-
-    sourceSets {
-        main {
-            java {
-                filter.excludes = [
-                        "com/android/car/ui/paintbooth/overlays/OverlayManagerImpl.java",
-                        "com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java",
-                ]
-            }
-        }
-    }
-
-    // This is the gradle equivalent of the libs: ["android.car"] in the Android.bp
-    useLibrary 'android.car'
-}
-
-dependencies {
-    implementation project(':car-ui-lib')
-    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0'
-    api 'androidx.annotation:annotation:1.2.0'
-    api 'androidx.constraintlayout:constraintlayout:2.0.4'
-    api 'androidx.recyclerview:recyclerview:1.2.0'
-}
diff --git a/car-ui-lib/paintbooth/src/main/AndroidManifest.xml b/car-ui-lib/paintbooth/src/main/AndroidManifest.xml
deleted file mode 100644
index c6d2e89..0000000
--- a/car-ui-lib/paintbooth/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.car.ui.paintbooth">
-  <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
-  <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
-  <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
-  <uses-permission android:name="android.permission.MANAGE_USERS"/>
-  <!-- Required to use the TYPE_DISPLAY_OVERLAY layout param for the current activity overlay -->
-  <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
-  <!-- Required for listening to android task stack changes -->
-  <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
-  <uses-permission android:name="android.permission.REAL_GET_TASKS" />
-  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
-  <!-- Required for using TYPE_APPLICATION_OVERLAY to display overlays -->
-  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-  <!-- Required to test permission dialogs -->
-  <uses-permission android:name="android.permission.CAMERA"/>
-  <uses-permission android:name="android.permission.READ_CONTACTS"/>
-  <uses-permission android:name="android.permission.SEND_SMS"/>
-  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
-  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
-
-  <application
-      android:name=".PaintBoothApplication"
-      android:supportsRtl="true"
-      android:icon="@drawable/ic_launcher"
-      android:label="@string/app_name"
-      android:theme="@style/Theme.CarUi.WithToolbar">
-    <activity
-        android:name=".MainActivity"
-        android:exported="true">
-      <intent-filter>
-        <action android:name="android.intent.action.MAIN"/>
-        <category android:name="android.intent.category.LAUNCHER"/>
-      </intent-filter>
-      <meta-data android:name="distractionOptimized" android:value="true"/>
-    </activity>
-
-    <activity
-        android:name=".dialogs.DialogsActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-    <activity
-        android:name=".appstyledview.AppStyledViewSampleActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-    <activity
-        android:name=".caruirecyclerview.CarUiRecyclerViewActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-    <activity
-        android:name=".caruirecyclerview.GridCarUiRecyclerViewActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-    <activity
-        android:name=".preferences.PreferenceActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity">
-      <meta-data android:name="distractionOptimized" android:value="true"/>
-    </activity>
-    <activity
-        android:name=".preferences.SplitPreferenceActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-    <activity
-        android:name=".widescreenime.WideScreenImeActivity"
-        android:windowSoftInputMode="stateHidden|adjustNothing"
-        android:exported="false"
-        android:parentActivityName=".MainActivity">
-    </activity>
-    <activity
-        android:name=".widescreenime.WideScreenTestView"
-        android:windowSoftInputMode="stateHidden|adjustNothing"
-        android:exported="false"
-        android:parentActivityName=".MainActivity">
-    </activity>
-    <activity
-        android:name=".toolbar.ToolbarActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity">
-      <meta-data android:name="distractionOptimized" android:value="true"/>
-    </activity>
-    <activity
-        android:name=".toolbar.NoCarUiToolbarActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"
-        android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
-    <activity
-        android:name=".toolbar.OldToolbarActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"
-        android:theme="@style/Theme.CarUi"/>
-    <activity
-        android:name=".overlays.OverlayActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity">
-      <meta-data android:name="distractionOptimized" android:value="true"/>
-    </activity>
-    <activity
-        android:name=".widgets.WidgetActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-    <activity
-        android:name=".caruirecyclerview.CarUiListItemActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-    <activity
-        android:name=".button.CarUiButtonActivity"
-        android:exported="false"
-        android:parentActivityName=".MainActivity"/>
-
-    <service
-        android:label="Current Activity Service"
-        android:exported="false"
-        android:name=".currentactivity.CurrentActivityService"/>
-    <service
-        android:label="Visible Bounds Simulator"
-        android:exported="false"
-        android:name=".VisibleBoundsSimulator"/>
-  </application>
-</manifest>
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/MainActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/MainActivity.java
deleted file mode 100644
index 6b1b8f7..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/MainActivity.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth;
-
-import static com.android.car.ui.paintbooth.PaintBoothApplication.SHARED_PREFERENCES_FILE;
-import static com.android.car.ui.paintbooth.PaintBoothApplication.SHARED_PREFERENCES_SHARED_LIB_DENYLIST;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.Switch;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.core.util.Supplier;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.appstyledview.AppStyledViewSampleActivity;
-import com.android.car.ui.paintbooth.caruirecyclerview.CarUiListItemActivity;
-import com.android.car.ui.paintbooth.caruirecyclerview.CarUiRecyclerViewActivity;
-import com.android.car.ui.paintbooth.caruirecyclerview.GridCarUiRecyclerViewActivity;
-import com.android.car.ui.paintbooth.currentactivity.CurrentActivityService;
-import com.android.car.ui.paintbooth.dialogs.DialogsActivity;
-import com.android.car.ui.paintbooth.overlays.OverlayActivity;
-import com.android.car.ui.paintbooth.preferences.PreferenceActivity;
-import com.android.car.ui.paintbooth.preferences.SplitPreferenceActivity;
-import com.android.car.ui.paintbooth.toolbar.NoCarUiToolbarActivity;
-import com.android.car.ui.paintbooth.toolbar.ToolbarActivity;
-import com.android.car.ui.paintbooth.widescreenime.WideScreenImeActivity;
-import com.android.car.ui.paintbooth.widescreenime.WideScreenTestView;
-import com.android.car.ui.paintbooth.widgets.WidgetActivity;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Paint booth app
- */
-public class MainActivity extends Activity implements InsetsChangedListener {
-
-    public static final String STOP_SERVICE = "com.android.car.ui.paintbooth.StopService";
-
-    /**
-     * List of all sample activities.
-     */
-    private final List<ListElement> mActivities = Arrays.asList(
-            new ServiceElement("Show foreground activities", CurrentActivityService.class),
-            new ServiceElement("Simulate Screen Bounds", VisibleBoundsSimulator.class),
-            new SwitchElement("Enable shared library", this::isSharedLibEnabled,
-                    this::onSharedLibSwitchChanged),
-            new ActivityElement("Dialogs sample", DialogsActivity.class),
-            new ActivityElement("App Styled View Modal", AppStyledViewSampleActivity.class),
-            new ActivityElement("List sample", CarUiRecyclerViewActivity.class),
-            new ActivityElement("Grid sample", GridCarUiRecyclerViewActivity.class),
-            new ActivityElement("Preferences sample", PreferenceActivity.class),
-            new ActivityElement("Split preferences sample", SplitPreferenceActivity.class),
-            new ActivityElement("Overlays", OverlayActivity.class),
-            new ActivityElement("Toolbar sample", ToolbarActivity.class),
-            new ActivityElement("No CarUiToolbar sample", NoCarUiToolbarActivity.class),
-            new ActivityElement("Widget sample", WidgetActivity.class),
-            new ActivityElement("Wide Screen IME", WideScreenImeActivity.class),
-            new ActivityElement("Wide Screen View IME", WideScreenTestView.class),
-            new ActivityElement("ListItem sample", CarUiListItemActivity.class));
-
-    private abstract static class ViewHolder extends RecyclerView.ViewHolder {
-
-        ViewHolder(@NonNull View itemView) {
-            super(itemView);
-        }
-
-        public abstract void bind(ListElement element);
-    }
-
-    private class ActivityViewHolder extends ViewHolder {
-        private final Button mButton;
-
-        ActivityViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mButton = itemView.requireViewById(R.id.button);
-        }
-
-        @Override
-        public void bind(ListElement e) {
-            if (!(e instanceof ActivityElement)) {
-                throw new IllegalArgumentException("Expected an ActivityElement");
-            }
-            ActivityElement element = (ActivityElement) e;
-            mButton.setText(element.getText());
-            mButton.setOnClickListener(v ->
-                    startActivity(new Intent(itemView.getContext(), element.getActivity())));
-        }
-    }
-
-    private static class SwitchViewHolder extends ViewHolder {
-        private final Switch mSwitch;
-
-        SwitchViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mSwitch = itemView.requireViewById(R.id.button);
-        }
-
-        @Override
-        public void bind(ListElement e) {
-            if (!(e instanceof SwitchElement)) {
-                throw new IllegalArgumentException("Expected an ActivityElement");
-            }
-            SwitchElement element = (SwitchElement) e;
-            mSwitch.setChecked(element.isChecked());
-            mSwitch.setText(element.getText());
-            mSwitch.setOnCheckedChangeListener(element.getOnCheckedChangedListener());
-        }
-    }
-
-    private final RecyclerView.Adapter<ViewHolder> mAdapter =
-            new RecyclerView.Adapter<ViewHolder>() {
-                @NonNull
-                @Override
-                public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
-                    LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
-                    if (viewType == ListElement.TYPE_ACTIVITY) {
-                        return new ActivityViewHolder(
-                                inflater.inflate(R.layout.list_item, parent, false));
-                    } else if (viewType == ListElement.TYPE_SWITCH) {
-                        return new SwitchViewHolder(
-                                inflater.inflate(R.layout.list_item_switch, parent, false));
-                    } else {
-                        throw new IllegalArgumentException("Unknown viewType: " + viewType);
-                    }
-                }
-
-                @Override
-                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
-                    holder.bind(mActivities.get(position));
-                }
-
-                @Override
-                public int getItemCount() {
-                    return mActivities.size();
-                }
-
-                @Override
-                public int getItemViewType(int position) {
-                    return mActivities.get(position).getType();
-                }
-            };
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_activity);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setLogo(R.drawable.ic_launcher);
-        toolbar.setTitle(getTitle());
-
-        CarUiRecyclerView prv = findViewById(R.id.list);
-        prv.setAdapter(mAdapter);
-
-        initLeakCanary();
-    }
-
-    private void initLeakCanary() {
-        // This sets LeakCanary to report errors after a single leak instead of 5, and to ask for
-        // permission to use storage, which it needs to work.
-        //
-        // Equivalent to this non-reflection code:
-        //
-        // Config config = LeakCanary.INSTANCE.getConfig();
-        // LeakCanary.INSTANCE.setConfig(config.copy(config.getDumpHeap(),
-        //     config.getDumpHeapWhenDebugging(),
-        //     1,
-        //     config.getReferenceMatchers(),
-        //     config.getObjectInspectors(),
-        //     config.getOnHeapAnalyzedListener(),
-        //     config.getMetatadaExtractor(),
-        //     config.getComputeRetainedHeapSize(),
-        //     config.getMaxStoredHeapDumps(),
-        //     true,
-        //     config.getUseExperimentalLeakFinders()));
-        try {
-            Class<?> canaryClass = Class.forName("leakcanary.LeakCanary");
-            try {
-                Class<?> onHeapAnalyzedListenerClass =
-                        Class.forName("leakcanary.OnHeapAnalyzedListener");
-                Class<?> metadataExtractorClass = Class.forName("shark.MetadataExtractor");
-                Method getConfig = canaryClass.getMethod("getConfig");
-                Class<?> configClass = getConfig.getReturnType();
-                Method setConfig = canaryClass.getMethod("setConfig", configClass);
-                Method copy = configClass.getMethod("copy", boolean.class, boolean.class,
-                        int.class, List.class, List.class, onHeapAnalyzedListenerClass,
-                        metadataExtractorClass, boolean.class, int.class, boolean.class,
-                        boolean.class);
-
-                Object canary = canaryClass.getField("INSTANCE").get(null);
-                Object currentConfig = getConfig.invoke(canary);
-
-                Boolean dumpHeap = (Boolean) configClass
-                        .getMethod("getDumpHeap").invoke(currentConfig);
-                Boolean dumpHeapWhenDebugging = (Boolean) configClass
-                        .getMethod("getDumpHeapWhenDebugging").invoke(currentConfig);
-                List<?> referenceMatchers = (List<?>) configClass
-                        .getMethod("getReferenceMatchers").invoke(currentConfig);
-                List<?> objectInspectors = (List<?>) configClass
-                        .getMethod("getObjectInspectors").invoke(currentConfig);
-                Object onHeapAnalyzedListener = configClass
-                        .getMethod("getOnHeapAnalyzedListener").invoke(currentConfig);
-                // Yes, LeakCanary misspelled metadata
-                Object metadataExtractor = configClass
-                        .getMethod("getMetatadaExtractor").invoke(currentConfig);
-                Boolean computeRetainedHeapSize = (Boolean) configClass
-                        .getMethod("getComputeRetainedHeapSize").invoke(currentConfig);
-                Integer maxStoredHeapDumps = (Integer) configClass
-                        .getMethod("getMaxStoredHeapDumps").invoke(currentConfig);
-                Boolean useExperimentalLeakFinders = (Boolean) configClass
-                        .getMethod("getUseExperimentalLeakFinders").invoke(currentConfig);
-
-                setConfig.invoke(canary, copy.invoke(currentConfig,
-                        dumpHeap,
-                        dumpHeapWhenDebugging,
-                        1,
-                        referenceMatchers,
-                        objectInspectors,
-                        onHeapAnalyzedListener,
-                        metadataExtractor,
-                        computeRetainedHeapSize,
-                        maxStoredHeapDumps,
-                        true,
-                        useExperimentalLeakFinders));
-
-            } catch (ReflectiveOperationException e) {
-                Log.e("paintbooth", "Error initializing LeakCanary", e);
-                Toast.makeText(this, "Error initializing LeakCanary", Toast.LENGTH_LONG).show();
-            }
-        } catch (ClassNotFoundException e) {
-            // LeakCanary is not used in this build, do nothing.
-        }
-    }
-
-    private boolean isServiceRunning(Class<? extends Service> serviceClazz) {
-        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
-        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
-                Integer.MAX_VALUE)) {
-            if (serviceClazz.getName().equals(service.service.getClassName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void setServiceRunning(Class<? extends Service> serviceClass, boolean running) {
-        Intent intent = new Intent(this, serviceClass);
-        if (!running) {
-            intent.setAction(STOP_SERVICE);
-        }
-        startForegroundService(intent);
-    }
-
-    private boolean isSharedLibEnabled() {
-        return getSharedPreferences(SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE)
-                .getStringSet(SHARED_PREFERENCES_SHARED_LIB_DENYLIST, null) == null;
-    }
-
-    private void onSharedLibSwitchChanged(CompoundButton unused, boolean checked) {
-        getSharedPreferences(SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE)
-                .edit()
-                .putStringSet(SHARED_PREFERENCES_SHARED_LIB_DENYLIST,
-                        checked ? null : Collections.singleton("com.chassis.car.ui.sharedlibrary"))
-                .apply();
-        Toast.makeText(this, "Relaunch PaintBooth to see effects", Toast.LENGTH_SHORT).show();
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        FocusArea focusArea = requireViewById(R.id.focus_area);
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-
-    private abstract static class ListElement {
-        static final int TYPE_ACTIVITY = 0;
-        static final int TYPE_SWITCH = 1;
-
-        private final String mText;
-
-        ListElement(String text) {
-            mText = text;
-        }
-
-        String getText() {
-            return mText;
-        }
-
-        abstract int getType();
-    }
-
-    private static class ActivityElement extends ListElement {
-        private final Class<? extends Activity> mActivityClass;
-
-        ActivityElement(String text, Class<? extends Activity> activityClass) {
-            super(text);
-            mActivityClass = activityClass;
-        }
-
-        Class<? extends Activity> getActivity() {
-            return mActivityClass;
-        }
-
-        @Override
-        int getType() {
-            return TYPE_ACTIVITY;
-        }
-    }
-
-    private static class SwitchElement extends ListElement {
-        private final Supplier<Boolean> mIsCheckedSupplier;
-        private final OnCheckedChangeListener mOnCheckedChanged;
-
-        private SwitchElement(String text, Supplier<Boolean> isCheckedSupplier,
-                OnCheckedChangeListener onCheckedChanged) {
-            super(text);
-            mIsCheckedSupplier = isCheckedSupplier;
-            mOnCheckedChanged = onCheckedChanged;
-        }
-
-        public boolean isChecked() {
-            return mIsCheckedSupplier.get();
-        }
-
-        public OnCheckedChangeListener getOnCheckedChangedListener() {
-            return mOnCheckedChanged;
-        }
-
-        @Override
-        int getType() {
-            return TYPE_SWITCH;
-        }
-    }
-
-    private class ServiceElement extends SwitchElement {
-        ServiceElement(String text, Class<? extends Service> serviceClass) {
-            super(text,
-                    () -> isServiceRunning(serviceClass),
-                    (v, checked) -> setServiceRunning(serviceClass, checked));
-        }
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/PaintBoothApplication.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/PaintBoothApplication.java
deleted file mode 100644
index 2b11038..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/PaintBoothApplication.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.paintbooth;
-
-import android.app.Application;
-import android.content.Context;
-
-import com.android.car.ui.sharedlibrarysupport.SharedLibraryConfigProvider;
-import com.android.car.ui.sharedlibrarysupport.SharedLibrarySpecifier;
-
-import java.util.Collections;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * A {@link Application} subclass that implements {@link SharedLibraryConfigProvider},
- * allowing PaintBooth to disable the shared library.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class PaintBoothApplication extends Application implements SharedLibraryConfigProvider {
-    public static final String SHARED_PREFERENCES_FILE = "paintbooth_shared_prefs";
-    public static final String SHARED_PREFERENCES_SHARED_LIB_DENYLIST =
-            "paintbooth_shared_lib_deny";
-
-    @Override
-    public Set<SharedLibrarySpecifier> getSharedLibraryDenyList() {
-        return getSharedPreferences(SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE)
-                .getStringSet(SHARED_PREFERENCES_SHARED_LIB_DENYLIST, Collections.emptySet())
-                .stream()
-                .map(packageName -> SharedLibrarySpecifier.builder()
-                        .setPackageName(packageName)
-                        .build())
-                .collect(Collectors.toSet());
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/VisibleBoundsSimulator.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/VisibleBoundsSimulator.java
deleted file mode 100644
index 2d552b0..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/VisibleBoundsSimulator.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.os.IBinder;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager;
-
-import androidx.core.app.NotificationCompat;
-
-/**
- * To start the service:
- * adb shell am start-foreground-service com.android.car.ui.paintbooth/.DisplayService
- *
- * To stop the service:
- * adb shell am stopservice com.android.car.ui.paintbooth/.DisplayService
- *
- * When the service is started it will draw a overlay view on top of the screen displayed. This
- * overlay comes from a SVG file that can be modified to take different shapes. This service will be
- * used to display different screen styles from OEMs.
- */
-public class VisibleBoundsSimulator extends Service {
-    private static final int FOREGROUND_SERVICE_ID = 222;
-    private View mContainer;
-
-    private WindowManager mWindowManager;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        throw new UnsupportedOperationException("Not yet implemented.");
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (MainActivity.STOP_SERVICE.equals(intent.getAction())) {
-            stopSelf();
-        }
-
-        return START_STICKY;
-    }
-
-    @Override
-    public void onCreate() {
-
-        Intent notificationIntent = new Intent(this, VisibleBoundsSimulator.class);
-
-        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
-                notificationIntent, PendingIntent.FLAG_IMMUTABLE);
-
-        NotificationChannel channel = new NotificationChannel("DisplayService",
-                "Show overlay screen",
-                NotificationManager.IMPORTANCE_DEFAULT);
-        NotificationManager notificationManager =
-                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-        notificationManager.createNotificationChannel(channel);
-
-        Notification notification =
-                new NotificationCompat.Builder(this, "DisplayService")
-                        .setSmallIcon(R.drawable.ic_launcher)
-                        .setContentTitle("DisplayService")
-                        .setContentText("Show overlay screen")
-                        .setContentIntent(pendingIntent).build();
-
-        startForeground(FOREGROUND_SERVICE_ID, notification);
-        applyDisplayOverlay();
-    }
-
-    /**
-     * Creates a view overlay on top of a new window. The overlay gravity is set to left and
-     * bottom. If the width and height is not provided then the default is to take up the entire
-     * screen. Overlay will show bounds around the view and we can still click through the window.
-     */
-    private void applyDisplayOverlay() {
-        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
-
-        DisplayMetrics displayMetrics = new DisplayMetrics();
-
-        mWindowManager.getDefaultDisplay().getRealMetrics(displayMetrics);
-        int screenHeight = displayMetrics.heightPixels;
-        int screenWidth = displayMetrics.widthPixels;
-        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
-        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
-                WindowManager.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
-                PixelFormat.TRANSLUCENT);
-
-        params.packageName = this.getPackageName();
-        params.gravity = Gravity.BOTTOM | Gravity.LEFT;
-
-        Display display = mWindowManager.getDefaultDisplay();
-        Point size = new Point();
-        display.getSize(size);
-        int height = size.y;
-
-        params.x = 0;
-        // If the sysUI is showing and nav bar is taking up some space at the bottom we want to
-        // offset the height of the navBar so that the overlay starts from the bottom left.
-        params.y = -(screenHeight - height);
-
-        float overlayWidth = getApplicationContext().getResources().getDimension(
-                R.dimen.screen_shape_container_width);
-        float overlayHeight = getApplicationContext().getResources().getDimension(
-                R.dimen.screen_shape_container_height);
-
-
-        params.width = (int) (overlayWidth == 0 ? screenWidth : overlayHeight);
-        params.height = (int) (overlayHeight == 0 ? screenHeight : overlayHeight);
-        params.setTitle("Simulated display bound");
-
-        mContainer = inflater.inflate(R.layout.simulated_screen_shape_container, null);
-        mContainer.setLayoutParams(params);
-
-        mWindowManager.addView(mContainer, params);
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        mWindowManager.removeView(mContainer);
-        stopSelf();
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/appstyledview/AppStyledViewSampleActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/appstyledview/AppStyledViewSampleActivity.java
deleted file mode 100644
index d4609a3..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/appstyledview/AppStyledViewSampleActivity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.paintbooth.appstyledview;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.android.car.ui.appstyledview.AppStyledDialogController;
-import com.android.car.ui.appstyledview.AppStyledViewController.AppStyledViewNavIcon;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-/**
- * Sample activity to show app styled Dialog fragment.
- */
-public class AppStyledViewSampleActivity extends AppCompatActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
-
-        setContentView(R.layout.app_styled_view_sample_activity);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-        toolbar.setLogo(R.drawable.ic_launcher);
-
-        AppStyledDialogController controller = new AppStyledDialogController(this);
-        int width = controller.getAppStyledViewDialogWidth();
-
-        Resources resources = getResources();
-        Configuration config = resources.getConfiguration();
-
-        config.smallestScreenWidthDp = width;
-        // fake the min screen size so resources load from the corresponding folders. For eg.
-        // layout-sw400dp
-        Context testContext = createConfigurationContext(config);
-
-        Context contextThemeWrapper = new ContextThemeWrapper(testContext,
-                R.style.AppStyledDialogThemeSample);
-
-        View appStyledTestView = LayoutInflater.from(contextThemeWrapper)
-                .inflate(R.layout.app_styled_view_test_sample, null, false);
-
-        Button btn = findViewById(R.id.show_app_styled_fragment);
-        btn.setOnClickListener(v -> {
-            controller.setContentView(appStyledTestView);
-            controller.setNavIcon(AppStyledViewNavIcon.CLOSE);
-            controller.show();
-        });
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java
deleted file mode 100644
index f94dc2f..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.caruirecyclerview;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiHeaderListItem;
-import com.android.car.ui.recyclerview.CarUiListItem;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.ArrayList;
-
-/**
- * Activity that shows {@link CarUiRecyclerView} with sample {@link CarUiContentListItem} entries
- */
-public class CarUiListItemActivity extends Activity implements InsetsChangedListener {
-
-    private final ArrayList<CarUiListItem> mData = new ArrayList<>();
-    private RecyclerView.Adapter<? extends RecyclerView.ViewHolder> mAdapter;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_activity);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-
-        CarUiRecyclerView recyclerView = findViewById(R.id.list);
-        mAdapter = CarUi.createListItemAdapter(this, generateSampleData());
-        recyclerView.setAdapter(mAdapter);
-    }
-
-    private ArrayList<CarUiListItem> generateSampleData() {
-        Context context = this;
-
-        CarUiHeaderListItem header = new CarUiHeaderListItem(getString(R.string.first_header));
-        mData.add(header);
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(getString(R.string.test_title));
-        item.setBody(getString(R.string.test_body));
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(getString(R.string.test_title_no_body));
-        mData.add(item);
-
-        header = new CarUiHeaderListItem(getString(R.string.random_header),
-                getString(R.string.header_with_body));
-        mData.add(header);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setBody(getString(R.string.test_body_no_title));
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(getString(R.string.test_title));
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(getString(R.string.test_title));
-        item.setBody(getString(R.string.test_body));
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(getString(R.string.title_with_content_icon));
-        item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT);
-        item.setIcon(getDrawable(R.drawable.ic_sample_logo));
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(getString(R.string.test_title));
-        item.setBody(getString(R.string.with_avatar_icon));
-        item.setIcon(getDrawable(R.drawable.ic_sample_logo));
-        item.setPrimaryIconType(CarUiContentListItem.IconType.AVATAR);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle(getString(R.string.test_title));
-        item.setBody(getString(R.string.display_toast_on_click));
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setOnItemClickedListener(item1 -> {
-            Toast.makeText(context, "Item clicked", Toast.LENGTH_SHORT).show();
-        });
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setTitle(getString(R.string.title_item_with_checkbox));
-        item.setBody(getString(R.string.toast_on_selection_changed));
-        item.setOnCheckedChangeListener(
-                (listItem, isChecked) -> Toast.makeText(context,
-                        "Item checked state is: " + isChecked, Toast.LENGTH_SHORT).show());
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setEnabled(false);
-        item.setTitle(getString(R.string.title_with_disabled_checkbox));
-        item.setBody(getString(R.string.click_should_have_no_effect));
-        item.setOnCheckedChangeListener(
-                (listItem, isChecked) -> Toast.makeText(context,
-                        "Item checked state is: " + isChecked, Toast.LENGTH_SHORT).show());
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setBody(getString(R.string.body_item_with_switch));
-        item.setOnItemClickedListener(item1 -> {
-            Toast.makeText(context, "Click on item with switch", Toast.LENGTH_SHORT).show();
-        });
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setTitle(getString(R.string.title_item_with_checkbox));
-        item.setBody(getString(R.string.item_initially_checked));
-        item.setChecked(true);
-        mData.add(item);
-
-        CarUiContentListItem radioItem1 = new CarUiContentListItem(
-                CarUiContentListItem.Action.RADIO_BUTTON);
-        CarUiContentListItem radioItem2 = new CarUiContentListItem(
-                CarUiContentListItem.Action.RADIO_BUTTON);
-
-        radioItem1.setTitle(getString(R.string.title_item_with_radio_button));
-        radioItem1.setBody(getString(R.string.item_initially_checked));
-        radioItem1.setChecked(false);
-        radioItem1.setOnCheckedChangeListener((listItem, isChecked) -> {
-            if (isChecked) {
-                radioItem2.setChecked(false);
-                mAdapter.notifyItemChanged(mData.indexOf(radioItem2));
-            }
-        });
-        mData.add(radioItem1);
-
-        radioItem2.setIcon(getDrawable(R.drawable.ic_launcher));
-        radioItem2.setTitle(getString(R.string.item_mutually_exclusive_with_item_above));
-        radioItem2.setChecked(true);
-        radioItem2.setOnCheckedChangeListener((listItem, isChecked) -> {
-            if (isChecked) {
-                radioItem1.setChecked(false);
-                mAdapter.notifyItemChanged(mData.indexOf(radioItem1));
-            }
-        });
-        mData.add(radioItem2);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setTitle(getString(R.string.test_title));
-        item.setBody(getString(R.string.random_body_text_with_action_divider));
-        item.setActionDividerVisible(true);
-        item.setSupplementalIcon(getDrawable(R.drawable.ic_launcher));
-        item.setChecked(true);
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setTitle(getString(R.string.null_supplement_icon));
-        item.setChecked(true);
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
-        item.setTitle(getString(R.string.supplemental_icon_with_listener));
-        item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT);
-        item.setIcon(getDrawable(R.drawable.ic_launcher));
-        item.setBody(getString(R.string.test_body));
-        item.setOnItemClickedListener(v -> Toast.makeText(context, "Clicked item",
-                Toast.LENGTH_SHORT).show());
-        item.setSupplementalIcon(getDrawable(R.drawable.ic_launcher),
-                v -> Toast.makeText(context, "Clicked supplemental icon",
-                        Toast.LENGTH_SHORT).show());
-        item.setChecked(true);
-        mData.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.CHEVRON);
-        item.setTitle(getString(R.string.item_with_chevron));
-        item.setBody(getString(R.string.test_body));
-        mData.add(item);
-
-        return mData;
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        FocusArea focusArea = requireViewById(R.id.focus_area);
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/CarUiRecyclerViewActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/CarUiRecyclerViewActivity.java
deleted file mode 100644
index 28d2874..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/CarUiRecyclerViewActivity.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.caruirecyclerview;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.ArrayList;
-
-/**
- * Activity that shows CarUiRecyclerView example with sample data.
- */
-public class CarUiRecyclerViewActivity extends Activity implements InsetsChangedListener {
-    private final ArrayList<String> mData = new ArrayList<>();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_activity);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-
-        CarUiRecyclerView recyclerView = findViewById(R.id.list);
-        recyclerView.setLayoutManager(new LinearLayoutManager(this));
-
-        RecyclerViewAdapter adapter = new RecyclerViewAdapter(generateSampleData());
-        recyclerView.setAdapter(adapter);
-    }
-
-    private ArrayList<String> generateSampleData() {
-        for (int i = 0; i <= 100; i++) {
-            mData.add(getString(R.string.test_data) + i);
-        }
-        return mData;
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        FocusArea focusArea = requireViewById(R.id.focus_area);
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-}
-
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/GridCarUiRecyclerViewActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/GridCarUiRecyclerViewActivity.java
deleted file mode 100644
index ee08d25..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/GridCarUiRecyclerViewActivity.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.caruirecyclerview;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.ArrayList;
-
-/** Activity that shows GridCarUiRecyclerView example with sample data. */
-public class GridCarUiRecyclerViewActivity extends Activity implements
-        InsetsChangedListener {
-    private final ArrayList<String> mData = new ArrayList<>();
-    private final int mDataToGenerate = 200;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.grid_car_ui_recycler_view_activity);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-
-        CarUiRecyclerView recyclerView = findViewById(R.id.list);
-
-        RecyclerViewAdapter adapter = new RecyclerViewAdapter(generateSampleData());
-        recyclerView.setAdapter(adapter);
-    }
-
-    private ArrayList<String> generateSampleData() {
-        for (int i = 1; i <= mDataToGenerate; i++) {
-            mData.add("data" + i);
-        }
-        return mData;
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        FocusArea focusArea = requireViewById(R.id.focus_area);
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/RecyclerViewAdapter.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/RecyclerViewAdapter.java
deleted file mode 100644
index fbfd49f..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/caruirecyclerview/RecyclerViewAdapter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.caruirecyclerview;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.paintbooth.R;
-
-import java.util.List;
-
-/**
- * Implementation of {@link RecyclerViewAdapter} that can be used with RecyclerViews.
- */
-public class RecyclerViewAdapter extends
-        RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
-
-    private List<String> mData;
-
-    public RecyclerViewAdapter(List<String> data) {
-        this.mData = data;
-    }
-
-    @NonNull
-    @Override
-    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
-        LayoutInflater inflator = LayoutInflater.from(parent.getContext());
-        View view = inflator.inflate(R.layout.car_ui_recycler_view_list_item, parent, false);
-        return new RecyclerViewHolder(view);
-    }
-
-    @Override
-    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
-        String title = mData.get(position);
-        holder.mTextTitle.setText(title);
-    }
-
-    @Override
-    public int getItemCount() {
-        return mData.size();
-    }
-
-
-    /**
-     * Holds views for each element in the list.
-     */
-    public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
-        TextView mTextTitle;
-
-        RecyclerViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mTextTitle = itemView.findViewById(R.id.textTitle);
-        }
-    }
-}
-
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java
deleted file mode 100644
index 07c15b2..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.currentactivity;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.content.ComponentName;
-import android.os.RemoteException;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class is a wrapper around {@link android.app.ActivityTaskManager} that is excluded from
- * the gradle and google3 builds.
- */
-class ActivityTaskManagerImpl implements ActivityTaskManager {
-
-    android.app.ActivityTaskManager mActivityTaskManager =
-            android.app.ActivityTaskManager.getInstance();
-
-    Map<TaskStackListener, android.app.TaskStackListener> mListenerMapping = new HashMap<>();
-
-    @Override
-    public List<RunningTaskInfo> getTasks(int maxNum) throws RemoteException {
-        return mActivityTaskManager.getTasks(maxNum);
-    }
-
-    @Override
-    public void registerTaskStackListener(TaskStackListener listener) throws RemoteException {
-        mListenerMapping.put(listener, new android.app.TaskStackListener() {
-            @Override
-            public void onTaskCreated(int taskId, ComponentName componentName) {
-                listener.onTaskCreated(taskId, componentName);
-            }
-
-            @Override
-            public void onTaskRemoved(int taskId) {
-                listener.onTaskRemoved(taskId);
-            }
-
-            @Override
-            public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) {
-                listener.onTaskDescriptionChanged(taskInfo);
-            }
-
-            @Override
-            public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
-                listener.onTaskMovedToFront(taskInfo);
-            }
-        });
-
-        mActivityTaskManager.registerTaskStackListener(mListenerMapping.get(listener));
-    }
-
-    @Override
-    public void unregisterTaskStackListener(TaskStackListener listener) throws RemoteException {
-        mActivityTaskManager.unregisterTaskStackListener(mListenerMapping.get(listener));
-        mListenerMapping.remove(listener);
-    }
-
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/CurrentActivityService.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/CurrentActivityService.java
deleted file mode 100644
index fceea72..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/CurrentActivityService.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.currentactivity;
-
-import android.app.ActivityManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.core.app.NotificationCompat;
-import androidx.core.content.ContextCompat;
-
-import com.android.car.ui.paintbooth.MainActivity;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.paintbooth.currentactivity.ActivityTaskManager.TaskStackListener;
-
-import java.util.List;
-
-/**
- * To start the service:
- * adb shell am start-foreground-service -n com.android.car.ui.paintbooth/.CurrentActivityService
- *
- * To stop the service:
- * adb shell am start-foreground-service -n com.android.car.ui.paintbooth/.CurrentActivityService -a
- * com.android.car.ui.paintbooth.StopService
- */
-public class CurrentActivityService extends Service {
-    private static final int FOREGROUND_SERVICE_ID = 111;
-
-    private WindowManager mWindowManager;
-    private TextView mTextView;
-    private Handler mHandler;
-
-    @Override
-    public void onCreate() {
-        mHandler = new Handler(Looper.getMainLooper());
-
-        if (ContextCompat.checkSelfPermission(this, "android.permission.REAL_GET_TASKS")
-                != PackageManager.PERMISSION_GRANTED) {
-            Toast.makeText(this, "android.permission.REAL_GET_TASKS is not granted!",
-                    Toast.LENGTH_LONG).show();
-        }
-
-        Intent notificationIntent = new Intent(this, CurrentActivityService.class);
-
-        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
-                notificationIntent, PendingIntent.FLAG_IMMUTABLE);
-
-        NotificationChannel channel = new NotificationChannel("CurrentActivityService",
-                "Show current activity",
-                NotificationManager.IMPORTANCE_DEFAULT);
-        NotificationManager notificationManager =
-                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-        notificationManager.createNotificationChannel(channel);
-
-        Notification notification =
-                new NotificationCompat.Builder(this, "CurrentActivityService")
-                        .setSmallIcon(R.drawable.ic_launcher)
-                        .setContentTitle("CurrentActivityService")
-                        .setContentText("Show current activity")
-                        .setContentIntent(pendingIntent).build();
-
-        startForeground(FOREGROUND_SERVICE_ID, notification);
-
-        try {
-            ActivityTaskManager.getService().registerTaskStackListener(mTaskStackListener);
-        } catch (RemoteException e) {
-            Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
-        }
-
-        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
-        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
-                WindowManager.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
-                PixelFormat.TRANSLUCENT);
-
-        mTextView = new TextView(this);
-        layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
-        layoutParams.x = 0;
-        layoutParams.y = 100;
-        mTextView.setLayoutParams(layoutParams);
-        mTextView.setBackgroundColor(Color.argb(50, 0, 255, 0));
-
-        mTextView.setOnTouchListener(new View.OnTouchListener() {
-
-            private int mInitialX = 0;
-            private int mInitialY = 0;
-            private float mInitialTouchX;
-            private float mInitialTouchY;
-
-            @Override
-            public boolean onTouch(View view, MotionEvent event) {
-                switch (event.getAction() & MotionEvent.ACTION_MASK) {
-                    case MotionEvent.ACTION_DOWN:
-                        mInitialX = layoutParams.x;
-                        mInitialY = layoutParams.y;
-                        mInitialTouchX = event.getRawX();
-                        mInitialTouchY = event.getRawY();
-                        break;
-                    case MotionEvent.ACTION_MOVE:
-                        WindowManager.LayoutParams layoutParams =
-                                (WindowManager.LayoutParams) view.getLayoutParams();
-                        layoutParams.x = mInitialX + (int) (event.getRawX() - mInitialTouchX);
-                        layoutParams.y = mInitialY + (int) (event.getRawY() - mInitialTouchY);
-                        mWindowManager.updateViewLayout(view, layoutParams);
-                        return true;
-                    default:
-                        break;
-                }
-
-                return false;
-            }
-        });
-
-        try {
-            mWindowManager.addView(mTextView, layoutParams);
-        } catch (RuntimeException e) {
-            Toast.makeText(this, "Couldn't display overlay", Toast.LENGTH_SHORT)
-                .show();
-        }
-
-        showCurrentTask();
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (MainActivity.STOP_SERVICE.equals(intent.getAction())) {
-            stopSelf();
-        }
-
-        return START_STICKY;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public void onDestroy() {
-        mHandler.removeCallbacksAndMessages(null);
-        mWindowManager.removeView(mTextView);
-        try {
-            ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener);
-        } catch (RemoteException e) {
-            Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
-        }
-    }
-
-    /**
-     * This requires system permissions or else it will only fetch the current app and the launcher
-     * app
-     */
-    private void showCurrentTask() {
-        try {
-            List<ActivityManager.RunningTaskInfo> tasks =
-                    ActivityTaskManager.getService().getTasks(1);
-            if (!tasks.isEmpty()) {
-                updateComponentName(tasks.get(0).topActivity);
-            }
-        } catch (RemoteException e) {
-            Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
-        }
-    }
-
-    private void updateComponentName(ComponentName componentName) {
-        mHandler.post(() -> {
-            if (mTextView != null && componentName != null) {
-                mTextView.setText(componentName.flattenToShortString().replace('/', '\n'));
-            }
-        });
-    }
-
-    private final TaskStackListener mTaskStackListener = new TaskStackListener() {
-        @Override
-        public void onTaskCreated(int taskId, ComponentName componentName) {
-            updateComponentName(componentName);
-        }
-
-        @Override
-        public void onTaskRemoved(int taskId) {
-            showCurrentTask();
-        }
-
-        @Override
-        public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) {
-            updateComponentName(taskInfo.topActivity);
-        }
-
-        @Override
-        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
-            updateComponentName(taskInfo.topActivity);
-        }
-    };
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/dialogs/DialogsActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/dialogs/DialogsActivity.java
deleted file mode 100644
index bf62cc7..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/dialogs/DialogsActivity.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.dialogs;
-
-import android.Manifest;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.AlertDialogBuilder;
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRadioButtonListItem;
-import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Activity that shows different dialogs from the device default theme.
- */
-public class DialogsActivity extends Activity implements InsetsChangedListener {
-
-    private final List<Pair<Integer, View.OnClickListener>> mButtons = new ArrayList<>();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_activity);
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-
-        mButtons.add(Pair.create(R.string.dialog_show_dialog,
-                v -> showDialog()));
-        mButtons.add(Pair.create(R.string.dialog_show_dialog_icon,
-                v -> showDialogWithIcon()));
-        mButtons.add(Pair.create(R.string.dialog_show_dialog_edit,
-                v -> showDialogWithTextBox()));
-        mButtons.add(Pair.create(R.string.dialog_show_dialog_only_positive,
-                v -> showDialogWithOnlyPositiveButton()));
-        mButtons.add(Pair.create(R.string.dialog_show_dialog_no_button,
-                v -> showDialogWithNoButtonProvided()));
-        mButtons.add(Pair.create(R.string.dialog_show_dialog_checkbox,
-                v -> showDialogWithCheckbox()));
-        mButtons.add(Pair.create(R.string.dialog_show_dialog_no_title,
-                v -> showDialogWithoutTitle()));
-        mButtons.add(Pair.create(R.string.dialog_show_toast,
-                v -> showToast()));
-        mButtons.add(Pair.create(R.string.dialog_show_subtitle,
-                v -> showDialogWithSubtitle()));
-        mButtons.add(Pair.create(R.string.dialog_show_subtitle_and_icon,
-                v -> showDialogWithSubtitleAndIcon()));
-        mButtons.add(Pair.create(R.string.dialog_show_long_subtitle_and_icon,
-                v -> showDialogWithLongSubtitleAndIcon()));
-        mButtons.add(Pair.create(R.string.dialog_show_single_choice,
-                v -> showDialogWithSingleChoiceItems()));
-        mButtons.add(Pair.create(R.string.dialog_show_list_items_without_default_button,
-                v -> showDialogWithListItemsWithoutDefaultButton()));
-        mButtons.add(Pair.create(R.string.dialog_show_permission_dialog,
-                v -> showPermissionDialog()));
-        mButtons.add(Pair.create(R.string.dialog_show_multi_permission_dialog,
-                v -> showMultiPermissionDialog()));
-        mButtons.add(Pair.create(R.string.dialog_show_foreground_permission_dialog,
-                v -> showForegroundPermissionDialog()));
-        mButtons.add(Pair.create(R.string.dialog_show_background_permission_dialog,
-                v -> showBackgroundPermissionDialog()));
-
-        CarUiRecyclerView recyclerView = requireViewById(R.id.list);
-        recyclerView.setAdapter(mAdapter);
-    }
-
-    private void showDialog() {
-        new AlertDialogBuilder(this)
-                .setTitle(getString(R.string.standard_alert_dialog))
-                .setMessage(getString(R.string.my_message))
-                .setNeutralButton(getString(R.string.neutral), (dialogInterface, which) -> {
-                })
-                .setPositiveButton(getString(R.string.ok), (dialogInterface, which) -> {
-                })
-                .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> {
-                })
-                .show();
-    }
-
-    private void showDialogWithIcon() {
-        new AlertDialogBuilder(this)
-                .setTitle(getString(R.string.alert_dialog_with_icon))
-                .setMessage(getString(R.string.my_message))
-                .setIcon(R.drawable.ic_tracklist)
-                .show();
-    }
-
-    private void showDialogWithNoButtonProvided() {
-        new AlertDialogBuilder(this)
-                .setTitle(getString(R.string.standard_alert_dialog))
-                .show();
-    }
-
-    private void showDialogWithCheckbox() {
-        new AlertDialogBuilder(this)
-                .setTitle(R.string.custom_dialog_box)
-                .setMultiChoiceItems(
-                        new CharSequence[]{"I am a checkbox"},
-                        new boolean[]{false},
-                        (dialog, which, isChecked) -> {
-                        })
-                .setPositiveButton(getString(R.string.ok), (dialogInterface, which) -> {
-                })
-                .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> {
-                })
-                .show();
-    }
-
-    private void showDialogWithTextBox() {
-        new AlertDialogBuilder(this)
-                .setTitle(R.string.standard_alert_dialog)
-                .setEditBox(getString(R.string.edit_me_please), null, null)
-                .setAutoDescUpdateForWidescreen(true)
-                .setEditTextTitleAndDescForWideScreen("title", "desc from app")
-                .setPositiveButton("OK", (dialogInterface, i) -> {
-                })
-                .show();
-    }
-
-    private void showDialogWithOnlyPositiveButton() {
-        new AlertDialogBuilder(this)
-                .setTitle(R.string.standard_alert_dialog)
-                .setMessage(getString(R.string.my_message))
-                .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
-                })
-                .show();
-    }
-
-    private void showDialogWithoutTitle() {
-        new AlertDialogBuilder(this)
-                .setMessage(R.string.no_title_message)
-                .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
-                })
-                .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> {
-                })
-                .show();
-    }
-
-    private void showToast() {
-        Toast.makeText(this, "Toast message looks like this", Toast.LENGTH_LONG).show();
-    }
-
-    private void showDialogWithSubtitle() {
-        new AlertDialogBuilder(this)
-                .setTitle(R.string.my_title)
-                .setSubtitle(R.string.my_subtitle)
-                .setMessage(getString(R.string.my_message))
-                .show();
-    }
-
-    private void showDialogWithSingleChoiceItems() {
-        ArrayList<CarUiRadioButtonListItem> data = new ArrayList<>();
-
-        CarUiRadioButtonListItem item = new CarUiRadioButtonListItem();
-        item.setTitle(getString(R.string.first_item));
-        data.add(item);
-
-        item = new CarUiRadioButtonListItem();
-        item.setTitle(getString(R.string.second_item));
-        data.add(item);
-
-        item = new CarUiRadioButtonListItem();
-        item.setTitle(getString(R.string.third_item));
-        data.add(item);
-
-        new AlertDialogBuilder(this)
-                .setTitle(R.string.select_one_option)
-                .setSubtitle(R.string.select_one_option_at_a_time)
-                .setSingleChoiceItems(new CarUiRadioButtonListItemAdapter(data), null)
-                .show();
-    }
-
-    private void showDialogWithListItemsWithoutDefaultButton() {
-        ArrayList<CarUiContentListItem> data = new ArrayList<>();
-        AlertDialog[] dialog = new AlertDialog[1];
-
-        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle("First item");
-        item.setOnItemClickedListener(i -> dialog[0].dismiss());
-        data.add(item);
-
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle("Second item");
-        item.setOnItemClickedListener(i -> dialog[0].dismiss());
-        data.add(item);
-
-        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
-        item.setTitle("Third item");
-        item.setOnItemClickedListener(i -> dialog[0].dismiss());
-        data.add(item);
-
-        dialog[0] = new AlertDialogBuilder(this)
-                .setTitle("Select one option.")
-                .setSubtitle("Ony one option may be selected at a time")
-                .setAdapter(new CarUiListItemAdapter(data))
-                .setAllowDismissButton(false)
-                .show();
-    }
-
-    private void showDialogWithSubtitleAndIcon() {
-        new AlertDialogBuilder(this)
-                .setTitle(R.string.my_title)
-                .setSubtitle(R.string.my_subtitle)
-                .setMessage(getString(R.string.my_message))
-                .setIcon(R.drawable.ic_tracklist)
-                .show();
-    }
-
-    private void showDialogWithLongSubtitleAndIcon() {
-        new AlertDialogBuilder(this)
-                .setTitle(getString(R.string.long_title))
-                .setSubtitle(R.string.long_subtitle)
-                .setMessage(getString(R.string.my_message))
-                .setIcon(R.drawable.ic_tracklist)
-                .show();
-    }
-
-    private void showPermissionDialog() {
-        if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
-            Toast.makeText(this, "Permission already granted. Remove CAMERA permission from "
-                    + "Settings > All apps > PaintBooth", Toast.LENGTH_SHORT).show();
-            return;
-        }
-        requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
-    }
-
-    private void showMultiPermissionDialog() {
-        if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
-                && checkSelfPermission(Manifest.permission.SEND_SMS)
-                    == PackageManager.PERMISSION_GRANTED
-                && checkSelfPermission(Manifest.permission.READ_CONTACTS)
-                    == PackageManager.PERMISSION_GRANTED) {
-            Toast.makeText(this, "Permissions are already granted. Remove CAMERA, SEND_SMS or "
-                    + "READ_CONTACTS permission from Settings > All apps > PaintBooth",
-                    Toast.LENGTH_SHORT).show();
-            return;
-        }
-        requestPermissions(new String[]{Manifest.permission.CAMERA,
-                Manifest.permission.READ_CONTACTS, Manifest.permission.SEND_SMS}, 1);
-    }
-
-    private void showForegroundPermissionDialog() {
-        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
-    }
-
-    private void showBackgroundPermissionDialog() {
-        requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1);
-    }
-
-    @Override
-    public void onRequestPermissionsResult(int requestCode, String[] permissions,
-            int[] grantResults) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Permission ");
-        for (int i = 0; i < permissions.length; i++) {
-            sb.append(permissions[i]);
-            sb.append("=");
-            sb.append(grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied");
-            sb.append("\n");
-        }
-        Toast.makeText(this, sb.toString(), Toast.LENGTH_SHORT).show();
-    }
-
-    private static class ViewHolder extends RecyclerView.ViewHolder {
-
-        private final Button mButton;
-
-        ViewHolder(View itemView) {
-            super(itemView);
-            mButton = itemView.requireViewById(R.id.button);
-        }
-
-        public void bind(Integer title, View.OnClickListener listener) {
-            mButton.setText(title);
-            mButton.setOnClickListener(listener);
-        }
-    }
-
-    private final RecyclerView.Adapter<ViewHolder> mAdapter =
-            new RecyclerView.Adapter<ViewHolder>() {
-                @Override
-                public int getItemCount() {
-                    return mButtons.size();
-                }
-
-                @Override
-                public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
-                    View item =
-                            LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,
-                                    parent, false);
-                    return new ViewHolder(item);
-                }
-
-                @Override
-                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
-                    Pair<Integer, View.OnClickListener> pair = mButtons.get(position);
-                    holder.bind(pair.first, pair.second);
-                }
-            };
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        FocusArea focusArea = requireViewById(R.id.focus_area);
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/PreferenceDemoFragment.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/PreferenceDemoFragment.java
deleted file mode 100644
index b7636ad..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/PreferenceDemoFragment.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.preferences;
-
-import android.car.drivingstate.CarUxRestrictions;
-import android.os.Bundle;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceGroup;
-
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.preference.CarUiTwoActionBasePreference;
-import com.android.car.ui.preference.CarUiTwoActionIconPreference;
-import com.android.car.ui.preference.CarUiTwoActionSwitchPreference;
-import com.android.car.ui.preference.CarUiTwoActionTextPreference;
-import com.android.car.ui.preference.PreferenceFragment;
-import com.android.car.ui.preference.UxRestrictablePreference;
-import com.android.car.ui.utils.CarUxRestrictionsUtil;
-
-import java.util.Objects;
-
-/**
- * Fragment to load preferences
- */
-public class PreferenceDemoFragment extends PreferenceFragment {
-
-    CarUxRestrictionsUtil.OnUxRestrictionsChangedListener mOnUxRestrictionsChangedListener =
-            restrictions -> {
-                boolean isRestricted =
-                        (restrictions.getActiveRestrictions()
-                                & CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP)
-                                == CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP;
-
-                restrictPreference(getPreferenceScreen(), isRestricted);
-            };
-
-    private void restrictPreference(Preference preference, boolean restrict) {
-        if (preference == null) {
-            return;
-        }
-
-        if (preference instanceof UxRestrictablePreference) {
-            ((UxRestrictablePreference) preference).setUxRestricted(restrict);
-            ((UxRestrictablePreference) preference).setOnClickWhileRestrictedListener(p ->
-                    Toast.makeText(getContext(), R.string.car_ui_restricted_while_driving,
-                            Toast.LENGTH_LONG).show());
-        }
-
-        if (preference instanceof PreferenceGroup) {
-            PreferenceGroup preferenceGroup = (PreferenceGroup) preference;
-            for (int i = 0; i < preferenceGroup.getPreferenceCount(); i++) {
-                restrictPreference(preferenceGroup.getPreference(i), restrict);
-            }
-        }
-    }
-
-    @Override
-    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        // Load the preferences from an XML resource
-        setPreferencesFromResource(R.xml.preference_samples, rootKey);
-
-        setupTwoActionPreferenceClickListeners(requirePreference("twoactiontext"));
-        setupTwoActionPreferenceClickListeners(requirePreference("twoactiontextborderless"));
-        setupTwoActionPreferenceClickListeners(requirePreference("twoactionicon"));
-        setupTwoActionPreferenceClickListeners(requirePreference("twoactionswitch"));
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        CarUxRestrictionsUtil.getInstance(requireContext())
-                .register(mOnUxRestrictionsChangedListener);
-    }
-
-    @Override
-    public void onStop() {
-        CarUxRestrictionsUtil.getInstance(requireContext())
-                .unregister(mOnUxRestrictionsChangedListener);
-        super.onStop();
-    }
-
-    private void setupTwoActionPreferenceClickListeners(CarUiTwoActionBasePreference preference) {
-        if (preference instanceof CarUiTwoActionSwitchPreference) {
-            ((CarUiTwoActionSwitchPreference) preference).setOnSecondaryActionClickListener(
-                    (selected) -> preference.setSecondaryActionEnabled(false));
-        } else if (preference instanceof CarUiTwoActionTextPreference) {
-            ((CarUiTwoActionTextPreference) preference).setOnSecondaryActionClickListener(
-                    () -> preference.setSecondaryActionEnabled(false));
-        } else {
-            ((CarUiTwoActionIconPreference) preference).setOnSecondaryActionClickListener(
-                    () -> preference.setSecondaryActionEnabled(false));
-        }
-
-        preference.setOnPreferenceClickListener((pref) -> {
-            if (!preference.isSecondaryActionEnabled()) {
-                preference.setSecondaryActionEnabled(true);
-            } else {
-                preference.setSecondaryActionVisible(
-                        !preference.isSecondaryActionVisible());
-            }
-            return true;
-        });
-    }
-
-    @NonNull
-    private <T extends Preference> T requirePreference(CharSequence key) {
-        T pref = findPreference(key);
-        return Objects.requireNonNull(pref);
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/SplitPreferenceActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/SplitPreferenceActivity.java
deleted file mode 100644
index 8ede8b1..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/SplitPreferenceActivity.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.paintbooth.preferences;
-
-import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-/**
- * A demo activity showing off preferences that only take up half the screen, and
- * have their own toolbar independent from the main toolbar.
- */
-public class SplitPreferenceActivity extends AppCompatActivity implements InsetsChangedListener {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.split_preference_activity);
-
-        ToolbarController mainToolbar = CarUi.getToolbar(this);
-        if (mainToolbar != null) {
-            mainToolbar.setNavButtonMode(NavButtonMode.BACK);
-            mainToolbar.setTitle("Split preferences sample");
-        }
-
-        // We do this so that the insets are not automatically sent to the fragments.
-        // The fragments have their own insets handled by the installBaseLayoutAround().
-        CarUi.replaceInsetsChangedListenerWith(this, this);
-
-        SplitPreferenceDemoFragment fragment = new SplitPreferenceDemoFragment();
-        ToolbarController subToolbar = CarUi.installBaseLayoutAround(
-                requireViewById(R.id.preference_fragment_container),
-                fragment, true);
-        fragment.setToolbar(subToolbar);
-
-        if (savedInstanceState == null) {
-            getSupportFragmentManager()
-                    .beginTransaction()
-                    .replace(R.id.preference_fragment_container, fragment)
-                    .commitNow();
-        }
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), insets.getTop(),
-                        insets.getRight(), insets.getBottom());
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/SplitPreferenceDemoFragment.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/SplitPreferenceDemoFragment.java
deleted file mode 100644
index 6d09b75..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/SplitPreferenceDemoFragment.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.paintbooth.preferences;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.toolbar.ToolbarController;
-
-/**
- * A PreferenceFragment that can use a custom toolbar via the {@link #setToolbar(ToolbarController)}
- * method.
- */
-public class SplitPreferenceDemoFragment extends PreferenceDemoFragment {
-
-    private ToolbarController mToolbar;
-    private Insets mInsets;
-
-    @Override
-    public void setupToolbar(@NonNull ToolbarController toolbar) {
-        toolbar.setLogo(R.drawable.ic_launcher);
-        if (getPreferenceScreen() != null) {
-            toolbar.setTitle(getPreferenceScreen().getTitle());
-        }
-    }
-
-    @Override
-    public ToolbarController getPreferenceToolbar(@NonNull Fragment fragment) {
-        return mToolbar;
-    }
-
-    public void setToolbar(ToolbarController toolbar) {
-        mToolbar = toolbar;
-    }
-
-    @Nullable
-    @Override
-    protected Insets getPreferenceInsets(@NonNull Fragment fragment) {
-        return mInsets;
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        mInsets = insets;
-        super.onCarUiInsetsChanged(insets);
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java
deleted file mode 100644
index 5b4b2a2..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.paintbooth.toolbar;
-
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.AlertDialogBuilder;
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.MenuItem;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.SearchMode;
-import com.android.car.ui.toolbar.TabLayout;
-import com.android.car.ui.toolbar.Toolbar;
-import com.android.car.ui.toolbar.Toolbar.State;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ToolbarActivity extends AppCompatActivity implements InsetsChangedListener {
-
-    private final List<MenuItem> mMenuItems = new ArrayList<>();
-    private final List<Pair<CharSequence, View.OnClickListener>> mButtons = new ArrayList<>();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_activity);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-        toolbar.setLogo(R.drawable.ic_launcher);
-        boolean[] isSearching = new boolean[] { false };
-        toolbar.registerBackListener(
-                () -> {
-                    if (toolbar.getState() == Toolbar.State.SEARCH
-                            || toolbar.getState() == Toolbar.State.EDIT) {
-                        toolbar.setState(Toolbar.State.SUBPAGE);
-                        return true;
-                    } else if (isSearching[0]) {
-                        toolbar.setSearchMode(SearchMode.DISABLED);
-                        isSearching[0] = false;
-                        return true;
-                    }
-                    return false;
-                });
-
-        mMenuItems.add(MenuItem.builder(this)
-                .setToSearch()
-                .setOnClickListener(i -> {
-                    isSearching[0] = true;
-                    toolbar.setSearchMode(SearchMode.SEARCH);
-                })
-                .build());
-
-        toolbar.setMenuItems(mMenuItems);
-
-        mButtons.add(Pair.create("Toggle progress bar", v -> {
-            toolbar.getProgressBar().setVisible(!toolbar.getProgressBar().isVisible());
-        }));
-
-        mButtons.add(Pair.create("Change title", v ->
-                toolbar.setTitle(toolbar.getTitle() + " X")));
-
-        mButtons.add(Pair.create("Add/Change subtitle", v -> {
-            CharSequence subtitle = toolbar.getSubtitle();
-            if (TextUtils.isEmpty(subtitle)) {
-                toolbar.setSubtitle("Subtitle");
-            } else {
-                toolbar.setSubtitle(subtitle + " X");
-            }
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_cycle_nav_button), v -> {
-            Toolbar.NavButtonMode mode = toolbar.getNavButtonMode();
-            if (mode == Toolbar.NavButtonMode.DISABLED) {
-                toolbar.setNavButtonMode(NavButtonMode.BACK);
-            } else if (mode == Toolbar.NavButtonMode.BACK) {
-                toolbar.setNavButtonMode(NavButtonMode.CLOSE);
-            } else if (mode == Toolbar.NavButtonMode.CLOSE) {
-                toolbar.setNavButtonMode(NavButtonMode.DOWN);
-            } else {
-                toolbar.setNavButtonMode(NavButtonMode.DISABLED);
-            }
-        }));
-
-        Mutable<Boolean> hasLogo = new Mutable<>(true);
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_logo), v -> {
-            toolbar.setLogo(hasLogo.value ? 0 : R.drawable.ic_launcher);
-            hasLogo.value = !hasLogo.value;
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_cycle_state), v -> {
-            if (toolbar.getState() == State.HOME) {
-                toolbar.setState(State.SUBPAGE);
-            } else if (toolbar.getState() == State.SUBPAGE) {
-                toolbar.setState(State.EDIT);
-            } else {
-                toolbar.setState(State.HOME);
-            }
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_show_tabs_in_subpage), v ->
-                toolbar.setShowTabsInSubpage(!toolbar.getShowTabsInSubpage())));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_search_hint), v -> {
-            if (toolbar.getSearchHint().toString().contentEquals("Foo")) {
-                toolbar.setSearchHint("Bar");
-            } else {
-                toolbar.setSearchHint("Foo");
-            }
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_background),
-                v -> toolbar.setBackgroundShown(!toolbar.getBackgroundShown())));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_tab), v -> toolbar.addTab(
-                new TabLayout.Tab(getDrawable(R.drawable.ic_launcher), "Foo"))));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_tab_with_custom_text), v -> {
-            SimpleTextWatcher textWatcher = new SimpleTextWatcher();
-            new AlertDialogBuilder(this)
-                    .setEditBox(null, textWatcher, null)
-                    .setTitle("Enter the text for the title")
-                    .setPositiveButton(getString(R.string.ok), (dialog, which) ->
-                            toolbar.addTab(new TabLayout.Tab(
-                                    getDrawable(R.drawable.ic_launcher),
-                                    textWatcher.getText())))
-                    .show();
-        }));
-
-        Mutable<Boolean> showingLauncherIcon = new Mutable<>(false);
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_search_icon), v -> {
-            if (showingLauncherIcon.value) {
-                toolbar.setSearchIcon(null);
-            } else {
-                toolbar.setSearchIcon(R.drawable.ic_launcher);
-            }
-            showingLauncherIcon.value = !showingLauncherIcon.value;
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_set_xml_resource), v -> {
-            mMenuItems.clear();
-            toolbar.setMenuItems(R.xml.menuitems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setToSettings()
-                    .setOnClickListener(i -> Toast.makeText(this, "Clicked",
-                            Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_untined_icon), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setIcon(R.drawable.ic_tracklist)
-                    .setTinted(false)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_switch), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setCheckable()
-                    .setOnClickListener(
-                            i ->
-                                    Toast.makeText(this,
-                                            "Checked? " + i.isChecked(),
-                                            Toast.LENGTH_SHORT)
-                                            .show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_text), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setTitle("Baz")
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon_text), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setIcon(R.drawable.ic_tracklist)
-                    .setTitle("Bar")
-                    .setShowIconAndTitle(true)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_bordered_text), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setTitle("Baz")
-                    .setPrimary(true)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_bordered_icon_text), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setIcon(R.drawable.ic_tracklist)
-                    .setTitle("Bar")
-                    .setPrimary(true)
-                    .setShowIconAndTitle(true)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_untinted_icon_and_text), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setIcon(R.drawable.ic_tracklist)
-                    .setTitle("Bar")
-                    .setShowIconAndTitle(true)
-                    .setTinted(false)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_activatable), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setIcon(R.drawable.ic_tracklist)
-                    .setActivatable()
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_morphing), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setTitle("Become icon")
-                    .setOnClickListener(i ->
-                            i.setIcon(i.getIcon() == null ? R.drawable.ic_tracklist : 0))
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        Mutable<Integer> overflowCounter = new Mutable<>(1);
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_overflow), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setTitle("Foo " + overflowCounter.value)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-            overflowCounter.value++;
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_overflow_switch), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setTitle("Foo " + overflowCounter.value)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this,
-                                    i.isChecked() ? "Checked" : "Unchecked",
-                                    Toast.LENGTH_SHORT)
-                                    .show())
-                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
-                    .setCheckable()
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-            overflowCounter.value++;
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon_text_overflow), v -> {
-            mMenuItems.add(MenuItem.builder(this)
-                    .setIcon(R.drawable.ic_tracklist)
-                    .setTitle("Bar")
-                    .setShowIconAndTitle(true)
-                    .setOnClickListener(
-                            i -> Toast.makeText(this, "Clicked",
-                                    Toast.LENGTH_SHORT).show())
-                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
-                    .build());
-            toolbar.setMenuItems(mMenuItems);
-        }));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_visibility),
-                v -> getMenuItem(item -> item.setVisible(!item.isVisible()))));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_enable),
-                v -> getMenuItem(item -> item.setEnabled(!item.isEnabled()))));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_perform_click),
-                v -> getMenuItem(MenuItem::performClick)));
-
-        final Drawable altIcon = getDrawable(R.drawable.ic_cut);
-        Map<MenuItem, Drawable> iconBackups = new HashMap<>();
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_icon), v ->
-                getMenuItem(item -> {
-                    Drawable currentIcon = item.getIcon();
-                    Drawable newIcon = altIcon;
-                    if (iconBackups.containsKey(item)) {
-                        newIcon = iconBackups.get(item);
-                    }
-                    item.setIcon(newIcon);
-                    iconBackups.put(item, currentIcon);
-                })));
-
-        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_show_while_search), v ->
-                toolbar.setShowMenuItemsWhileSearching(
-                        !toolbar.getShowMenuItemsWhileSearching())));
-
-        CarUiRecyclerView prv = requireViewById(R.id.list);
-        prv.setAdapter(mAdapter);
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        FocusArea focusArea = requireViewById(R.id.focus_area);
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-
-    public void xmlMenuItemClicked(MenuItem item) {
-        Toast.makeText(this, "Xml item clicked! " + item.getTitle() + ", id: " + item.getId(),
-                Toast.LENGTH_SHORT).show();
-    }
-
-    private void getMenuItem(MenuItem.OnClickListener listener) {
-        if (mMenuItems.size() == 1) {
-            listener.onClick(mMenuItems.get(0));
-            return;
-        }
-
-        SimpleTextWatcher textWatcher = new SimpleTextWatcher();
-        new AlertDialogBuilder(this)
-                .setEditBox("", textWatcher, null, InputType.TYPE_CLASS_NUMBER)
-                .setTitle("Enter the index of the MenuItem")
-                .setPositiveButton(getString(R.string.ok), (dialog, which) -> {
-                    try {
-                        MenuItem item = mMenuItems.get(
-                                Integer.parseInt(textWatcher.getText()));
-                        listener.onClick(item);
-                    } catch (NumberFormatException | IndexOutOfBoundsException e) {
-                        Toast.makeText(this, "Invalid index \"" + textWatcher.getText()
-                                        + "\", valid range is 0 to " + (mMenuItems.size() - 1),
-                                Toast.LENGTH_LONG).show();
-                    }
-                }).show();
-    }
-
-    private static class ViewHolder extends RecyclerView.ViewHolder {
-
-        private final Button mButton;
-
-        ViewHolder(View itemView) {
-            super(itemView);
-            mButton = itemView.requireViewById(R.id.button);
-        }
-
-        public void bind(CharSequence title, View.OnClickListener listener) {
-            mButton.setText(title);
-            mButton.setOnClickListener(listener);
-        }
-    }
-
-    private final RecyclerView.Adapter<ViewHolder> mAdapter =
-            new RecyclerView.Adapter<ViewHolder>() {
-                @Override
-                public int getItemCount() {
-                    return mButtons.size();
-                }
-
-                @Override
-                public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
-                    View item =
-                            LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,
-                                    parent, false);
-                    return new ViewHolder(item);
-                }
-
-                @Override
-                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
-                    Pair<CharSequence, View.OnClickListener> pair = mButtons.get(position);
-                    holder.bind(pair.first, pair.second);
-                }
-            };
-
-    /**
-     * For changing values from lambdas
-     */
-    private static final class Mutable<E> {
-
-        public E value;
-
-        Mutable() {
-            value = null;
-        }
-
-        Mutable(E value) {
-            this.value = value;
-        }
-    }
-
-    /**
-     * Used for getting text from a dialog.
-     */
-    private static final class SimpleTextWatcher implements TextWatcher {
-
-        private String mValue;
-
-        @Override
-        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-        }
-
-        @Override
-        public void onTextChanged(CharSequence s, int start, int before, int count) {
-        }
-
-        @Override
-        public void afterTextChanged(Editable s) {
-            mValue = s.toString();
-        }
-
-        public String getText() {
-            return mValue;
-        }
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java
deleted file mode 100644
index f056ced..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.widescreenime;
-
-import static android.view.inputmethod.EditorInfo.IME_FLAG_NO_EXTRACT_UI;
-
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_DESC_TITLE_TO_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_DESC_TO_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.ADD_ERROR_DESC_TO_INPUT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.REQUEST_RENDER_CONTENT_AREA;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_ACTION;
-import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnFocusChangeListener;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.content.ContextCompat;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.FocusArea;
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.recyclerview.CarUiContentListItem;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.MenuItem;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.SearchConfig;
-import com.android.car.ui.toolbar.SearchMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Activity that shows different scenarios for wide screen ime.
- */
-public class WideScreenImeActivity extends AppCompatActivity implements InsetsChangedListener {
-    private static final String TAG = "PaintBooth";
-
-    private final List<MenuItem> mMenuItems = new ArrayList<>();
-    private final List<ListElement> mWidescreenItems = new ArrayList<>();
-    private final List<CarUiImeSearchListItem> mSearchItems = new ArrayList<>();
-
-    private InputMethodManager mInputMethodManager;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_activity);
-
-        mInputMethodManager = (InputMethodManager)
-                getSystemService(Context.INPUT_METHOD_SERVICE);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-        toolbar.setLogo(R.drawable.ic_launcher);
-        boolean[] isSearching = new boolean[]{false};
-        toolbar.registerBackListener(
-                () -> {
-                    if (isSearching[0]) {
-                        toolbar.setSearchMode(SearchMode.DISABLED);
-                        isSearching[0] = false;
-                        return true;
-                    }
-                    return false;
-                });
-
-        CarUiContentListItem.OnClickListener mainClickListener = i -> {
-            CharSequence title = i.getTitle() != null
-                    ? i.getTitle().getPreferredText()
-                    : null;
-            Toast.makeText(this, "Item clicked! " + title, Toast.LENGTH_SHORT).show();
-            Log.i(TAG, "Item clicked! " + title);
-        };
-        CarUiContentListItem.OnClickListener secondaryClickListener = i -> {
-            Toast.makeText(this, "Item's secondary action clicked!", Toast.LENGTH_SHORT).show();
-            Log.i(TAG, "Item's secondary action clicked!");
-        };
-
-        Drawable icon = ContextCompat.getDrawable(this, R.drawable.ic_launcher);
-
-        for (int i = 1; i <= 100; i++) {
-            CarUiImeSearchListItem item = new CarUiImeSearchListItem(
-                    CarUiContentListItem.Action.ICON);
-            item.setTitle("Title " + i);
-            item.setBody("Sub title " + i);
-            item.setIcon(icon);
-            item.setSupplementalIcon(icon, secondaryClickListener);
-            item.setOnItemClickedListener(mainClickListener);
-
-            mSearchItems.add(item);
-        }
-
-        mMenuItems.add(MenuItem.builder(this)
-                .setToSearch()
-                .setOnClickListener(i -> {
-                    isSearching[0] = true;
-                    toolbar.setSearchMode(SearchMode.SEARCH);
-                    if (toolbar.getSearchCapabilities().canShowSearchResultItems()) {
-                        toolbar.setSearchConfig(SearchConfig.builder()
-                                .setSearchResultItems(mSearchItems)
-                                .setSearchResultsInputViewIcon(ContextCompat.getDrawable(
-                                        this, R.drawable.car_ui_icon_search))
-                                .build());
-                    }
-                })
-                .build());
-
-        toolbar.setMenuItems(mMenuItems);
-
-        mWidescreenItems.add(new EditTextElement("Default Input Edit Text field", null));
-        mWidescreenItems.add(
-                new EditTextElement("Add Desc to content area", this::addDescToContentArea));
-        mWidescreenItems.add(new EditTextElement("Hide the content area", this::hideContentArea));
-        mWidescreenItems.add(new EditTextElement("Hide extraction view", this::hideExtractionView));
-
-        mWidescreenItems.add(
-                new EditTextElement("Add icon to extracted view", this::addIconToExtractedView));
-        mWidescreenItems.add(new EditTextElement("Add error message to content area",
-                this::addErrorDescToContentArea));
-
-        CarUiRecyclerView recyclerView = requireViewById(R.id.list);
-        recyclerView.setAdapter(mAdapter);
-    }
-
-    private void addIconToExtractedView(View view, boolean hasFocus) {
-        if (!hasFocus) {
-            return;
-        }
-
-        Bundle bundle = new Bundle();
-        bundle.putInt(WIDE_SCREEN_EXTRACTED_TEXT_ICON_RES_ID, R.drawable.car_ui_icon_edit);
-        mInputMethodManager.sendAppPrivateCommand(view, WIDE_SCREEN_ACTION, bundle);
-    }
-
-    private void addErrorDescToContentArea(View view, boolean hasFocus) {
-        if (!hasFocus) {
-            return;
-        }
-
-        Bundle bundle = new Bundle();
-        bundle.putString(ADD_ERROR_DESC_TO_INPUT_AREA, "Some error message");
-        bundle.putString(ADD_DESC_TITLE_TO_CONTENT_AREA, "Title");
-        bundle.putString(ADD_DESC_TO_CONTENT_AREA, "Description provided by the application");
-        mInputMethodManager.sendAppPrivateCommand(view, WIDE_SCREEN_ACTION, bundle);
-    }
-
-    private void hideExtractionView(View view, boolean hasFocus) {
-        if (!hasFocus) {
-            return;
-        }
-
-        EditText editText = (EditText) view;
-        editText.setImeOptions(IME_FLAG_NO_EXTRACT_UI);
-
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(REQUEST_RENDER_CONTENT_AREA, false);
-        mInputMethodManager.sendAppPrivateCommand(view, WIDE_SCREEN_ACTION, bundle);
-    }
-
-    private void addDescToContentArea(View view, boolean hasFocus) {
-        if (!hasFocus) {
-            return;
-        }
-
-        Bundle bundle = new Bundle();
-        bundle.putString(ADD_DESC_TITLE_TO_CONTENT_AREA, "Title");
-        bundle.putString(ADD_DESC_TO_CONTENT_AREA, "Description provided by the application");
-        mInputMethodManager.sendAppPrivateCommand(view, WIDE_SCREEN_ACTION, bundle);
-    }
-
-    private void hideContentArea(View view, boolean hasFocus) {
-        if (!hasFocus) {
-            return;
-        }
-
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(REQUEST_RENDER_CONTENT_AREA, false);
-        mInputMethodManager.sendAppPrivateCommand(view, WIDE_SCREEN_ACTION, bundle);
-    }
-
-    private abstract static class ViewHolder extends RecyclerView.ViewHolder {
-
-        ViewHolder(@NonNull View itemView) {
-            super(itemView);
-        }
-
-        public abstract void bind(ListElement element);
-    }
-
-    private static class EditTextViewHolder extends ViewHolder {
-
-        private final EditText mEditText;
-
-        EditTextViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mEditText = itemView.requireViewById(R.id.edit_text);
-        }
-
-        @Override
-        public void bind(ListElement e) {
-            if (!(e instanceof EditTextElement)) {
-                throw new IllegalArgumentException("Expected an EditTextElement");
-            }
-            EditTextElement element = (EditTextElement) e;
-            mEditText.setText(element.getText());
-            mEditText.setOnFocusChangeListener(element.getOnFocusChangeListener());
-        }
-    }
-
-    private final RecyclerView.Adapter<ViewHolder> mAdapter =
-            new RecyclerView.Adapter<ViewHolder>() {
-                @Override
-                public int getItemCount() {
-                    return mWidescreenItems.size();
-                }
-
-                @Override
-                public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-                    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-                    if (viewType == ListElement.TYPE_EDIT_TEXT) {
-                        return new EditTextViewHolder(
-                                inflater.inflate(R.layout.edit_text_list_item, parent, false));
-                    } else {
-                        throw new IllegalArgumentException("Unknown viewType: " + viewType);
-                    }
-                }
-
-                @Override
-                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
-                    holder.bind(mWidescreenItems.get(position));
-                }
-
-                @Override
-                public int getItemViewType(int position) {
-                    return mWidescreenItems.get(position).getType();
-                }
-            };
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        FocusArea focusArea = requireViewById(R.id.focus_area);
-        focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom());
-        focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-
-    private abstract static class ListElement {
-
-        static final int TYPE_EDIT_TEXT = 0;
-
-        private final String mText;
-
-        ListElement(String text) {
-            mText = text;
-        }
-
-        String getText() {
-            return mText;
-        }
-
-        abstract int getType();
-    }
-
-    private static class EditTextElement extends ListElement {
-
-        private final OnFocusChangeListener mListener;
-
-        EditTextElement(String text, OnFocusChangeListener listener) {
-            super(text);
-            mListener = listener;
-        }
-
-        OnFocusChangeListener getOnFocusChangeListener() {
-            return mListener;
-        }
-
-        @Override
-        int getType() {
-            return TYPE_EDIT_TEXT;
-        }
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenTestView.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenTestView.java
deleted file mode 100644
index edd5ae2..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenTestView.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.widescreenime;
-
-import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.recyclerview.widget.LinearLayoutManager;
-
-import com.android.car.ui.baselayout.Insets;
-import com.android.car.ui.baselayout.InsetsChangedListener;
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.paintbooth.caruirecyclerview.RecyclerViewAdapter;
-import com.android.car.ui.recyclerview.CarUiRecyclerView;
-import com.android.car.ui.toolbar.MenuItem;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.SearchConfig;
-import com.android.car.ui.toolbar.SearchMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Activity that the custom view inflated in IME window.
- */
-public class WideScreenTestView extends AppCompatActivity implements InsetsChangedListener {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_ui_recycler_view_activity);
-
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-        toolbar.setLogo(R.drawable.ic_launcher);
-        boolean[] isSearching = new boolean[]{false};
-        toolbar.registerBackListener(
-                () -> {
-                    if (isSearching[0]) {
-                        toolbar.setSearchMode(SearchMode.DISABLED);
-                        isSearching[0] = false;
-                        return true;
-                    }
-                    return false;
-                });
-
-        toolbar.setMenuItems(Collections.singletonList(MenuItem.builder(this)
-                .setToSearch()
-                .setOnClickListener(i -> {
-                    isSearching[0] = true;
-                    toolbar.setSearchMode(SearchMode.SEARCH);
-                    if (toolbar.getSearchCapabilities().canShowSearchResultsView()) {
-                        toolbar.setSearchConfig(SearchConfig.builder()
-                                .setSearchResultsView(findViewById(R.id.list)).build());
-                    }
-                }).build()));
-
-        CarUiRecyclerView recyclerView = findViewById(R.id.list);
-        recyclerView.setLayoutManager(new LinearLayoutManager(this));
-
-        RecyclerViewAdapter adapter = new RecyclerViewAdapter(generateSampleData());
-        recyclerView.setAdapter(adapter);
-    }
-
-    private List<String> generateSampleData() {
-        List<String> data = new ArrayList<>();
-        for (int i = 0; i <= 100; i++) {
-            data.add(getString(R.string.test_data) + i);
-        }
-        return data;
-    }
-
-    @Override
-    public void onCarUiInsetsChanged(@NonNull Insets insets) {
-        requireViewById(R.id.list)
-                .setPadding(0, insets.getTop(), 0, insets.getBottom());
-        requireViewById(android.R.id.content)
-                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widgets/WidgetActivity.java b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widgets/WidgetActivity.java
deleted file mode 100644
index 1c4208d..0000000
--- a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widgets/WidgetActivity.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.ui.paintbooth.widgets;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.car.ui.core.CarUi;
-import com.android.car.ui.paintbooth.R;
-import com.android.car.ui.toolbar.NavButtonMode;
-import com.android.car.ui.toolbar.ToolbarController;
-
-/**
- * Activity that shows different widgets from the device default theme.
- */
-public class WidgetActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.widgets_activity);
-        ToolbarController toolbar = CarUi.requireToolbar(this);
-        toolbar.setTitle(getTitle());
-        toolbar.setNavButtonMode(NavButtonMode.BACK);
-    }
-}
diff --git a/car-ui-lib/paintbooth/src/main/res-overlayable/values/overlayable.xml b/car-ui-lib/paintbooth/src/main/res-overlayable/values/overlayable.xml
deleted file mode 100644
index 13ca2e4..0000000
--- a/car-ui-lib/paintbooth/src/main/res-overlayable/values/overlayable.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!--Copyright (C) 2021 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.-->
-<resources>
-  <overlayable name="PaintBooth">
-    <policy type="public">
-      <item type="drawable" name="simulated_screen_shape"/>
-    </policy>
-  </overlayable>
-</resources>
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/button_background_for_rotary.xml b/car-ui-lib/paintbooth/src/main/res/drawable/button_background_for_rotary.xml
deleted file mode 100644
index a3dcf43..0000000
--- a/car-ui-lib/paintbooth/src/main/res/drawable/button_background_for_rotary.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-  <item android:state_focused="true">
-    <shape android:shape="rectangle">
-      <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
-      <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
-          android:color="@color/car_ui_rotary_focus_stroke_color"/>
-    </shape>
-  </item>
-</selector>
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_settings_wifi.xml b/car-ui-lib/paintbooth/src/main/res/drawable/ic_settings_wifi.xml
deleted file mode 100644
index c16424c..0000000
--- a/car-ui-lib/paintbooth/src/main/res/drawable/ic_settings_wifi.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="64dp"
-    android:height="64dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-  <path
-      android:pathData="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"
-      android:fillColor="@color/car_ui_text_color_primary"/>
-</vector>
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/app_styled_view_sample_activity.xml b/car-ui-lib/paintbooth/src/main/res/layout/app_styled_view_sample_activity.xml
deleted file mode 100644
index d32e4df..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/app_styled_view_sample_activity.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<com.android.car.ui.FocusArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:theme="@style/AppStyledDialogThemeSample"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-  <FrameLayout
-      android:layout_width="match_parent"
-      android:layout_height="match_parent">
-    <Button
-        android:id="@+id/show_app_styled_fragment"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:background="@drawable/button_background_for_rotary"
-        android:layout_gravity="center"
-        android:text="show App Styled Fragment"/>
-  </FrameLayout>
-</com.android.car.ui.FocusArea>
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/app_styled_view_test_sample.xml b/car-ui-lib/paintbooth/src/main/res/layout/app_styled_view_test_sample.xml
deleted file mode 100644
index 500c528..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/app_styled_view_test_sample.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<com.android.car.ui.FocusArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-  <TextView android:id="@+id/loginscrn"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_marginTop="80dp"
-      android:text="ScrollView"
-      android:textSize="25dp"
-      android:textStyle="bold"
-      android:layout_gravity="center"/>
-  <TextView android:id="@+id/fstTxt"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_marginTop="20dp"
-      android:text="Welcome"
-      android:layout_gravity="center"/>
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_gravity="center"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_marginTop="60dp"
-      android:text="Button One" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_gravity="center"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_marginTop="60dp"
-      android:text="Button Two" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_gravity="center"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_marginTop="60dp"
-      android:text="Button Three" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_gravity="center"
-      android:layout_marginTop="60dp"
-      android:text="Button Four" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_gravity="center"
-      android:layout_marginTop="60dp"
-      android:text="Button Five" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_gravity="center"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_marginTop="60dp"
-      android:text="Button Six" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_gravity="center"
-      android:layout_marginTop="60dp"
-      android:text="Button Seven" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_gravity="center"
-      android:layout_marginTop="60dp"
-      android:text="Button Eight" />
-  <Button android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:background="@drawable/button_background_for_rotary"
-      android:layout_gravity="center"
-      android:layout_marginTop="60dp"
-      android:text="Button Nine" />
-</LinearLayout>
-</com.android.car.ui.FocusArea>
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/car_ui_recycler_view_activity.xml b/car-ui-lib/paintbooth/src/main/res/layout/car_ui_recycler_view_activity.xml
deleted file mode 100644
index b544808..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/car_ui_recycler_view_activity.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<com.android.car.ui.FocusArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/focus_area"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/car_ui_activity_background">
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/list"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-</com.android.car.ui.FocusArea>
-
-
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/edit_text_list_item.xml b/car-ui-lib/paintbooth/src/main/res/layout/edit_text_list_item.xml
deleted file mode 100644
index a04edd7..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/edit_text_list_item.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-
-    <EditText
-        android:id="@+id/edit_text"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:inputType="text"
-        android:layout_centerHorizontal="true"
-        android:layout_marginTop="20dp"
-        android:text="Edit Text Box"/>
-</RelativeLayout>
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/grid_car_ui_recycler_view_activity.xml b/car-ui-lib/paintbooth/src/main/res/layout/grid_car_ui_recycler_view_activity.xml
deleted file mode 100644
index f57e1e2..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/grid_car_ui_recycler_view_activity.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<com.android.car.ui.FocusArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/focus_area"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/car_ui_activity_background">
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/list"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:numOfColumns="4"
-        app:layoutStyle="grid"/>
-</com.android.car.ui.FocusArea>
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml b/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml
deleted file mode 100644
index 1118ce9..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/car_ui_activity_background">
-  <Button
-      android:id="@+id/button_1"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="Button 1"
-      android:theme="@android:style/Theme.DeviceDefault"
-      android:textSize="@dimen/car_ui_ime_wide_screen_action_button_text_size"
-      app:layout_constraintTop_toTopOf="parent"
-      app:layout_constraintBottom_toBottomOf="parent"
-      app:layout_constraintStart_toStartOf="parent"
-      app:layout_constraintEnd_toEndOf="parent"/>
-  <Button
-      android:id="@+id/button_2"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_marginTop="20dp"
-      android:text="Clear View"
-      android:theme="@android:style/Theme.DeviceDefault"
-      android:textSize="@dimen/car_ui_ime_wide_screen_action_button_text_size"
-      app:layout_constraintTop_toBottomOf="@+id/button_1"
-      app:layout_constraintStart_toStartOf="parent"
-      app:layout_constraintEnd_toEndOf="parent"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
-
-
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/split_preference_activity.xml b/car-ui-lib/paintbooth/src/main/res/layout/split_preference_activity.xml
deleted file mode 100644
index f86da99..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/split_preference_activity.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/half_screen_guideline"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        android:text="@string/split_preference_screen_message"/>
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/half_screen_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintGuide_percent="0.5"
-        android:orientation="vertical"/>
-
-    <FrameLayout
-        android:id="@+id/preference_fragment_container"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        app:layout_constraintStart_toEndOf="@id/half_screen_guideline"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/widgets_activity.xml b/car-ui-lib/paintbooth/src/main/res/layout/widgets_activity.xml
deleted file mode 100644
index 34f8174..0000000
--- a/car-ui-lib/paintbooth/src/main/res/layout/widgets_activity.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<com.android.car.ui.FocusArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <CheckBox
-        android:id="@+id/check"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/widget_checkbox_text"/>
-
-    <Switch
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/widget_switch_text"/>
-</com.android.car.ui.FocusArea>
diff --git a/car-ui-lib/paintbooth/src/main/res/values/strings.xml b/car-ui-lib/paintbooth/src/main/res/values/strings.xml
deleted file mode 100644
index c53050c..0000000
--- a/car-ui-lib/paintbooth/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,353 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<resources
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:ignore="MissingTranslation">
-  <!-- Application name [CHAR LIMIT=30] -->
-  <string name="app_name" translatable="false">Paint Booth (Gerrit)</string>
-
-  <!-- Description of the CurrentActivityService. [CHAR_LIMIT=200] -->
-  <string name="current_activity_service_description">Shows the current activity</string>
-
-  <!-- Strings for Preference Samples -->
-  <eat-comment/>
-
-  <!-- Preferences page title [CHAR_LIMIT=13] -->
-  <string name="preferences_screen_title">Settings</string>
-
-  <string name="split_preference_screen_message">This area is used for some other content</string>
-
-  <!--This section is for basic attributes -->
-  <eat-comment/>
-  <!-- Category title for basic preferences [CHAR_LIMIT=26]-->
-  <string name="basic_preferences">Basic attributes</string>
-  <!-- Title of a basic preference [CHAR_LIMIT=10]-->
-  <string name="title_basic_preference">Preference</string>
-  <!-- Summary of a basic preference [CHAR_LIMIT=71]-->
-  <string name="summary_basic_preference">Simple preference with no special attributes</string>
-
-  <!-- Title of a preference with stylized text [CHAR_LIMIT=71]-->
-  <string name="title_stylish_preference"><b>Very</b> <i>stylish</i> <u>preference</u></string>
-  <!-- Summary of a preference with stylized text [CHAR_LIMIT=150]-->
-  <string name="summary_stylish_preference">Define style tags such as &lt;b&gt; in a string resource to customize a preference\'s text</string>
-
-  <!-- Title of an icon preference [CHAR_LIMIT=25]-->
-  <string name="title_icon_preference">Icon preference</string>
-  <!-- Summary of an icon preference [CHAR_LIMIT=103]-->
-  <string name="summary_icon_preference">Define a drawable to display it at the start of the preference</string>
-
-  <!-- Title of a single line title preference [CHAR_LIMIT=165]-->
-  <string name="title_single_line_title_preference">Single line title preference - no matter how long the title is it will never wrap to multiple lines</string>
-  <!-- Summary of a single line title preference [CHAR_LIMIT=108]-->
-  <string name="summary_single_line_title_preference">This title will be ellipsized instead of wrapping to another line</string>
-
-  <!-- Title of a single line title preference without summary [CHAR_LIMIT=28]-->
-  <string name="title_single_line_no_summary">Single line preference - no summary</string>
-
-  <!--This section is for preferences that contain a widget in their layout -->
-  <eat-comment/>
-  <!-- Category title for preferences with widgets [CHAR_LIMIT=12]-->
-  <string name="widgets">Widgets</string>
-
-  <!-- Title of a two action preference [CHAR_LIMIT=31]-->
-  <string name="title_twoaction_preference">TwoAction preference</string>
-  <!-- Summary of a two action preference [CHAR_LIMIT=70]-->
-  <string name="summary_twoaction_preference">A widget should be visible on the right</string>
-  <!-- Summary of the deprecated two action preference [CHAR_LIMIT=70]-->
-  <string name="summary_deprecated_twoaction_preference">The deprecated version of TwoActionPreference</string>
-
-  <!-- Title of a checkbox preference [CHAR_LIMIT=31]-->
-  <string name="title_checkbox_preference">Checkbox preference</string>
-  <!-- Summary of a checkbox preference [CHAR_LIMIT=78]-->
-  <string name="summary_checkbox_preference">Tap anywhere in this preference to toggle state</string>
-
-  <!-- Title of a switch preference [CHAR_LIMIT=28]-->
-  <string name="title_switch_preference">Switch preference</string>
-  <!-- Summary of a switch preference [CHAR_LIMIT=78]-->
-  <string name="summary_switch_preference">Tap anywhere in this preference to toggle state</string>
-
-  <!-- Title of a dropdown preference [CHAR_LIMIT=31]-->
-  <string name="title_dropdown_preference">Dropdown preference</string>
-
-  <!-- Title of a seekbar preference [CHAR_LIMIT=30]-->
-  <string name="title_seekbar_preference">Seekbar preference</string>
-  <!-- Summary of an seekbar preference [CHAR_LIMIT=32]-->
-  <string name="summary_seekbar_preference">Seekbar summary</string>
-
-  <!--This section is for preferences that launch a dialog to edit the preference -->
-  <eat-comment/>
-  <!-- Category title for preferences which launch dialogs [CHAR_LIMIT=12]-->
-  <string name="dialogs">Dialogs</string>
-
-  <!-- Title of an edittext preference [CHAR_LIMIT=32]-->
-  <string name="title_edittext_preference">EditText preference</string>
-  <!-- Title of the dialog for an edittext preference [CHAR_LIMIT=43]-->
-  <string name="dialog_title_edittext_preference">This title can be changed!</string>
-
-  <!-- Title of a list preference [CHAR_LIMIT=25]-->
-  <string name="title_list_preference">List preference</string>
-  <!-- Title of the dialog for a list preference [CHAR_LIMIT=30]-->
-  <string name="dialog_title_list_preference">Choose one option!</string>
-
-  <!-- Title of a multi-select list preference [CHAR_LIMIT=46]-->
-  <string name="title_multi_list_preference">Multi-select list preference</string>
-  <!-- Summary of a multi-select list preference [CHAR_LIMIT=71]-->
-  <string name="summary_multi_list_preference">Shows a dialog with multiple choice options</string>
-  <!-- Title of the dialog for a multi-select list preference [CHAR_LIMIT=33]-->
-  <string name="dialog_title_multi_list_preference">Choose some options!</string>
-
-  <!--This section is for advanced attributes-->
-  <eat-comment/>
-  <!-- Category title for preferences with advanced attributes [CHAR_LIMIT=32]-->
-  <string name="advanced_attributes">Advanced attributes</string>
-
-  <!-- Title of an expandable preference [CHAR_LIMIT=45]-->
-  <string name="title_expandable_preference">Expandable preference group</string>
-  <!-- Summary of an expandable preference [CHAR_LIMIT=131]-->
-  <string name="summary_expandable_preference">This group shows one item and collapses the rest into the advanced button below</string>
-
-  <!-- Title of a preference which launches an intent [CHAR_LIMIT=28]-->
-  <string name="title_intent_preference">Intent preference</string>
-  <!-- Summary of a preference which launches an intent [CHAR_LIMIT=51]-->
-  <string name="summary_intent_preference">Launches an intent when pressed</string>
-
-  <!-- Title of a parent preference [CHAR_LIMIT=28]-->
-  <string name="title_parent_preference">Parent preference</string>
-  <!-- Summary of a parent preference [CHAR_LIMIT=130]-->
-  <string name="summary_parent_preference">Toggling this preference will change the enabled state of the preference below</string>
-
-  <!-- Title of a child preference [CHAR_LIMIT=26]-->
-  <string name="title_child_preference">Child preference</string>
-  <!-- Summary of a child preference [CHAR_LIMIT=123]-->
-  <string name="summary_child_preference">The enabled state of this preference is controlled by the preference above</string>
-
-  <!-- Title of a switch preference with variable summaries [CHAR_LIMIT=45]-->
-  <string name="title_toggle_summary_preference">Variable summary preference</string>
-  <!-- Summary of a variable summary preference when the preference is on [CHAR_LIMIT=118]-->
-  <string name="summary_on_toggle_summary_preference">On! :) - the summary of this preference changes depending on its state</string>
-  <!-- Summary of a variable summary preference when the preference is off [CHAR_LIMIT=118]-->
-  <string name="summary_off_toggle_summary_preference">Off! :( - the summary of this preference changes depending on its state</string>
-
-  <!-- Title of a copyable preference [CHAR_LIMIT=31]-->
-  <string name="title_copyable_preference">Copyable preference</string>
-  <!-- Summary of a copyable preference [CHAR_LIMIT=81]-->
-  <string name="summary_copyable_preference">Long press on this preference to copy its summary</string>
-
-  <!-- Title of a Advanced preference [CHAR_LIMIT=13]-->
-  <string name="advanced_preference">Advanced</string>
-
-  <!-- Title of a Intent preference [CHAR_LIMIT=28]-->
-  <string name="intent_preference">Intent preference</string>
-
-  <!--This section is for toolbar attributes -->
-  <eat-comment/>
-
-  <!-- Text for change title button [CHAR_LIMIT=20]-->
-  <string name="toolbar_change_title">Change title</string>
-
-  <!-- Text for set xml button [CHAR_LIMIT=45]-->
-  <string name="toolbar_set_xml_resource">MenuItem: Set to XML source</string>
-
-  <!-- Text for add icon button [CHAR_LIMIT=30]-->
-  <string name="toolbar_add_icon">MenuItem: Add Icon</string>
-
-  <!-- Text for add untined icon button [CHAR_LIMIT=45]-->
-  <string name="toolbar_add_untined_icon">MenuItem: Add untinted icon</string>
-
-  <!-- Text for add overflow button [CHAR_LIMIT=36]-->
-  <string name="toolbar_add_overflow">Overflow MenuItem: Add Simple</string>
-
-  <!-- Text for add overflow button [CHAR_LIMIT=36]-->
-  <string name="toolbar_add_overflow_switch">Overflow MenuItem: Add switchable</string>
-
-  <!-- Text for add icon text overflow button [CHAR_LIMIT=45]-->
-  <string name="toolbar_add_icon_text_overflow">Overflow MenuItem: Add icon and text</string>
-
-  <!-- Text for add switch button [CHAR_LIMIT=33]-->
-  <string name="toolbar_add_switch">MenuItem: Add Switch</string>
-
-  <!-- Text for add text button [CHAR_LIMIT=30]-->
-  <string name="toolbar_add_text">MenuItem: Add text</string>
-
-  <!-- Text for add icon text button [CHAR_LIMIT=45]-->
-  <string name="toolbar_add_icon_text">MenuItem: Add icon and text</string>
-
-
-  <!-- Text for add text button [CHAR_LIMIT=30]-->
-  <string name="toolbar_add_bordered_text">MenuItem: Add bordered text</string>
-
-  <!-- Text for add icon text button [CHAR_LIMIT=45]-->
-  <string name="toolbar_add_bordered_icon_text">MenuItem: Add bordered icon and text</string>
-
-  <!-- Text for add untined icon and text button [CHAR_LIMIT=60]-->
-  <string name="toolbar_add_untinted_icon_and_text">MenuItem: Add untinted icon and text</string>
-
-  <!-- Text for add activatable button [CHAR_LIMIT=41]-->
-  <string name="toolbar_add_activatable">MenuItem: Add activatable</string>
-
-  <!-- Text for add activatable button [CHAR_LIMIT=36]-->
-  <string name="toolbar_add_morphing">MenuItem: Add morphing</string>
-
-  <!-- Text for toggle visibility button [CHAR_LIMIT=45]-->
-  <string name="toolbar_toggle_visibility">MenuItem: Toggle Visibility</string>
-
-  <!-- Text for toggle enable button [CHAR_LIMIT=40]-->
-  <string name="toolbar_toggle_enable">MenuItem: Toggle Enabled</string>
-
-  <!-- Text for toggle enable button [CHAR_LIMIT=49]-->
-  <string name="toolbar_toggle_perform_click">MenuItem: Call PerformClick()</string>
-
-  <!-- Text for toggle icon button [CHAR_LIMIT=35]-->
-  <string name="toolbar_toggle_icon">MenuItem: Toggle Icon</string>
-
-  <!-- Text for toggle show while search button [CHAR_LIMIT=61]-->
-  <string name="toolbar_toggle_show_while_search">MenuItem: Toggle show while searching</string>
-
-  <!-- Text for cycle nav button mode button [CHAR_LIMIT=35]-->
-  <string name="toolbar_cycle_nav_button">Cycle nav button mode</string>
-
-  <!-- Text for toggle logo button [CHAR_LIMIT=19]-->
-  <string name="toolbar_toggle_logo">Toggle logo</string>
-
-  <!-- Text for cycle state button [CHAR_LIMIT=20]-->
-  <string name="toolbar_cycle_state">Cycle state (Deprecated)</string>
-
-  <!-- Text for toggle search hint button [CHAR_LIMIT=30]-->
-  <string name="toolbar_toggle_search_hint">Toggle search hint</string>
-
-  <!-- Text for toggle background button [CHAR_LIMIT=30]-->
-  <string name="toolbar_toggle_background">Toggle background</string>
-
-  <!-- Text for add tab button [CHAR_LIMIT=12]-->
-  <string name="toolbar_add_tab">Add tab</string>
-
-  <!-- Text for add tab with custom text button [CHAR_LIMIT=40]-->
-  <string name="toolbar_add_tab_with_custom_text">Add tab with custom text</string>
-
-  <!-- Text for showing tabs in subpages [CHAR_LIMIT=50]-->
-  <string name="toolbar_show_tabs_in_subpage">Toggle showing tabs in subpages (Deprecated)</string>
-
-  <!-- Text for toggle search icon button [CHAR_LIMIT=30]-->
-  <string name="toolbar_toggle_search_icon">Toggle search icon</string>
-
-  <!--This section is for dialog attributes -->
-  <eat-comment/>
-
-  <!-- Text for show dialog button [CHAR_LIMIT=18]-->
-  <string name="dialog_show_dialog">Show Dialog</string>
-
-  <!-- Text for show dialog button [CHAR_LIMIT=30]-->
-  <string name="dialog_show_dialog_icon">Show Dialog with icon</string>
-
-  <!-- Text for Dialog with edit text box button [CHAR_LIMIT=50]-->
-  <string name="dialog_show_dialog_edit">Show Dialog with edit text box</string>
-
-  <!-- Text for show Dialog with only positive button button [CHAR_LIMIT=61]-->
-  <string name="dialog_show_dialog_only_positive">Show Dialog with only positive button</string>
-
-  <!-- Text for show Dialog With no button provided button [CHAR_LIMIT=60]-->
-  <string name="dialog_show_dialog_no_button">Show Dialog With no button provided</string>
-
-  <!-- Text for show Dialog With Checkbox button [CHAR_LIMIT=41]-->
-  <string name="dialog_show_dialog_checkbox">Show Dialog With Checkbox</string>
-
-  <!-- Text for show Dialog without title button [CHAR_LIMIT=41]-->
-  <string name="dialog_show_dialog_no_title">Show Dialog without title</string>
-
-  <!-- Text for show Toast button [CHAR_LIMIT=16]-->
-  <string name="dialog_show_toast">Show Toast</string>
-
-  <!-- Button that shows a dialog with a subtitle [CHAR_LIMIT=50]-->
-  <string name="dialog_show_subtitle">Show Dialog with title and subtitle</string>
-
-  <!-- Button that shows a dialog with a subtitle and icon [CHAR_LIMIT=50]-->
-  <string name="dialog_show_subtitle_and_icon">Show Dialog with title, subtitle, and icon</string>
-
-  <!-- Button that shows a dialog with a long title, subtitle and icon [CHAR_LIMIT=500]-->
-  <string name="dialog_show_long_subtitle_and_icon">Show Dialog with a long title, subtitle, and icon</string>
-
-  <!-- Text to show Dialog with single choice items-->
-  <string name="dialog_show_single_choice">Show with single choice items</string>
-
-  <!-- Text to show a dialog with single choice items and no default button [CHAR_LIMIT=200] -->
-  <string name="dialog_show_list_items_without_default_button">Show with single choice items and no default button</string>
-
-  <!-- Text to show a permission Dialog [CHAR_LIMIT=50] -->
-  <string name="dialog_show_permission_dialog">Show permission dialog</string>
-
-  <!-- Text to show a permission Dialog for multiple permissions [CHAR_LIMIT=50] -->
-  <string name="dialog_show_multi_permission_dialog">Show multiple permissions dialog</string>
-
-  <!-- Text on button to show a permission dialog asking for the users location. [CHAR_LIMIT=100] -->
-  <string name="dialog_show_foreground_permission_dialog">Show foreground permission dialog</string>
-
-  <!-- Text on button to show a permission dialog asking for the users location in the background [CHAR_LIMIT=100] -->
-  <string name="dialog_show_background_permission_dialog">Show background permission dialog</string>
-
-  <!--This section is for widget attributes -->
-  <eat-comment/>
-  <!-- Text for checkbox [CHAR_LIMIT=16]-->
-  <string name="widget_checkbox_text">I\'m a check box</string>
-  <!-- Text for switch [CHAR_LIMIT=25]-->
-  <string name="widget_switch_text">I\'m a switch</string>
-
-  <!-- ListItem related resources  -->
-  <string name="first_header">First header</string>
-  <string name="test_title">Test title</string>
-  <string name="test_body">Test body</string>
-  <string name="test_title_no_body">Test title with no body</string>
-  <string name="random_header">Random header</string>
-  <string name="header_with_body">with header body</string>
-  <string name="test_body_no_title">Test body with no title</string>
-  <string name="title_with_content_icon">Test Title — with content icon</string>
-  <string name="with_avatar_icon">With avatar icon.</string>
-  <string name="display_toast_on_click">Displays toast on click</string>
-  <string name="title_item_with_checkbox">Title — Item with checkbox</string>
-  <string name="toast_on_selection_changed">Will present toast on change of selection state.</string>
-  <string name="title_with_disabled_checkbox">Title — Checkbox that is disabled</string>
-  <string name="click_should_have_no_effect">Clicks should not have any affect</string>
-  <string name="body_item_with_switch">Body — Item with switch  — with click listener</string>
-  <string name="item_initially_checked">Item is initially checked</string>
-  <string name="title_item_with_radio_button">Title — Item with radio button</string>
-  <string name="item_mutually_exclusive_with_item_above">Item is mutually exclusive with item above</string>
-  <string name="item_with_chevron">Item with chevron</string>
-  <string name="random_body_text_with_action_divider">Random body text — with action divider</string>
-  <string name="null_supplement_icon">Null supplemental icon</string>
-  <string name="supplemental_icon_with_listener">Supplemental icon with listener</string>
-  <string name="test_data">Test data</string>
-
-  <!-- Dialog -->
-  <string name="standard_alert_dialog">Standard Alert Dialog</string>
-  <string name="my_message">My message</string>
-  <string name="alert_dialog_with_icon">Alert dialog with icon</string>
-  <string name="neutral">NEUTRAL</string>
-  <string name="ok">OK</string>
-  <string name="cancel">CANCEL</string>
-  <string name="custom_dialog_box">Custom Dialog Box</string>
-  <string name="edit_me_please">Edit me please</string>
-  <string name="no_title_message">I don\'t have a title.</string>
-  <string name="my_title">My Title!</string>
-  <string name="my_subtitle">My Subtitle!</string>
-  <string name="first_item">First item</string>
-  <string name="second_item">Second item</string>
-  <string name="third_item">Third item</string>
-  <string name="select_one_option">Select one option.</string>
-  <string name="select_one_option_at_a_time">Ony one option may be selected at a time</string>
-  <string name="long_title">This is a very long title. It should likely span across multiple lines or something. It shouldn\'t get cut off.</string>
-  <string name="long_subtitle">This is a very long subtitle. It should likely span across  multiple lines or something. It shouldn\'t get cut off.</string>
-
-</resources>
diff --git a/car-ui-lib/paintbooth/src/main/res/values/themes.xml b/car-ui-lib/paintbooth/src/main/res/values/themes.xml
deleted file mode 100644
index 1820a70..0000000
--- a/car-ui-lib/paintbooth/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-  <style name="AppStyledDialogThemeSample" parent="Theme.AppCompat.Light.Dialog">
-    <item name="android:windowContentOverlay">@null</item>
-    <item name="android:windowSoftInputMode">stateAlwaysHidden</item>
-    <item name="windowActionModeOverlay">true</item>
-    <item name="android:windowIsTranslucent">true</item>
-
-    <item name="android:windowCloseOnTouchOutside">false</item>
-    <item name="android:colorBackgroundCacheHint">@null</item>
-    <item name="android:backgroundDimEnabled">false</item>
-
-    <item name="windowActionBar">false</item>
-    <item name="windowNoTitle">true</item>
-    <item name="android:windowBackground">@android:color/transparent</item>
-    <item name="android:windowIsFloating">true</item>
-    <item name="android:background">#969696</item>
-  </style>
-</resources>
diff --git a/car-ui-lib/paintbooth/src/main/res/xml/preference_samples.xml b/car-ui-lib/paintbooth/src/main/res/xml/preference_samples.xml
deleted file mode 100644
index 4cc4ada..0000000
--- a/car-ui-lib/paintbooth/src/main/res/xml/preference_samples.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    app:title="@string/preferences_screen_title">
-
-    <PreferenceCategory
-        android:title="@string/basic_preferences">
-
-        <Preference
-            android:key="preference"
-            android:summary="@string/summary_basic_preference"
-            android:title="@string/title_basic_preference"/>
-
-        <Preference
-            android:key="stylized"
-            android:dependency="preference"
-            android:summary="@string/summary_stylish_preference"
-            android:title="@string/title_stylish_preference"/>
-
-        <Preference
-            android:icon="@drawable/ic_settings_wifi"
-            android:key="icon"
-            android:summary="@string/summary_icon_preference"
-            android:title="@string/title_icon_preference"/>
-
-        <Preference
-            android:key="single_line_title"
-            android:summary="@string/summary_single_line_title_preference"
-            android:title="@string/title_single_line_title_preference"
-            app:singleLineTitle="true"/>
-
-        <Preference
-            android:key="single_line_no_summary"
-            android:title="@string/title_single_line_no_summary"
-            app:singleLineTitle="true"/>
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:title="@string/widgets">
-
-        <CheckBoxPreference
-            android:key="checkbox"
-            android:summary="@string/summary_checkbox_preference"
-            android:title="@string/title_checkbox_preference"/>
-
-        <DropDownPreference
-            android:entries="@array/entries"
-            android:entryValues="@array/entry_values"
-            android:key="dropdown"
-            android:title="@string/title_dropdown_preference"
-            app:useSimpleSummaryProvider="true"/>
-
-        <SeekBarPreference
-            android:defaultValue="5"
-            android:key="seekbar"
-            android:max="10"
-            android:title="@string/title_seekbar_preference"/>
-
-        <SwitchPreference
-            android:key="switch"
-            android:summary="@string/summary_switch_preference"
-            android:title="@string/title_switch_preference"/>
-
-        <com.android.car.ui.preference.CarUiTwoActionPreference
-            android:key="twoaction"
-            android:summary="@string/summary_deprecated_twoaction_preference"
-            android:title="@string/title_twoaction_preference"
-            android:widgetLayout="@layout/details_preference_widget"/>
-
-        <com.android.car.ui.preference.CarUiTwoActionTextPreference
-            android:key="twoactiontext"
-            android:summary="@string/summary_twoaction_preference"
-            android:title="@string/title_twoaction_preference"
-            app:secondaryActionText="Secondary action"/>
-        <com.android.car.ui.preference.CarUiTwoActionTextPreference
-            android:key="twoactiontextborderless"
-            android:icon="@drawable/ic_settings_wifi"
-            android:summary="@string/summary_twoaction_preference"
-            android:title="@string/title_twoaction_preference"
-            app:secondaryActionStyle="borderless"
-            app:secondaryActionText="Secondary action"/>
-        <com.android.car.ui.preference.CarUiTwoActionIconPreference
-            android:key="twoactionicon"
-            android:icon="@drawable/ic_settings_wifi"
-            android:summary="@string/summary_twoaction_preference"
-            android:title="@string/title_twoaction_preference"
-            app:secondaryActionIcon="@drawable/ic_launcher"/>
-        <com.android.car.ui.preference.CarUiTwoActionSwitchPreference
-            android:key="twoactionswitch"
-            android:icon="@drawable/ic_settings_wifi"
-            android:summary="@string/summary_twoaction_preference"
-            android:title="@string/title_twoaction_preference"/>
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:title="@string/dialogs">
-
-        <EditTextPreference
-            android:dialogTitle="@string/dialog_title_edittext_preference"
-            android:key="edittext"
-            android:title="@string/title_edittext_preference"
-            app:useSimpleSummaryProvider="true"/>
-
-        <ListPreference
-            android:dialogTitle="@string/dialog_title_list_preference"
-            android:entries="@array/entries"
-            android:entryValues="@array/entry_values"
-            android:key="list"
-            android:title="@string/title_list_preference"
-            app:useSimpleSummaryProvider="true"/>
-
-        <MultiSelectListPreference
-            android:dialogTitle="@string/dialog_title_multi_list_preference"
-            android:entries="@array/entries"
-            android:entryValues="@array/entry_values"
-            android:key="multi_select_list"
-            android:summary="@string/summary_multi_list_preference"
-            android:title="@string/title_multi_list_preference"/>
-
-        <com.android.car.ui.preference.CarUiSeekBarDialogPreference
-            android:dialogTitle="Seekbar Dialog"
-            android:key="seekbarDialog"
-            android:summary="@string/summary_seekbar_preference"
-            android:title="@string/title_seekbar_preference"/>
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="@string/advanced_preference"
-        android:title="@string/advanced_attributes"
-        app:initialExpandedChildrenCount="1">
-
-        <Preference
-            android:key="expandable"
-            android:summary="@string/summary_expandable_preference"
-            android:title="@string/title_expandable_preference"/>
-
-        <Preference
-            android:summary="@string/summary_intent_preference"
-            android:title="@string/title_intent_preference">
-
-            <intent android:action="android.intent.action.VIEW"
-                    android:data="http://www.android.com"/>
-
-        </Preference>
-
-        <Preference
-            android:key="copyable"
-            android:selectable="false"
-            android:summary="@string/summary_copyable_preference"
-            android:title="@string/title_copyable_preference"
-            app:enableCopying="true"/>
-
-        <SwitchPreference
-            android:dependency="parent"
-            android:key="child"
-            android:summary="@string/summary_child_preference"
-            android:title="@string/title_child_preference"/>
-
-        <SwitchPreference
-            android:key="toggle_summary"
-            android:summaryOff="@string/summary_off_toggle_summary_preference"
-            android:summaryOn="@string/summary_on_toggle_summary_preference"
-            android:title="@string/title_toggle_summary_preference"/>
-
-        <SwitchPreference
-            android:key="parent"
-            android:summary="@string/summary_parent_preference"
-            android:title="@string/title_parent_preference"/>
-    </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/car-ui-lib/referencedesign/Android.mk b/car-ui-lib/referencedesign/Android.mk
index 0d63c18..7da04dc 100644
--- a/car-ui-lib/referencedesign/Android.mk
+++ b/car-ui-lib/referencedesign/Android.mk
@@ -2,12 +2,9 @@
 include $(CLEAR_VARS)
 
 CAR_UI_RRO_SET_NAME := googlecarui
-CAR_UI_RRO_MANIFEST_FILE := $(LOCAL_PATH)/AndroidManifest.xml
 CAR_UI_RESOURCE_DIR := $(LOCAL_PATH)/res
 CAR_UI_RRO_TARGETS := \
     com.android.car.ui.paintbooth \
-    com.google.android.car.ui.paintbooth \
-    com.google.android.carui.ats \
     com.android.car.rotaryplayground \
     com.android.car.themeplayground \
     com.android.car.carlauncher \
@@ -22,19 +19,15 @@
     com.android.car.settings \
     com.android.car.voicecontrol \
     com.android.car.faceenroll \
-    com.android.managedprovisioning \
+    com.android.permissioncontroller \
     com.android.settings.intelligence \
     com.google.android.apps.automotive.inputmethod \
     com.google.android.apps.automotive.inputmethod.dev \
-    com.google.android.apps.automotive.templates.host \
     com.google.android.embedded.projection \
     com.google.android.gms \
-    com.google.android.gsf \
     com.google.android.packageinstaller \
-    com.google.android.permissioncontroller \
     com.google.android.carassistant \
     com.google.android.tts \
-    com.android.htmlviewer \
     com.android.vending \
 
 include packages/apps/Car/libs/car-ui-lib/generate_rros.mk
diff --git a/car-ui-lib/referencedesign/AndroidManifest.xml b/car-ui-lib/referencedesign/AndroidManifest.xml
index 1b0585a..a6dbae3 100644
--- a/car-ui-lib/referencedesign/AndroidManifest.xml
+++ b/car-ui-lib/referencedesign/AndroidManifest.xml
@@ -3,9 +3,8 @@
     <application android:hasCode="false"/>
     <overlay android:priority="10"
         android:targetPackage="{{TARGET_PACKAGE_NAME}}"
-        android:targetName="car-ui-lib"
         android:resourcesMap="@xml/overlays"
         android:isStatic="true"
-        android:requiredSystemPropertyName="ro.build.car_ui_rros_enabled"
-        android:requiredSystemPropertyValue="true"/>
+        android:requiredSystemPropertyName="ro.build.characteristics"
+        android:requiredSystemPropertyValue="automotive"/>
 </manifest>
diff --git a/car-ui-lib/referencedesign/car-ui-lib-preinstalled-packages.xml b/car-ui-lib/referencedesign/car-ui-lib-preinstalled-packages.xml
deleted file mode 100644
index 5c26a2c..0000000
--- a/car-ui-lib/referencedesign/car-ui-lib-preinstalled-packages.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<!-- System packages to preinstall on all automotive devices, per user type.
-     OEMs must provide they own as well, listing their specific apps (like launcher, settings, etc...)
-     Documentation at frameworks/base/data/etc/preinstalled-packages-platform.xml
--->
-<config>
-    <install-in-user-type package="com.chassis.car.ui.sharedlibrary">
-       <install-in user-type="SYSTEM"/>
-       <install-in user-type="FULL"/>
-       <install-in user-type="PROFILE"/>
-    </install-in-user-type>
-</config>
diff --git a/car-ui-lib/referencedesign/product.mk b/car-ui-lib/referencedesign/product.mk
index a68e882..915f31b 100644
--- a/car-ui-lib/referencedesign/product.mk
+++ b/car-ui-lib/referencedesign/product.mk
@@ -1,30 +1,8 @@
 # Inherit from this product to include the "Reference Design" RROs for CarUi
 
-#############################################
-#                  WARNING                  #
-#############################################
-# The OEM APIs as they appear on this       #
-# branch of android are not finalized!      #
-# If a shared library is built using them,  #
-# it will cause apps to crash!              #
-#                                           #
-# Please only use a shared library with     #
-# a later version of car-ui-lib.            #
-#############################################
-#PRODUCT_PACKAGES += \
-#   car-ui-lib-sharedlibrary \
-
-PRODUCT_PRODUCT_PROPERTIES += ro.build.automotive.car.ui.shared.library.package.name=com.chassis.car.ui.sharedlibrary
-
-PRODUCT_COPY_FILES += \
-    packages/apps/Car/libs/car-ui-lib/referencedesign/car-ui-lib-preinstalled-packages.xml:system/etc/sysconfig/car-ui-lib-preinstalled-packages.xml \
-
-
 # Include generated RROs
 PRODUCT_PACKAGES += \
     googlecarui-com-android-car-ui-paintbooth \
-    googlecarui-com-google-android-car-ui-paintbooth \
-    googlecarui-com-google-android-carui-ats \
     googlecarui-com-android-car-rotaryplayground \
     googlecarui-com-android-car-themeplayground \
     googlecarui-com-android-car-carlauncher \
@@ -39,21 +17,13 @@
     googlecarui-com-android-car-settings \
     googlecarui-com-android-car-voicecontrol \
     googlecarui-com-android-car-faceenroll \
-    googlecarui-com-android-managedprovisioning \
+    googlecarui-com-android-permissioncontroller \
     googlecarui-com-android-settings-intelligence \
     googlecarui-com-google-android-apps-automotive-inputmethod \
     googlecarui-com-google-android-apps-automotive-inputmethod-dev \
-    googlecarui-com-google-android-apps-automotive-templates-host \
     googlecarui-com-google-android-embedded-projection \
     googlecarui-com-google-android-gms \
-    googlecarui-com-google-android-gsf \
     googlecarui-com-google-android-packageinstaller \
-    googlecarui-com-google-android-permissioncontroller \
     googlecarui-com-google-android-carassistant \
     googlecarui-com-google-android-tts \
-    googlecarui-com-android-htmlviewer \
     googlecarui-com-android-vending \
-
-# This system property is used to enable the RROs on startup via
-# the requiredSystemPropertyName/Value attributes in the manifest
-PRODUCT_PRODUCT_PROPERTIES += ro.build.car_ui_rros_enabled=true
diff --git a/car-ui-lib/referencedesign/res/color/car_ui_seekbar_thumb_inner_ring_color.xml b/car-ui-lib/referencedesign/res/color/car_ui_seekbar_thumb_inner_ring_color.xml
deleted file mode 100644
index 1f197c0..0000000
--- a/car-ui-lib/referencedesign/res/color/car_ui_seekbar_thumb_inner_ring_color.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="#3D94CBFF"/>
-    <item android:color="@android:color/transparent"/>
-</selector>
diff --git a/car-ui-lib/referencedesign/res/color/car_ui_seekbar_thumb_outer_ring_color.xml b/car-ui-lib/referencedesign/res/color/car_ui_seekbar_thumb_outer_ring_color.xml
deleted file mode 100644
index d03fe13..0000000
--- a/car-ui-lib/referencedesign/res/color/car_ui_seekbar_thumb_outer_ring_color.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="#94CBFF"/>
-    <item android:color="@android:color/transparent"/>
-</selector>
diff --git a/car-ui-lib/referencedesign/res/color/car_ui_text_color_primary.xml b/car-ui-lib/referencedesign/res/color/car_ui_text_color_primary.xml
index d310838..34033e2 100644
--- a/car-ui-lib/referencedesign/res/color/car_ui_text_color_primary.xml
+++ b/car-ui-lib/referencedesign/res/color/car_ui_text_color_primary.xml
@@ -21,8 +21,5 @@
     <item android:state_enabled="false"
           android:alpha="?android:attr/disabledAlpha"
           android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
     <item android:color="?android:attr/colorForeground"/>
 </selector>
diff --git a/car-ui-lib/referencedesign/res/color/car_ui_toolbar_menu_item_icon_background_color.xml b/car-ui-lib/referencedesign/res/color/car_ui_toolbar_menu_item_icon_background_color.xml
deleted file mode 100644
index 01b70aa..0000000
--- a/car-ui-lib/referencedesign/res/color/car_ui_toolbar_menu_item_icon_background_color.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<!-- The same as @color/car_ui_text_color_primary but with an activated state.
-     ColorStateLists don't support switching to complex colors, so we have to repeat
-     car_ui_text_color_primary here. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_activated="false"
-          android:color="@android:color/transparent"/>
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:color="?android:attr/colorForeground" />
-</selector>
diff --git a/car-ui-lib/referencedesign/res/color/car_ui_toolbar_menu_item_icon_color.xml b/car-ui-lib/referencedesign/res/color/car_ui_toolbar_menu_item_icon_color.xml
deleted file mode 100644
index a15bcba..0000000
--- a/car-ui-lib/referencedesign/res/color/car_ui_toolbar_menu_item_icon_color.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<!-- The same as @color/car_ui_text_color_primary but with an activated state.
-     ColorStateLists don't support switching to complex colors, so we have to repeat
-     car_ui_text_color_primary here. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_activated="true"
-          android:color="?android:attr/colorBackground"/>
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:color="?android:attr/colorForeground" />
-</selector>
diff --git a/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_button_ripple_background.xml b/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_button_ripple_background.xml
deleted file mode 100644
index 0acb196..0000000
--- a/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_button_ripple_background.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/car_ui_ripple_color" />
diff --git a/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_scrollbar_thumb.xml b/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_scrollbar_thumb.xml
deleted file mode 100644
index ec6318a..0000000
--- a/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_scrollbar_thumb.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<shape
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/car_ui_scrollbar_thumb" />
-    <corners android:radius="@dimen/car_ui_scrollbar_thumb_radius"/>
-</shape>
diff --git a/car-ui-lib/referencedesign/res/drawable/car_ui_seekbar_preference_background.xml b/car-ui-lib/referencedesign/res/drawable/car_ui_seekbar_preference_background.xml
deleted file mode 100644
index 405403b..0000000
--- a/car-ui-lib/referencedesign/res/drawable/car_ui_seekbar_preference_background.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- Highlight the preference when it's focused but not selected. The preference is selected in
-    direct manipulation mode. -->
-    <item android:state_focused="true" android:state_selected="false">
-        <shape android:shape="rectangle">
-            <solid android:color="#3D94CBFF"/>
-            <stroke android:width="8dp"
-                    android:color="#94CBFF"/>
-        </shape>
-    </item>
-</selector>
diff --git a/car-ui-lib/referencedesign/res/drawable/car_ui_seekbar_thumb.xml b/car-ui-lib/referencedesign/res/drawable/car_ui_seekbar_thumb.xml
deleted file mode 100644
index 2d6723e..0000000
--- a/car-ui-lib/referencedesign/res/drawable/car_ui_seekbar_thumb.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- Padding ensures the intrinsic size of this drawable includes the rings. -->
-    <item>
-        <shape android:shape="oval">
-            <solid android:color="?android:attr/colorAccent"/>
-            <size android:width="24dp" android:height="24dp"/>
-        </shape>
-    </item>
-    <item>
-        <shape android:shape="ring"
-               android:innerRadius="12dp"
-               android:thickness="4dp"
-               android:useLevel="false">
-            <solid android:color="@color/car_ui_seekbar_thumb_inner_ring_color"/>
-        </shape>
-    </item>
-    <item>
-        <shape android:shape="ring"
-               android:innerRadius="16dp"
-               android:thickness="8dp"
-               android:useLevel="false">
-            <solid android:color="@color/car_ui_seekbar_thumb_outer_ring_color"/>
-        </shape>
-    </item>
-</layer-list>
diff --git a/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_background.xml b/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_background.xml
deleted file mode 100644
index 3f96409..0000000
--- a/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_background.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~
-  ~ Copyright (C) 2020 Google Inc.
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="oval">
-    <size
-        android:width="54dp"
-        android:height="54dp"/>
-    <solid android:color="@color/car_ui_toolbar_menu_item_icon_background_color"/>
-</shape>
diff --git a/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml b/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
index 14f6cd0..03f8d82 100644
--- a/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
+++ b/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
@@ -16,32 +16,6 @@
   ~ limitations under the License.
   ~
  -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:state_pressed="true">
-        <shape android:shape="oval">
-            <solid android:color="#8A94CBFF"/>
-            <stroke android:width="4dp"
-                    android:color="#94CBFF"/>
-            <size android:width="48dp"
-                  android:height="48dp"/>
-        </shape>
-    </item>
-    <item android:state_focused="true">
-        <shape android:shape="oval">
-            <solid android:color="#3D94CBFF"/>
-            <stroke android:width="8dp"
-                    android:color="#94CBFF"/>
-            <size android:width="48dp"
-                  android:height="48dp"/>
-        </shape>
-    </item>
-    <item>
-        <ripple android:color="#27ffffff">
-            <item android:id="@android:id/mask">
-                <shape android:shape="oval">
-                    <solid android:color="#FFFFFF"/>
-                </shape>
-            </item>
-        </ripple>
-    </item>
-</selector>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:color="#27ffffff"
+        android:radius="48dp"/>
diff --git a/car-ui-lib/referencedesign/res/layout-ldrtl-port/car_ui_base_layout_toolbar.xml b/car-ui-lib/referencedesign/res/layout-ldrtl-port/car_ui_base_layout_toolbar.xml
index d6470eb..10c7de6 100644
--- a/car-ui-lib/referencedesign/res/layout-ldrtl-port/car_ui_base_layout_toolbar.xml
+++ b/car-ui-lib/referencedesign/res/layout-ldrtl-port/car_ui_base_layout_toolbar.xml
@@ -28,11 +28,11 @@
          highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
          -->
     <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_width="1dp"
+        android:layout_height="1dp"/>
 
     <FrameLayout
-        android:id="@+id/car_ui_base_layout_content_container"
+        android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         app:layout_constraintBottom_toBottomOf="parent"
@@ -64,8 +64,7 @@
 
             <FrameLayout
                 android:id="@+id/car_ui_toolbar_nav_icon_container"
-                style="@style/Widget.CarUi.Toolbar.NavIconContainer"
-                android:layout_width="@dimen/car_ui_toolbar_margin"
+                android:layout_width="112dp"
                 android:layout_height="0dp"
                 app:layout_constraintBottom_toTopOf="@id/car_ui_toolbar_row_separator_guideline"
                 app:layout_constraintLeft_toLeftOf="parent"
@@ -73,11 +72,11 @@
 
                 <ImageView
                     android:id="@+id/car_ui_toolbar_nav_icon"
-                    style="@style/Widget.CarUi.Toolbar.NavIcon"
                     android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
                     android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
                     android:layout_gravity="center"
                     android:scaleType="fitXY"
+                    android:background="@drawable/car_ui_toolbar_menu_item_icon_ripple"
                     android:tint="@color/car_ui_text_color_primary"/>
 
                 <ImageView
@@ -133,7 +132,7 @@
                 android:layout_height="0dp"
                 app:layout_constraintBottom_toTopOf="@id/car_ui_toolbar_row_separator_guideline"
                 app:layout_constraintLeft_toRightOf="@+id/car_ui_toolbar_menu_items_container"
-                app:layout_constraintRight_toLeftOf="@id/car_ui_toolbar_title_logo_container"
+                app:layout_constraintRight_toRightOf="parent"
                 app:layout_constraintTop_toTopOf="parent" />
 
             <LinearLayout
diff --git a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_base_layout_toolbar.xml b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_base_layout_toolbar.xml
index e8b4c36..2028530 100644
--- a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_base_layout_toolbar.xml
+++ b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_base_layout_toolbar.xml
@@ -27,11 +27,11 @@
          highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
          -->
     <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_width="1dp"
+        android:layout_height="1dp"/>
 
     <FrameLayout
-        android:id="@+id/car_ui_base_layout_content_container"
+        android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         app:layout_constraintBottom_toBottomOf="parent"
@@ -56,8 +56,7 @@
 
             <FrameLayout
                 android:id="@+id/car_ui_toolbar_nav_icon_container"
-                style="@style/Widget.CarUi.Toolbar.NavIconContainer"
-                android:layout_width="@dimen/car_ui_toolbar_margin"
+                android:layout_width="112dp"
                 android:layout_height="0dp"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintLeft_toLeftOf="parent"
@@ -65,7 +64,7 @@
 
                 <ImageView
                     android:id="@+id/car_ui_toolbar_nav_icon"
-                    style="@style/Widget.CarUi.Toolbar.NavIcon"
+                    android:background="@drawable/car_ui_toolbar_menu_item_icon_ripple"
                     android:tint="@color/car_ui_text_color_primary"
                     android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
                     android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
@@ -145,9 +144,9 @@
                 android:layout_width="0dp"
                 android:layout_height="0dp"
                 app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintLeft_toRightOf="@id/car_ui_toolbar_menu_items_container"
-                app:layout_constraintRight_toLeftOf="@id/car_ui_toolbar_title_logo_container"
-                app:layout_constraintTop_toTopOf="parent"/>
+                app:layout_constraintLeft_toRightOf="@+id/car_ui_toolbar_menu_items_container"
+                app:layout_constraintRight_toRightOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
 
             <ProgressBar
                 android:id="@+id/car_ui_toolbar_progress_bar"
diff --git a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_recycler_view.xml b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_recycler_view.xml
deleted file mode 100644
index f487e35..0000000
--- a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_recycler_view.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <com.android.car.ui.recyclerview.CarUiRecyclerViewContainer
-        android:id="@+id/car_ui_recycler_view"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingStart="@dimen/car_ui_scrollbar_margin"
-        android:paddingEnd="@dimen/car_ui_scrollbar_margin"
-        android:tag="carUiRecyclerView" />
-
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="left" >
-        <include layout="@layout/car_ui_recyclerview_scrollbar"/>
-    </FrameLayout>
-</merge>
diff --git a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_recyclerview_scrollbar.xml b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_recyclerview_scrollbar.xml
deleted file mode 100644
index d5e626a..0000000
--- a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_recyclerview_scrollbar.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="@dimen/car_ui_scrollbar_container_width"
-    android:layout_height="match_parent"
-    android:id="@+id/car_ui_scroll_bar"
-    android:gravity="center">
-
-    <ImageView
-        android:id="@+id/car_ui_scrollbar_page_up"
-        android:layout_width="@dimen/car_ui_scrollbar_button_size"
-        android:layout_height="@dimen/car_ui_scrollbar_button_size"
-        android:background="@drawable/car_ui_recyclerview_button_ripple_background"
-        android:contentDescription="@string/car_ui_scrollbar_page_up_button"
-        android:focusable="false"
-        android:hapticFeedbackEnabled="false"
-        android:src="@drawable/car_ui_recyclerview_ic_up"
-        android:scaleType="centerInside"
-        android:layout_marginTop="15dp"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"/>
-
-    <!-- View height is dynamically calculated during layout. -->
-    <View
-        android:id="@+id/car_ui_scrollbar_thumb"
-        android:layout_width="@dimen/car_ui_scrollbar_thumb_width"
-        android:layout_height="0dp"
-        android:layout_gravity="center_horizontal"
-        android:background="@drawable/car_ui_recyclerview_scrollbar_thumb"
-        app:layout_constraintTop_toTopOf="@+id/car_ui_scrollbar_track"
-        app:layout_constraintBottom_toBottomOf="@+id/car_ui_scrollbar_track"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"/>
-
-    <View
-        android:id="@+id/car_ui_scrollbar_track"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_marginTop="@dimen/car_ui_scrollbar_separator_margin"
-        android:layout_marginBottom="@dimen/car_ui_scrollbar_separator_margin"
-        app:layout_constraintTop_toBottomOf="@+id/car_ui_scrollbar_page_up"
-        app:layout_constraintBottom_toTopOf="@+id/car_ui_scrollbar_page_down"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
-
-    <ImageView
-        android:id="@+id/car_ui_scrollbar_page_down"
-        android:layout_width="@dimen/car_ui_scrollbar_button_size"
-        android:layout_height="@dimen/car_ui_scrollbar_button_size"
-        android:background="@drawable/car_ui_recyclerview_button_ripple_background"
-        android:contentDescription="@string/car_ui_scrollbar_page_down_button"
-        android:focusable="false"
-        android:hapticFeedbackEnabled="false"
-        android:src="@drawable/car_ui_recyclerview_ic_down"
-        android:scaleType="centerInside"
-        android:layout_marginBottom="15dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar.xml b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar.xml
index 2714f44..a2d884d 100644
--- a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar.xml
+++ b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar.xml
@@ -23,8 +23,7 @@
 
     <FrameLayout
         android:id="@+id/car_ui_toolbar_nav_icon_container"
-        style="@style/Widget.CarUi.Toolbar.NavIconContainer"
-        android:layout_width="@dimen/car_ui_toolbar_margin"
+        android:layout_width="112dp"
         android:layout_height="0dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintLeft_toLeftOf="parent"
@@ -32,7 +31,7 @@
 
         <ImageView
             android:id="@+id/car_ui_toolbar_nav_icon"
-            style="@style/Widget.CarUi.Toolbar.NavIcon"
+            android:background="@drawable/car_ui_toolbar_menu_item_icon_ripple"
             android:tint="@color/car_ui_text_color_primary"
             android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
             android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
diff --git a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar_two_row.xml b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar_two_row.xml
index 6935121..395e48a 100644
--- a/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar_two_row.xml
+++ b/car-ui-lib/referencedesign/res/layout-ldrtl/car_ui_toolbar_two_row.xml
@@ -30,8 +30,7 @@
 
     <FrameLayout
         android:id="@+id/car_ui_toolbar_nav_icon_container"
-        style="@style/Widget.CarUi.Toolbar.NavIconContainer"
-        android:layout_width="@dimen/car_ui_toolbar_margin"
+        android:layout_width="112dp"
         android:layout_height="0dp"
         app:layout_constraintBottom_toTopOf="@id/car_ui_toolbar_row_separator_guideline"
         app:layout_constraintLeft_toLeftOf="parent"
@@ -39,11 +38,11 @@
 
         <ImageView
             android:id="@+id/car_ui_toolbar_nav_icon"
-            style="@style/Widget.CarUi.Toolbar.NavIcon"
             android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
             android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
             android:layout_gravity="center"
             android:scaleType="fitXY"
+            android:background="@drawable/car_ui_toolbar_menu_item_icon_ripple"
             android:tint="@color/car_ui_text_color_primary"/>
 
         <ImageView
diff --git a/car-ui-lib/referencedesign/res/layout-port/car_ui_base_layout_toolbar.xml b/car-ui-lib/referencedesign/res/layout-port/car_ui_base_layout_toolbar.xml
index d8b6d93..7aaa72d 100644
--- a/car-ui-lib/referencedesign/res/layout-port/car_ui_base_layout_toolbar.xml
+++ b/car-ui-lib/referencedesign/res/layout-port/car_ui_base_layout_toolbar.xml
@@ -28,11 +28,11 @@
          highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
          -->
     <com.android.car.ui.FocusParkingView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_width="1dp"
+        android:layout_height="1dp"/>
 
     <FrameLayout
-        android:id="@+id/car_ui_base_layout_content_container"
+        android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         app:layout_constraintBottom_toBottomOf="parent"
@@ -64,8 +64,7 @@
 
             <FrameLayout
                 android:id="@+id/car_ui_toolbar_nav_icon_container"
-                style="@style/Widget.CarUi.Toolbar.NavIconContainer"
-                android:layout_width="@dimen/car_ui_toolbar_margin"
+                android:layout_width="112dp"
                 android:layout_height="0dp"
                 app:layout_constraintBottom_toTopOf="@id/car_ui_toolbar_row_separator_guideline"
                 app:layout_constraintStart_toStartOf="parent"
@@ -73,11 +72,11 @@
 
                 <ImageView
                     android:id="@+id/car_ui_toolbar_nav_icon"
-                    style="@style/Widget.CarUi.Toolbar.NavIcon"
                     android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
                     android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
                     android:layout_gravity="center"
                     android:scaleType="fitXY"
+                    android:background="@drawable/car_ui_toolbar_menu_item_icon_ripple"
                     android:tint="@color/car_ui_text_color_primary"/>
 
                 <ImageView
@@ -134,10 +133,8 @@
                 android:layout_height="0dp"
                 app:layout_constraintBottom_toTopOf="@id/car_ui_toolbar_row_separator_guideline"
                 app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_menu_items_container"
-                app:layout_constraintStart_toEndOf="@id/car_ui_toolbar_title_logo_container"
-                app:layout_constraintTop_toTopOf="parent"
-                android:layout_marginStart="16dp"
-                app:layout_goneMarginStart="0dp" />
+                app:layout_constraintStart_toEndOf="@+id/car_ui_toolbar_nav_icon_container"
+                app:layout_constraintTop_toTopOf="parent" />
 
             <LinearLayout
                 android:id="@+id/car_ui_toolbar_menu_items_container"
diff --git a/car-ui-lib/referencedesign/res/layout/car_ui_preference_widget_seekbar.xml b/car-ui-lib/referencedesign/res/layout/car_ui_preference_widget_seekbar.xml
deleted file mode 100644
index 16d4ea0..0000000
--- a/car-ui-lib/referencedesign/res/layout/car_ui_preference_widget_seekbar.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:gravity="center_vertical"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:orientation="horizontal"
-    android:background="@drawable/car_ui_seekbar_preference_background"
-    android:clipChildren="false"
-    android:clipToPadding="false">
-
-    <ImageView
-        android:id="@android:id/icon"
-        android:layout_width="44dp"
-        android:layout_height="44dp"
-        android:layout_marginTop="16dp"
-        android:layout_marginBottom="16dp"
-        android:layout_marginEnd="16dp"
-        android:scaleType="fitCenter"
-        android:tint="@color/car_ui_text_color_primary"/>
-
-    <RelativeLayout
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:layout_marginTop="16dp"
-        android:layout_marginBottom="16dp"
-        android:clipChildren="false"
-        android:clipToPadding="false">
-
-        <TextView
-            android:id="@android:id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"/>
-
-        <TextView
-            android:id="@android:id/summary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignStart="@android:id/title"
-            android:layout_below="@android:id/title"
-            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"/>
-
-        <!-- Using UnPressableLinearLayout as a workaround to disable the pressed state propagation
-        to the children of this container layout. Otherwise, the animated pressed state will also
-        play for the thumb in the AbsSeekBar in addition to the preference's ripple background.
-        The background of the SeekBar is also set to null to disable the ripple background -->
-        <androidx.preference.UnPressableLinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignStart="@android:id/title"
-            android:layout_below="@android:id/summary"
-            android:clipChildren="false"
-            android:clipToPadding="false">
-            <SeekBar
-                android:id="@+id/seekbar"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                style="@style/Widget.CarUi.SeekbarPreference.Seekbar"/>
-
-            <TextView
-                android:id="@+id/seekbar_value"
-                android:layout_width="0dp"
-                android:layout_height="0dp"
-                android:visibility="gone"/>
-        </androidx.preference.UnPressableLinearLayout>
-
-    </RelativeLayout>
-
-</LinearLayout>
diff --git a/car-ui-lib/referencedesign/res/layout/car_ui_toolbar_menu_item.xml b/car-ui-lib/referencedesign/res/layout/car_ui_toolbar_menu_item.xml
deleted file mode 100644
index 0a6b24c..0000000
--- a/car-ui-lib/referencedesign/res/layout/car_ui_toolbar_menu_item.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2020, The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:focusable="false">
-    <FrameLayout
-        android:id="@+id/car_ui_toolbar_menu_item_icon_container"
-        style="@style/Widget.CarUi.Toolbar.MenuItem.IndividualContainer"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center">
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="center"
-            android:src="@drawable/car_ui_toolbar_menu_item_icon_background"
-            android:scaleType="center"/>
-        <ImageView
-            android:id="@+id/car_ui_toolbar_menu_item_icon"
-            android:layout_width="44dp"
-            android:layout_height="44dp"
-            android:layout_gravity="center"
-            android:tint="@color/car_ui_toolbar_menu_item_icon_color"
-            android:tintMode="src_in"/>
-    </FrameLayout>
-    <com.android.car.ui.uxr.DrawableStateSwitch
-        android:id="@+id/car_ui_toolbar_menu_item_switch"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-
-    <!-- These buttons must have clickable="false" or they will steal the click events from the container -->
-    <com.android.car.ui.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text"
-        style="@style/Widget.CarUi.Toolbar.TextButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-    <com.android.car.ui.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text_with_icon"
-        style="@style/Widget.CarUi.Toolbar.TextButton.WithIcon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/res/layout/car_ui_toolbar_menu_item_primary.xml b/car-ui-lib/referencedesign/res/layout/car_ui_toolbar_menu_item_primary.xml
deleted file mode 100644
index 716c8ee..0000000
--- a/car-ui-lib/referencedesign/res/layout/car_ui_toolbar_menu_item_primary.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2020, The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:focusable="false">
-    <FrameLayout
-        android:id="@+id/car_ui_toolbar_menu_item_icon_container"
-        style="@style/Widget.CarUi.Toolbar.MenuItem.IndividualContainer"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center">
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="center"
-            android:src="@drawable/car_ui_toolbar_menu_item_icon_background"
-            android:scaleType="center"/>
-        <ImageView
-            android:id="@+id/car_ui_toolbar_menu_item_icon"
-            android:layout_width="44dp"
-            android:layout_height="44dp"
-            android:layout_gravity="center"
-            android:tint="@color/car_ui_toolbar_menu_item_icon_color"
-            android:tintMode="src_in"/>
-    </FrameLayout>
-    <com.android.car.ui.uxr.DrawableStateSwitch
-        android:id="@+id/car_ui_toolbar_menu_item_switch"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-
-    <!-- These buttons must have clickable="false" or they will steal the click events from the container -->
-    <com.android.car.ui.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text"
-        style="@style/Widget.CarUi.Toolbar.TextButton.Primary"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-    <com.android.car.ui.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text_with_icon"
-        style="@style/Widget.CarUi.Toolbar.TextButton.Primary"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/res/values-ldrtl/values.xml b/car-ui-lib/referencedesign/res/values-ldrtl/values.xml
index 24552a5..2d50133 100644
--- a/car-ui-lib/referencedesign/res/values-ldrtl/values.xml
+++ b/car-ui-lib/referencedesign/res/values-ldrtl/values.xml
@@ -1,17 +1,4 @@
 <resources>
     <bool name="car_ui_toolbar_nav_icon_reserve_space">false</bool>
     <bool name="car_ui_toolbar_logo_fills_nav_icon_space">false</bool>
-
-    <dimen name="car_ui_scrollbar_margin">112dp</dimen>
-    <dimen name="car_ui_scrollbar_container_width">112dp</dimen>
-    <dimen name="car_ui_scrollbar_button_size">76dp</dimen>
-    <dimen name="car_ui_scrollbar_thumb_width">7dp</dimen>
-    <dimen name="car_ui_scrollbar_separator_margin">16dp</dimen>
-
-    <string name="car_ui_scrollbar_page_up_button">Scroll up</string>
-    <string name="car_ui_scrollbar_page_down_button">Scroll down</string>
-
-    <color name="car_ui_ripple_color">#27ffffff</color>
-    <color name="car_ui_scrollbar_thumb">#99ffffff</color>
-    <dimen name="car_ui_scrollbar_thumb_radius">100dp</dimen>
 </resources>
diff --git a/car-ui-lib/referencedesign/res/values-night/colors.xml b/car-ui-lib/referencedesign/res/values-night/colors.xml
deleted file mode 100644
index 42d706d..0000000
--- a/car-ui-lib/referencedesign/res/values-night/colors.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <!-- Rotary focus -->
-
-    <color name="car_ui_rotary_focus_stroke_color">#94CBFF</color>
-    <color name="car_ui_rotary_focus_fill_color">#3D94CBFF</color>
-</resources>
diff --git a/car-ui-lib/referencedesign/res/values/attrs.xml b/car-ui-lib/referencedesign/res/values/attrs.xml
index 74adbf9..a0b53df 100644
--- a/car-ui-lib/referencedesign/res/values/attrs.xml
+++ b/car-ui-lib/referencedesign/res/values/attrs.xml
@@ -56,6 +56,4 @@
     <attr name="layout_goneMarginStart" format="dimension"/>
     <attr name="layout_goneMarginEnd" format="dimension"/>
 
-    <attr name="state_ux_restricted"/>
-
 </resources>
diff --git a/car-ui-lib/referencedesign/res/values/dimens.xml b/car-ui-lib/referencedesign/res/values/dimens.xml
deleted file mode 100644
index 80fc15b..0000000
--- a/car-ui-lib/referencedesign/res/values/dimens.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-    <dimen name="car_ui_toolbar_margin">76dp</dimen>
-</resources>
diff --git a/car-ui-lib/referencedesign/res/values/styles.xml b/car-ui-lib/referencedesign/res/values/styles.xml
deleted file mode 100644
index d46763f..0000000
--- a/car-ui-lib/referencedesign/res/values/styles.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <style name="Widget.CarUi" parent="android:Widget.DeviceDefault"/>
-
-    <style name="Widget.CarUi.Toolbar"/>
-
-    <style name="Widget.CarUi.Toolbar.NavIconContainer">
-        <item name="android:layout_marginVertical">10dp</item>
-        <item name="android:layout_marginHorizontal">18dp</item>
-        <item name="android:background">@drawable/car_ui_toolbar_menu_item_icon_ripple</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.NavIcon">
-        <item name="android:tint">@color/car_ui_text_color_primary</item>
-        <item name="android:src">@drawable/car_ui_icon_arrow_back</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.MenuItem"/>
-
-    <style name="Widget.CarUi.Toolbar.MenuItem.IndividualContainer">
-        <item name="android:minHeight">76dp</item>
-        <item name="android:minWidth">76dp</item>
-        <item name="android:background">@drawable/car_ui_toolbar_menu_item_icon_ripple</item>
-        <item name="android:focusable">true</item>
-    </style>
-
-    <style name="Widget.CarUi.Button.Borderless.Colored"
-           parent="android:Widget.DeviceDefault.Button.Borderless.Colored"/>
-
-    <style name="Widget.CarUi.Button"
-           parent="android:Widget.DeviceDefault.Button"/>
-
-    <style name="Widget.CarUi.Toolbar.TextButton" parent="Widget.CarUi.Button.Borderless.Colored">
-        <item name="android:drawableTint">@color/car_ui_toolbar_menu_item_icon_color</item>
-        <item name="android:drawablePadding">10dp</item>
-        <item name="android:maxWidth">350dp</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.TextButton.WithIcon">
-        <item name="android:textColor">@color/car_ui_toolbar_menu_item_icon_color</item>
-    </style>
-
-    <style name="Widget.CarUi.Toolbar.TextButton.Primary" parent="Widget.CarUi.Button">
-        <item name="android:drawableTint">@color/car_ui_toolbar_menu_item_icon_color</item>
-        <item name="android:drawablePadding">10dp</item>
-        <item name="android:maxWidth">350dp</item>
-    </style>
-
-    <style name="Widget.CarUi.SeekbarPreference"/>
-
-    <!-- Style applied to the seekbar widget within the seekbar preference -->
-    <style name="Widget.CarUi.SeekbarPreference.Seekbar">
-        <item name="android:background">@null</item>
-        <item name="android:clickable">false</item>
-        <item name="android:focusable">false</item>
-        <item name="android:thumb">@drawable/car_ui_seekbar_thumb</item>
-        <item name="android:splitTrack">false</item>
-    </style>
-
-    <style name="TextAppearance.CarUi" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textColor">@color/car_ui_text_color_primary</item>
-        <item name="android:textAlignment">viewStart</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Body1">
-        <item name="android:textSize">32sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.PreferenceCategoryTitle" parent="TextAppearance.CarUi.Body3">
-        <item name="android:fontFamily">sans-serif-medium</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.PreferenceTitle" parent="TextAppearance.CarUi.Body1"/>
-
-    <style name="TextAppearance.CarUi.Body3">
-        <item name="android:textSize">24sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.PreferenceSummary" parent="TextAppearance.CarUi.Body3">
-        <item name="android:textColor">@color/car_ui_text_color_secondary</item>
-    </style>
-
-</resources>
diff --git a/car-ui-lib/referencedesign/res/values/values.xml b/car-ui-lib/referencedesign/res/values/values.xml
index d7f6526..0cbb8ee 100644
--- a/car-ui-lib/referencedesign/res/values/values.xml
+++ b/car-ui-lib/referencedesign/res/values/values.xml
@@ -1,5 +1,7 @@
 <resources>
-    <style name="TextAppearance.CarUi.Widget" parent="android:TextAppearance.DeviceDefault.Widget"/>
+    <style name="TextAppearance.CarUi.Widget" parent="android:TextAppearance.DeviceDefault.Widget">
+        <item name="android:textAlignment">viewStart</item>
+    </style>
 
     <style name="TextAppearance.CarUi.Widget.Toolbar"/>
 
@@ -10,6 +12,4 @@
 
     <dimen name="car_ui_toolbar_logo_size">44dp</dimen>
     <dimen name="car_ui_toolbar_nav_icon_size">44dp</dimen>
-
-    <bool name="car_ui_toolbar_menuitem_individual_click_listeners">true</bool>
 </resources>
diff --git a/car-ui-lib/referencedesign/res/xml/overlays.xml b/car-ui-lib/referencedesign/res/xml/overlays.xml
index f870c48..0d0eb74 100644
--- a/car-ui-lib/referencedesign/res/xml/overlays.xml
+++ b/car-ui-lib/referencedesign/res/xml/overlays.xml
@@ -1,94 +1,45 @@
 <overlay>
-    <item target="attr/layout_constraintBottom_toBottomOf" value="@attr/layout_constraintBottom_toBottomOf"/>
-    <item target="attr/layout_constraintBottom_toTopOf" value="@attr/layout_constraintBottom_toTopOf"/>
-    <item target="attr/layout_constraintEnd_toEndOf" value="@attr/layout_constraintEnd_toEndOf"/>
-    <item target="attr/layout_constraintEnd_toStartOf" value="@attr/layout_constraintEnd_toStartOf"/>
+    <item target="layout/car_ui_base_layout_toolbar" value="@layout/car_ui_base_layout_toolbar"/>
+    <item target="layout/car_ui_toolbar" value="@layout/car_ui_toolbar"/>
+    <item target="layout/car_ui_toolbar_two_row" value="@layout/car_ui_toolbar_two_row"/>
+
+    <item target="bool/car_ui_toolbar_nav_icon_reserve_space" value="@bool/car_ui_toolbar_nav_icon_reserve_space" />
+    <item target="bool/car_ui_toolbar_logo_fills_nav_icon_space" value="@bool/car_ui_toolbar_logo_fills_nav_icon_space" />
+
+    <item target="id/car_ui_toolbar_background" value="@id/car_ui_toolbar_background" />
+    <item target="id/car_ui_toolbar_nav_icon_container" value="@id/car_ui_toolbar_nav_icon_container" />
+    <item target="id/car_ui_toolbar_nav_icon" value="@id/car_ui_toolbar_nav_icon" />
+    <item target="id/car_ui_toolbar_logo" value="@id/car_ui_toolbar_logo" />
+    <item target="id/car_ui_toolbar_title_logo_container" value="@id/car_ui_toolbar_title_logo_container" />
+    <item target="id/car_ui_toolbar_title_logo" value="@id/car_ui_toolbar_title_logo" />
+    <item target="id/car_ui_toolbar_title" value="@id/car_ui_toolbar_title" />
+    <item target="id/car_ui_toolbar_title_container" value="@id/car_ui_toolbar_title_container" />
+    <item target="id/car_ui_toolbar_subtitle" value="@id/car_ui_toolbar_subtitle" />
+    <item target="id/car_ui_toolbar_tabs" value="@id/car_ui_toolbar_tabs" />
+    <item target="id/car_ui_toolbar_menu_items_container" value="@id/car_ui_toolbar_menu_items_container" />
+    <item target="id/car_ui_toolbar_search_view_container" value="@id/car_ui_toolbar_search_view_container" />
+    <item target="id/car_ui_toolbar_progress_bar" value="@id/car_ui_toolbar_progress_bar" />
+    <item target="id/content" value="@id/content" />
+
     <item target="attr/layout_constraintGuide_begin" value="@attr/layout_constraintGuide_begin"/>
     <item target="attr/layout_constraintGuide_end" value="@attr/layout_constraintGuide_end"/>
-    <item target="attr/layout_constraintHorizontal_bias" value="@attr/layout_constraintHorizontal_bias"/>
+    <item target="attr/layout_constraintStart_toStartOf" value="@attr/layout_constraintStart_toStartOf"/>
+    <item target="attr/layout_constraintStart_toEndOf" value="@attr/layout_constraintStart_toEndOf"/>
+    <item target="attr/layout_constraintEnd_toStartOf" value="@attr/layout_constraintEnd_toStartOf"/>
+    <item target="attr/layout_constraintEnd_toEndOf" value="@attr/layout_constraintEnd_toEndOf"/>
     <item target="attr/layout_constraintLeft_toLeftOf" value="@attr/layout_constraintLeft_toLeftOf"/>
     <item target="attr/layout_constraintLeft_toRightOf" value="@attr/layout_constraintLeft_toRightOf"/>
     <item target="attr/layout_constraintRight_toLeftOf" value="@attr/layout_constraintRight_toLeftOf"/>
     <item target="attr/layout_constraintRight_toRightOf" value="@attr/layout_constraintRight_toRightOf"/>
-    <item target="attr/layout_constraintStart_toEndOf" value="@attr/layout_constraintStart_toEndOf"/>
-    <item target="attr/layout_constraintStart_toStartOf" value="@attr/layout_constraintStart_toStartOf"/>
-    <item target="attr/layout_constraintTop_toBottomOf" value="@attr/layout_constraintTop_toBottomOf"/>
     <item target="attr/layout_constraintTop_toTopOf" value="@attr/layout_constraintTop_toTopOf"/>
-    <item target="attr/layout_goneMarginBottom" value="@attr/layout_goneMarginBottom"/>
-    <item target="attr/layout_goneMarginEnd" value="@attr/layout_goneMarginEnd"/>
+    <item target="attr/layout_constraintTop_toBottomOf" value="@attr/layout_constraintTop_toBottomOf"/>
+    <item target="attr/layout_constraintBottom_toTopOf" value="@attr/layout_constraintBottom_toTopOf"/>
+    <item target="attr/layout_constraintBottom_toBottomOf" value="@attr/layout_constraintBottom_toBottomOf"/>
+    <item target="attr/layout_constraintHorizontal_bias" value="@attr/layout_constraintHorizontal_bias"/>
     <item target="attr/layout_goneMarginLeft" value="@attr/layout_goneMarginLeft"/>
-    <item target="attr/layout_goneMarginRight" value="@attr/layout_goneMarginRight"/>
-    <item target="attr/layout_goneMarginStart" value="@attr/layout_goneMarginStart"/>
-    <item target="attr/layout_goneMarginTop" value="@attr/layout_goneMarginTop"/>
-    <item target="attr/state_ux_restricted" value="@attr/state_ux_restricted"/>
-
-    <item target="bool/car_ui_toolbar_logo_fills_nav_icon_space" value="@bool/car_ui_toolbar_logo_fills_nav_icon_space" />
-    <item target="bool/car_ui_toolbar_menuitem_individual_click_listeners" value="@bool/car_ui_toolbar_menuitem_individual_click_listeners" />
-    <item target="bool/car_ui_toolbar_nav_icon_reserve_space" value="@bool/car_ui_toolbar_nav_icon_reserve_space" />
-    <item target="bool/car_ui_toolbar_tab_flexible_layout" value="@bool/car_ui_toolbar_tab_flexible_layout" />
-    <item target="bool/car_ui_toolbar_tabs_on_second_row" value="@bool/car_ui_toolbar_tabs_on_second_row" />
-
-    <item target="color/car_ui_text_color_secondary" value="@color/car_ui_text_color_secondary"/>
-    <item target="color/car_ui_toolbar_menu_item_icon_background_color" value="@color/car_ui_toolbar_menu_item_icon_background_color"/>
-    <item target="color/car_ui_toolbar_menu_item_icon_color" value="@color/car_ui_toolbar_menu_item_icon_color"/>
-
-    <item target="dimen/car_ui_toolbar_margin" value="@dimen/car_ui_toolbar_margin"/>
-
-    <item target="drawable/car_ui_icon_arrow_back" value="@drawable/car_ui_icon_arrow_back"/>
-    <item target="drawable/car_ui_toolbar_menu_item_icon_background" value="@drawable/car_ui_toolbar_menu_item_icon_background"/>
-    <item target="drawable/car_ui_toolbar_menu_item_icon_ripple" value="@drawable/car_ui_toolbar_menu_item_icon_ripple"/>
-
-    <item target="id/car_ui_base_layout_content_container" value="@id/car_ui_base_layout_content_container" />
-    <item target="id/car_ui_recycler_view" value="@id/car_ui_recycler_view" />
-    <item target="id/car_ui_scrollbar_page_down" value="@id/car_ui_scrollbar_page_down"/>
-    <item target="id/car_ui_scrollbar_page_up" value="@id/car_ui_scrollbar_page_up"/>
-    <item target="id/car_ui_scrollbar_thumb" value="@id/car_ui_scrollbar_thumb"/>
-    <item target="id/car_ui_scrollbar_track" value="@id/car_ui_scrollbar_track"/>
-    <item target="id/car_ui_scroll_bar" value="@id/car_ui_scroll_bar"/>
-    <item target="id/car_ui_toolbar_background" value="@id/car_ui_toolbar_background" />
-    <item target="id/car_ui_toolbar_logo" value="@id/car_ui_toolbar_logo" />
-    <item target="id/car_ui_toolbar_menu_item_icon_container" value="@id/car_ui_toolbar_menu_item_icon_container"/>
-    <item target="id/car_ui_toolbar_menu_item_icon" value="@id/car_ui_toolbar_menu_item_icon"/>
-    <item target="id/car_ui_toolbar_menu_items_container" value="@id/car_ui_toolbar_menu_items_container" />
-    <item target="id/car_ui_toolbar_menu_item_switch" value="@id/car_ui_toolbar_menu_item_switch"/>
-    <item target="id/car_ui_toolbar_menu_item_text" value="@id/car_ui_toolbar_menu_item_text"/>
-    <item target="id/car_ui_toolbar_menu_item_text_with_icon" value="@id/car_ui_toolbar_menu_item_text_with_icon"/>
-    <item target="id/car_ui_toolbar_nav_icon_container" value="@id/car_ui_toolbar_nav_icon_container" />
-    <item target="id/car_ui_toolbar_nav_icon" value="@id/car_ui_toolbar_nav_icon" />
-    <item target="id/car_ui_toolbar_progress_bar" value="@id/car_ui_toolbar_progress_bar" />
-    <item target="id/car_ui_toolbar_search_view_container" value="@id/car_ui_toolbar_search_view_container" />
-    <item target="id/car_ui_toolbar_subtitle" value="@id/car_ui_toolbar_subtitle" />
-    <item target="id/car_ui_toolbar_tabs" value="@id/car_ui_toolbar_tabs" />
-    <item target="id/car_ui_toolbar_title_container" value="@id/car_ui_toolbar_title_container" />
-    <item target="id/car_ui_toolbar_title_logo_container" value="@id/car_ui_toolbar_title_logo_container" />
-    <item target="id/car_ui_toolbar_title_logo" value="@id/car_ui_toolbar_title_logo" />
-    <item target="id/car_ui_toolbar_title" value="@id/car_ui_toolbar_title" />
-    <item target="id/seekbar" value="@id/seekbar"/>
-    <item target="id/seekbar_value" value="@id/seekbar_value"/>
-
-    <item target="layout/car_ui_base_layout_toolbar" value="@layout/car_ui_base_layout_toolbar"/>
-    <item target="layout/car_ui_preference_widget_seekbar" value="@layout/car_ui_preference_widget_seekbar"/>
-    <item target="layout/car_ui_recycler_view" value="@layout/car_ui_recycler_view"/>
-    <item target="layout/car_ui_toolbar_menu_item_primary" value="@layout/car_ui_toolbar_menu_item_primary"/>
-    <item target="layout/car_ui_toolbar_menu_item" value="@layout/car_ui_toolbar_menu_item"/>
-    <item target="layout/car_ui_toolbar_two_row" value="@layout/car_ui_toolbar_two_row"/>
-    <item target="layout/car_ui_toolbar" value="@layout/car_ui_toolbar"/>
-
-    <item target="style/TextAppearance.CarUi.Body1" value="@style/TextAppearance.CarUi.Body1"/>
-    <item target="style/TextAppearance.CarUi.Body3" value="@style/TextAppearance.CarUi.Body3"/>
-    <item target="style/TextAppearance.CarUi.PreferenceCategoryTitle" value="@style/TextAppearance.CarUi.PreferenceCategoryTitle"/>
-    <item target="style/TextAppearance.CarUi.PreferenceSummary" value="@style/TextAppearance.CarUi.PreferenceSummary"/>
-    <item target="style/TextAppearance.CarUi.PreferenceTitle" value="@style/TextAppearance.CarUi.PreferenceTitle"/>
-    <item target="style/TextAppearance.CarUi" value="@style/TextAppearance.CarUi"/>
-    <item target="style/Widget.CarUi.Button.Borderless.Colored" value="@style/Widget.CarUi.Button.Borderless.Colored"/>
-    <item target="style/Widget.CarUi.SeekbarPreference.Seekbar" value="@style/Widget.CarUi.SeekbarPreference.Seekbar"/>
-    <item target="style/Widget.CarUi.SeekbarPreference" value="@style/Widget.CarUi.SeekbarPreference"/>
-    <item target="style/Widget.CarUi.Toolbar.MenuItem.IndividualContainer" value="@style/Widget.CarUi.Toolbar.MenuItem.IndividualContainer"/>
-    <item target="style/Widget.CarUi.Toolbar.MenuItem" value="@style/Widget.CarUi.Toolbar.MenuItem"/>
-    <item target="style/Widget.CarUi.Toolbar.NavIconContainer" value="@style/Widget.CarUi.Toolbar.NavIconContainer"/>
-    <item target="style/Widget.CarUi.Toolbar.NavIcon" value="@style/Widget.CarUi.Toolbar.NavIcon"/>
-    <item target="style/Widget.CarUi.Toolbar.TextButton" value="@style/Widget.CarUi.Toolbar.TextButton"/>
-    <item target="style/Widget.CarUi.Toolbar.TextButton.WithIcon" value="@style/Widget.CarUi.Toolbar.TextButton.WithIcon"/>
-    <item target="style/Widget.CarUi.Toolbar" value="@style/Widget.CarUi.Toolbar"/>
-    <item target="style/Widget.CarUi" value="@style/Widget.CarUi"/>
+    <item target="attr/layout_goneMarginLeft" value="@attr/layout_goneMarginRight"/>
+    <item target="attr/layout_goneMarginLeft" value="@attr/layout_goneMarginTop"/>
+    <item target="attr/layout_goneMarginLeft" value="@attr/layout_goneMarginBottom"/>
+    <item target="attr/layout_goneMarginLeft" value="@attr/layout_goneMarginStart"/>
+    <item target="attr/layout_goneMarginLeft" value="@attr/layout_goneMarginEnd"/>
 </overlay>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/Android.bp b/car-ui-lib/referencedesign/sharedlibrary/Android.bp
deleted file mode 100644
index 384b741..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_app_certificate {
-    name: "car-ui-lib-sharedlibrary-certificate",
-    certificate: "chassis_upload_key"
-}
-
-android_app {
-    name: "car-ui-lib-sharedlibrary",
-
-    min_sdk_version: "28",
-    target_sdk_version: "30",
-    sdk_version: "current",
-
-    manifest: "src/main/AndroidManifest.xml",
-    srcs: ["src/main/java/**/*.java"],
-    resource_dirs: ["src/main/res"],
-
-    static_libs: [
-        "car-ui-lib-oem-apis",
-        "androidx.annotation_annotation",
-        "androidx.appcompat_appcompat",
-        "androidx-constraintlayout_constraintlayout",
-        "androidx.preference_preference",
-        "androidx.recyclerview_recyclerview",
-        "androidx-constraintlayout_constraintlayout-solver",
-        "androidx.asynclayoutinflater_asynclayoutinflater",
-    ],
-
-    optimize: {
-        enabled: false,
-    },
-
-    certificate: ":car-ui-lib-sharedlibrary-certificate",
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/build.gradle b/car-ui-lib/referencedesign/sharedlibrary/build.gradle
deleted file mode 100644
index 99e0b1d..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/build.gradle
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Library-level build file
-
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion 30
-
-    defaultConfig {
-        minSdkVersion 28
-        targetSdkVersion 30
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
-    }
-
-    // In order to adb install a new version of an app over it's preinstalled version, the new
-    // version must be signed with the same key as the preinstalled version. If you don't specify
-    // a certificate in the Android.bp file, the default certificate that will
-    // be used is build/target/product/security/testkey.{pk8,x509.pem}. Android studio doesn't
-    // support signing apps using individual pk8 and x509.pem files, it requires a keystore file.
-    signingConfigs {
-        debug {
-            storeFile file('chassis_upload_key.pepk')
-            storePassword 'chassis'
-            keyAlias 'chassis'
-            keyPassword 'chassis'
-        }
-    }
-}
-
-dependencies {
-    implementation project(':oem-apis')
-    api 'androidx.annotation:annotation:1.2.0'
-    api 'androidx.appcompat:appcompat:1.3.0'
-    api 'androidx.constraintlayout:constraintlayout:2.0.4'
-    api 'androidx.preference:preference:1.1.1'
-    api 'androidx.recyclerview:recyclerview:1.2.0'
-    api 'androidx.core:core:1.5.0'
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.pepk b/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.pepk
deleted file mode 100644
index b765db1..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.pepk
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.pk8 b/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.pk8
deleted file mode 100644
index a867fdd..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.pk8
+++ /dev/null
Binary files differ
diff --git a/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.x509.pem b/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.x509.pem
deleted file mode 100644
index 027a197..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/chassis_upload_key.x509.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC9zCCAd+gAwIBAgIELMWXmDANBgkqhkiG9w0BAQsFADAsMQswCQYDVQQGEwJV
-UzELMAkGA1UECBMCQ0ExEDAOBgNVBAMTB0NoYXNzaXMwHhcNMjEwNTAzMTg1NDM5
-WhcNNDYwNDI3MTg1NDM5WjAsMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAO
-BgNVBAMTB0NoYXNzaXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp
-JPZiygVOD1LEz+Hw3hS3SfCpqm5l57lje9K6hYqXN31l2xUsHaTBdz1w4AOTZgjm
-UQaY2m73HxMtOAli9OJUY6594orGYJS5dKqkuAnmMP4sCxvHRQvA413JERaKHXSz
-sg6AMkzOzPnTPqr+L2N013GaDj3knrz/7xKDvTJbHGVbPbogEDLZUs9hH7N8k03I
-jeU0ThDJpd2oJ/vzpv2bdV89gFmYAzu5hw+v1O2yPVf+OEsbL1kY+rJTmhTldtWJ
-/OPjHQQU/IV3TtQzy1xwEAsXC8M69VgoeGSBmQOo7tswuOMKngJ9OU8y0qFjbVUm
-xlwGix8nI6GxNlULrmSdAgMBAAGjITAfMB0GA1UdDgQWBBTkNQPmsZZ8KAjxOKXu
-u1fVHWWT7DANBgkqhkiG9w0BAQsFAAOCAQEAPQrN4tUM1lc40DsrMdAoSg7MZ0ji
-KOfGAjnPezJDqJY1fxoB4jRDd+ut13YiBFcnpH1LsJTekhkxLcL6mdCSOJO4f9UK
-YP/eMRS1tI5r/903qtdStzlYrBp+AKXicSV2q2Zr25AhZsFqDPR211xcKQNrmml1
-slCBK53Llk3wi795Disu1IlCsNN0CR4RmHAGOjZUU3QTNYyE6RhD3cdHZyzy0utt
-BkADfLvT7MCGHETDh1fvsNaieRzasV9dK30PTdQ8itj9+xel0cUnXTAXGs9YpudJ
-6ynTWXHZMU3N8Ay1Ip9d+J5pDSl//JXCSGFzVA3vO07AfUscQbtRoA/6lg==
------END CERTIFICATE-----
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/AndroidManifest.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/AndroidManifest.xml
deleted file mode 100644
index ba07316..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.chassis.car.ui.sharedlibrary"
-    android:versionName="0.0.4"
-    android:versionCode="4">
-
-    <uses-feature android:name="android.hardware.type.automotive" />
-
-    <application>
-        <activity android:name=".MainActivity"
-            android:exported="true">
-            <intent-filter>
-                <action android:name="com.android.car.ui.intent.action.SHARED_LIBRARY"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/android/car/ui/sharedlibrary/SharedLibraryVersionProviderImpl.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/android/car/ui/sharedlibrary/SharedLibraryVersionProviderImpl.java
deleted file mode 100644
index 038dc6e..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/android/car/ui/sharedlibrary/SharedLibraryVersionProviderImpl.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.ui.sharedlibrary;
-
-import android.content.Context;
-
-import com.android.car.ui.sharedlibrary.oemapis.SharedLibraryVersionProviderOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.SharedLibraryFactoryImpl;
-
-/**
- * An implementation of {@link SharedLibraryVersionProviderOEMV1} for the reference design
- * shared library.
- */
-public class SharedLibraryVersionProviderImpl implements SharedLibraryVersionProviderOEMV1 {
-
-    @Override
-    public Object getSharedLibraryFactory(int maxVersion, Context context, String packageName) {
-        return new SharedLibraryFactoryImpl(context);
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/MainActivity.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/MainActivity.java
deleted file mode 100644
index 0549128..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/MainActivity.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary;
-
-import android.app.Activity;
-
-/**
- * A blank activity. It's only purpose is for responding to the
- * {@code com.android.car.ui.intent.action.SHARED_LIBRARY} intent.
- */
-public class MainActivity extends Activity {
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/SharedLibraryFactoryImpl.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/SharedLibraryFactoryImpl.java
deleted file mode 100644
index bfbf7dd..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/SharedLibraryFactoryImpl.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.sharedlibrary.oemapis.FocusAreaOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.FocusParkingViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.InsetsOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.SharedLibraryFactoryOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.appstyledview.AppStyledViewControllerOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewAttributesOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ViewHolderOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.toolbar.BaseLayoutInstaller;
-
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * An implementation of {@link SharedLibraryFactoryImpl} for creating the reference design
- * car-ui-lib components.
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class SharedLibraryFactoryImpl implements SharedLibraryFactoryOEMV1 {
-
-    private final Context mSharedLibraryContext;
-    @Nullable
-    private Function<Context, FocusParkingViewOEMV1> mFocusParkingViewFactory;
-    @Nullable
-    private Function<Context, FocusAreaOEMV1> mFocusAreaFactory;
-
-    public SharedLibraryFactoryImpl(Context sharedLibraryContext) {
-        mSharedLibraryContext = sharedLibraryContext;
-    }
-
-    @Override
-    public void setRotaryFactories(
-            Function<Context, FocusParkingViewOEMV1> focusParkingViewFactory,
-            Function<Context, FocusAreaOEMV1> focusAreaFactory) {
-        mFocusParkingViewFactory = focusParkingViewFactory;
-        mFocusAreaFactory = focusAreaFactory;
-    }
-
-    @Override
-    public ToolbarControllerOEMV1 installBaseLayoutAround(View contentView,
-            Consumer<InsetsOEMV1> insetsChangedListener, boolean toolbarEnabled,
-            boolean fullscreen) {
-
-        return BaseLayoutInstaller.installBaseLayoutAround(
-                mSharedLibraryContext,
-                contentView,
-                insetsChangedListener,
-                toolbarEnabled,
-                fullscreen,
-                mFocusParkingViewFactory,
-                mFocusAreaFactory);
-    }
-
-    @Override
-    public boolean customizesBaseLayout() {
-        return true;
-    }
-
-    @Override
-    public AppStyledViewControllerOEMV1 createAppStyledView() {
-        //return new AppStyleViewControllerImpl(mSharedLibraryContext);
-        return null;
-    }
-
-    @Override
-    public RecyclerViewOEMV1 createRecyclerView(Context context,
-            RecyclerViewAttributesOEMV1 attrs) {
-        //return new RecyclerViewImpl(context, attrs);
-        return null;
-    }
-
-    @Override
-    public AdapterOEMV1<? extends ViewHolderOEMV1> createListItemAdapter(
-            List<ListItemOEMV1> items) {
-        //return new ListItemAdapter(items);
-        return null;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/appstyleview/AppStyleViewControllerImpl.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/appstyleview/AppStyleViewControllerImpl.java
deleted file mode 100644
index 14dee37..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/appstyleview/AppStyleViewControllerImpl.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.chassis.car.ui.sharedlibrary.appstyleview;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager.LayoutParams;
-import android.widget.ImageView;
-import android.widget.ScrollView;
-
-import com.android.car.ui.sharedlibrary.oemapis.appstyledview.AppStyledViewControllerOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-
-/**
- * The OEM implementation for {@link AppStyledViewControllerOEMV1} for a AppStyledView.
- */
-public class AppStyleViewControllerImpl implements AppStyledViewControllerOEMV1 {
-
-    private final Context mContext;
-    private View mAppStyleView;
-    private int mNavIcon;
-    private Runnable mCloseListener = null;
-
-    public AppStyleViewControllerImpl(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public View getAppStyledView(View content) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        mAppStyleView = inflater.inflate(R.layout.app_styled_view, null, false);
-
-        ScrollView scrollview = mAppStyleView.findViewById(R.id.app_styled_content);
-        scrollview.addView(content);
-
-        ImageView navIcon = mAppStyleView.findViewById(R.id.app_styled_view_icon_close);
-        if (mNavIcon == 0) {
-            navIcon.setImageResource(R.drawable.icon_back);
-        } else if (mNavIcon == 1) {
-            navIcon.setImageResource(R.drawable.icon_close);
-        } else {
-            navIcon.setImageResource(R.drawable.icon_close);
-        }
-
-        if (mCloseListener != null) {
-            navIcon.setOnClickListener((v) -> {
-                mCloseListener.run();
-            });
-        }
-
-        return mAppStyleView;
-    }
-
-    @Override
-    public void setOnCloseClickListener(Runnable listener) {
-        mCloseListener = listener;
-    }
-
-    @Override
-    public void setNavIcon(int navIcon) {
-        mNavIcon = navIcon;
-    }
-
-    @Override
-    public LayoutParams getDialogWindowLayoutParam(LayoutParams params) {
-        params.width = Math.round(
-                mContext.getResources().getDimension(R.dimen.app_styled_dialog_width));
-        params.height = Math.round(
-                mContext.getResources().getDimension(R.dimen.app_styled_dialog_height));
-        params.gravity = Gravity.TOP | Gravity.START;
-        params.x = Math.round(
-                mContext.getResources().getDimension(R.dimen.app_styled_dialog_position_x));
-        params.y = Math.round(
-                mContext.getResources().getDimension(R.dimen.app_styled_dialog_position_y));
-        return params;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/AdapterWrapper.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/AdapterWrapper.java
deleted file mode 100644
index fd7503a..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/AdapterWrapper.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.recyclerview;
-
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterDataObserverOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ViewHolderOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.recyclerview.AdapterWrapper.ViewHolderWrapper;
-
-/**
- * Wrapper class that passes the data to car-ui via AdapterOEMV1 interface
- */
-public final class AdapterWrapper extends RecyclerView.Adapter<ViewHolderWrapper> {
-
-    @NonNull
-    private AdapterOEMV1 mAdapter;
-
-    @NonNull
-    private AdapterDataObserverOEMV1 mAdapterDataObserver = new AdapterDataObserverOEMV1() {
-        @Override
-        public void onChanged() {
-            AdapterWrapper.super.notifyDataSetChanged();
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount) {
-            AdapterWrapper.super.notifyItemRangeChanged(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemRangeChanged(int positionStart, int itemCount,
-                @Nullable Object payload) {
-            AdapterWrapper.super.notifyItemRangeChanged(positionStart, itemCount, payload);
-        }
-
-        @Override
-        public void onItemRangeInserted(int positionStart, int itemCount) {
-            AdapterWrapper.super.notifyItemRangeInserted(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemRangeRemoved(int positionStart, int itemCount) {
-            AdapterWrapper.super.notifyItemRangeRemoved(positionStart, itemCount);
-        }
-
-        @Override
-        public void onItemMoved(int fromPosition, int toPosition) {
-            AdapterWrapper.super.notifyItemMoved(fromPosition, toPosition);
-        }
-
-        @Override
-        public void onStateRestorationPolicyChanged() {
-            AdapterWrapper.this.updateStateRestorationPolicy();
-        }
-    };
-
-    public AdapterWrapper(@NonNull AdapterOEMV1 adapter) {
-        this.mAdapter = adapter;
-        AdapterWrapper.super.setHasStableIds(adapter.hasStableIds());
-        updateStateRestorationPolicy();
-    }
-
-    private void updateStateRestorationPolicy() {
-        switch (mAdapter.getStateRestorationPolicyInt()) {
-            case 2:
-                AdapterWrapper.super.setStateRestorationPolicy(
-                        RecyclerView.Adapter.StateRestorationPolicy.PREVENT);
-                break;
-            case 1:
-                AdapterWrapper.super.setStateRestorationPolicy(
-                        RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);
-                break;
-            case 0:
-            default:
-                AdapterWrapper.super.setStateRestorationPolicy(
-                        RecyclerView.Adapter.StateRestorationPolicy.ALLOW);
-        }
-    }
-
-    @Override
-    public int getItemCount() {
-        return mAdapter.getItemCount();
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return mAdapter.getItemId(position);
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mAdapter.getItemViewType(position);
-    }
-
-    @Override
-    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
-        mAdapter.onAttachedToRecyclerView((RecyclerViewOEMV1) recyclerView);
-    }
-
-    @Override
-    public void onBindViewHolder(ViewHolderWrapper holder, int position) {
-        mAdapter.bindViewHolder(holder.getViewHolder(), position);
-    }
-
-    @Override
-    public ViewHolderWrapper onCreateViewHolder(ViewGroup parent, int viewType) {
-        return new ViewHolderWrapper(mAdapter.createViewHolder(parent, viewType));
-    }
-
-    @Override
-    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
-        mAdapter.onDetachedFromRecyclerView((RecyclerViewOEMV1) recyclerView);
-    }
-
-    @Override
-    public boolean onFailedToRecycleView(ViewHolderWrapper holder) {
-        return mAdapter.onFailedToRecycleView(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewAttachedToWindow(ViewHolderWrapper holder) {
-        mAdapter.onViewAttachedToWindow(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewDetachedFromWindow(ViewHolderWrapper holder) {
-        mAdapter.onViewDetachedFromWindow(holder.getViewHolder());
-    }
-
-    @Override
-    public void onViewRecycled(ViewHolderWrapper holder) {
-        mAdapter.onViewRecycled(holder.getViewHolder());
-    }
-
-    @Override
-    public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) {
-        if (!super.hasObservers()) {
-            mAdapter.registerAdapterDataObserver(mAdapterDataObserver);
-        }
-        super.registerAdapterDataObserver(observer);
-    }
-
-    @Override
-    public void unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver observer) {
-        super.unregisterAdapterDataObserver(observer);
-        if (!super.hasObservers()) {
-            mAdapter.registerAdapterDataObserver(mAdapterDataObserver);
-        }
-    }
-
-    /**
-     * Holds views for each element in the list.
-     */
-    public static class ViewHolderWrapper extends RecyclerView.ViewHolder {
-        @NonNull
-        private ViewHolderOEMV1 mViewHolder;
-
-        ViewHolderWrapper(@NonNull ViewHolderOEMV1 viewHolder) {
-            super(viewHolder.getItemView());
-            mViewHolder = viewHolder;
-            setIsRecyclable(viewHolder.isRecyclable());
-        }
-
-        @NonNull
-        public ViewHolderOEMV1 getViewHolder() {
-            return mViewHolder;
-        }
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/ListItemAdapter.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/ListItemAdapter.java
deleted file mode 100644
index 863f518..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/ListItemAdapter.java
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.recyclerview;
-
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.RadioButton;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterDataObserverOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ContentListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.HeaderListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ListItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.ViewHolderOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * Adapter for {@link RecyclerViewOEMV1} to display {@link ContentListItemOEMV1} and {@link
- * HeaderListItemOEMV1}.
- */
-public class ListItemAdapter extends RecyclerView.Adapter<ListItemAdapter.BaseViewHolder> implements
-        AdapterOEMV1<ListItemAdapter.BaseViewHolder> {
-    static final int VIEW_TYPE_LIST_ITEM = 1;
-    static final int VIEW_TYPE_LIST_HEADER = 2;
-
-    private final List<? extends ListItemOEMV1> mItems;
-    @NonNull
-    private final List<AdapterDataObserverOEMV1> mAdapterDataObservers = new ArrayList<>();
-    private final RecyclerView.AdapterDataObserver mAdapterDataObserver =
-            new RecyclerView.AdapterDataObserver() {
-                @Override
-                public void onChanged() {
-                    for (AdapterDataObserverOEMV1 observer : mAdapterDataObservers) {
-                        observer.onChanged();
-                    }
-                }
-
-                @Override
-                public void onItemRangeChanged(int positionStart, int itemCount) {
-                    for (AdapterDataObserverOEMV1 observer : mAdapterDataObservers) {
-                        observer.onItemRangeChanged(positionStart, itemCount);
-                    }
-                }
-
-                @Override
-                public void onItemRangeChanged(int positionStart, int itemCount,
-                        @Nullable Object payload) {
-                    for (AdapterDataObserverOEMV1 observer : mAdapterDataObservers) {
-                        observer.onItemRangeChanged(positionStart, itemCount, payload);
-                    }
-                }
-
-                @Override
-                public void onItemRangeInserted(int positionStart, int itemCount) {
-                    for (AdapterDataObserverOEMV1 observer : mAdapterDataObservers) {
-                        observer.onItemRangeInserted(positionStart, itemCount);
-                    }
-                }
-
-                @Override
-                public void onItemRangeRemoved(int positionStart, int itemCount) {
-                    for (AdapterDataObserverOEMV1 observer : mAdapterDataObservers) {
-                        observer.onItemRangeRemoved(positionStart, itemCount);
-                    }
-                }
-
-                @Override
-                public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-                    for (AdapterDataObserverOEMV1 observer : mAdapterDataObservers) {
-                        for (int i = 0; i < itemCount; i++) {
-                            observer.onItemMoved(fromPosition + i, toPosition + i);
-                        }
-                    }
-                }
-
-                @Override
-                public void onStateRestorationPolicyChanged() {
-                    for (AdapterDataObserverOEMV1 observer : mAdapterDataObservers) {
-                        observer.onStateRestorationPolicyChanged();
-                    }
-                }
-            };
-
-    public ListItemAdapter(List<? extends ListItemOEMV1> items) {
-        mItems = items;
-    }
-
-    @NonNull
-    @Override
-    public ListItemAdapter.BaseViewHolder onCreateViewHolder(
-            @NonNull ViewGroup parent, int viewType) {
-        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-
-        switch (viewType) {
-            case VIEW_TYPE_LIST_ITEM:
-                return new ListItemViewHolder(
-                        inflater.inflate(R.layout.list_item, parent, false));
-            case VIEW_TYPE_LIST_HEADER:
-                return new HeaderViewHolder(
-                        inflater.inflate(R.layout.header_list_item, parent, false));
-            default:
-                throw new IllegalStateException("Unknown item type.");
-        }
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        if (mItems.get(position) instanceof ContentListItemOEMV1) {
-            return VIEW_TYPE_LIST_ITEM;
-        } else if (mItems.get(position) instanceof HeaderListItemOEMV1) {
-            return VIEW_TYPE_LIST_HEADER;
-        }
-
-        throw new IllegalStateException("Unknown view type.");
-    }
-
-    @Override
-    public int getStateRestorationPolicyInt() {
-        switch (getStateRestorationPolicy()) {
-            case PREVENT:
-                return AdapterOEMV1.PREVENT;
-            case PREVENT_WHEN_EMPTY:
-                return AdapterOEMV1.PREVENT_WHEN_EMPTY;
-            case ALLOW:
-            default:
-                return AdapterOEMV1.ALLOW;
-        }
-    }
-
-    @Override
-    public void onAttachedToRecyclerView(RecyclerViewOEMV1 recyclerView) {
-        //  Do nothing. This method will never be invoked.
-    }
-
-    @Override
-    public void onDetachedFromRecyclerView(RecyclerViewOEMV1 recyclerView) {
-        //  Do nothing. This method will never be invoked.
-    }
-
-    @Override
-    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
-        registerAdapterDataObserver(mAdapterDataObserver);
-    }
-
-    @Override
-    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
-        unregisterAdapterDataObserver(mAdapterDataObserver);
-    }
-
-    @Override
-    public void registerAdapterDataObserver(AdapterDataObserverOEMV1 observer) {
-        if (observer == null) {
-            return;
-        }
-        mAdapterDataObservers.add(observer);
-    }
-
-    @Override
-    public void unregisterAdapterDataObserver(AdapterDataObserverOEMV1 observer) {
-        if (observer == null) {
-            return;
-        }
-        mAdapterDataObservers.remove(observer);
-    }
-
-    @Override
-    public void setRecyclerView(View recyclerview) {
-        //  Do nothing. This method will never be invoked.
-    }
-
-    @Override
-    public void onBindViewHolder(@NonNull ListItemAdapter.BaseViewHolder holder, int position) {
-        switch (holder.getItemViewType()) {
-            case VIEW_TYPE_LIST_ITEM:
-                if (!(holder instanceof ListItemViewHolder)) {
-                    throw new IllegalStateException("Incorrect view holder type for list item.");
-                }
-
-                ListItemOEMV1 item = mItems.get(position);
-                if (!(item instanceof ContentListItemOEMV1)) {
-                    throw new IllegalStateException(
-                            "Expected item to be bound to viewHolder to be instance of "
-                                    + "CarUiContentListItem.");
-                }
-
-                ((ListItemViewHolder) holder).bind((ContentListItemOEMV1) item);
-                break;
-            case VIEW_TYPE_LIST_HEADER:
-                if (!(holder instanceof HeaderViewHolder)) {
-                    throw new IllegalStateException("Incorrect view holder type for list item.");
-                }
-
-                ListItemOEMV1 header = mItems.get(position);
-                if (!(header instanceof HeaderListItemOEMV1)) {
-                    throw new IllegalStateException(
-                            "Expected item to be bound to viewHolder to be instance of "
-                                    + "CarUiHeaderListItem.");
-                }
-
-                ((HeaderViewHolder) holder).bind((HeaderListItemOEMV1) header);
-                break;
-            default:
-                throw new IllegalStateException("Unknown item view type.");
-        }
-    }
-
-    @Override
-    public int getItemCount() {
-        return mItems.size();
-    }
-
-    abstract static class BaseViewHolder extends RecyclerView.ViewHolder implements
-            ViewHolderOEMV1 {
-        BaseViewHolder(@NonNull View itemView) {
-            super(itemView);
-        }
-    }
-
-    /**
-     * Holds views of {@link ContentListItemOEMV1}.
-     */
-    static class ListItemViewHolder extends ListItemAdapter.BaseViewHolder {
-        final TextView mTitle;
-        final TextView mBody;
-        final ImageView mIcon;
-        final ImageView mContentIcon;
-        final ImageView mAvatarIcon;
-        final ViewGroup mIconContainer;
-        final ViewGroup mActionContainer;
-        final View mActionDivider;
-        final Switch mSwitch;
-        final CheckBox mCheckBox;
-        final RadioButton mRadioButton;
-        final ImageView mSupplementalIcon;
-        final View mTouchInterceptor;
-        final View mReducedTouchInterceptor;
-        final View mActionContainerTouchInterceptor;
-
-        ListItemViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mTitle = itemView.requireViewById(R.id.list_item_title);
-            mBody = itemView.requireViewById(R.id.list_item_body);
-            mIcon = itemView.requireViewById(R.id.list_item_icon);
-            mContentIcon = itemView.requireViewById(R.id.list_item_content_icon);
-            mAvatarIcon = itemView.requireViewById(R.id.list_item_avatar_icon);
-            mIconContainer = itemView.requireViewById(R.id.list_item_icon_container);
-            mActionContainer = itemView.requireViewById(R.id.list_item_action_container);
-            mActionDivider = itemView.requireViewById(R.id.list_item_action_divider);
-            mSwitch = itemView.requireViewById(R.id.list_item_switch_widget);
-            mCheckBox = itemView.requireViewById(R.id.list_item_checkbox_widget);
-            mRadioButton = itemView.requireViewById(R.id.list_item_radio_button_widget);
-            mSupplementalIcon = itemView.requireViewById(R.id.list_item_supplemental_icon);
-            mReducedTouchInterceptor = itemView.requireViewById(
-                    R.id.list_item_reduced_touch_interceptor);
-            mTouchInterceptor = itemView.requireViewById(
-                    R.id.list_item_touch_interceptor);
-            mActionContainerTouchInterceptor = itemView.requireViewById(
-                    R.id.list_item_action_container_touch_interceptor);
-        }
-
-        void bind(@NonNull ContentListItemOEMV1 item) {
-            if (item.getTitle() != null) {
-                mTitle.setText(item.getTitle());
-                mTitle.setVisibility(View.VISIBLE);
-            } else {
-                mTitle.setVisibility(View.GONE);
-            }
-
-            if (item.getBody() != null) {
-                mBody.setText(TextUtils.join("\n", item.getBody()));
-                mBody.setVisibility(View.VISIBLE);
-            } else {
-                mBody.setVisibility(View.GONE);
-            }
-
-            mIcon.setVisibility(View.GONE);
-            mContentIcon.setVisibility(View.GONE);
-            mAvatarIcon.setVisibility(View.GONE);
-
-            Drawable icon = item.getIcon();
-            if (icon != null) {
-                mIconContainer.setVisibility(View.VISIBLE);
-
-                switch (item.getPrimaryIconType()) {
-                    case CONTENT:
-                        mContentIcon.setVisibility(View.VISIBLE);
-                        mContentIcon.setImageDrawable(icon);
-                        break;
-                    case STANDARD:
-                        mIcon.setVisibility(View.VISIBLE);
-                        mIcon.setImageDrawable(icon);
-                        break;
-                    case AVATAR:
-                        mAvatarIcon.setVisibility(View.VISIBLE);
-                        mAvatarIcon.setImageDrawable(icon);
-                        mAvatarIcon.setClipToOutline(true);
-                        break;
-                }
-            } else {
-                mIconContainer.setVisibility(View.GONE);
-            }
-
-            mActionDivider.setVisibility(
-                    item.isActionDividerVisible() ? View.VISIBLE : View.GONE);
-            mSwitch.setVisibility(View.GONE);
-            mCheckBox.setVisibility(View.GONE);
-            mRadioButton.setVisibility(View.GONE);
-            mSupplementalIcon.setVisibility(View.GONE);
-
-            Consumer<ContentListItemOEMV1> itemOnClickListener = item.getOnClickListener();
-
-            switch (item.getAction()) {
-                case NONE:
-                    mActionContainer.setVisibility(View.GONE);
-
-                    // Display ripple effects across entire item when clicked by using full-sized
-                    // touch interceptor.
-                    mTouchInterceptor.setVisibility(View.VISIBLE);
-                    mTouchInterceptor.setOnClickListener(v -> {
-                        if (itemOnClickListener != null) {
-                            itemOnClickListener.accept(item);
-                        }
-                    });
-                    mTouchInterceptor.setClickable(itemOnClickListener != null);
-                    mReducedTouchInterceptor.setVisibility(View.GONE);
-                    mActionContainerTouchInterceptor.setVisibility(View.GONE);
-                    break;
-                case SWITCH:
-                    bindCompoundButton(item, mSwitch, itemOnClickListener);
-                    break;
-                case CHECK_BOX:
-                    bindCompoundButton(item, mCheckBox, itemOnClickListener);
-                    break;
-                case RADIO_BUTTON:
-                    bindCompoundButton(item, mRadioButton, itemOnClickListener);
-                    break;
-                case CHEVRON:
-                    mSupplementalIcon.setVisibility(View.VISIBLE);
-                    mSupplementalIcon.setImageDrawable(itemView.getContext().getDrawable(
-                            R.drawable.icon_chevron));
-                    mActionContainer.setVisibility(View.VISIBLE);
-                    mTouchInterceptor.setVisibility(View.VISIBLE);
-                    mTouchInterceptor.setOnClickListener(v -> {
-                        if (itemOnClickListener != null) {
-                            itemOnClickListener.accept(item);
-                        }
-                    });
-                    mTouchInterceptor.setClickable(itemOnClickListener != null);
-                    mReducedTouchInterceptor.setVisibility(View.GONE);
-                    mActionContainerTouchInterceptor.setVisibility(View.GONE);
-                    break;
-                case ICON:
-                    mSupplementalIcon.setVisibility(View.VISIBLE);
-                    mSupplementalIcon.setImageDrawable(item.getSupplementalIcon());
-
-                    mActionContainer.setVisibility(View.VISIBLE);
-
-                    // If the icon has a click listener, use a reduced touch interceptor to create
-                    // two distinct touch area; the action container and the remainder of the list
-                    // item. Each touch area will have its own ripple effect. If the icon has no
-                    // click listener, it shouldn't be clickable.
-                    if (item.getSupplementalIconOnClickListener() == null) {
-                        mTouchInterceptor.setVisibility(View.VISIBLE);
-                        mTouchInterceptor.setOnClickListener(v -> {
-                            if (itemOnClickListener != null) {
-                                itemOnClickListener.accept(item);
-                            }
-                        });
-                        mTouchInterceptor.setClickable(itemOnClickListener != null);
-                        mReducedTouchInterceptor.setVisibility(View.GONE);
-                        mActionContainerTouchInterceptor.setVisibility(View.GONE);
-                    } else {
-                        mReducedTouchInterceptor.setVisibility(View.VISIBLE);
-                        mReducedTouchInterceptor.setOnClickListener(v -> {
-                            if (itemOnClickListener != null) {
-                                itemOnClickListener.accept(item);
-                            }
-                        });
-                        mReducedTouchInterceptor.setClickable(itemOnClickListener != null);
-                        mActionContainerTouchInterceptor.setVisibility(View.VISIBLE);
-                        mActionContainerTouchInterceptor.setOnClickListener(
-                                (container) -> {
-                                    if (item.getSupplementalIconOnClickListener() != null) {
-                                        item.getSupplementalIconOnClickListener().accept(item);
-                                    }
-                                });
-                        mActionContainerTouchInterceptor.setClickable(
-                                item.getSupplementalIconOnClickListener() != null);
-                        mTouchInterceptor.setVisibility(View.GONE);
-                    }
-                    break;
-                default:
-                    throw new IllegalStateException("Unknown secondary action type.");
-            }
-
-            itemView.setActivated(item.isActivated());
-            setEnabled(itemView, item.isEnabled());
-        }
-
-        void setEnabled(View view, boolean enabled) {
-            view.setEnabled(enabled);
-            if (view instanceof ViewGroup) {
-                ViewGroup group = (ViewGroup) view;
-
-                for (int i = 0; i < group.getChildCount(); i++) {
-                    setEnabled(group.getChildAt(i), enabled);
-                }
-            }
-        }
-
-        void bindCompoundButton(@NonNull ContentListItemOEMV1 item,
-                @NonNull CompoundButton compoundButton,
-                @Nullable Consumer<ContentListItemOEMV1> itemOnClickListener) {
-            compoundButton.setVisibility(View.VISIBLE);
-            compoundButton.setOnCheckedChangeListener(null);
-            compoundButton.setChecked(item.isChecked());
-            compoundButton.setOnCheckedChangeListener(
-                    (buttonView, isChecked) -> item.setChecked(isChecked));
-
-            // Clicks anywhere on the item should toggle the checkbox state. Use full touch
-            // interceptor.
-            mTouchInterceptor.setVisibility(View.VISIBLE);
-            mTouchInterceptor.setOnClickListener(v -> {
-                compoundButton.toggle();
-                if (itemOnClickListener != null) {
-                    itemOnClickListener.accept(item);
-                }
-            });
-            // Compound button list items should always be clickable
-            mTouchInterceptor.setClickable(true);
-            mReducedTouchInterceptor.setVisibility(View.GONE);
-            mActionContainerTouchInterceptor.setVisibility(View.GONE);
-
-            mActionContainer.setVisibility(View.VISIBLE);
-            mActionContainer.setClickable(false);
-        }
-
-        @Override
-        public View getItemView() {
-            return super.itemView;
-        }
-    }
-
-    /**
-     * Holds views of {@link HeaderListItemOEMV1}.
-     */
-    static class HeaderViewHolder extends ListItemAdapter.BaseViewHolder {
-        private final TextView mTitle;
-        private final TextView mBody;
-
-        HeaderViewHolder(@NonNull View itemView) {
-            super(itemView);
-            mTitle = itemView.requireViewById(R.id.list_item_title);
-            mBody = itemView.requireViewById(R.id.list_item_body);
-        }
-
-        private void bind(@NonNull HeaderListItemOEMV1 item) {
-            mTitle.setText(item.getTitle());
-
-            CharSequence body = item.getBody();
-            if (!TextUtils.isEmpty(body)) {
-                mBody.setText(body);
-            } else {
-                mBody.setVisibility(View.GONE);
-            }
-        }
-
-        @Override
-        public View getItemView() {
-            return super.itemView;
-        }
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/RecyclerViewImpl.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/RecyclerViewImpl.java
deleted file mode 100644
index f8c4d6a..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/recyclerview/RecyclerViewImpl.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.recyclerview;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.AdapterOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.LayoutStyleOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.OnScrollListenerOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewAttributesOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.recyclerview.RecyclerViewOEMV1;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Reference OEM implementation for RecyclerView
- */
-public final class RecyclerViewImpl extends RecyclerView implements RecyclerViewOEMV1 {
-
-    @NonNull
-    private List<OnScrollListenerOEMV1> mScrollListeners = new ArrayList<>();
-
-    @NonNull
-    private RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
-        @Override
-        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
-            for (OnScrollListenerOEMV1 listener: mScrollListeners) {
-                listener.onScrolled((RecyclerViewOEMV1) recyclerView, dx, dy);
-            }
-        }
-
-        @Override
-        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
-            for (OnScrollListenerOEMV1 listener: mScrollListeners) {
-                listener.onScrollStateChanged((RecyclerViewOEMV1) recyclerView, newState);
-            }
-        }
-    };
-
-    public RecyclerViewImpl(@NonNull Context context) {
-        super(context);
-    }
-
-    public RecyclerViewImpl(Context context, RecyclerViewAttributesOEMV1 attrs) {
-        super(context);
-        setLayoutStyle(attrs.getLayoutStyle());
-    }
-
-    @Override
-    public void setAdapter(AdapterOEMV1 adapterV1) {
-        if (adapterV1 == null) {
-            super.setAdapter(null);
-        } else {
-            super.setAdapter(new AdapterWrapper(adapterV1));
-        }
-    }
-
-    @Override
-    public void addOnScrollListener(OnScrollListenerOEMV1 listener) {
-        if (listener == null) {
-            return;
-        }
-        if (mScrollListeners.isEmpty()) {
-            super.addOnScrollListener(mOnScrollListener);
-        }
-        mScrollListeners.add(listener);
-    }
-
-    @Override
-    public void removeOnScrollListener(OnScrollListenerOEMV1 listener) {
-        if (listener == null) {
-            return;
-        }
-        mScrollListeners.remove(listener);
-        if (mScrollListeners.isEmpty()) {
-            super.removeOnScrollListener(mOnScrollListener);
-        }
-    }
-
-    @Override
-    public void clearOnScrollListeners() {
-        if (mScrollListeners != null) {
-            mScrollListeners.clear();
-            super.clearOnScrollListeners();
-        }
-    }
-
-    @Override
-    public void scrollToPosition(int position) {
-        super.scrollToPosition(position);
-    }
-
-    @Override
-    public void smoothScrollBy(int dx, int dy) {
-        super.smoothScrollBy(dx, dy);
-    }
-
-    @Override
-    public void smoothScrollToPosition(int position) {
-        super.smoothScrollToPosition(position);
-    }
-
-    @Override
-    public void setHasFixedSize(boolean hasFixedSize) {
-        super.setHasFixedSize(hasFixedSize);
-    }
-
-    @Override
-    public boolean hasFixedSize() {
-        return super.hasFixedSize();
-    }
-
-    @Override
-    public void setLayoutStyle(LayoutStyleOEMV1 layoutStyle) {
-        if (layoutStyle.getLayoutType() == LayoutStyleOEMV1.LAYOUT_TYPE_LINEAR) {
-            setLayoutManager(new LinearLayoutManager(getContext(),
-                    layoutStyle.getOrientation(),
-                    layoutStyle.getReverseLayout()));
-        } else {
-            setLayoutManager(new GridLayoutManager(getContext(),
-                    layoutStyle.getSpanCount(),
-                    layoutStyle.getOrientation(),
-                    layoutStyle.getReverseLayout()));
-            if (layoutStyle.getSpanSizeLookup() != null) {
-                ((GridLayoutManager) getLayoutManager()).setSpanSizeLookup(new SpanSizeLookup() {
-                    @Override
-                    public int getSpanSize(int position) {
-                        return layoutStyle.getSpanSizeLookup().getSpanSize(position);
-                    }
-                });
-            }
-        }
-    }
-
-    public View getView() {
-        return this;
-    }
-
-    @Override
-    public View getContainer() {
-        return this;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/BaseLayoutInstaller.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/BaseLayoutInstaller.java
deleted file mode 100644
index e5dcb80..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/BaseLayoutInstaller.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-
-import androidx.annotation.LayoutRes;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.sharedlibrary.oemapis.FocusAreaOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.FocusParkingViewOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.InsetsOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * A helper class for implementing installBaseLayoutAround from
- * {@link com.android.car.ui.sharedlibrary.oemapis.SharedLibraryFactoryOEMV1}
- */
-@SuppressWarnings("AndroidJdkLibsChecker")
-public class BaseLayoutInstaller {
-    /**
-     * Implementation of installBaseLayoutAround from
-     * {@link com.android.car.ui.sharedlibrary.oemapis.SharedLibraryFactoryOEMV1}
-     */
-    public static ToolbarControllerOEMV1 installBaseLayoutAround(
-            Context sharedLibraryContext,
-            View contentView,
-            Consumer<InsetsOEMV1> insetsChangedListener,
-            boolean toolbarEnabled,
-            boolean fullscreen,
-            @Nullable Function<Context, FocusParkingViewOEMV1> focusParkingViewFactory,
-            @Nullable Function<Context, FocusAreaOEMV1> focusAreaFactory) {
-
-        Context activityContext = contentView.getContext();
-
-        // Add the configuration from the activity context to the shared library context,
-        // or else when inflating views with the shared library context, they won't have access
-        // to stuff like the screen size. It will also cause a StrictMode violation without this.
-        sharedLibraryContext = sharedLibraryContext.createConfigurationContext(
-                activityContext.getResources().getConfiguration());
-
-        @LayoutRes int layout = toolbarEnabled
-                ? R.layout.base_layout_toolbar
-                : R.layout.base_layout;
-        FrameLayout baseLayout = (FrameLayout) LayoutInflater.from(sharedLibraryContext).inflate(
-                layout, null, false);
-
-        // Replace the app's content view with a base layout
-        ViewGroup contentViewParent = (ViewGroup) contentView.getParent();
-        int contentIndex = contentViewParent.indexOfChild(contentView);
-        contentViewParent.removeView(contentView);
-        contentViewParent.addView(baseLayout, contentIndex, contentView.getLayoutParams());
-
-        // Add the app's content view to the baseLayout's content view container
-        FrameLayout contentViewContainer = baseLayout.requireViewById(
-                R.id.base_layout_content_container);
-        contentViewContainer.addView(contentView, new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT));
-
-        // Add FocusParkingView to base layout.
-        // Make sure to use the application context here, not the shared library context,
-        // as the implementation of FocusParkingView/FocusArea is in the static car-ui-lib.
-        if (focusParkingViewFactory != null) {
-            View focusParkingView = focusParkingViewFactory.apply(activityContext).getView();
-            if (focusParkingView != null) {
-                baseLayout.addView(focusParkingView, 0,
-                        new FrameLayout.LayoutParams(
-                                ViewGroup.LayoutParams.WRAP_CONTENT,
-                                ViewGroup.LayoutParams.WRAP_CONTENT));
-            }
-        }
-
-        // Replace toolbar_background with a FocusArea.
-        // Note that FocusArea must be created like this, as opposed to using a custom
-        // layout inflater factory and specifying it in XML, because a LayoutInflater will
-        // use a parent view's context for creating all the child views. We have to create
-        // the FocusArea using the app's context, so that it can access it's resources,
-        // but we want children of the FocusArea to use the shared library context, so we can
-        // access shared library resources.
-        if (focusAreaFactory != null && toolbarEnabled) {
-            LinearLayout focusArea = focusAreaFactory.apply(activityContext).getView();
-            if (focusArea != null) {
-                View toolbar = baseLayout.requireViewById(R.id.toolbar_background);
-                int toolbarIndex = baseLayout.indexOfChild(toolbar);
-                baseLayout.removeView(toolbar);
-                baseLayout.addView(focusArea, toolbarIndex, toolbar.getLayoutParams());
-                focusArea.addView(toolbar, new LinearLayout.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-            }
-        }
-
-
-        ToolbarControllerOEMV1 toolbarController = null;
-        if (toolbarEnabled) {
-            toolbarController = new ToolbarControllerImpl(
-                    baseLayout, sharedLibraryContext, activityContext);
-        }
-
-        InsetsUpdater updater = new InsetsUpdater(baseLayout, contentView);
-        updater.replaceInsetsChangedListenerWith(insetsChangedListener);
-        updater.installListeners();
-
-        return toolbarController;
-    }
-
-    /**
-     * InsetsUpdater waits for layout changes, and when there is one, calculates the appropriate
-     * insets into the content view.
-     */
-    private static final class InsetsUpdater implements ViewTreeObserver.OnGlobalLayoutListener {
-        // These tags mark views that should overlay the content view in the base layout.
-        // Apps will then be able to draw under these views, but will be encouraged to not put
-        // any user-interactable content there.
-        private static final String LEFT_INSET_TAG = "shared_lib_left_inset";
-        private static final String RIGHT_INSET_TAG = "shared_lib_right_inset";
-        private static final String TOP_INSET_TAG = "shared_lib_top_inset";
-        private static final String BOTTOM_INSET_TAG = "shared_lib_bottom_inset";
-
-        private final View mContentView;
-        private final View mContentViewContainer; // Equivalent to mContentView except in Media
-        private final View mLeftInsetView;
-        private final View mRightInsetView;
-        private final View mTopInsetView;
-        private final View mBottomInsetView;
-        private Consumer<InsetsOEMV1> mInsetsChangedListenerDelegate;
-
-        private boolean mInsetsDirty = true;
-        private InsetsOEMV1 mInsets = new InsetsOEMV1();
-
-        /**
-         * Constructs an InsetsUpdater that calculates and dispatches insets to the method provided
-         * via {@link #replaceInsetsChangedListenerWith(Consumer)}.
-         *
-         * @param baseLayout  The root view of the base layout
-         * @param contentView The android.R.id.content View
-         */
-        InsetsUpdater(
-                View baseLayout,
-                View contentView) {
-            mContentView = contentView;
-            mContentViewContainer = baseLayout.requireViewById(R.id.base_layout_content_container);
-
-            mLeftInsetView = baseLayout.findViewWithTag(LEFT_INSET_TAG);
-            mRightInsetView = baseLayout.findViewWithTag(RIGHT_INSET_TAG);
-            mTopInsetView = baseLayout.findViewWithTag(TOP_INSET_TAG);
-            mBottomInsetView = baseLayout.findViewWithTag(BOTTOM_INSET_TAG);
-
-            final View.OnLayoutChangeListener layoutChangeListener =
-                    (View v, int left, int top, int right, int bottom,
-                            int oldLeft, int oldTop, int oldRight, int oldBottom) -> {
-                        if (left != oldLeft || top != oldTop
-                                || right != oldRight || bottom != oldBottom) {
-                            mInsetsDirty = true;
-                        }
-                    };
-
-            if (mLeftInsetView != null) {
-                mLeftInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            if (mRightInsetView != null) {
-                mRightInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            if (mTopInsetView != null) {
-                mTopInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            if (mBottomInsetView != null) {
-                mBottomInsetView.addOnLayoutChangeListener(layoutChangeListener);
-            }
-            contentView.addOnLayoutChangeListener(layoutChangeListener);
-            mContentViewContainer.addOnLayoutChangeListener(layoutChangeListener);
-        }
-
-        /**
-         * Install a global layout listener, during which the insets will be recalculated and
-         * dispatched.
-         */
-        public void installListeners() {
-            // The global layout listener will run after all the individual layout change listeners
-            // so that we only updateInsets once per layout, even if multiple inset views changed
-            mContentView.getRootView().getViewTreeObserver()
-                    .addOnGlobalLayoutListener(this);
-        }
-
-        InsetsOEMV1 getInsets() {
-            return mInsets;
-        }
-
-        // TODO remove this method / cleanup this class
-        public void replaceInsetsChangedListenerWith(Consumer<InsetsOEMV1> listener) {
-            mInsetsChangedListenerDelegate = listener;
-        }
-
-        /**
-         * onGlobalLayout() should recalculate the amount of insets we need, and then dispatch them.
-         */
-        @Override
-        public void onGlobalLayout() {
-            if (!mInsetsDirty) {
-                return;
-            }
-
-            // Calculate how much each inset view overlays the content view
-
-            // These initial values are for Media Center's implementation of base layouts.
-            // They should evaluate to 0 in all other apps, because the content view and content
-            // view container have the same size and position there.
-            int top = Math.max(0,
-                    getTopOfView(mContentViewContainer) - getTopOfView(mContentView));
-            int left = Math.max(0,
-                    getLeftOfView(mContentViewContainer) - getLeftOfView(mContentView));
-            int right = Math.max(0,
-                    getRightOfView(mContentView) - getRightOfView(mContentViewContainer));
-            int bottom = Math.max(0,
-                    getBottomOfView(mContentView) - getBottomOfView(mContentViewContainer));
-            if (mTopInsetView != null) {
-                top += Math.max(0,
-                        getBottomOfView(mTopInsetView) - getTopOfView(mContentViewContainer));
-            }
-            if (mBottomInsetView != null) {
-                bottom += Math.max(0,
-                        getBottomOfView(mContentViewContainer) - getTopOfView(mBottomInsetView));
-            }
-            if (mLeftInsetView != null) {
-                left += Math.max(0,
-                        getRightOfView(mLeftInsetView) - getLeftOfView(mContentViewContainer));
-            }
-            if (mRightInsetView != null) {
-                right += Math.max(0,
-                        getRightOfView(mContentViewContainer) - getLeftOfView(mRightInsetView));
-            }
-            InsetsOEMV1 insets = new InsetsOEMV1(left, top, right, bottom);
-
-            mInsetsDirty = false;
-            if (!insets.equals(mInsets)) {
-                mInsets = insets;
-                if (mInsetsChangedListenerDelegate != null) {
-                    mInsetsChangedListenerDelegate.accept(insets);
-                }
-            }
-        }
-
-        private static int getLeftOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[0];
-        }
-
-        private static int getRightOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[0] + v.getWidth();
-        }
-
-        private static int getTopOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[1];
-        }
-
-        private static int getBottomOfView(View v) {
-            int[] position = new int[2];
-            v.getLocationOnScreen(position);
-            return position[1] + v.getHeight();
-        }
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ClickBlockingView.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ClickBlockingView.java
deleted file mode 100644
index 77cc7f5..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ClickBlockingView.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-/**
- * A view that doesn't allow any touches to pass through it to views below.
- *
- * <p>Used in baselayouts to prevent clicking through the toolbar.
- */
-public class ClickBlockingView extends View {
-
-    private boolean mEatingTouch = false;
-    private boolean mEatingHover = false;
-
-    public ClickBlockingView(Context context) {
-        super(context);
-    }
-
-    public ClickBlockingView(Context context,
-            @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ClickBlockingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public ClickBlockingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        // Copied from androidx.appcompat.widget.Toolbar
-
-        // We always eat touch events, but should still respect the touch event dispatch
-        // contract. If the normal View implementation doesn't want the events, we'll just silently
-        // eat the rest of the gesture without reporting the events to the default implementation
-        // since that's what it expects.
-
-        final int action = ev.getActionMasked();
-        if (action == MotionEvent.ACTION_DOWN) {
-            mEatingTouch = false;
-        }
-
-        if (!mEatingTouch) {
-            final boolean handled = super.onTouchEvent(ev);
-            if (action == MotionEvent.ACTION_DOWN && !handled) {
-                mEatingTouch = true;
-            }
-        }
-
-        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
-            mEatingTouch = false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean onHoverEvent(MotionEvent ev) {
-        // Copied from androidx.appcompat.widget.Toolbar
-
-        // Same deal as onTouchEvent() above. Eat all hover events, but still
-        // respect the touch event dispatch contract.
-
-        final int action = ev.getActionMasked();
-        if (action == MotionEvent.ACTION_HOVER_ENTER) {
-            mEatingHover = false;
-        }
-
-        if (!mEatingHover) {
-            final boolean handled = super.onHoverEvent(ev);
-            if (action == MotionEvent.ACTION_HOVER_ENTER && !handled) {
-                mEatingHover = true;
-            }
-        }
-
-        if (action == MotionEvent.ACTION_HOVER_EXIT || action == MotionEvent.ACTION_CANCEL) {
-            mEatingHover = false;
-        }
-
-        return true;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/MenuItemView.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/MenuItemView.java
deleted file mode 100644
index 2831d22..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/MenuItemView.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.MenuItemOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-import com.chassis.car.ui.sharedlibrary.uxr.DrawableStateView;
-
-class MenuItemView extends FrameLayout {
-    private static final int[] RESTRICTED_STATE = new int[] {R.attr.state_ux_restricted};
-    private static final int[] ENABLED_STATE = new int[] {android.R.attr.state_enabled};
-
-    private final MenuItemOEMV1 mMenuItem;
-
-    private final View mIconContainer;
-    private final ImageView mIconView;
-    private final Switch mSwitch;
-    private final TextView mTextView;
-    private final TextView mTextWithIconView;
-
-    private final int mMenuItemIconSize;
-
-    MenuItemView(
-            @NonNull Context context,
-            MenuItemOEMV1 menuItem) {
-        super(context);
-        mMenuItemIconSize = getResources().getDimensionPixelSize(R.dimen.primary_icon_size);
-
-        setVisibility(View.GONE);
-
-        LayoutInflater.from(getContext()).inflate(menuItem.isPrimary()
-                ? R.layout.toolbar_menu_item_primary
-                : R.layout.toolbar_menu_item, this, true);
-
-        mIconContainer = requireViewById(R.id.car_ui_toolbar_menu_item_icon_container);
-        mIconView = requireViewById(R.id.car_ui_toolbar_menu_item_icon);
-        mSwitch = requireViewById(R.id.car_ui_toolbar_menu_item_switch);
-        mTextView = requireViewById(R.id.car_ui_toolbar_menu_item_text);
-        mTextWithIconView = requireViewById(R.id.car_ui_toolbar_menu_item_text_with_icon);
-
-        mMenuItem = menuItem;
-        mMenuItem.setUpdateListener(this::onMenuItemUpdated);
-        onMenuItemUpdated(mMenuItem);
-    }
-
-    public void onMenuItemUpdated(MenuItemOEMV1 menuItem) {
-        setId(mMenuItem.getId());
-
-        boolean hasIcon = mMenuItem.getIcon() != null;
-        boolean hasText = !TextUtils.isEmpty(mMenuItem.getTitle());
-        boolean textAndIcon = mMenuItem.isShowingIconAndTitle();
-        boolean checkable = mMenuItem.isCheckable();
-
-        if (!mMenuItem.isVisible() || (!checkable && !hasIcon && !hasText)) {
-            setVisibility(View.GONE);
-            return;
-        }
-        setVisibility(View.VISIBLE);
-        setContentDescription(mMenuItem.getTitle());
-
-        View clickTarget;
-        if (checkable) {
-            mSwitch.setChecked(mMenuItem.isChecked());
-            clickTarget = mSwitch;
-        } else if (hasText && hasIcon && textAndIcon) {
-            mMenuItem.getIcon().setBounds(0, 0, mMenuItemIconSize, mMenuItemIconSize);
-            mTextWithIconView.setCompoundDrawables(mMenuItem.getIcon(), null, null, null);
-            mTextWithIconView.setText(mMenuItem.getTitle());
-            clickTarget = mTextWithIconView;
-        } else if (hasIcon) {
-            mIconView.setImageDrawable(mMenuItem.getIcon());
-            clickTarget = mIconContainer;
-        } else { // hasText will be true
-            mTextView.setText(mMenuItem.getTitle());
-            clickTarget = mTextView;
-        }
-
-        mIconContainer.setVisibility(clickTarget == mIconContainer ? View.VISIBLE : View.GONE);
-        mTextView.setVisibility(clickTarget == mTextView ? View.VISIBLE : View.GONE);
-        mTextWithIconView.setVisibility(clickTarget == mTextWithIconView
-                ? View.VISIBLE : View.GONE);
-        mSwitch.setVisibility(clickTarget == mSwitch ? View.VISIBLE : View.GONE);
-
-        if (!mMenuItem.isTinted() && hasIcon) {
-            mMenuItem.getIcon().setTintList(null);
-        }
-
-        recursiveSetEnabledAndDrawableState(this);
-        setActivated(mMenuItem.isActivated());
-
-        clickTarget.setOnClickListener(v -> {
-            if (mMenuItem.isEnabled()) {
-                mMenuItem.performClick();
-            }
-        });
-    }
-
-    private void recursiveSetEnabledAndDrawableState(View view) {
-        int[] drawableState = mMenuItem.isRestricted() ? RESTRICTED_STATE : null;
-        int[] drawableStateToRemove = mMenuItem.isEnabled() ? null : ENABLED_STATE;
-
-        if (view instanceof DrawableStateView) {
-            ((DrawableStateView) view).setExtraDrawableState(drawableState, drawableStateToRemove);
-        }
-
-        if (view instanceof ViewGroup) {
-            ViewGroup viewGroup = ((ViewGroup) view);
-            for (int i = 0; i < viewGroup.getChildCount(); i++) {
-                recursiveSetEnabledAndDrawableState(viewGroup.getChildAt(i));
-            }
-        }
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/OnPrivateImeCommandEditText.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/OnPrivateImeCommandEditText.java
deleted file mode 100644
index 07bd2fc..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/OnPrivateImeCommandEditText.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.widget.EditText;
-
-import java.util.function.BiConsumer;
-
-/**
- * This is a regular {@link EditText}, but with the addition of a
- * {@link #setOnPrivateImeCommandListener} argument. This allows listening to calls to
- * {@link android.widget.TextView#onPrivateIMECommand(String, Bundle)}.
- */
-public class OnPrivateImeCommandEditText extends EditText {
-
-    private BiConsumer<String, Bundle> mOnAppPrivateCommandListener;
-
-    public OnPrivateImeCommandEditText(Context context) {
-        super(context);
-    }
-
-    public OnPrivateImeCommandEditText(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public OnPrivateImeCommandEditText(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public OnPrivateImeCommandEditText(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    public boolean onPrivateIMECommand(String action, Bundle data) {
-        if (mOnAppPrivateCommandListener != null) {
-            mOnAppPrivateCommandListener.accept(action, data);
-        }
-        return false;
-    }
-
-    /**
-     * Sets a listener to be called when {@link #onPrivateIMECommand(String, Bundle)} is called.
-     */
-    public void setOnPrivateImeCommandListener(BiConsumer<String, Bundle> listener) {
-        mOnAppPrivateCommandListener = listener;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/OverflowMenuItem.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/OverflowMenuItem.java
deleted file mode 100644
index 301b235..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/OverflowMenuItem.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.MenuItemOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Consumer;
-
-class OverflowMenuItem implements MenuItemOEMV1 {
-
-    @NonNull
-    private final Context mSharedLibraryContext;
-
-    @NonNull
-    private final Context mActivityContext;
-
-    @NonNull
-    private List<? extends MenuItemOEMV1> mOverflowMenuItems = Collections.emptyList();
-
-    @Nullable
-    private Consumer<MenuItemOEMV1> mUpdateListener;
-
-    @Nullable
-    private Dialog mDialog;
-
-    OverflowMenuItem(
-            @NonNull Context sharedLibraryContext,
-            @NonNull Context activityContext) {
-        mSharedLibraryContext = sharedLibraryContext;
-        mActivityContext = activityContext;
-    }
-
-    public void setOverflowMenuItems(List<? extends MenuItemOEMV1> menuItems) {
-        mOverflowMenuItems = menuItems;
-
-        if (mDialog != null) {
-            mDialog.dismiss();
-            mDialog = null;
-        }
-
-        if (mUpdateListener != null) {
-            mUpdateListener.accept(this);
-        }
-    }
-
-    @Override
-    public void setUpdateListener(@Nullable Consumer<MenuItemOEMV1> listener) {
-        mUpdateListener = listener;
-    }
-
-    @Override
-    public void performClick() {
-        if (!isEnabled() || !isVisible()) {
-            return;
-        }
-
-        String[] titles = mOverflowMenuItems.stream()
-                .map(MenuItemOEMV1::getTitle)
-                .toArray(String[]::new);
-
-        mDialog = new AlertDialog.Builder(mActivityContext)
-                .setItems(titles, (dialog, which) -> {
-                    mOverflowMenuItems.get(which).performClick();
-                    dialog.dismiss();
-                }).create();
-        mDialog.show();
-    }
-
-    @Override
-    public int getId() {
-        return View.NO_ID;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-    @Override
-    public boolean isCheckable() {
-        return false;
-    }
-
-    @Override
-    public boolean isChecked() {
-        return false;
-    }
-
-    @Override
-    public boolean isTinted() {
-        return false;
-    }
-
-    @Override
-    public boolean isVisible() {
-        return mOverflowMenuItems.size() > 0;
-    }
-
-    @Override
-    public boolean isActivatable() {
-        return false;
-    }
-
-    @Override
-    public boolean isActivated() {
-        return false;
-    }
-
-    @Override
-    public String getTitle() {
-        return mSharedLibraryContext.getString(R.string.toolbar_menu_item_overflow_title);
-    }
-
-    @Override
-    public boolean isRestricted() {
-        return false;
-    }
-
-    @Override
-    public boolean isShowingIconAndTitle() {
-        return false;
-    }
-
-    @Override
-    public boolean isClickable() {
-        return true;
-    }
-
-    @Override
-    public int getDisplayBehavior() {
-        return MenuItemOEMV1.DISPLAY_BEHAVIOR_ALWAYS;
-    }
-
-    @Override
-    public Drawable getIcon() {
-        return mSharedLibraryContext.getDrawable(R.drawable.toolbar_menu_item_overflow);
-    }
-
-    @Override
-    public boolean isPrimary() {
-        return false;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ProgressBarController.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ProgressBarController.java
deleted file mode 100644
index f04ad13..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ProgressBarController.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.view.View;
-import android.widget.ProgressBar;
-
-import androidx.annotation.NonNull;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ProgressBarControllerOEMV1;
-
-class ProgressBarController implements ProgressBarControllerOEMV1 {
-    private final ProgressBar mProgressBar;
-
-    ProgressBarController(@NonNull ProgressBar progressBar) {
-        mProgressBar = progressBar;
-    }
-
-    @Override
-    public void setVisible(boolean visible) {
-        mProgressBar.setVisibility(visible ? View.VISIBLE : View.GONE);
-    }
-
-    @Override
-    public void setIndeterminate(boolean indeterminate) {
-        mProgressBar.setIndeterminate(indeterminate);
-    }
-
-    @Override
-    public void setMax(int max) {
-        mProgressBar.setMax(max);
-    }
-
-    @Override
-    public void setMin(int min) {
-        mProgressBar.setMin(min);
-    }
-
-    @Override
-    public void setProgress(int progress) {
-        mProgressBar.setProgress(progress);
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/SearchController.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/SearchController.java
deleted file mode 100644
index 47d255a..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/SearchController.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewStub;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-
-import java.util.Objects;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-class SearchController {
-
-    @NonNull
-    private final InputMethodManager mInputMethodManager;
-
-    @NonNull
-    private final ViewStub mStub;
-    private View mInflatedView;
-    private ImageView mSearchIconView;
-    private OnPrivateImeCommandEditText mEditText;
-    private View mCloseIcon;
-
-    private int mStartPaddingWithoutIcon;
-    private int mStartPadding;
-    private int mEndPadding;
-
-    private Drawable mSearchIcon;
-    @Nullable
-    private String mSearchQuery;
-    private String mSearchHint;
-
-    @Nullable
-    private Consumer<String> mSearchListener = null;
-    @Nullable
-    private Runnable mSearchCompletedListener = null;
-
-    @Nullable
-    private Consumer<TextView> mSearchTextViewConsumer;
-    @Nullable
-    private BiConsumer<String, Bundle> mOnPrivateImeCommandListener;
-
-    private final TextWatcher mTextWatcher = new TextWatcher() {
-        @Override
-        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-        }
-
-        @Override
-        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-        }
-
-        @Override
-        public void afterTextChanged(Editable editable) {
-            onSearch(editable.toString());
-        }
-    };
-
-    SearchController(@NonNull ViewStub searchStub) {
-        mInputMethodManager = Objects.requireNonNull((InputMethodManager)
-                searchStub.getContext().getSystemService(Context.INPUT_METHOD_SERVICE));
-        mStub = Objects.requireNonNull(searchStub);
-        mSearchIcon = getDrawable(R.drawable.icon_search);
-        mSearchHint = mStub.getContext().getString(R.string.toolbar_default_search_hint);
-    }
-
-    public void setSearchTextViewConsumer(@Nullable Consumer<TextView> textViewConsumer) {
-        mSearchTextViewConsumer = textViewConsumer;
-        if (mEditText != null && textViewConsumer != null) {
-            mSearchTextViewConsumer.accept(mEditText);
-        }
-    }
-
-    public void setOnPrivateImeCommandListener(
-            @Nullable BiConsumer<String, Bundle> onPrivateImeCommandListener) {
-        mOnPrivateImeCommandListener = onPrivateImeCommandListener;
-        if (mEditText != null) {
-            mEditText.setOnPrivateImeCommandListener(mOnPrivateImeCommandListener);
-        }
-    }
-
-    public void setSearchMode(int searchMode) {
-        if (searchMode != ToolbarControllerOEMV1.SEARCH_MODE_DISABLED && mInflatedView == null) {
-            mInflatedView = mStub.inflate();
-            mSearchIconView = mInflatedView.requireViewById(R.id.toolbar_search_icon);
-            mEditText = mInflatedView.requireViewById(R.id.toolbar_search_bar);
-            mCloseIcon = mInflatedView.requireViewById(R.id.toolbar_search_close);
-            if (mSearchTextViewConsumer != null) {
-                mSearchTextViewConsumer.accept(mEditText);
-            }
-            mEditText.setOnPrivateImeCommandListener(mOnPrivateImeCommandListener);
-
-            mInflatedView.setVisibility(View.GONE); // So our later check if it's showing will pass
-            mSearchIconView.setImageDrawable(mSearchIcon);
-            mEditText.setSaveEnabled(false);
-            mEditText.setText(mSearchQuery);
-            mEditText.setHint(mSearchHint);
-
-            mEditText.setOnClickListener(view -> mInputMethodManager.showSoftInput(view, 0));
-            mEditText.setOnFocusChangeListener(
-                    (view, hasFocus) -> {
-                        if (!hasFocus) {
-                            mInputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
-                        }
-                    });
-            mEditText.addTextChangedListener(mTextWatcher);
-            mEditText.setOnEditorActionListener((v, actionId, event) -> {
-                if (actionId == EditorInfo.IME_ACTION_DONE
-                        || actionId == EditorInfo.IME_ACTION_SEARCH) {
-                    mEditText.clearFocus();
-                    if (mSearchCompletedListener != null) {
-                        mSearchCompletedListener.run();
-                    }
-                } else if (isEnter(event)) {
-                    if (event.getAction() == KeyEvent.ACTION_UP) {
-                        // Note that we want to trigger search only on ACTION_UP, but want to return
-                        // true for all actions for the relevant key event.
-                        mEditText.clearFocus();
-                        if (mSearchCompletedListener != null) {
-                            mSearchCompletedListener.run();
-                        }
-                    }
-                    return true;
-                }
-                return false;
-            });
-            mCloseIcon.setVisibility(TextUtils.isEmpty(mSearchQuery) ? View.GONE : View.VISIBLE);
-            mCloseIcon.setOnClickListener(view -> {
-                mEditText.getText().clear();
-                mEditText.requestFocus();
-                mInputMethodManager.showSoftInput(mEditText, 0);
-            });
-
-            Resources resources = mEditText.getContext().getResources();
-            mStartPaddingWithoutIcon = mEditText.getPaddingStart();
-            mStartPadding = resources.getDimensionPixelSize(
-                    R.dimen.toolbar_search_icon_container_width);
-            mEndPadding = resources.getDimensionPixelSize(
-                    R.dimen.toolbar_search_close_icon_container_width);
-            mEditText.setPaddingRelative(mStartPadding, 0, mEndPadding, 0);
-        }
-
-        boolean showingSearch = !mInflatedView.isShown()
-                && searchMode != ToolbarControllerOEMV1.SEARCH_MODE_DISABLED;
-
-        switch (searchMode) {
-            case ToolbarControllerOEMV1.SEARCH_MODE_DISABLED:
-                mInflatedView.setVisibility(View.GONE);
-                break;
-            case ToolbarControllerOEMV1.SEARCH_MODE_SEARCH:
-                mInflatedView.setVisibility(View.VISIBLE);
-                mEditText.setPaddingRelative(mStartPadding, 0, mEndPadding, 0);
-                mEditText.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
-                mSearchIconView.setImageDrawable(mSearchIcon);
-                mSearchIconView.setVisibility(View.VISIBLE);
-                break;
-            case ToolbarControllerOEMV1.SEARCH_MODE_EDIT:
-                mInflatedView.setVisibility(View.VISIBLE);
-                mEditText.setPaddingRelative(mStartPaddingWithoutIcon, 0, mEndPadding, 0);
-                mEditText.setImeOptions(EditorInfo.IME_ACTION_DONE);
-                mSearchIconView.setVisibility(View.GONE);
-                break;
-        }
-
-        if (showingSearch && mEditText.isShown()) {
-            mEditText.requestFocus();
-            mInputMethodManager.showSoftInput(mEditText, 0);
-        }
-    }
-
-    public void setSearchIcon(@Nullable Drawable drawable) {
-        if (drawable == null) {
-            mSearchIcon = getDrawable(R.drawable.icon_search);
-        } else {
-            mSearchIcon = drawable;
-        }
-
-        if (mSearchIconView != null) {
-            mSearchIconView.setImageDrawable(mSearchIcon);
-        }
-    }
-
-    public void setSearchHint(@Nullable String hint) {
-        if (hint == null) {
-            hint = mStub.getContext().getString(R.string.toolbar_default_search_hint);
-        }
-        mSearchHint = hint;
-
-        if (mEditText != null) {
-            mEditText.setHint(hint);
-        }
-    }
-
-    public void setSearchQuery(@Nullable String query) {
-        mSearchQuery = query;
-
-        if (mEditText != null) {
-            mEditText.setText(query);
-        }
-    }
-
-    public void setSearchListener(@Nullable Consumer<String> listener) {
-        mSearchListener = listener;
-    }
-
-    public void setSearchCompletedListener(@Nullable Runnable listener) {
-        mSearchCompletedListener = listener;
-    }
-
-    private void onSearch(@Nullable String query) {
-        mCloseIcon.setVisibility(TextUtils.isEmpty(query) ? View.GONE : View.VISIBLE);
-
-        if (query == null) {
-            query = "";
-        }
-
-        if (mSearchListener != null) {
-            mSearchListener.accept(query);
-        }
-    }
-
-    @NonNull
-    private Drawable getDrawable(@DrawableRes int resId) {
-        return Objects.requireNonNull(ContextCompat.getDrawable(mStub.getContext(), resId));
-    }
-
-    private boolean isEnter(KeyEvent event) {
-        boolean result = false;
-        if (event != null) {
-            int keyCode = event.getKeyCode();
-            result = keyCode == KeyEvent.KEYCODE_ENTER
-                    || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER
-                    || keyCode == KeyEvent.KEYCODE_SEARCH;
-        }
-        return result;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/TabLayout.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/TabLayout.java
deleted file mode 100644
index 868193d..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/TabLayout.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.TabOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A view that can show tabs via the {@link #setTabs(List, int)} method.
- */
-public class TabLayout extends LinearLayout {
-    private List<? extends TabOEMV1> mTabs = new ArrayList<>();
-    private TabOEMV1 mSelectedTab;
-    private final Map<TabOEMV1, View> mTabViews = new HashMap<>();
-
-    public TabLayout(Context context) {
-        super(context);
-    }
-
-    public TabLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public TabLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    /**
-     * Sets a list of tabs to show.
-     *
-     * @param tabs The tabs to show.
-     * @param selectedTab Which tab is selected.
-     */
-    public void setTabs(@NonNull List<? extends TabOEMV1> tabs, int selectedTab) {
-        removeAllViews();
-        mTabViews.clear();
-        mSelectedTab = null;
-        mTabs = tabs;
-
-        if (tabs.size() > 0) {
-            mSelectedTab = tabs.get(selectedTab);
-            for (TabOEMV1 tab : tabs) {
-                View view = LayoutInflater.from(getContext())
-                        .inflate(R.layout.toolbar_tab, this, false);
-                addView(view);
-                mTabViews.put(tab, view);
-                bindTab(tab);
-            }
-        }
-    }
-
-    private void bindTab(TabOEMV1 tab) {
-        View view = mTabViews.get(tab);
-        if (view == null) {
-            return;
-        }
-
-        ImageView iconView = view.requireViewById(R.id.car_ui_toolbar_tab_item_icon);
-        TextView textView = view.requireViewById(R.id.car_ui_toolbar_tab_item_text);
-
-        view.setOnClickListener(v -> selectTab(tab, true));
-        iconView.setImageDrawable(tab.getIcon());
-        textView.setText(tab.getTitle());
-
-        boolean selected = tab == mSelectedTab;
-        view.setActivated(selected);
-        textView.setTextAppearance(selected
-                ? R.style.TextAppearance_CarUi_Widget_Toolbar_Tab_Selected
-                : R.style.TextAppearance_CarUi_Widget_Toolbar_Tab);
-    }
-
-    /**
-     * Selects a particular tab.
-     */
-    private void selectTab(TabOEMV1 tab, boolean sendCallback) {
-        if (mSelectedTab == tab) {
-            return;
-        }
-
-        TabOEMV1 oldSelectedTab = mSelectedTab;
-        mSelectedTab = tab;
-        bindTab(oldSelectedTab);
-        bindTab(mSelectedTab);
-
-        Runnable onSelectedListener = tab.getOnSelectedListener();
-        if (onSelectedListener != null && sendCallback) {
-            onSelectedListener.run();
-        }
-    }
-
-    /**
-     * Selects a particular tab by its position in the list.
-     */
-    public void selectTab(int position, boolean sendCallback) {
-        selectTab(mTabs.get(position), sendCallback);
-    }
-
-    /**
-     * Returns if this TabLayout has at least one tab.
-     */
-    public boolean hasTabs() {
-        return mTabs != null && mTabs.size() > 0;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ToolbarControllerImpl.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ToolbarControllerImpl.java
deleted file mode 100644
index fdecb60..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/toolbar/ToolbarControllerImpl.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.toolbar;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ImeSearchInterfaceOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.MenuItemOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ProgressBarControllerOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.TabOEMV1;
-import com.android.car.ui.sharedlibrary.oemapis.toolbar.ToolbarControllerOEMV1;
-
-import com.chassis.car.ui.sharedlibrary.R;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-@SuppressWarnings("AndroidJdkLibsChecker")
-class ToolbarControllerImpl implements ToolbarControllerOEMV1 {
-
-    private final Context mSharedLibraryContext;
-    private final ImageView mBackButtonView;
-    private final TextView mTitleView;
-    private final TextView mSubtitleView;
-    private final ImageView mLogo;
-    private final ImageView mLogoInNavIconSpace;
-    private final ProgressBarController mProgressBar;
-    private final TabLayout mTabContainer;
-    private final ViewGroup mMenuItemsContainer;
-    private final SearchController mSearchController;
-    private final ViewGroup mNavIconContainer;
-
-    private final boolean mTitleAndTabsMutuallyExclusive;
-    private final boolean mLogoFillsNavSpace;
-    private final boolean mNavIconSpaceReserved;
-
-    private Runnable mBackListener;
-
-    private boolean mBackButtonVisible = false;
-    private boolean mHasLogo = false;
-    private int mSearchMode = ToolbarControllerOEMV1.SEARCH_MODE_DISABLED;
-    private final OverflowMenuItem mOverflowMenuItem;
-
-
-    ToolbarControllerImpl(View view, Context sharedLibraryContext, Context activityContext) {
-        mSharedLibraryContext = sharedLibraryContext;
-        mBackButtonView = view.requireViewById(R.id.toolbar_nav_icon);
-        mNavIconContainer = view.requireViewById(R.id.toolbar_nav_icon_container);
-        mTitleView = view.requireViewById(R.id.toolbar_title);
-        mSubtitleView = view.requireViewById(R.id.toolbar_subtitle);
-        mLogo = view.requireViewById(R.id.toolbar_title_logo);
-        mLogoInNavIconSpace = view.requireViewById(R.id.toolbar_logo);
-        mProgressBar = new ProgressBarController(
-                view.requireViewById(R.id.toolbar_progress_bar));
-        mTabContainer = view.requireViewById(R.id.toolbar_tabs);
-        mMenuItemsContainer = view.requireViewById(R.id.toolbar_menu_items_container);
-        mSearchController = new SearchController(
-                view.requireViewById(R.id.toolbar_search_view_stub));
-        mOverflowMenuItem = new OverflowMenuItem(sharedLibraryContext, activityContext);
-
-        mTitleAndTabsMutuallyExclusive = sharedLibraryContext.getResources()
-                .getBoolean(R.bool.toolbar_title_and_tabs_mutually_exclusive);
-        mLogoFillsNavSpace = sharedLibraryContext.getResources()
-                .getBoolean(R.bool.toolbar_logo_fills_nav_icon_space);
-        mNavIconSpaceReserved = sharedLibraryContext.getResources()
-                .getBoolean(R.bool.toolbar_nav_icon_space_reserved);
-    }
-
-    @Override
-    public void setTitle(String title) {
-        boolean hadTitle = !TextUtils.isEmpty(getTitle());
-        mTitleView.setText(title);
-        boolean hasTitle = !TextUtils.isEmpty(getTitle());
-
-        if (hadTitle != hasTitle) {
-            update();
-        }
-    }
-
-    private CharSequence getTitle() {
-        return mTitleView.getText();
-    }
-
-    @Override
-    public void setSubtitle(String title) {
-        boolean hadSubtitle = !TextUtils.isEmpty(getSubtitle());
-        mSubtitleView.setText(title);
-        boolean hasSubtitle = !TextUtils.isEmpty(getSubtitle());
-
-        if (hadSubtitle != hasSubtitle) {
-            update();
-        }
-    }
-
-    private CharSequence getSubtitle() {
-        return mSubtitleView.getText();
-    }
-
-    @Override
-    public void setTabs(List<? extends TabOEMV1> tabs, int selectedTab) {
-        if (tabs == null) {
-            tabs = Collections.emptyList();
-        }
-
-        boolean hadTabs = mTabContainer.hasTabs();
-        mTabContainer.setTabs(tabs, selectedTab);
-        boolean hasTabs = mTabContainer.hasTabs();
-
-        if (hadTabs != hasTabs) {
-            update();
-        }
-    }
-
-    @Override
-    public void selectTab(int position, boolean sendCallback) {
-        mTabContainer.selectTab(position, sendCallback);
-    }
-
-    @Override
-    public void setLogo(Drawable drawable) {
-        mLogo.setImageDrawable(drawable);
-        mLogoInNavIconSpace.setImageDrawable(drawable);
-
-        boolean hasLogo = drawable != null;
-        if (hasLogo != mHasLogo) {
-            mHasLogo = hasLogo;
-            update();
-        }
-    }
-
-    @Override
-    public void setSearchHint(@Nullable String hint) {
-        mSearchController.setSearchHint(hint);
-    }
-
-    @Override
-    public void setSearchIcon(@Nullable Drawable d) {
-        mSearchController.setSearchIcon(d);
-    }
-
-    @Override
-    public void setSearchQuery(@Nullable String query) {
-        mSearchController.setSearchQuery(query);
-    }
-
-    @Override
-    public void setSearchMode(int searchMode) {
-        if (mSearchMode != searchMode) {
-            mSearchMode = searchMode;
-            mSearchController.setSearchMode(searchMode);
-            update();
-        }
-    }
-
-    @Override
-    public ImeSearchInterfaceOEMV1 getImeSearchInterface() {
-        return new ImeSearchInterfaceOEMV1() {
-            @Override
-            public void setSearchTextViewConsumer(Consumer<TextView> textViewConsumer) {
-                mSearchController.setSearchTextViewConsumer(textViewConsumer);
-            }
-
-            @Override
-            public void setOnPrivateImeCommandListener(
-                    BiConsumer<String, Bundle> onPrivateImeCommandListener) {
-                mSearchController.setOnPrivateImeCommandListener(onPrivateImeCommandListener);
-            }
-        };
-    }
-
-    @Override
-    public void setNavButtonMode(int mode) {
-        boolean visible = mode != NAV_BUTTON_MODE_DISABLED;
-        if (visible != mBackButtonVisible) {
-            mBackButtonVisible = visible;
-            mNavIconContainer.setOnClickListener(mBackButtonVisible ? v -> {
-                if (mBackListener != null) {
-                    mBackListener.run();
-                }
-            } : null);
-            mNavIconContainer.setClickable(mBackButtonVisible);
-
-            mNavIconContainer.setContentDescription(mBackButtonVisible
-                    ? mSharedLibraryContext
-                        .getString(R.string.toolbar_nav_icon_content_description)
-                    : null);
-            update();
-        }
-
-        switch (mode) {
-            case ToolbarControllerOEMV1.NAV_BUTTON_MODE_CLOSE:
-                mBackButtonView.setImageResource(R.drawable.icon_close);
-                break;
-            case ToolbarControllerOEMV1.NAV_BUTTON_MODE_DOWN:
-                mBackButtonView.setImageResource(R.drawable.icon_down);
-                break;
-            default:
-                mBackButtonView.setImageResource(R.drawable.icon_back);
-                break;
-        }
-    }
-
-    @Override
-    public void setMenuItems(List<? extends MenuItemOEMV1> menuItems) {
-        if (menuItems == null) {
-            menuItems = Collections.emptyList();
-        }
-
-        List<? extends MenuItemOEMV1> overflowMenuItems = menuItems.stream()
-                .filter(i -> i.getDisplayBehavior() != MenuItemOEMV1.DISPLAY_BEHAVIOR_ALWAYS)
-                .collect(Collectors.toList());
-
-        List<? extends MenuItemOEMV1> regularMenuItems = Stream.concat(
-                menuItems.stream(),
-                Stream.of(mOverflowMenuItem))
-                .filter(i -> i.getDisplayBehavior() == MenuItemOEMV1.DISPLAY_BEHAVIOR_ALWAYS)
-                .collect(Collectors.toList());
-
-        mOverflowMenuItem.setOverflowMenuItems(overflowMenuItems);
-
-        mMenuItemsContainer.removeAllViews();
-        for (MenuItemOEMV1 menuItem : regularMenuItems) {
-            MenuItemView menuItemView = new MenuItemView(mSharedLibraryContext, menuItem);
-            mMenuItemsContainer.addView(menuItemView,
-                    new LinearLayout.LayoutParams(
-                            LinearLayout.LayoutParams.WRAP_CONTENT,
-                            LinearLayout.LayoutParams.WRAP_CONTENT));
-        }
-    }
-
-    @Override
-    public void setSearchListener(@Nullable Consumer<String> listener) {
-        mSearchController.setSearchListener(listener);
-    }
-
-    @Override
-    public void setSearchCompletedListener(@Nullable Runnable listener) {
-        mSearchController.setSearchCompletedListener(listener);
-    }
-
-    @Override
-    public void setBackListener(Runnable listener) {
-        mBackListener = listener;
-    }
-
-    @Override
-    public ProgressBarControllerOEMV1 getProgressBar() {
-        return mProgressBar;
-    }
-
-    private void update() {
-        boolean isSearching = mSearchMode != ToolbarControllerOEMV1.SEARCH_MODE_DISABLED;
-        boolean hasTabs = mTabContainer.hasTabs();
-
-        setVisible(mBackButtonView, mBackButtonVisible);
-        boolean hasLogoInNavIconSpace = mHasLogo && !mBackButtonVisible && mLogoFillsNavSpace;
-        setVisible(mLogoInNavIconSpace, hasLogoInNavIconSpace);
-        setVisible(mLogo, mHasLogo && (mBackButtonVisible || !mLogoFillsNavSpace));
-        setVisible(mNavIconContainer,
-                mNavIconSpaceReserved || hasLogoInNavIconSpace || mBackButtonVisible);
-        setVisible(mTabContainer, hasTabs && !isSearching);
-        setVisible(mTitleView, !TextUtils.isEmpty(getTitle()) && !isSearching
-                && (!hasTabs || !mTitleAndTabsMutuallyExclusive));
-        setVisible(mSubtitleView, !TextUtils.isEmpty(getSubtitle()) && !isSearching
-                && (!hasTabs || !mTitleAndTabsMutuallyExclusive));
-    }
-
-    private static void setVisible(View view, boolean visible) {
-        if (view != null) {
-            view.setVisibility(visible ? View.VISIBLE : View.GONE);
-        }
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateButton.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateButton.java
deleted file mode 100644
index 61d3cab..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateButton.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Button;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link Button} that implements {@link DrawableStateView}, for allowing additional states
- * such as ux restriction.
- */
-public class DrawableStateButton extends Button implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateButton(Context context) {
-        super(context);
-    }
-
-    public DrawableStateButton(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateConstraintLayout.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateConstraintLayout.java
deleted file mode 100644
index ec01766..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateConstraintLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import androidx.annotation.Nullable;
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-/**
- * A {@link ConstraintLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateConstraintLayout extends ConstraintLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateConstraintLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateConstraintLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateConstraintLayout(Context context,
-            @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateFrameLayout.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateFrameLayout.java
deleted file mode 100644
index 9586640..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateFrameLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link FrameLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateFrameLayout extends FrameLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateFrameLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateFrameLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateFrameLayout(Context context,
-            @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateImageView.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateImageView.java
deleted file mode 100644
index d7eb2f3..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateImageView.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link ImageView} that implements {@link DrawableStateView}, for allowing additional states
- * such as ux restriction.
- */
-public class DrawableStateImageView extends ImageView implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateImageView(Context context) {
-        super(context);
-    }
-
-    public DrawableStateImageView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateLinearLayout.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateLinearLayout.java
deleted file mode 100644
index 02edf73..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateLinearLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link LinearLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateLinearLayout extends LinearLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateLinearLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateLinearLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateLinearLayout(Context context, @Nullable AttributeSet attrs,
-            int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateRelativeLayout.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateRelativeLayout.java
deleted file mode 100644
index 5f03bb5..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateRelativeLayout.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.RelativeLayout;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link RelativeLayout} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateRelativeLayout extends RelativeLayout implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateRelativeLayout(Context context) {
-        super(context);
-    }
-
-    public DrawableStateRelativeLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateRelativeLayout(Context context,
-            @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateSwitch.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateSwitch.java
deleted file mode 100644
index 120f46e..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateSwitch.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Switch;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link Switch} that implements {@link DrawableStateView}, for allowing additional states
- * such as ux restriction.
- */
-public class DrawableStateSwitch extends Switch implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateSwitch(Context context) {
-        super(context);
-    }
-
-    public DrawableStateSwitch(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateSwitch(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public DrawableStateSwitch(
-            Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateTextView.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateTextView.java
deleted file mode 100644
index 78068d7..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateTextView.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-
-/**
- * A {@link TextView} that implements {@link DrawableStateView}, for allowing additional
- * states such as ux restriction.
- */
-public class DrawableStateTextView extends TextView implements DrawableStateView {
-    private DrawableStateUtil mUtil;
-
-    public DrawableStateTextView(Context context) {
-        super(context);
-    }
-
-    public DrawableStateTextView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DrawableStateTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        mUtil.setExtraDrawableState(stateToAdd, stateToRemove);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        if (mUtil == null) {
-            mUtil = new DrawableStateUtil(this);
-        }
-        return mUtil.onCreateDrawableState(extraSpace, space -> super.onCreateDrawableState(space));
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateUtil.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateUtil.java
deleted file mode 100644
index 296d322..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateUtil.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.function.Function;
-
-/**
- * This is a utility class designed to make it easier to create a new {@link DrawableStateView}.
- *
- * To use, subclass a view and forward it's {@link View#onCreateDrawableState(int)} and
- * {@link DrawableStateView#setExtraDrawableState(int[], int[])} methods to this object.
- */
-class DrawableStateUtil implements DrawableStateView {
-
-    private final View mView;
-    @Nullable
-    private int[] mStateToAdd;
-    @Nullable
-    private int[] mStateToRemove;
-
-    DrawableStateUtil(View view) {
-        mView = view;
-    }
-
-    /**
-     * Forward the View's onCreateDrawableState to this method.
-     *
-     * @param extraSpace The extraSpace parameter passed to the View's onCreateDrawableState
-     * @param callSuper  A reference to the View's super.onCreateDrawableState()
-     * @return The intended result of the View's onCreateDrawableState()
-     */
-    public int[] onCreateDrawableState(int extraSpace, Function<Integer, int[]> callSuper) {
-        int[] result;
-        if (mStateToAdd == null) {
-            result = callSuper.apply(extraSpace);
-        } else {
-            result = mergeDrawableStates(
-                    callSuper.apply(extraSpace + mStateToAdd.length), mStateToAdd);
-        }
-
-        if (mStateToRemove != null && mStateToRemove.length != 0) {
-            result = Arrays.stream(result)
-                    .filter(state -> Arrays.stream(mStateToRemove).noneMatch(
-                            toRemove -> state == toRemove))
-                    .toArray();
-        }
-
-        return result;
-    }
-
-    /**
-     * Forward your View's setExtraDrawableState here.
-     */
-    @Override
-    public void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove) {
-        mStateToAdd = stateToAdd;
-        mStateToRemove = stateToRemove;
-        mView.refreshDrawableState();
-    }
-
-    /** Copied from {@link View} */
-    private static int[] mergeDrawableStates(int[] baseState, int[] additionalState) {
-        int i = baseState.length - 1;
-        while (i >= 0 && baseState[i] == 0) {
-            i--;
-        }
-        System.arraycopy(additionalState, 0, baseState, i + 1, additionalState.length);
-        return baseState;
-    }
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateView.java b/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateView.java
deleted file mode 100644
index 7995bca..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/java/com/chassis/car/ui/sharedlibrary/uxr/DrawableStateView.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chassis.car.ui.sharedlibrary.uxr;
-
-import androidx.annotation.Nullable;
-
-/**
- * An Interface to manipulate a view's drawable state.
- *
- * <p>Used by {@link com.android.car.ui.toolbar.MenuItem MenuItems} to make the views display
- * if they are ux restricted.
- */
-public interface DrawableStateView {
-    /**
-     * Sets the drawable state. This should merge with existing drawable states
-     *
-     * @param stateToAdd An array of drawable states to add to the view's drawable state, along
-     *                   with any drawable state that would normally be there.
-     * @param stateToRemove An array of drawable states to remove from what would normally be
-     *                      used to display the view.
-     */
-    void setExtraDrawableState(@Nullable int[] stateToAdd, @Nullable int[] stateToRemove);
-}
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/list_item_divider.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/list_item_divider.xml
deleted file mode 100644
index 6cb8cca..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/list_item_divider.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-    Copyright (C) 2021 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:alpha="0.22" android:color="@android:color/white" />
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_hint.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_hint.xml
deleted file mode 100644
index 5292699..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_hint.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<!-- We need this to be a selector instead of a straight reference or else the
-     app will crash when using it as a TextView's text color -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="?android:attr/textColorHint"/>
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_primary.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_primary.xml
deleted file mode 100644
index d310838..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_primary.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<!-- Copy of ?android:attr/textColorPrimary (frameworks/base/res/res/color/text_color_primary.xml)
-     but with a ux restricted state. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:color="?android:attr/colorForeground"/>
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_secondary.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_secondary.xml
deleted file mode 100644
index 4c9f267..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/text_color_secondary.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<!-- Copy of ?android:attr/textColorSecondary (frameworks/base/res/res/color/text_color_secondary.xml)
-     but with a ux restricted state. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:alpha="?android:attr/secondaryContentAlpha"
-          android:color="?android:attr/colorForeground"/>
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_menu_item_icon_background_color.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_menu_item_icon_background_color.xml
deleted file mode 100644
index dd63e6f..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_menu_item_icon_background_color.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2021 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<!-- The same as @color/text_color_primary but with an activated state.
-     ColorStateLists don't support switching to complex colors, so we have to repeat
-     text_color_primary here. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_activated="false"
-          android:color="@android:color/transparent"/>
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:color="?android:attr/colorForeground" />
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_menu_item_icon_color.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_menu_item_icon_color.xml
deleted file mode 100644
index 911aab3..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_menu_item_icon_color.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<!-- The same as @color/text_color_primary but with an activated state.
-     ColorStateLists don't support switching to complex colors, so we have to repeat
-     text_color_primary here. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_activated="true"
-          android:color="?android:attr/colorBackground"/>
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item app:state_ux_restricted="true"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/colorForeground"/>
-    <item android:color="?android:attr/colorForeground" />
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_tab_item_selector.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_tab_item_selector.xml
deleted file mode 100644
index 6c7fc4c..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/color/toolbar_tab_item_selector.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@color/text_color_primary" android:state_activated="true"/>
-    <item android:color="@color/text_color_secondary"/>
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/app_styled_view_background.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/app_styled_view_background.xml
deleted file mode 100644
index db135b1..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/app_styled_view_background.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-  <solid android:color="#000000"/>
-  <stroke android:width="3dp" android:color="#B1BCBE" />
-  <corners android:radius="10dp"/>
-  <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
-</shape>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_back.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_back.xml
deleted file mode 100644
index 68d5dc9..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_back.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2020, The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:autoMirrored="true"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
-</vector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_chevron.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_chevron.xml
deleted file mode 100644
index ad74a26..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_chevron.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="48dp"
-    android:height="48dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24">
-    <path
-        android:fillColor="@color/text_color_primary"
-        android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
-</vector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_close.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_close.xml
deleted file mode 100644
index a02d199..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_close.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0">
-    <path
-        android:fillColor="#FFF"
-        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
-</vector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_down.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_down.xml
deleted file mode 100644
index dac6001..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_down.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
-  <path
-      android:pathData="M7.41,8.59L12,13.17l4.59-4.58L18,10l-6,6l-6-6L7.41,8.59z"
-      android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_search.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_search.xml
deleted file mode 100644
index 72b0c9b..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/icon_search.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="48dp"
-    android:height="48dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-    <path
-        android:fillColor="@color/toolbar_menu_item_icon_color"
-        android:pathData="M31 28h-1.59l-.55-.55C30.82 25.18 32 22.23 32 19c0-7.18-5.82-13-13-13S6 11.82 6
-19s5.82 13 13 13c3.23 0 6.18-1.18 8.45-3.13l.55 .55 V31l10 9.98L40.98 38 31
-28zm-12 0c-4.97 0-9-4.03-9-9s4.03-9 9-9 9 4.03 9 9-4.03 9-9 9z" />
-    <path
-        android:pathData="M0 0h48v48H0z" />
-</vector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_avatar_icon_outline.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_avatar_icon_outline.xml
deleted file mode 100644
index cf1f889..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_avatar_icon_outline.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="oval">
-</shape>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_background.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_background.xml
deleted file mode 100644
index 3e6b990..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_background.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:state_pressed="true">
-        <shape android:shape="rectangle">
-            <solid android:color="@color/rotary_focus_pressed_fill_color"/>
-            <stroke android:width="@dimen/rotary_focus_pressed_stroke_width"
-                android:color="@color/rotary_focus_pressed_stroke_color"/>
-        </shape>
-    </item>
-    <item android:state_focused="true">
-        <shape android:shape="rectangle">
-            <solid android:color="@color/rotary_focus_fill_color"/>
-            <stroke android:width="@dimen/rotary_focus_stroke_width"
-                android:color="@color/rotary_focus_stroke_color"/>
-        </shape>
-    </item>
-    <item android:state_activated="true">
-        <shape android:shape="rectangle">
-            <solid android:color="?android:attr/colorControlHighlight"/>
-        </shape>
-    </item>
-    <item>
-        <ripple android:color="?android:attr/colorControlHighlight">
-            <item android:id="@android:id/mask">
-                <shape android:shape="rectangle">
-                    <solid android:color="?android:colorAccent"/>
-                </shape>
-            </item>
-        </ripple>
-    </item>
-</selector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_divider.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_divider.xml
deleted file mode 100644
index 2c100a6..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/list_item_divider.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <size android:height="@dimen/list_item_action_divider_height" />
-    <solid android:color="@color/list_item_divider" />
-</shape>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_divider.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_divider.xml
deleted file mode 100644
index 1e9a5a2..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_divider.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~
-  ~ Copyright (C) 2019 Google Inc.
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
- -->
-<shape
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <size
-        android:width="16dp"/>
-</shape>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_icon_background.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_icon_background.xml
deleted file mode 100644
index 699cf0c..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_icon_background.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~
-  ~ Copyright (C) 2019 Google Inc.
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="oval">
-    <size
-        android:width="54dp"
-        android:height="54dp"/>
-    <solid android:color="@color/toolbar_menu_item_icon_background_color"/>
-</shape>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_icon_ripple.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_icon_ripple.xml
deleted file mode 100644
index 41d1abc..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_icon_ripple.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~
-  ~ Copyright (C) 2019 Google Inc.
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
- -->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@color/ripple_color"
-        android:radius="@dimen/toolbar_menu_item_icon_ripple_radius"/>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_overflow.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_overflow.xml
deleted file mode 100644
index 6228c3b..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/drawable/toolbar_menu_item_overflow.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0">
-    <path
-        android:fillColor="#FFF"
-        android:pathData="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>
-</vector>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-ldrtl-port/base_layout_toolbar.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-ldrtl-port/base_layout_toolbar.xml
deleted file mode 100644
index cb4133c..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-ldrtl-port/base_layout_toolbar.xml
+++ /dev/null
@@ -1,146 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <FrameLayout
-        android:id="@+id/base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/toolbar_background"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="#E0000000"
-        android:tag="shared_lib_top_inset">
-        <com.chassis.car.ui.sharedlibrary.toolbar.ClickBlockingView
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-
-        <androidx.constraintlayout.widget.Guideline
-            android:id="@+id/toolbar_row_separator_guideline"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            app:layout_constraintGuide_begin="@dimen/toolbar_row_height" />
-
-        <!-- The horizontal bias set to 0.0 here is so that when you set this view as GONE, it will
-             be treated as if it's all the way to the left instead of centered in the margin -->
-        <FrameLayout
-            android:id="@+id/toolbar_nav_icon_container"
-            android:layout_width="@dimen/toolbar_margin"
-            android:layout_height="0dp"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintHorizontal_bias="0.0"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintTop_toTopOf="parent">
-
-            <ImageView
-                android:id="@+id/toolbar_nav_icon"
-                android:tint="@color/toolbar_menu_item_icon_color"
-                android:src="@drawable/icon_back"
-                android:background="@drawable/toolbar_menu_item_icon_ripple"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-
-            <ImageView
-                android:id="@+id/toolbar_logo"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-        </FrameLayout>
-
-        <ImageView
-            android:id="@+id/toolbar_title_logo"
-            android:layout_width="44dp"
-            android:layout_height="44dp"
-            android:layout_marginRight="34dp"
-            android:layout_gravity="center"
-            android:scaleType="fitXY"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <LinearLayout
-            android:layout_height="wrap_content"
-            android:layout_width="0dp"
-            android:id="@+id/toolbar_title_container"
-            android:orientation="vertical"
-            android:layout_marginRight="@dimen/toolbar_margin"
-            android:gravity="right"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintLeft_toRightOf="@id/toolbar_menu_items_container"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent">
-            <TextView
-                android:id="@+id/toolbar_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                android:textAlignment="viewStart"
-                android:textAppearance="@style/TextAppearance.CarUi.Body1"/>
-            <TextView
-                android:id="@+id/toolbar_subtitle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall"/>
-        </LinearLayout>
-
-        <com.chassis.car.ui.sharedlibrary.toolbar.TabLayout
-            android:id="@+id/toolbar_tabs"
-            android:layout_width="0dp"
-            android:layout_height="@dimen/toolbar_row_height"
-            android:orientation="horizontal"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintHorizontal_bias="0.0"/>
-
-        <LinearLayout
-            android:id="@+id/toolbar_menu_items_container"
-            android:divider="@drawable/toolbar_menu_item_divider"
-            android:showDividers="beginning|middle|end"
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            android:gravity="center_vertical"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintLeft_toRightOf="@id/toolbar_nav_icon_container"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <ViewStub
-            android:id="@+id/toolbar_search_view_stub"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout="@layout/toolbar_search_view"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintLeft_toRightOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <ProgressBar
-            android:id="@+id/toolbar_progress_bar"
-            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:indeterminate="true"
-            android:visibility="gone"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintRight_toRightOf="parent"/>
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-ldrtl/base_layout_toolbar.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-ldrtl/base_layout_toolbar.xml
deleted file mode 100644
index debe09b..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-ldrtl/base_layout_toolbar.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <FrameLayout
-        android:id="@+id/base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/toolbar_background"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/toolbar_row_height"
-        android:background="#E0000000"
-        android:tag="shared_lib_top_inset">
-        <com.chassis.car.ui.sharedlibrary.toolbar.ClickBlockingView
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-
-        <!-- The horizontal bias set to 0.0 here is so that when you set this view as GONE, it will
-             be treated as if it's all the way to the left instead of centered in the margin -->
-        <FrameLayout
-            android:id="@+id/toolbar_nav_icon_container"
-            android:layout_width="@dimen/toolbar_margin"
-            android:layout_height="0dp"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintHorizontal_bias="0.0"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintTop_toTopOf="parent">
-
-            <ImageView
-                android:id="@+id/toolbar_nav_icon"
-                android:tint="@color/toolbar_menu_item_icon_color"
-                android:src="@drawable/icon_back"
-                android:background="@drawable/toolbar_menu_item_icon_ripple"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-
-            <ImageView
-                android:id="@+id/toolbar_logo"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-        </FrameLayout>
-
-        <ImageView
-            android:id="@+id/toolbar_title_logo"
-            android:layout_width="44dp"
-            android:layout_height="44dp"
-            android:layout_marginRight="34dp"
-            android:layout_gravity="center"
-            android:scaleType="fitXY"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <LinearLayout
-            android:layout_height="wrap_content"
-            android:layout_width="0dp"
-            android:id="@+id/toolbar_title_container"
-            android:orientation="vertical"
-            android:layout_marginRight="@dimen/toolbar_margin"
-            android:gravity="right"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintLeft_toRightOf="@id/toolbar_menu_items_container"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent">
-            <TextView
-                android:id="@+id/toolbar_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                android:textAlignment="viewStart"
-                android:textAppearance="@style/TextAppearance.CarUi.Body1"/>
-            <TextView
-                android:id="@+id/toolbar_subtitle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall"/>
-        </LinearLayout>
-
-        <com.chassis.car.ui.sharedlibrary.toolbar.TabLayout
-            android:id="@+id/toolbar_tabs"
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintLeft_toRightOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintRight_toLeftOf="@+id/toolbar_title_logo"
-            app:layout_constraintHorizontal_bias="0.0"/>
-
-        <LinearLayout
-            android:id="@+id/toolbar_menu_items_container"
-            android:divider="@drawable/toolbar_menu_item_divider"
-            android:showDividers="beginning|middle|end"
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            android:gravity="center_vertical"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintLeft_toRightOf="@id/toolbar_nav_icon_container"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <ViewStub
-            android:id="@+id/toolbar_search_view_stub"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout="@layout/toolbar_search_view"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintLeft_toRightOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <ProgressBar
-            android:id="@+id/toolbar_progress_bar"
-            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:indeterminate="true"
-            android:visibility="gone"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintRight_toRightOf="parent"/>
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-port/base_layout_toolbar.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-port/base_layout_toolbar.xml
deleted file mode 100644
index 654e502..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-port/base_layout_toolbar.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <FrameLayout
-        android:id="@+id/base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/toolbar_background"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="#E0000000"
-        android:tag="shared_lib_top_inset">
-        <com.chassis.car.ui.sharedlibrary.toolbar.ClickBlockingView
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-
-        <androidx.constraintlayout.widget.Guideline
-            android:id="@+id/toolbar_row_separator_guideline"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            app:layout_constraintGuide_begin="@dimen/toolbar_row_height" />
-
-        <!-- The horizontal bias set to 0.0 here is so that when you set this view as GONE, it will
-             be treated as if it's all the way to the left instead of centered in the margin -->
-        <FrameLayout
-            android:id="@+id/toolbar_nav_icon_container"
-            android:layout_width="@dimen/toolbar_margin"
-            android:layout_height="0dp"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintHorizontal_bias="0.0"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent">
-
-            <ImageView
-                android:id="@+id/toolbar_nav_icon"
-                android:tint="@color/toolbar_menu_item_icon_color"
-                android:src="@drawable/icon_back"
-                android:background="@drawable/toolbar_menu_item_icon_ripple"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-
-            <ImageView
-                android:id="@+id/toolbar_logo"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-        </FrameLayout>
-
-        <ImageView
-            android:id="@+id/toolbar_title_logo"
-            android:layout_width="44dp"
-            android:layout_height="44dp"
-            android:layout_gravity="center"
-            android:scaleType="fitXY"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintStart_toEndOf="@id/toolbar_nav_icon_container"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <LinearLayout android:layout_height="wrap_content"
-            android:layout_width="0dp"
-            android:id="@+id/toolbar_title_container"
-            android:orientation="vertical"
-            android:layout_marginStart="16dp"
-            app:layout_goneMarginStart="0dp"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintEnd_toStartOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintStart_toEndOf="@+id/toolbar_title_logo"
-            app:layout_constraintTop_toTopOf="parent">
-            <TextView android:id="@+id/toolbar_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                android:textAlignment="viewStart"
-                android:textAppearance="@style/TextAppearance.CarUi.Body1"/>
-            <TextView android:id="@+id/toolbar_subtitle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall"/>
-        </LinearLayout>
-
-        <com.chassis.car.ui.sharedlibrary.toolbar.TabLayout
-            android:id="@+id/toolbar_tabs"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/toolbar_row_height"
-            android:orientation="horizontal"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/toolbar_row_separator_guideline" />
-
-        <LinearLayout
-            android:id="@+id/toolbar_menu_items_container"
-            android:divider="@drawable/toolbar_menu_item_divider"
-            android:showDividers="beginning|middle|end"
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            android:gravity="center_vertical"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <ViewStub
-            android:id="@+id/toolbar_search_view_stub"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout="@layout/toolbar_search_view"
-            app:layout_constraintBottom_toTopOf="@id/toolbar_row_separator_guideline"
-            app:layout_constraintEnd_toStartOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintStart_toEndOf="@+id/toolbar_title_logo"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <ProgressBar
-            android:id="@+id/toolbar_progress_bar"
-            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:indeterminate="true"
-            android:visibility="gone"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"/>
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-port/toolbar_tab.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-port/toolbar_tab.xml
deleted file mode 100644
index 8854de1..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout-port/toolbar_tab.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="0dp"
-    android:layout_height="match_parent"
-    android:layout_weight="1"
-    android:orientation="vertical"
-    android:paddingStart="12dp"
-    android:paddingEnd="12dp"
-    android:gravity="center"
-    android:background="?android:attr/selectableItemBackground">
-    <ImageView
-        android:id="@+id/car_ui_toolbar_tab_item_icon"
-        android:layout_width="36dp"
-        android:layout_height="36dp"
-        android:scaleType="fitCenter"
-        android:tint="@color/toolbar_tab_item_selector"
-        android:tintMode="src_in" />
-    <TextView
-        android:id="@+id/car_ui_toolbar_tab_item_text"
-        android:layout_width="135dp"
-        android:layout_height="wrap_content"
-        android:singleLine="true"
-        android:gravity="center"
-        android:textAppearance="@style/TextAppearance.CarUi.Widget.Toolbar.Tab"/>
-</LinearLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/app_styled_view.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/app_styled_view.xml
deleted file mode 100644
index f2cf94b..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/app_styled_view.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:padding="20dp"
-    android:background="@drawable/app_styled_view_background"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-  <ImageView
-      android:id="@+id/app_styled_view_icon_close"
-      android:layout_width="44dp"
-      android:layout_height="44dp"
-      android:src="@drawable/icon_close"
-      android:background="@drawable/toolbar_menu_item_icon_ripple"
-      app:layout_constraintStart_toStartOf="parent"
-      />
-
-  <ScrollView
-      android:id="@+id/app_styled_content"
-      android:layout_width="match_parent"
-      android:layout_height="0dp"
-      android:padding="20dp"
-      app:layout_constraintStart_toStartOf="parent"
-      app:layout_constraintTop_toBottomOf="@+id/app_styled_view_icon_close"
-      app:layout_constraintBottom_toBottomOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/base_layout.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/base_layout.xml
deleted file mode 100644
index fc2b830..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/base_layout.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <FrameLayout
-        android:id="@+id/base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/base_layout_toolbar.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/base_layout_toolbar.xml
deleted file mode 100644
index 8baf991..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/base_layout_toolbar.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <FrameLayout
-        android:id="@+id/base_layout_content_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/toolbar_background"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/toolbar_row_height"
-        android:background="#E0000000"
-        android:tag="shared_lib_top_inset">
-        <com.chassis.car.ui.sharedlibrary.toolbar.ClickBlockingView
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"/>
-
-        <!-- The horizontal bias set to 0.0 here is so that when you set this view as GONE, it will
-             be treated as if it's all the way to the left instead of centered in the margin -->
-        <FrameLayout
-            android:id="@+id/toolbar_nav_icon_container"
-            android:layout_width="@dimen/toolbar_margin"
-            android:layout_height="0dp"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintHorizontal_bias="0.0"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent">
-
-            <ImageView
-                android:id="@+id/toolbar_nav_icon"
-                android:tint="@color/toolbar_menu_item_icon_color"
-                android:src="@drawable/icon_back"
-                android:background="@drawable/toolbar_menu_item_icon_ripple"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"
-                tools:ignore="UseAppTint" />
-
-            <ImageView
-                android:id="@+id/toolbar_logo"
-                android:layout_width="44dp"
-                android:layout_height="44dp"
-                android:layout_gravity="center"
-                android:scaleType="fitXY"/>
-        </FrameLayout>
-
-        <ImageView
-            android:id="@+id/toolbar_title_logo"
-            android:layout_width="44dp"
-            android:layout_height="44dp"
-            android:layout_gravity="center"
-            android:scaleType="fitXY"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toEndOf="@id/toolbar_nav_icon_container"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <LinearLayout android:layout_height="wrap_content"
-            android:layout_width="0dp"
-            android:id="@+id/toolbar_title_container"
-            android:orientation="vertical"
-            android:layout_marginStart="16dp"
-            app:layout_goneMarginStart="0dp"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toEndOf="@+id/toolbar_title_logo"
-            app:layout_constraintEnd_toStartOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintTop_toTopOf="parent">
-            <TextView android:id="@+id/toolbar_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                android:textAlignment="viewStart"
-                android:textAppearance="@style/TextAppearance.CarUi.Body1"/>
-            <TextView android:id="@+id/toolbar_subtitle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:textAlignment="viewStart"
-                android:textAppearance="?android:attr/textAppearanceSmall"/>
-        </LinearLayout>
-
-        <com.chassis.car.ui.sharedlibrary.toolbar.TabLayout
-            android:id="@+id/toolbar_tabs"
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toStartOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintHorizontal_bias="0.0"
-            app:layout_constraintStart_toEndOf="@+id/toolbar_title_logo"
-            app:layout_constraintTop_toTopOf="parent" />
-
-        <LinearLayout
-            android:id="@+id/toolbar_menu_items_container"
-            android:divider="@drawable/toolbar_menu_item_divider"
-            android:showDividers="beginning|middle|end"
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:orientation="horizontal"
-            android:gravity="center_vertical"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent"/>
-
-        <ViewStub
-            android:id="@+id/toolbar_search_view_stub"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout="@layout/toolbar_search_view"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toStartOf="@+id/toolbar_menu_items_container"
-            app:layout_constraintStart_toEndOf="@+id/toolbar_title_logo"
-            app:layout_constraintTop_toTopOf="parent"
-            android:layout_marginStart="16dp"
-            app:layout_goneMarginStart="0dp"/>
-
-        <ProgressBar
-            android:id="@+id/toolbar_progress_bar"
-            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:indeterminate="true"
-            android:visibility="gone"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"/>
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/header_list_item.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/header_list_item.xml
deleted file mode 100644
index 2805774..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/header_list_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:background="@android:color/transparent"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/list_item_header_height">
-
-    <TextView
-        android:id="@+id/list_item_title"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/header_list_item_text_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Header"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toTopOf="@+id/list_item_body"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_chainStyle="packed" />
-
-    <TextView
-        android:id="@+id/list_item_body"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/list_item_text_no_icon_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/list_item_title" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/list_item.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/list_item.xml
deleted file mode 100644
index 32499e6..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/list_item.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:tag="carUiListItem"
-    android:minHeight="@dimen/list_item_height">
-
-    <!-- The following touch interceptor views are sized to encompass the specific sub-sections of
-    the list item view to easily control the bounds of a background ripple effects. -->
-    <View
-        android:id="@+id/list_item_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/list_item_background"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <!-- This touch interceptor does not include the action container -->
-    <View
-        android:id="@+id/list_item_reduced_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/list_item_background"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/list_item_action_container"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <FrameLayout
-        android:id="@+id/list_item_icon_container"
-        android:layout_width="112dp"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <ImageView
-            android:id="@+id/list_item_icon"
-            android:layout_width="@dimen/list_item_icon_size"
-            android:layout_height="@dimen/list_item_icon_size"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-
-        <ImageView
-            android:id="@+id/list_item_content_icon"
-            android:layout_width="@dimen/list_item_content_icon_width"
-            android:layout_height="@dimen/list_item_content_icon_height"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-
-        <ImageView
-            android:id="@+id/list_item_avatar_icon"
-            android:background="@drawable/list_item_avatar_icon_outline"
-            android:layout_width="@dimen/list_item_icon_size"
-            android:layout_height="@dimen/list_item_icon_size"
-            android:layout_gravity="center"
-            android:visibility="gone"
-            android:scaleType="fitCenter" />
-    </FrameLayout>
-
-    <TextView
-        android:id="@+id/list_item_title"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/list_item_text_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toTopOf="@+id/list_item_body"
-        app:layout_constraintEnd_toStartOf="@+id/list_item_action_container"
-        app:layout_constraintStart_toEndOf="@+id/list_item_icon_container"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_chainStyle="packed"
-        app:layout_goneMarginStart="@dimen/list_item_text_no_icon_start_margin" />
-    <TextView
-        android:id="@+id/list_item_body"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/list_item_text_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
-        android:textAlignment="viewStart"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/list_item_action_container"
-        app:layout_constraintStart_toEndOf="@+id/list_item_icon_container"
-        app:layout_constraintTop_toBottomOf="@+id/list_item_title"
-        app:layout_goneMarginStart="@dimen/list_item_text_no_icon_start_margin" />
-
-    <!-- This touch interceptor is sized and positioned to encompass the action container   -->
-    <View
-        android:id="@+id/list_item_action_container_touch_interceptor"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:background="@drawable/list_item_background"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="@id/list_item_action_container"
-        app:layout_constraintEnd_toEndOf="@id/list_item_action_container"
-        app:layout_constraintStart_toStartOf="@id/list_item_action_container"
-        app:layout_constraintTop_toTopOf="@id/list_item_action_container" />
-
-    <FrameLayout
-        android:id="@+id/list_item_action_container"
-        android:layout_width="wrap_content"
-        android:minWidth="@dimen/list_item_icon_container_width"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <View
-            android:id="@+id/list_item_action_divider"
-            android:layout_width="@dimen/list_item_action_divider_width"
-            android:layout_height="@dimen/list_item_action_divider_height"
-            android:layout_gravity="start|center_vertical"
-            android:background="@drawable/list_item_divider" />
-
-        <Switch
-            android:id="@+id/list_item_switch_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <CheckBox
-            android:id="@+id/list_item_checkbox_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <RadioButton
-            android:id="@+id/list_item_radio_button_widget"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-
-        <ImageView
-            android:id="@+id/list_item_supplemental_icon"
-            android:layout_width="@dimen/list_item_icon_size"
-            android:layout_height="@dimen/list_item_icon_size"
-            android:layout_gravity="center"
-            android:scaleType="fitCenter" />
-    </FrameLayout>
-</androidx.constraintlayout.widget.ConstraintLayout>
-
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_menu_item.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_menu_item.xml
deleted file mode 100644
index c2d3609..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_menu_item.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2021, The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:minWidth="@dimen/touch_target_size"
-    android:minHeight="@dimen/touch_target_size">
-    <FrameLayout
-        android:id="@+id/car_ui_toolbar_menu_item_icon_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center">
-        <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateImageView
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:src="@drawable/toolbar_menu_item_icon_background"
-            android:background="@drawable/toolbar_menu_item_icon_ripple"
-            android:scaleType="center"/>
-        <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateImageView
-            android:id="@+id/car_ui_toolbar_menu_item_icon"
-            android:layout_width="@dimen/primary_icon_size"
-            android:layout_height="@dimen/primary_icon_size"
-            android:layout_gravity="center"
-            android:tint="@color/toolbar_menu_item_icon_color"
-            android:tintMode="src_in"/>
-    </FrameLayout>
-    <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateSwitch
-        android:id="@+id/car_ui_toolbar_menu_item_switch"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-
-    <!-- These buttons must have clickable="false" or they will steal the click events from the container -->
-    <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text"
-        style="@style/Toolbar.MenuItem.Text.Borderless"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-    <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text_with_icon"
-        style="@style/Toolbar.MenuItem.Text.Borderless"
-        android:drawableTint="@color/toolbar_menu_item_icon_color"
-        android:drawablePadding="10dp"
-        android:textColor="@color/toolbar_menu_item_icon_color"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_menu_item_primary.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_menu_item_primary.xml
deleted file mode 100644
index df0e783..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_menu_item_primary.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2021, The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:minWidth="@dimen/touch_target_size"
-    android:minHeight="@dimen/touch_target_size">
-    <FrameLayout
-        android:id="@+id/car_ui_toolbar_menu_item_icon_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center">
-        <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateImageView
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:src="@drawable/toolbar_menu_item_icon_background"
-            android:background="@drawable/toolbar_menu_item_icon_ripple"
-            android:scaleType="center"/>
-        <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateImageView
-            android:id="@+id/car_ui_toolbar_menu_item_icon"
-            android:layout_width="@dimen/primary_icon_size"
-            android:layout_height="@dimen/primary_icon_size"
-            android:layout_gravity="center"
-            android:tint="@color/toolbar_menu_item_icon_color"
-            android:tintMode="src_in"/>
-    </FrameLayout>
-    <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateSwitch
-        android:id="@+id/car_ui_toolbar_menu_item_switch"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-
-    <!-- These buttons must have clickable="false" or they will steal the click events from the container -->
-    <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text"
-        style="@style/Toolbar.MenuItem.Text"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-    <com.chassis.car.ui.sharedlibrary.uxr.DrawableStateButton
-        android:id="@+id/car_ui_toolbar_menu_item_text_with_icon"
-        style="@style/Toolbar.MenuItem.Text"
-        android:drawableTint="@color/toolbar_menu_item_icon_color"
-        android:drawablePadding="10dp"
-        android:textColor="@color/toolbar_menu_item_icon_color"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:clickable="false"/>
-</FrameLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_search_view.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_search_view.xml
deleted file mode 100644
index c2ab9f5..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_search_view.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="0dp"
-    android:layout_height="0dp"
-    app:layout_constraintBottom_toBottomOf="parent"
-    app:layout_constraintEnd_toStartOf="@+id/toolbar_menu_items_container"
-    app:layout_constraintStart_toEndOf="@+id/toolbar_nav_icon_container"
-    app:layout_constraintTop_toTopOf="parent">
-
-  <com.chassis.car.ui.sharedlibrary.toolbar.OnPrivateImeCommandEditText
-      android:id="@+id/toolbar_search_bar"
-      android:layout_height="match_parent"
-      android:layout_width="match_parent"
-      android:hint="@string/toolbar_default_search_hint"
-      android:textColorHint="@color/text_color_hint"
-      android:inputType="text"
-      android:singleLine="true"
-      android:imeOptions="actionSearch"
-      style="@android:style/Widget.DeviceDefault.EditText"
-      app:layout_constraintTop_toTopOf="parent"
-      app:layout_constraintBottom_toBottomOf="parent"
-      app:layout_constraintStart_toStartOf="parent"
-      app:layout_constraintEnd_toEndOf="parent"/>
-    <FrameLayout
-        android:layout_width="@dimen/toolbar_search_icon_container_width"
-        android:layout_height="match_parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent">
-      <ImageView
-          android:id="@+id/toolbar_search_icon"
-          android:layout_width="@dimen/primary_icon_size"
-          android:layout_height="@dimen/primary_icon_size"
-          android:layout_gravity="center"
-          android:src="@drawable/icon_search"
-          android:scaleType="fitXY"/>
-    </FrameLayout>
-
-    <FrameLayout
-        android:id="@+id/toolbar_search_close"
-        android:layout_width="@dimen/toolbar_search_close_icon_container_width"
-        android:layout_height="match_parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent">
-      <ImageView
-          android:layout_width="@dimen/primary_icon_size"
-          android:layout_height="@dimen/primary_icon_size"
-          android:layout_gravity="center"
-          android:src="@drawable/icon_close"
-          android:scaleType="fitXY"
-          android:background="@drawable/toolbar_menu_item_icon_background"/>
-    </FrameLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_tab.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_tab.xml
deleted file mode 100644
index 4b70766..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/layout/toolbar_tab.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:paddingStart="12dp"
-    android:paddingEnd="12dp"
-    android:gravity="center"
-    android:background="?android:attr/selectableItemBackground">
-    <ImageView
-        android:id="@+id/car_ui_toolbar_tab_item_icon"
-        android:layout_width="36dp"
-        android:layout_height="36dp"
-        android:scaleType="fitCenter"
-        android:tint="@color/toolbar_tab_item_selector"
-        android:tintMode="src_in"
-        tools:ignore="UseAppTint" />
-    <TextView
-        android:id="@+id/car_ui_toolbar_tab_item_text"
-        android:layout_width="135dp"
-        android:layout_height="wrap_content"
-        android:singleLine="true"
-        android:gravity="center"
-        android:textAppearance="@style/TextAppearance.CarUi.Widget.Toolbar.Tab"/>
-</LinearLayout>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values-ldrtl/values-toolbar.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values-ldrtl/values-toolbar.xml
deleted file mode 100644
index 4b5ae1c..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values-ldrtl/values-toolbar.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <bool name="toolbar_logo_fills_nav_icon_space">false</bool>
-    <bool name="toolbar_nav_icon_space_reserved">false</bool>
-</resources>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values-port/values-toolbar.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values-port/values-toolbar.xml
deleted file mode 100644
index c9aa806..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values-port/values-toolbar.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <bool name="toolbar_title_and_tabs_mutually_exclusive">false</bool>
-</resources>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/colors.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/colors.xml
deleted file mode 100644
index d26379f..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <color name="rotary_focus_stroke_color">#94CBFF</color>
-    <color name="rotary_focus_fill_color">#3D94CBFF</color>
-    <color name="rotary_focus_pressed_stroke_color">#94CBFF</color>
-    <color name="rotary_focus_pressed_fill_color">#8A94CBFF</color>
-    <color name="rotary_focus_stroke_secondary_color">#0059B3</color>
-    <color name="rotary_focus_fill_secondary_color">#3D0059B3</color>
-    <color name="rotary_focus_pressed_stroke_secondary_color">#0059B3</color>
-    <color name="rotary_focus_pressed_fill_secondary_color">#8A0059B3</color>
-</resources>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/dimens.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/dimens.xml
deleted file mode 100644
index 3df04c8..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-    <!-- height and width of the dialog modal.  -->
-    <dimen name="app_styled_dialog_width">1400dp</dimen>
-    <dimen name="app_styled_dialog_height">600dp</dimen>
-    <dimen name="app_styled_dialog_position_x">20dp</dimen>
-    <dimen name="app_styled_dialog_position_y">40dp</dimen>
-
-    <!-- Rotary focus highlight  -->
-    <dimen name="rotary_focus_stroke_width">8dp</dimen>
-    <dimen name="rotary_focus_pressed_stroke_width">4dp</dimen>
-
-    <!-- List item  -->
-    <dimen name="list_item_height">116dp</dimen>
-    <dimen name="list_item_header_height">76dp</dimen>
-    <dimen name="list_item_icon_size">44dp</dimen>
-    <dimen name="list_item_content_icon_width">@dimen/list_item_icon_container_width</dimen>
-    <dimen name="list_item_content_icon_height">@dimen/list_item_icon_container_width</dimen>
-    <dimen name="list_item_avatar_icon_width">@dimen/list_item_icon_size</dimen>
-    <dimen name="list_item_avatar_icon_height">@dimen/list_item_icon_size</dimen>
-    <dimen name="list_item_supplemental_icon_size">@dimen/list_item_icon_size</dimen>
-    <dimen name="list_item_icon_container_width">112dp</dimen>
-    <dimen name="list_item_action_divider_width">1dp</dimen>
-    <dimen name="list_item_action_divider_height">60dp</dimen>
-    <dimen name="header_list_item_text_start_margin">0dp</dimen>
-    <dimen name="list_item_text_start_margin">24dp</dimen>
-    <dimen name="list_item_text_no_icon_start_margin">24dp</dimen>
-</resources>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/strings.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/strings.xml
deleted file mode 100644
index 3e77a56..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <!-- Search hint, displayed inside the search box [CHAR LIMIT=50] -->
-  <string name="toolbar_default_search_hint">Search&#8230;</string>
-
-  <!-- The content description on the toolbar back button [CHAR_LIMIT=100] -->
-  <string name="toolbar_nav_icon_content_description">Back</string>
-
-  <!-- The content description of the toolber menu item overflow button [CHAR_LIMIT=50] -->
-  <string name="toolbar_menu_item_overflow_title">Overflow</string>
-</resources>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/values-toolbar.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/values-toolbar.xml
deleted file mode 100644
index 378ed75..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/values-toolbar.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <bool name="toolbar_title_and_tabs_mutually_exclusive">true</bool>
-    <bool name="toolbar_logo_fills_nav_icon_space">true</bool>
-    <bool name="toolbar_nav_icon_space_reserved">true</bool>
-
-    <dimen name="toolbar_margin">112dp</dimen>
-    <dimen name="toolbar_row_height">96dp</dimen>
-    <dimen name="toolbar_menu_item_icon_ripple_radius">48dp</dimen>
-    <dimen name="toolbar_search_icon_container_width">76dp</dimen>
-    <dimen name="toolbar_search_close_icon_container_width">76dp</dimen>
-
-    <style name="TextAppearance.CarUi.Widget.Toolbar.Tab" parent="TextAppearance.CarUi.Body3">
-        <item name="android:textColor">@color/toolbar_tab_item_selector</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textFontWeight">400</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Widget.Toolbar.Tab.Selected">
-        <item name="android:textFontWeight">500</item>
-    </style>
-
-    <style name="Toolbar.MenuItem.Text"
-        parent="android:Widget.Material.Button">
-        <item name="android:textSize">26sp</item>
-        <item name="android:textAllCaps">false</item>
-        <item name="android:maxWidth">350dp</item>
-    </style>
-
-    <style name="Toolbar.MenuItem.Text.Borderless"
-        parent="android:Widget.Material.Button.Borderless.Colored">
-        <item name="android:textSize">26sp</item>
-        <item name="android:textAllCaps">false</item>
-        <item name="android:maxWidth">350dp</item>
-    </style>
-</resources>
diff --git a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/values.xml b/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/values.xml
deleted file mode 100644
index 925f36f..0000000
--- a/car-ui-lib/referencedesign/sharedlibrary/src/main/res/values/values.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<resources>
-    <attr name="state_ux_restricted"/>
-    <color name="ripple_color">#27ffffff</color>
-    <dimen name="touch_target_size">76dp</dimen>
-    <dimen name="primary_icon_size">44dp</dimen>
-
-    <style name="TextAppearance.CarUi" parent="android:TextAppearance.DeviceDefault">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Body1">
-        <item name="android:textSize">32sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Body2">
-        <item name="android:textSize">28sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Body3">
-        <item name="android:textSize">24sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Sub1">
-        <item name="android:textSize">22sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Sub2">
-        <item name="android:textSize">20sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.Sub3">
-        <item name="android:textSize">18sp</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.ListItem" parent="TextAppearance.CarUi.Body1"/>
-
-    <style name="TextAppearance.CarUi.ListItem.Body" parent="TextAppearance.CarUi.Body3">
-        <item name="android:textColor">@color/text_color_secondary</item>
-    </style>
-
-    <style name="TextAppearance.CarUi.ListItem.Header" parent="TextAppearance.CarUi.Body3">
-        <item name="android:textColor">?android:attr/colorAccent</item>
-    </style>
-</resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_color_accent.xml b/car-ui-lib/res/color/car_ui_color_accent.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/color/car_ui_color_accent.xml
rename to car-ui-lib/res/color/car_ui_color_accent.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_dialog_icon_color.xml b/car-ui-lib/res/color/car_ui_dialog_icon_color.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/color/car_ui_dialog_icon_color.xml
rename to car-ui-lib/res/color/car_ui_dialog_icon_color.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_list_item_divider.xml b/car-ui-lib/res/color/car_ui_list_item_divider.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/color/car_ui_list_item_divider.xml
rename to car-ui-lib/res/color/car_ui_list_item_divider.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_text_color_hint.xml b/car-ui-lib/res/color/car_ui_text_color_hint.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/color/car_ui_text_color_hint.xml
rename to car-ui-lib/res/color/car_ui_text_color_hint.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_text_color_primary.xml b/car-ui-lib/res/color/car_ui_text_color_primary.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/color/car_ui_text_color_primary.xml
rename to car-ui-lib/res/color/car_ui_text_color_primary.xml
diff --git a/car-ui-lib/referencedesign/res/color/car_ui_text_color_secondary.xml b/car-ui-lib/res/color/car_ui_text_color_secondary.xml
similarity index 100%
rename from car-ui-lib/referencedesign/res/color/car_ui_text_color_secondary.xml
rename to car-ui-lib/res/color/car_ui_text_color_secondary.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_toolbar_menu_item_icon_background_color.xml b/car-ui-lib/res/color/car_ui_toolbar_menu_item_icon_background_color.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/color/car_ui_toolbar_menu_item_icon_background_color.xml
rename to car-ui-lib/res/color/car_ui_toolbar_menu_item_icon_background_color.xml
diff --git a/car-ui-lib/res/color/car_ui_toolbar_menu_item_icon_color.xml b/car-ui-lib/res/color/car_ui_toolbar_menu_item_icon_color.xml
new file mode 100644
index 0000000..d6e5dea
--- /dev/null
+++ b/car-ui-lib/res/color/car_ui_toolbar_menu_item_icon_color.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<!-- The same as @color/car_ui_text_color_primary but with an activated state.
+     ColorStateLists don't support switching to complex colors, so we have to repeat
+     car_ui_text_color_primary here. -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item android:state_activated="true"
+          android:color="?android:attr/colorBackground"/>
+    <item android:state_enabled="false"
+          android:alpha="?android:attr/disabledAlpha"
+          android:color="?android:attr/colorForeground"/>
+    <item app:state_ux_restricted="true"
+          android:alpha="?android:attr/disabledAlpha"
+          android:color="?android:attr/colorForeground"/>
+    <item android:color="?android:attr/colorForeground" />
+</selector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/color/car_ui_toolbar_tab_item_selector.xml b/car-ui-lib/res/color/car_ui_toolbar_tab_item_selector.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/color/car_ui_toolbar_tab_item_selector.xml
rename to car-ui-lib/res/color/car_ui_toolbar_tab_item_selector.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_divider.xml b/car-ui-lib/res/drawable/car_ui_divider.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_divider.xml
rename to car-ui-lib/res/drawable/car_ui_divider.xml
diff --git a/car-ui-lib/res/drawable/car_ui_focus_area_background_highlight.xml b/car-ui-lib/res/drawable/car_ui_focus_area_background_highlight.xml
new file mode 100644
index 0000000..74b8d13
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_focus_area_background_highlight.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="#00FF00"/>
+</shape>
diff --git a/car-ui-lib/res/drawable/car_ui_focus_area_foreground_highlight.xml b/car-ui-lib/res/drawable/car_ui_focus_area_foreground_highlight.xml
new file mode 100644
index 0000000..b6955f6
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_focus_area_foreground_highlight.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle" >
+    <stroke android:width="10dp" android:color="#FF0000"/>
+</shape>
diff --git a/car-ui-lib/res/drawable/car_ui_icon_add.xml b/car-ui-lib/res/drawable/car_ui_icon_add.xml
new file mode 100644
index 0000000..2fa6580
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_icon_add.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<!-- Used in Carboard's toolbar. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+<path
+    android:fillColor="@color/car_ui_toolbar_menu_item_icon_color"
+    android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
+</vector>
diff --git a/car-ui-lib/referencedesign/res/drawable/car_ui_icon_arrow_back.xml b/car-ui-lib/res/drawable/car_ui_icon_arrow_back.xml
similarity index 100%
rename from car-ui-lib/referencedesign/res/drawable/car_ui_icon_arrow_back.xml
rename to car-ui-lib/res/drawable/car_ui_icon_arrow_back.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_close.xml b/car-ui-lib/res/drawable/car_ui_icon_close.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_close.xml
rename to car-ui-lib/res/drawable/car_ui_icon_close.xml
diff --git a/car-ui-lib/res/drawable/car_ui_icon_delete.xml b/car-ui-lib/res/drawable/car_ui_icon_delete.xml
new file mode 100644
index 0000000..63aa782
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_icon_delete.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<!-- Used in Carboard's toolbar. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+<path
+    android:fillColor="@color/car_ui_toolbar_menu_item_icon_color"
+    android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
+</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_down.xml b/car-ui-lib/res/drawable/car_ui_icon_down.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_down.xml
rename to car-ui-lib/res/drawable/car_ui_icon_down.xml
diff --git a/car-ui-lib/res/drawable/car_ui_icon_edit.xml b/car-ui-lib/res/drawable/car_ui_icon_edit.xml
new file mode 100644
index 0000000..a418c7f
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_icon_edit.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<!-- Used in Carboard's toolbar. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+<path
+    android:fillColor="@color/car_ui_toolbar_menu_item_icon_color"
+    android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
+</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_overflow_menu.xml b/car-ui-lib/res/drawable/car_ui_icon_overflow_menu.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_overflow_menu.xml
rename to car-ui-lib/res/drawable/car_ui_icon_overflow_menu.xml
diff --git a/car-ui-lib/res/drawable/car_ui_icon_save.xml b/car-ui-lib/res/drawable/car_ui_icon_save.xml
new file mode 100644
index 0000000..f65682a
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_icon_save.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<!-- Used in Carboard's toolbar. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+<path
+    android:fillColor="@color/car_ui_toolbar_menu_item_icon_color"
+    android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
+</vector>
diff --git a/car-ui-lib/res/drawable/car_ui_icon_search.xml b/car-ui-lib/res/drawable/car_ui_icon_search.xml
new file mode 100644
index 0000000..52fbad9
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_icon_search.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+
+    <path
+        android:fillColor="@color/car_ui_toolbar_menu_item_icon_color"
+        android:pathData="M31 28h-1.59l-.55-.55C30.82 25.18 32 22.23 32 19c0-7.18-5.82-13-13-13S6 11.82 6
+19s5.82 13 13 13c3.23 0 6.18-1.18 8.45-3.13l.55 .55 V31l10 9.98L40.98 38 31
+28zm-12 0c-4.97 0-9-4.03-9-9s4.03-9 9-9 9 4.03 9 9-4.03 9-9 9z" />
+    <path
+        android:pathData="M0 0h48v48H0z" />
+</vector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_settings.xml b/car-ui-lib/res/drawable/car_ui_icon_settings.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_settings.xml
rename to car-ui-lib/res/drawable/car_ui_icon_settings.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_header_background.xml b/car-ui-lib/res/drawable/car_ui_list_header_background.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_header_background.xml
rename to car-ui-lib/res/drawable/car_ui_list_header_background.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_avatar_icon_outline.xml b/car-ui-lib/res/drawable/car_ui_list_item_avatar_icon_outline.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_avatar_icon_outline.xml
rename to car-ui-lib/res/drawable/car_ui_list_item_avatar_icon_outline.xml
diff --git a/car-ui-lib/res/drawable/car_ui_list_item_background.xml b/car-ui-lib/res/drawable/car_ui_list_item_background.xml
new file mode 100644
index 0000000..15585b2
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_list_item_background.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true">
+        <ripple android:color="@color/car_ui_rotary_focus_color">
+            <item android:id="@android:id/mask">
+                <shape android:shape="rectangle">
+                    <solid android:color="?android:colorAccent"/>
+                </shape>
+            </item>
+        </ripple>
+    </item>
+    <item>
+        <ripple android:color="?android:attr/colorControlHighlight">
+            <item android:id="@android:id/mask">
+                <shape android:shape="rectangle">
+                    <solid android:color="?android:colorAccent"/>
+                </shape>
+            </item>
+        </ripple>
+    </item>
+</selector>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_divider.xml b/car-ui-lib/res/drawable/car_ui_list_item_divider.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_divider.xml
rename to car-ui-lib/res/drawable/car_ui_list_item_divider.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_preference_icon_chevron.xml b/car-ui-lib/res/drawable/car_ui_preference_icon_chevron.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_preference_icon_chevron.xml
rename to car-ui-lib/res/drawable/car_ui_preference_icon_chevron.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_button_ripple_background.xml b/car-ui-lib/res/drawable/car_ui_recyclerview_button_ripple_background.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_button_ripple_background.xml
rename to car-ui-lib/res/drawable/car_ui_recyclerview_button_ripple_background.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_divider.xml b/car-ui-lib/res/drawable/car_ui_recyclerview_divider.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_divider.xml
rename to car-ui-lib/res/drawable/car_ui_recyclerview_divider.xml
diff --git a/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_ic_down.xml b/car-ui-lib/res/drawable/car_ui_recyclerview_ic_down.xml
similarity index 100%
rename from car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_ic_down.xml
rename to car-ui-lib/res/drawable/car_ui_recyclerview_ic_down.xml
diff --git a/car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_ic_up.xml b/car-ui-lib/res/drawable/car_ui_recyclerview_ic_up.xml
similarity index 100%
rename from car-ui-lib/referencedesign/res/drawable-ldrtl/car_ui_recyclerview_ic_up.xml
rename to car-ui-lib/res/drawable/car_ui_recyclerview_ic_up.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_scrollbar_thumb.xml b/car-ui-lib/res/drawable/car_ui_recyclerview_scrollbar_thumb.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recyclerview_scrollbar_thumb.xml
rename to car-ui-lib/res/drawable/car_ui_recyclerview_scrollbar_thumb.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_toolbar_menu_item_divider.xml b/car-ui-lib/res/drawable/car_ui_toolbar_menu_item_divider.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_toolbar_menu_item_divider.xml
rename to car-ui-lib/res/drawable/car_ui_toolbar_menu_item_divider.xml
diff --git a/car-ui-lib/res/drawable/car_ui_toolbar_menu_item_icon_background.xml b/car-ui-lib/res/drawable/car_ui_toolbar_menu_item_icon_background.xml
new file mode 100644
index 0000000..33594c2
--- /dev/null
+++ b/car-ui-lib/res/drawable/car_ui_toolbar_menu_item_icon_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~
+  ~ Copyright (C) 2019 Google Inc.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <size
+        android:width="@dimen/car_ui_toolbar_menu_item_icon_background_size"
+        android:height="@dimen/car_ui_toolbar_menu_item_icon_background_size"/>
+    <solid android:color="@color/car_ui_toolbar_menu_item_icon_background_color"/>
+</shape>
+
+
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml b/car-ui-lib/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
rename to car-ui-lib/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
diff --git a/car-ui-lib/res/layout-ldrtl/car_ui_recycler_view.xml b/car-ui-lib/res/layout-ldrtl/car_ui_recycler_view.xml
new file mode 100644
index 0000000..4847388
--- /dev/null
+++ b/car-ui-lib/res/layout-ldrtl/car_ui_recycler_view.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <com.android.car.ui.recyclerview.CarUiRecyclerViewContainer
+        android:id="@+id/car_ui_recycler_view"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_marginStart="@dimen/car_ui_scrollbar_margin"
+        android:tag="carUiRecyclerView"
+        android:layout_weight="1"/>
+
+    <include layout="@layout/car_ui_recyclerview_scrollbar"/>
+</merge>
diff --git a/car-ui-lib/res/layout/car_ui_alert_dialog_edit_text.xml b/car-ui-lib/res/layout/car_ui_alert_dialog_edit_text.xml
new file mode 100644
index 0000000..d654b2b
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_alert_dialog_edit_text.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
+    <EditText
+              android:id="@+id/textbox"
+              android:layout_width="match_parent"
+              android:layout_height="@dimen/car_ui_dialog_edittext_height"
+              android:layout_marginTop="@dimen/car_ui_dialog_edittext_margin_top"
+              android:layout_marginBottom="@dimen/car_ui_dialog_edittext_margin_bottom"
+              android:layout_marginStart="@dimen/car_ui_dialog_edittext_margin_start"
+              android:layout_marginEnd="@dimen/car_ui_dialog_edittext_margin_end"/>
+</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_alert_dialog_list.xml b/car-ui-lib/res/layout/car_ui_alert_dialog_list.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_alert_dialog_list.xml
rename to car-ui-lib/res/layout/car_ui_alert_dialog_list.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_alert_dialog_title_with_subtitle.xml b/car-ui-lib/res/layout/car_ui_alert_dialog_title_with_subtitle.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_alert_dialog_title_with_subtitle.xml
rename to car-ui-lib/res/layout/car_ui_alert_dialog_title_with_subtitle.xml
diff --git a/car-ui-lib/res/layout/car_ui_base_layout.xml b/car-ui-lib/res/layout/car_ui_base_layout.xml
new file mode 100644
index 0000000..14dfb75
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_base_layout.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/content">
+    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
+         first focusable view in the window automatically. Adding a FocusParkingView to the window
+         can fix this issue, because it can take focus, and it is transparent and its default focus
+         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
+         -->
+    <com.android.car.ui.FocusParkingView
+        android:layout_width="1dp"
+        android:layout_height="1dp"/>
+</FrameLayout>
diff --git a/car-ui-lib/res/layout/car_ui_base_layout_toolbar.xml b/car-ui-lib/res/layout/car_ui_base_layout_toolbar.xml
new file mode 100644
index 0000000..2d0cde8
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_base_layout_toolbar.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:tag="CarUiBaseLayoutToolbar">
+
+    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
+         first focusable view in the window automatically. Adding a FocusParkingView to the window
+         can fix this issue, because it can take focus, and it is transparent and its default focus
+         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
+         -->
+    <com.android.car.ui.FocusParkingView
+        android:layout_width="1dp"
+        android:layout_height="1dp"/>
+
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toTopOf="parent"/>
+
+    <com.android.car.ui.FocusArea
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/car_ui_toolbar_first_row_height">
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/car_ui_toolbar_background"
+            style="@style/Widget.CarUi.Toolbar.Container"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:tag="car_ui_top_inset"
+            app:layout_constraintTop_toTopOf="parent">
+            <com.android.car.ui.baselayout.ClickBlockingView
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"/>
+
+            <!-- The horizontal bias set to 0.0 here is so that when you set this view as GONE, it will
+                 be treated as if it's all the way to the left instead of centered in the margin -->
+            <FrameLayout
+                android:id="@+id/car_ui_toolbar_nav_icon_container"
+                style="@style/Widget.CarUi.Toolbar.NavIconContainer"
+                android:layout_width="@dimen/car_ui_toolbar_margin"
+                android:layout_height="0dp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintHorizontal_bias="0.0"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent">
+
+                <ImageView
+                    android:id="@+id/car_ui_toolbar_nav_icon"
+                    style="@style/Widget.CarUi.Toolbar.NavIcon"
+                    android:layout_width="@dimen/car_ui_toolbar_nav_icon_size"
+                    android:layout_height="@dimen/car_ui_toolbar_nav_icon_size"
+                    android:layout_gravity="center"
+                    android:scaleType="fitXY"/>
+
+                <ImageView
+                    android:id="@+id/car_ui_toolbar_logo"
+                    android:layout_width="@dimen/car_ui_toolbar_logo_size"
+                    android:layout_height="@dimen/car_ui_toolbar_logo_size"
+                    android:layout_gravity="center"
+                    android:scaleType="fitXY"/>
+            </FrameLayout>
+
+            <FrameLayout
+                android:id="@+id/car_ui_toolbar_title_logo_container"
+                style="@style/Widget.CarUi.Toolbar.LogoContainer"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toEndOf="@id/car_ui_toolbar_nav_icon_container"
+                app:layout_constraintTop_toTopOf="parent">
+
+                <ImageView
+                    android:id="@+id/car_ui_toolbar_title_logo"
+                    style="@style/Widget.CarUi.Toolbar.Logo"
+                    android:layout_width="@dimen/car_ui_toolbar_logo_size"
+                    android:layout_height="@dimen/car_ui_toolbar_logo_size"
+                    android:layout_gravity="center"
+                    android:scaleType="fitXY"/>
+            </FrameLayout>
+
+            <LinearLayout android:layout_height="wrap_content"
+                          android:layout_width="0dp"
+                          android:id="@+id/car_ui_toolbar_title_container"
+                          android:orientation="vertical"
+                          android:layout_marginStart="@dimen/car_ui_toolbar_title_margin_start"
+                          app:layout_goneMarginStart="@dimen/car_ui_toolbar_title_no_logo_margin_start"
+                          app:layout_constraintBottom_toBottomOf="parent"
+                          app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_menu_items_container"
+                          app:layout_constraintStart_toEndOf="@+id/car_ui_toolbar_title_logo_container"
+                          app:layout_constraintTop_toTopOf="parent">
+                <TextView android:id="@+id/car_ui_toolbar_title"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:singleLine="true"
+                          style="@style/Widget.CarUi.Toolbar.Title"/>
+                <TextView android:id="@+id/car_ui_toolbar_subtitle"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:visibility="gone"
+                          style="@style/Widget.CarUi.Toolbar.Subtitle"/>
+            </LinearLayout>
+
+            <com.android.car.ui.toolbar.TabLayout
+                android:id="@+id/car_ui_toolbar_tabs"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_menu_items_container"
+                app:layout_constraintHorizontal_bias="0.0"
+                app:layout_constraintStart_toEndOf="@+id/car_ui_toolbar_title_logo_container"
+                app:layout_constraintTop_toTopOf="parent"/>
+
+            <LinearLayout
+                android:id="@+id/car_ui_toolbar_menu_items_container"
+                style="@style/Widget.CarUi.Toolbar.MenuItem.Container"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:orientation="horizontal"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toTopOf="parent"/>
+
+            <FrameLayout
+                android:id="@+id/car_ui_toolbar_search_view_container"
+                android:layout_width="0dp"
+                android:layout_height="@dimen/car_ui_toolbar_search_height"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_menu_items_container"
+                app:layout_constraintStart_toEndOf="@+id/car_ui_toolbar_nav_icon_container"
+                app:layout_constraintTop_toTopOf="parent"/>
+
+            <ProgressBar
+                android:id="@+id/car_ui_toolbar_progress_bar"
+                style="@style/Widget.CarUi.Toolbar.ProgressBar"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:indeterminate="true"
+                android:visibility="gone"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </com.android.car.ui.FocusArea>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/res/layout/car_ui_base_layout_toolbar_legacy.xml b/car-ui-lib/res/layout/car_ui_base_layout_toolbar_legacy.xml
new file mode 100644
index 0000000..0a55746
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_base_layout_toolbar_legacy.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<!-- This layout is used on P or earlier, to support OEMs that shipped
+     on P and only customized the non-baselayout version of the toolbar -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <!-- When not in touch mode, if we clear focus in current window, Android will re-focus the
+         first focusable view in the window automatically. Adding a FocusParkingView to the window
+         can fix this issue, because it can take focus, and it is transparent and its default focus
+         highlight is disabled, so it's invisible to the user no matter whether it's focused or not.
+         -->
+    <com.android.car.ui.FocusParkingView
+        android:layout_width="1dp"
+        android:layout_height="1dp"/>
+
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.android.car.ui.toolbar.Toolbar
+        android:id="@+id/car_ui_toolbar"
+        android:tag="car_ui_top_inset"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/res/layout/car_ui_check_box_list_item.xml b/car-ui-lib/res/layout/car_ui_check_box_list_item.xml
new file mode 100644
index 0000000..2f5c7a8
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_check_box_list_item.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:background="?android:attr/selectableItemBackground"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/car_ui_list_item_check_box_height">
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/car_ui_check_box_start_guideline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_begin="@dimen/car_ui_list_item_check_box_start_inset" />
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/car_ui_check_box_end_guideline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_end="@dimen/car_ui_list_item_check_box_end_inset" />
+
+    <FrameLayout
+        android:id="@+id/check_box_container"
+        android:layout_width="@dimen/car_ui_list_item_check_box_icon_container_width"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="@+id/car_ui_check_box_start_guideline"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <CheckBox
+            android:id="@+id/checkbox"
+            android:clickable="false"
+            android:focusable="false"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center" />
+    </FrameLayout>
+
+    <TextView
+        android:id="@+id/text"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
+        android:textAppearance="@style/TextAppearance.CarUi.ListItem"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="@+id/car_ui_check_box_end_guideline"
+        app:layout_constraintStart_toEndOf="@+id/check_box_container"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/res/layout/car_ui_header_list_item.xml b/car-ui-lib/res/layout/car_ui_header_list_item.xml
new file mode 100644
index 0000000..d91512e
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_header_list_item.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:background="@drawable/car_ui_list_header_background"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/car_ui_list_item_header_height">
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/car_ui_list_item_start_guideline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_begin="@dimen/car_ui_list_item_header_start_inset" />
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/car_ui_header_list_item_text_start_margin"
+        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Header"
+        app:layout_constraintBottom_toTopOf="@+id/body"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="@id/car_ui_list_item_start_guideline"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed" />
+
+    <TextView
+        android:id="@+id/body"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/car_ui_list_item_text_no_icon_start_margin"
+        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="@id/car_ui_list_item_start_guideline"
+        app:layout_constraintTop_toBottomOf="@+id/title" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/res/layout/car_ui_list_item.xml b/car-ui-lib/res/layout/car_ui_list_item.xml
new file mode 100644
index 0000000..cc5c39a
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_list_item.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:tag="carUiListItem"
+    android:minHeight="@dimen/car_ui_list_item_height"
+    app:layout_optimizationLevel="none">
+
+    <!-- The following touch interceptor views are sized to encompass the specific sub-sections of
+    the list item view to easily control the bounds of a background ripple effects. -->
+    <View
+        android:id="@+id/touch_interceptor"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="@drawable/car_ui_list_item_background"
+        android:clickable="true"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <!-- This touch interceptor does not include the action container -->
+    <View
+        android:id="@+id/reduced_touch_interceptor"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="@drawable/car_ui_list_item_background"
+        android:clickable="true"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/action_container"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/car_ui_list_item_start_guideline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_begin="@dimen/car_ui_list_item_start_inset" />
+
+    <FrameLayout
+        android:id="@+id/icon_container"
+        android:layout_width="@dimen/car_ui_list_item_icon_container_width"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="@+id/car_ui_list_item_start_guideline"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="@dimen/car_ui_list_item_icon_size"
+            android:layout_height="@dimen/car_ui_list_item_icon_size"
+            android:layout_gravity="center"
+            android:visibility="gone"
+            android:scaleType="fitXY" />
+
+        <ImageView
+            android:id="@+id/content_icon"
+            android:layout_width="@dimen/car_ui_list_item_content_icon_width"
+            android:layout_height="@dimen/car_ui_list_item_content_icon_height"
+            android:layout_gravity="center"
+            android:visibility="gone"
+            android:scaleType="fitXY" />
+
+        <ImageView
+            android:id="@+id/avatar_icon"
+            android:background="@drawable/car_ui_list_item_avatar_icon_outline"
+            android:layout_width="@dimen/car_ui_list_item_avatar_icon_width"
+            android:layout_height="@dimen/car_ui_list_item_avatar_icon_height"
+            android:layout_gravity="center"
+            android:visibility="gone"
+            android:scaleType="fitXY" />
+    </FrameLayout>
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
+        android:singleLine="@bool/car_ui_list_item_single_line_title"
+        android:textAppearance="@style/TextAppearance.CarUi.ListItem"
+        app:layout_constraintBottom_toTopOf="@+id/body"
+        app:layout_constraintEnd_toStartOf="@+id/action_container"
+        app:layout_constraintStart_toEndOf="@+id/icon_container"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" />
+
+    <TextView
+        android:id="@+id/body"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
+        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/action_container"
+        app:layout_constraintStart_toEndOf="@+id/icon_container"
+        app:layout_constraintTop_toBottomOf="@+id/title"
+        app:layout_goneMarginStart="@dimen/car_ui_list_item_text_no_icon_start_margin" />
+
+    <!-- This touch interceptor is sized and positioned to encompass the action container   -->
+    <View
+        android:id="@+id/action_container_touch_interceptor"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="@drawable/car_ui_list_item_background"
+        android:clickable="true"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@id/action_container"
+        app:layout_constraintEnd_toEndOf="@id/action_container"
+        app:layout_constraintStart_toStartOf="@id/action_container"
+        app:layout_constraintTop_toTopOf="@id/action_container" />
+
+    <FrameLayout
+        android:id="@+id/action_container"
+        android:layout_width="wrap_content"
+        android:minWidth="@dimen/car_ui_list_item_icon_container_width"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="@+id/car_ui_list_item_end_guideline"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <View
+            android:id="@+id/action_divider"
+            android:layout_width="@dimen/car_ui_list_item_action_divider_width"
+            android:layout_height="@dimen/car_ui_list_item_action_divider_height"
+            android:layout_gravity="start|center_vertical"
+            android:background="@drawable/car_ui_list_item_divider" />
+
+        <Switch
+            android:id="@+id/switch_widget"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:clickable="false"
+            android:focusable="false" />
+
+        <CheckBox
+            android:id="@+id/checkbox_widget"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:clickable="false"
+            android:focusable="false" />
+
+        <RadioButton
+            android:id="@+id/radio_button_widget"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:clickable="false"
+            android:focusable="false" />
+
+        <ImageView
+            android:id="@+id/supplemental_icon"
+            android:layout_width="@dimen/car_ui_list_item_supplemental_icon_size"
+            android:layout_height="@dimen/car_ui_list_item_supplemental_icon_size"
+            android:layout_gravity="center"
+            android:scaleType="fitXY" />
+    </FrameLayout>
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/car_ui_list_item_end_guideline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_end="@dimen/car_ui_list_item_end_inset" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
+
diff --git a/car-ui-lib/res/layout/car_ui_list_preference.xml b/car-ui-lib/res/layout/car_ui_list_preference.xml
new file mode 100644
index 0000000..70bf96d
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_list_preference.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background">
+
+    <com.android.car.ui.recyclerview.CarUiRecyclerView
+        android:id="@+id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:tag="carUiPreferenceRecyclerView"
+        app:enableDivider="true" />
+
+</FrameLayout>
diff --git a/car-ui-lib/res/layout/car_ui_list_preference_with_toolbar.xml b/car-ui-lib/res/layout/car_ui_list_preference_with_toolbar.xml
new file mode 100644
index 0000000..f42c9f1
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_list_preference_with_toolbar.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background">
+
+    <com.android.car.ui.recyclerview.CarUiRecyclerView
+        android:id="@+id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:tag="carUiPreferenceRecyclerView"
+        app:enableDivider="true" />
+
+    <com.android.car.ui.toolbar.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:car_ui_state="subpage" />
+
+</FrameLayout>
diff --git a/car-ui-lib/res/layout/car_ui_preference.xml b/car-ui-lib/res/layout/car_ui_preference.xml
new file mode 100644
index 0000000..52dbd68
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_preference.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2019 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:tag="carUiPreference"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart">
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/car_ui_preference_icon_size"
+        android:layout_height="@dimen/car_ui_preference_icon_size"
+        android:layout_alignParentStart="true"
+        android:layout_centerVertical="true"
+        android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
+        android:layout_marginEnd="@dimen/car_ui_preference_icon_margin_end"
+        android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
+        android:scaleType="fitCenter"
+        style="@style/Preference.CarUi.Icon"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
+        android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
+        android:layout_toEndOf="@android:id/icon"
+        android:layout_toStartOf="@android:id/widget_frame"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"/>
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"/>
+
+    </LinearLayout>
+
+    <!-- Preference should place its actual preference widget here. -->
+    <FrameLayout
+        android:id="@android:id/widget_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentEnd="true"
+        android:layout_centerVertical="true"/>
+
+</RelativeLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_category.xml b/car-ui-lib/res/layout/car_ui_preference_category.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_category.xml
rename to car-ui-lib/res/layout/car_ui_preference_category.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_chevron.xml b/car-ui-lib/res/layout/car_ui_preference_chevron.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_chevron.xml
rename to car-ui-lib/res/layout/car_ui_preference_chevron.xml
diff --git a/car-ui-lib/res/layout/car_ui_preference_dialog_edittext.xml b/car-ui-lib/res/layout/car_ui_preference_dialog_edittext.xml
new file mode 100644
index 0000000..04c1c37
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_preference_dialog_edittext.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2019 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/car_ui_preference_edit_text_dialog_margin_top"
+    android:layout_marginBottom="@dimen/car_ui_preference_edit_text_dialog_margin_bottom"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@android:id/message"
+        style="@style/TextAppearance.CarUi.PreferenceEditTextDialogMessage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/car_ui_preference_edit_text_dialog_message_margin_bottom"
+        android:layout_marginStart="@dimen/car_ui_preference_edit_text_dialog_message_margin_start"
+        android:layout_marginEnd="@dimen/car_ui_preference_edit_text_dialog_message_margin_end"
+        android:visibility="gone"/>
+
+    <EditText
+        android:id="@android:id/edit"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/car_ui_preference_edit_text_dialog_text_margin_end"
+        android:layout_marginStart="@dimen/car_ui_preference_edit_text_dialog_text_margin_start"/>
+
+</LinearLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_dropdown.xml b/car-ui-lib/res/layout/car_ui_preference_dropdown.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_dropdown.xml
rename to car-ui-lib/res/layout/car_ui_preference_dropdown.xml
diff --git a/car-ui-lib/res/layout/car_ui_preference_fragment.xml b/car-ui-lib/res/layout/car_ui_preference_fragment.xml
new file mode 100644
index 0000000..e17664a
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_preference_fragment.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2019 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background">
+
+    <FrameLayout
+        android:id="@android:id/list_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <com.android.car.ui.recyclerview.CarUiRecyclerView
+            android:id="@+id/recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:tag="carUiPreferenceRecyclerView"
+            app:enableDivider="true"/>
+    </FrameLayout>
+</FrameLayout>
diff --git a/car-ui-lib/res/layout/car_ui_preference_fragment_with_toolbar.xml b/car-ui-lib/res/layout/car_ui_preference_fragment_with_toolbar.xml
new file mode 100644
index 0000000..cf55067
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_preference_fragment_with_toolbar.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/car_ui_preference_fragment_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background">
+
+    <FrameLayout
+        android:id="@android:id/list_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <com.android.car.ui.recyclerview.CarUiRecyclerView
+            android:id="@+id/recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:tag="carUiPreferenceRecyclerView"
+            app:enableDivider="true"/>
+    </FrameLayout>
+
+    <com.android.car.ui.toolbar.Toolbar
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/toolbar"
+        app:car_ui_state="subpage"/>
+</FrameLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_widget_checkbox.xml b/car-ui-lib/res/layout/car_ui_preference_widget_checkbox.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_widget_checkbox.xml
rename to car-ui-lib/res/layout/car_ui_preference_widget_checkbox.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_widget_seekbar.xml b/car-ui-lib/res/layout/car_ui_preference_widget_seekbar.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_widget_seekbar.xml
rename to car-ui-lib/res/layout/car_ui_preference_widget_seekbar.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_widget_switch.xml b/car-ui-lib/res/layout/car_ui_preference_widget_switch.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_preference_widget_switch.xml
rename to car-ui-lib/res/layout/car_ui_preference_widget_switch.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_radio_button_preference_widget.xml b/car-ui-lib/res/layout/car_ui_radio_button_preference_widget.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_radio_button_preference_widget.xml
rename to car-ui-lib/res/layout/car_ui_radio_button_preference_widget.xml
diff --git a/car-ui-lib/res/layout/car_ui_recycler_view.xml b/car-ui-lib/res/layout/car_ui_recycler_view.xml
new file mode 100644
index 0000000..1aa70fa
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_recycler_view.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <include layout="@layout/car_ui_recyclerview_scrollbar"/>
+
+    <com.android.car.ui.recyclerview.CarUiRecyclerViewContainer
+        android:id="@+id/car_ui_recycler_view"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_marginEnd="@dimen/car_ui_scrollbar_margin"
+        android:tag="carUiRecyclerView"
+        android:layout_weight="1"/>
+</merge>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recycler_view_item.xml b/car-ui-lib/res/layout/car_ui_recycler_view_item.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_recycler_view_item.xml
rename to car-ui-lib/res/layout/car_ui_recycler_view_item.xml
diff --git a/car-ui-lib/res/layout/car_ui_recyclerview_scrollbar.xml b/car-ui-lib/res/layout/car_ui_recyclerview_scrollbar.xml
new file mode 100644
index 0000000..5896819
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_recyclerview_scrollbar.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="@dimen/car_ui_scrollbar_container_width"
+    android:layout_height="match_parent"
+    android:id="@+id/car_ui_scroll_bar"
+    android:gravity="center">
+
+    <ImageView
+        android:id="@+id/car_ui_scrollbar_page_up"
+        android:layout_width="@dimen/car_ui_scrollbar_button_size"
+        android:layout_height="@dimen/car_ui_scrollbar_button_size"
+        android:background="@drawable/car_ui_recyclerview_button_ripple_background"
+        android:contentDescription="@string/car_ui_scrollbar_page_up_button"
+        android:focusable="false"
+        android:hapticFeedbackEnabled="false"
+        android:src="@drawable/car_ui_recyclerview_ic_up"
+        android:scaleType="centerInside"
+        android:layout_marginTop="15dp"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"/>
+
+    <!-- View height is dynamically calculated during layout. -->
+    <View
+        android:id="@+id/car_ui_scrollbar_thumb"
+        android:layout_width="@dimen/car_ui_scrollbar_thumb_width"
+        android:layout_height="0dp"
+        android:layout_gravity="center_horizontal"
+        android:background="@drawable/car_ui_recyclerview_scrollbar_thumb"
+        app:layout_constraintTop_toBottomOf="@+id/car_ui_scrollbar_page_up"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"/>
+
+    <View
+        android:id="@+id/car_ui_scrollbar_track"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginTop="@dimen/car_ui_scrollbar_separator_margin"
+        android:layout_marginBottom="@dimen/car_ui_scrollbar_separator_margin"
+        app:layout_constraintTop_toBottomOf="@+id/car_ui_scrollbar_page_up"
+        app:layout_constraintBottom_toTopOf="@+id/car_ui_scrollbar_page_down"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"/>
+
+    <ImageView
+        android:id="@+id/car_ui_scrollbar_page_down"
+        android:layout_width="@dimen/car_ui_scrollbar_button_size"
+        android:layout_height="@dimen/car_ui_scrollbar_button_size"
+        android:background="@drawable/car_ui_recyclerview_button_ripple_background"
+        android:contentDescription="@string/car_ui_scrollbar_page_down_button"
+        android:focusable="false"
+        android:hapticFeedbackEnabled="false"
+        android:src="@drawable/car_ui_recyclerview_ic_down"
+        android:scaleType="centerInside"
+        android:layout_marginBottom="15dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"/>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_seekbar_dialog.xml b/car-ui-lib/res/layout/car_ui_seekbar_dialog.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_seekbar_dialog.xml
rename to car-ui-lib/res/layout/car_ui_seekbar_dialog.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar.xml b/car-ui-lib/res/layout/car_ui_toolbar.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar.xml
rename to car-ui-lib/res/layout/car_ui_toolbar.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_menu_item.xml b/car-ui-lib/res/layout/car_ui_toolbar_menu_item.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_menu_item.xml
rename to car-ui-lib/res/layout/car_ui_toolbar_menu_item.xml
diff --git a/car-ui-lib/res/layout/car_ui_toolbar_search_view.xml b/car-ui-lib/res/layout/car_ui_toolbar_search_view.xml
new file mode 100644
index 0000000..c3ad68d
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_toolbar_search_view.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<merge
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <EditText
+        android:id="@+id/car_ui_toolbar_search_bar"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:hint="@string/car_ui_toolbar_default_search_hint"
+        android:textColorHint="@color/car_ui_toolbar_search_hint_text_color"
+        android:inputType="text"
+        android:singleLine="true"
+        android:imeOptions="actionSearch"
+        style="@style/Widget.CarUi.Toolbar.Search.EditText"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"/>
+
+    <!-- This constraintLayout is to provide a background for the ripples to draw on, so
+         they don't get drawn underneath the EditText's background -->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@android:color/transparent">
+        <FrameLayout
+            android:layout_width="@dimen/car_ui_toolbar_search_search_icon_container_width"
+            android:layout_height="match_parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent">
+            <ImageView
+                android:id="@+id/car_ui_toolbar_search_icon"
+                android:layout_width="@dimen/car_ui_toolbar_search_search_icon_size"
+                android:layout_height="@dimen/car_ui_toolbar_search_search_icon_size"
+                android:layout_gravity="center"
+                android:src="@drawable/car_ui_toolbar_search_search_icon"
+                android:scaleType="fitXY"
+                style="@style/Widget.CarUi.Toolbar.Search.SearchIcon"/>
+        </FrameLayout>
+
+        <FrameLayout
+            android:id="@+id/car_ui_toolbar_search_close"
+            android:layout_width="@dimen/car_ui_toolbar_search_close_icon_container_width"
+            android:layout_height="match_parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent">
+            <ImageView
+                android:layout_width="@dimen/car_ui_toolbar_search_close_icon_size"
+                android:layout_height="@dimen/car_ui_toolbar_search_close_icon_size"
+                android:layout_gravity="center"
+                android:src="@drawable/car_ui_toolbar_search_close_icon"
+                android:scaleType="fitXY"
+                style="@style/Widget.CarUi.Toolbar.Search.CloseIcon"/>
+        </FrameLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</merge>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_tab_item.xml b/car-ui-lib/res/layout/car_ui_toolbar_tab_item.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_tab_item.xml
rename to car-ui-lib/res/layout/car_ui_toolbar_tab_item.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_tab_item_flexible.xml b/car-ui-lib/res/layout/car_ui_toolbar_tab_item_flexible.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_tab_item_flexible.xml
rename to car-ui-lib/res/layout/car_ui_toolbar_tab_item_flexible.xml
diff --git a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_two_row.xml b/car-ui-lib/res/layout/car_ui_toolbar_two_row.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_toolbar_two_row.xml
rename to car-ui-lib/res/layout/car_ui_toolbar_two_row.xml
diff --git a/car-ui-lib/res/layout/car_ui_two_action_preference.xml b/car-ui-lib/res/layout/car_ui_two_action_preference.xml
new file mode 100644
index 0000000..4ad6ce4
--- /dev/null
+++ b/car-ui-lib/res/layout/car_ui_two_action_preference.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 2018 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@android:color/transparent"
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall">
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:clipToPadding="false"
+        android:gravity="start|center_vertical"
+        android:paddingBottom="@dimen/car_ui_preference_content_margin_bottom"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingTop="@dimen/car_ui_preference_content_margin_top">
+        <androidx.preference.internal.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="@dimen/car_ui_preference_icon_size"
+            android:layout_height="@dimen/car_ui_preference_icon_size"
+            android:layout_marginEnd="@dimen/car_ui_preference_icon_margin_end"/>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:orientation="vertical">
+            <TextView
+                android:id="@android:id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ellipsize="end"
+                android:singleLine="true"
+                android:textAppearance="@style/TextAppearance.CarUi.PreferenceTitle"/>
+            <TextView
+                android:id="@android:id/summary"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.CarUi.PreferenceSummary"/>
+        </LinearLayout>
+    </LinearLayout>
+    <LinearLayout
+        android:id="@+id/action_widget_container"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent">
+        <View
+            android:layout_width="@dimen/car_ui_divider_width"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="@dimen/car_ui_preference_content_margin_bottom"
+            android:layout_marginTop="@dimen/car_ui_preference_content_margin_top"
+            style="@style/Preference.CarUi.Divider"/>
+        <!-- Preference should place its actual preference widget here. -->
+        <FrameLayout
+            android:id="@android:id/widget_frame"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:background="?android:attr/selectableItemBackground"
+            android:minWidth="?android:attr/listPreferredItemHeightSmall"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+            android:paddingStart="?android:attr/listPreferredItemPaddingStart"/>
+    </LinearLayout>
+</LinearLayout>
diff --git a/car-ui-lib/res/values-af/strings.xml b/car-ui-lib/res/values-af/strings.xml
new file mode 100644
index 0000000..75130b9
--- /dev/null
+++ b/car-ui-lib/res/values-af/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Soek …"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Rollees af"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Rollees op"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Terug"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Soek"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Instellings"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Oorloop"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Aan"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Af"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Kenmerk is nie beskikbaar terwyl jy bestuur nie"</string>
+</resources>
diff --git a/car-ui-lib/res/values-am/strings.xml b/car-ui-lib/res/values-am/strings.xml
new file mode 100644
index 0000000..a78faec
--- /dev/null
+++ b/car-ui-lib/res/values-am/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ይፈልጉ…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"ወደ ታች ይሸብልሉ"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ወደ ላይ ይሸብልሉ"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ተመለስ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ፈልግ"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ቅንብሮች"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ትርፍ ፍሰት"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"አብራ"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ቅናሽ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"እየነዱ ሳለ ባህሪው አይገኝም"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ar/strings.xml b/car-ui-lib/res/values-ar/strings.xml
new file mode 100644
index 0000000..b64c521
--- /dev/null
+++ b/car-ui-lib/res/values-ar/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"بحث…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"التمرير للأسفل"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"التمرير للأعلى"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"رجوع"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"بحث"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"إعدادات"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"القائمة الكاملة"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"مفعّل"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"غير مفعَّل"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"لا تتوفَّر هذه الميزة أثناء القيادة."</string>
+</resources>
diff --git a/car-ui-lib/res/values-as/strings.xml b/car-ui-lib/res/values-as/strings.xml
new file mode 100644
index 0000000..6c7656b
--- /dev/null
+++ b/car-ui-lib/res/values-as/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"সন্ধান কৰক…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"তললৈ স্ক্ৰ’ল কৰক"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ওপৰলৈ স্ক্ৰ’ল কৰক"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"উভতি যাওক"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"সন্ধান কৰক"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ছেটিংসমূহ"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"অভাৰফ্ল’"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"অন আছে"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"অফ আছে"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"গাড়ী চলাই থকা সময়ত এই সুবিধাটো উপলব্ধ নহয়"</string>
+</resources>
diff --git a/car-ui-lib/res/values-az/strings.xml b/car-ui-lib/res/values-az/strings.xml
new file mode 100644
index 0000000..5e3670d
--- /dev/null
+++ b/car-ui-lib/res/values-az/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Axtarış…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Aşağı sürüşdürün"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Yuxarı sürüşdürün"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Geri"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Axtarış"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Ayarlar"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Kənara çıxma"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Aktiv"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Deaktiv"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funksiya avtomobil idarə edərkən əlçatan deyil"</string>
+</resources>
diff --git a/car-ui-lib/res/values-b+sr+Latn/strings.xml b/car-ui-lib/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..f1c2eb7
--- /dev/null
+++ b/car-ui-lib/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Pretražite…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Pomerite nadole"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Pomerite nagore"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Nazad"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Pretraži"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Podešavanja"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Preklopni meni"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Uključeno"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Isključeno"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkcija nije dostupna tokom vožnje"</string>
+</resources>
diff --git a/car-ui-lib/res/values-be/strings.xml b/car-ui-lib/res/values-be/strings.xml
new file mode 100644
index 0000000..054ba36
--- /dev/null
+++ b/car-ui-lib/res/values-be/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Пошук…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Прагартаць уніз"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Прагартаць уверх"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Назад"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Пошук"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Налады"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Дадатковае меню"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Уключана"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Выключана"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Функцыя недаступная, калі аўтамабіль рухаецца"</string>
+</resources>
diff --git a/car-ui-lib/res/values-bg/strings.xml b/car-ui-lib/res/values-bg/strings.xml
new file mode 100644
index 0000000..3ed930c
--- /dev/null
+++ b/car-ui-lib/res/values-bg/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Търсете…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Превъртане надолу"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Превъртане нагоре"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Назад"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Търсене"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Настройки"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Препълване"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Вкл."</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Изкл."</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Функцията не е налице по време на шофиране"</string>
+</resources>
diff --git a/car-ui-lib/res/values-bn/strings.xml b/car-ui-lib/res/values-bn/strings.xml
new file mode 100644
index 0000000..bb34e33
--- /dev/null
+++ b/car-ui-lib/res/values-bn/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"সার্চ করুন…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"নিচের দিকে স্ক্রল করুন"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"উপরের দিকে স্ক্রল করুন"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ফিরুন"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"সার্চ করুন"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"সেটিংস"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ওভারফ্লো মেনু"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"চালু"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"বন্ধ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"গাড়ি চালানোর সময় এই ফিচার কাজ করবে না"</string>
+</resources>
diff --git a/car-ui-lib/res/values-bs/strings.xml b/car-ui-lib/res/values-bs/strings.xml
new file mode 100644
index 0000000..7b5376a
--- /dev/null
+++ b/car-ui-lib/res/values-bs/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Pretražite…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Klizanje prema dolje"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Klizanje prema gore"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Nazad"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Pretraživanje"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Postavke"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Preklopni meni"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Uključeno"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Isključeno"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkcija nije dostupna tokom vožnje"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ca/strings.xml b/car-ui-lib/res/values-ca/strings.xml
new file mode 100644
index 0000000..5d284b7
--- /dev/null
+++ b/car-ui-lib/res/values-ca/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Cerca…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Desplaça cap avall"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Desplaça cap amunt"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Enrere"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Cerca"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Configuració"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Menú addicional"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Activat"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Desactivat"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Aquesta funció no està disponible mentre condueixes"</string>
+</resources>
diff --git a/car-ui-lib/res/values-cs/strings.xml b/car-ui-lib/res/values-cs/strings.xml
new file mode 100644
index 0000000..d230329
--- /dev/null
+++ b/car-ui-lib/res/values-cs/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Vyhledat…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Posunout dolů"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Posunout nahoru"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Zpět"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Hledat"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Nastavení"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Rozbalovací nabídka"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Zap"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Vyp"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkce při řízení není dostupná"</string>
+</resources>
diff --git a/car-ui-lib/res/values-da/strings.xml b/car-ui-lib/res/values-da/strings.xml
new file mode 100644
index 0000000..630494f
--- /dev/null
+++ b/car-ui-lib/res/values-da/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Søg…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Rul ned"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Rul op"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Tilbage"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Søg"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Indstillinger"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overløb"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Til"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Fra"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funktionen er ikke tilgængelig, mens du kører"</string>
+</resources>
diff --git a/car-ui-lib/res/values-de/strings.xml b/car-ui-lib/res/values-de/strings.xml
new file mode 100644
index 0000000..2c655d4
--- /dev/null
+++ b/car-ui-lib/res/values-de/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Suchen…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Nach unten scrollen"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Nach oben scrollen"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Zurück"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Suchen"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Einstellungen"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Dreipunkt-Menü"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"An"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Aus"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funktion während der Fahrt nicht verfügbar"</string>
+</resources>
diff --git a/car-ui-lib/res/values-el/strings.xml b/car-ui-lib/res/values-el/strings.xml
new file mode 100644
index 0000000..d08f663
--- /dev/null
+++ b/car-ui-lib/res/values-el/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Αναζήτηση…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Κύλιση προς τα κάτω"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Κύλιση προς τα επάνω"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Πίσω"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Αναζήτηση"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Ρυθμίσεις"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Υπερχείλιση"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Ενεργό"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Ανενεργή"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Η λειτουργία δεν διατίθεται κατά τη διάρκεια της οδήγησης."</string>
+</resources>
diff --git a/car-ui-lib/res/values-en-rAU/strings.xml b/car-ui-lib/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..271d61f
--- /dev/null
+++ b/car-ui-lib/res/values-en-rAU/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Search…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Scroll down"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Scroll up"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Back"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Search"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Settings"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overflow"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"On"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Off"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Feature not available while driving"</string>
+</resources>
diff --git a/car-ui-lib/res/values-en-rCA/strings.xml b/car-ui-lib/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..271d61f
--- /dev/null
+++ b/car-ui-lib/res/values-en-rCA/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Search…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Scroll down"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Scroll up"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Back"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Search"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Settings"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overflow"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"On"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Off"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Feature not available while driving"</string>
+</resources>
diff --git a/car-ui-lib/res/values-en-rGB/strings.xml b/car-ui-lib/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..271d61f
--- /dev/null
+++ b/car-ui-lib/res/values-en-rGB/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Search…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Scroll down"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Scroll up"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Back"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Search"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Settings"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overflow"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"On"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Off"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Feature not available while driving"</string>
+</resources>
diff --git a/car-ui-lib/res/values-en-rIN/strings.xml b/car-ui-lib/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..271d61f
--- /dev/null
+++ b/car-ui-lib/res/values-en-rIN/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Search…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Scroll down"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Scroll up"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Back"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Search"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Settings"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overflow"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"On"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Off"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Feature not available while driving"</string>
+</resources>
diff --git a/car-ui-lib/res/values-en-rXC/strings.xml b/car-ui-lib/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..9993024
--- /dev/null
+++ b/car-ui-lib/res/values-en-rXC/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‎Search…‎‏‎‎‏‎"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎Scroll down‎‏‎‎‏‎"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎Scroll up‎‏‎‎‏‎"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎Back‎‏‎‎‏‎"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎Search‎‏‎‎‏‎"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎Settings‎‏‎‎‏‎"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎Overflow‎‏‎‎‏‎"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎On‎‏‎‎‏‎"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎Off‎‏‎‎‏‎"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎Feature not available while driving‎‏‎‎‏‎"</string>
+</resources>
diff --git a/car-ui-lib/res/values-es-rUS/strings.xml b/car-ui-lib/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..71178e9
--- /dev/null
+++ b/car-ui-lib/res/values-es-rUS/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Buscar…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Desplazamiento hacia abajo"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Desplazamiento hacia arriba"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Atrás"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Buscar"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Configuración"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Ampliado"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Sí"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"No"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Esta función no está disponible mientras conduces"</string>
+</resources>
diff --git a/car-ui-lib/res/values-es/strings.xml b/car-ui-lib/res/values-es/strings.xml
new file mode 100644
index 0000000..dd5f07f
--- /dev/null
+++ b/car-ui-lib/res/values-es/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Realiza una búsqueda…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Desplazarse hacia abajo"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Desplazarse hacia arriba"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Atrás"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Buscar"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Ajustes"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Menú adicional"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Activado"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Desactivado"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Función no disponible mientras conduces"</string>
+</resources>
diff --git a/car-ui-lib/res/values-et/strings.xml b/car-ui-lib/res/values-et/strings.xml
new file mode 100644
index 0000000..2c4c2bb
--- /dev/null
+++ b/car-ui-lib/res/values-et/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Otsing …"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Keri alla"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Keri üles"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Tagasi"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Otsi"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Seaded"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Ületäide"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Sees"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Väljas"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funktsioon pole sõidu ajal saadaval"</string>
+</resources>
diff --git a/car-ui-lib/res/values-eu/strings.xml b/car-ui-lib/res/values-eu/strings.xml
new file mode 100644
index 0000000..b8b0c79
--- /dev/null
+++ b/car-ui-lib/res/values-eu/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Bilatu…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Egin behera"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Egin gora"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Atzera"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Bilaketa"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Ezarpenak"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Luzapena"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Aktibatuta"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Desaktibatuta"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Eginbide hau ezin da erabili gidatu bitartean"</string>
+</resources>
diff --git a/car-ui-lib/res/values-fa/strings.xml b/car-ui-lib/res/values-fa/strings.xml
new file mode 100644
index 0000000..c0cc566
--- /dev/null
+++ b/car-ui-lib/res/values-fa/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"جستجو…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"پیمایش به پایین"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"پیمایش به بالا"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"برگشت"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"جستجو"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"تنظیمات"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"لبریزشده"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"روشن"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"خاموش"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"این ویژگی هنگام رانندگی در دسترس نیست"</string>
+</resources>
diff --git a/car-ui-lib/res/values-fi/strings.xml b/car-ui-lib/res/values-fi/strings.xml
new file mode 100644
index 0000000..4b4a942
--- /dev/null
+++ b/car-ui-lib/res/values-fi/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Hae…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Vieritä alas"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Vieritä ylös"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Takaisin"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Haku"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Asetukset"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Ylivuoto"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Päällä"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Pois"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Ominaisuus ei ole käytettävissä ajon aikana"</string>
+</resources>
diff --git a/car-ui-lib/res/values-fr-rCA/strings.xml b/car-ui-lib/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..b83c159
--- /dev/null
+++ b/car-ui-lib/res/values-fr-rCA/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Rechercher…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Faire défiler vers le bas"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Faire défiler vers le haut"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Retour"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Rechercher"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Paramètres"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Menu déroulant"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Activé"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Désactivé"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Cette fonctionnalité n\'est pas accessible durant la conduite"</string>
+</resources>
diff --git a/car-ui-lib/res/values-fr/strings.xml b/car-ui-lib/res/values-fr/strings.xml
new file mode 100644
index 0000000..067f056
--- /dev/null
+++ b/car-ui-lib/res/values-fr/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Rechercher…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Défiler vers le bas"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Défiler vers le haut"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Retour"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Rechercher"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Paramètres"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Menu à développer"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Activé"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Désactivé"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Fonctionnalité non disponible lorsque vous conduisez"</string>
+</resources>
diff --git a/car-ui-lib/res/values-gl/strings.xml b/car-ui-lib/res/values-gl/strings.xml
new file mode 100644
index 0000000..853a780
--- /dev/null
+++ b/car-ui-lib/res/values-gl/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Busca…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Desprazarse cara abaixo"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Desprazarse cara arriba"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Atrás"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Buscar"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Configuración"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Elemento do menú adicional"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Si"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Non"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Esta función non está dispoñible mentres conduces"</string>
+</resources>
diff --git a/car-ui-lib/res/values-gu/strings.xml b/car-ui-lib/res/values-gu/strings.xml
new file mode 100644
index 0000000..82f5ba4
--- /dev/null
+++ b/car-ui-lib/res/values-gu/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"શોધો…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"નીચે સ્ક્રોલ કરો"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ઉપર સ્ક્રોલ કરો"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"પાછળ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"શોધો"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"સેટિંગ"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ઓવરફ્લો"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ચાલુ"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"બંધ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ડ્રાઇવિંગ કરતી વખતે આ સુવિધા ઉપલબ્ધ રહેશે નહીં"</string>
+</resources>
diff --git a/car-ui-lib/res/values-hi/strings.xml b/car-ui-lib/res/values-hi/strings.xml
new file mode 100644
index 0000000..30edfb9
--- /dev/null
+++ b/car-ui-lib/res/values-hi/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"खोजें…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"नीचे की ओर स्क्रोल करें"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ऊपर की ओर स्क्रोल करें"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"वापस जाएं"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"खोजें"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"सेटिंग"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ओवरफ़्लो मेन्यू"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"चालू है"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"बंद है"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"गाड़ी चलाते समय इस सुविधा का इस्तेमाल नहीं किया जा सकता"</string>
+</resources>
diff --git a/car-ui-lib/res/values-hr/strings.xml b/car-ui-lib/res/values-hr/strings.xml
new file mode 100644
index 0000000..2e2fcc7
--- /dev/null
+++ b/car-ui-lib/res/values-hr/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Pretražite…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Pomak prema dolje"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Pomak prema gore"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Natrag"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Pretražite"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Postavke"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Dodatno"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Uključeno"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Isključeno"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Značajka nije dostupna tijekom vožnje"</string>
+</resources>
diff --git a/car-ui-lib/res/values-hu/strings.xml b/car-ui-lib/res/values-hu/strings.xml
new file mode 100644
index 0000000..f731494
--- /dev/null
+++ b/car-ui-lib/res/values-hu/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Keresés…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Görgetés lefelé"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Görgetés felfelé"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Vissza"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Keresés"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Beállítások"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"További elemeket tartalmazó menü"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Be"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Ki"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Vezetés közben nem áll rendelkezésre a funkció"</string>
+</resources>
diff --git a/car-ui-lib/res/values-hy/strings.xml b/car-ui-lib/res/values-hy/strings.xml
new file mode 100644
index 0000000..fc5f19e
--- /dev/null
+++ b/car-ui-lib/res/values-hy/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Որոնում…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Ոլորել վար"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Ոլորել վեր"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Հետ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Որոնել"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Կարգավորումներ"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Լրացուցիչ ընտրացանկ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Միացված է"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Անջատված է"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Վարելու ընթացքում գործառույթը հասանելի չէ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-in/strings.xml b/car-ui-lib/res/values-in/strings.xml
new file mode 100644
index 0000000..3bffad0
--- /dev/null
+++ b/car-ui-lib/res/values-in/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Telusuri…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Scroll ke bawah"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Scroll ke atas"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Kembali"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Penelusuran"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Setelan"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Tambahan"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Aktif"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Nonaktif"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Fitur tidak tersedia saat mengemudi"</string>
+</resources>
diff --git a/car-ui-lib/res/values-is/strings.xml b/car-ui-lib/res/values-is/strings.xml
new file mode 100644
index 0000000..206dd62
--- /dev/null
+++ b/car-ui-lib/res/values-is/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Leita…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Fletta niður"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Fletta upp"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Til baka"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Leit"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Stillingar"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Yfirflæði"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Kveikt"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Slökkt"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Þessi eiginleiki er ekki í boði meðan á akstri stendur"</string>
+</resources>
diff --git a/car-ui-lib/res/values-it/strings.xml b/car-ui-lib/res/values-it/strings.xml
new file mode 100644
index 0000000..9534e68
--- /dev/null
+++ b/car-ui-lib/res/values-it/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Cerca…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Scorri verso il basso"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Scorri verso l\'alto"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Indietro"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Cerca"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Impostazioni"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Extra"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"On"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Off"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funzionalità non disponibile durante la guida"</string>
+</resources>
diff --git a/car-ui-lib/res/values-iw/strings.xml b/car-ui-lib/res/values-iw/strings.xml
new file mode 100644
index 0000000..24b6a1d
--- /dev/null
+++ b/car-ui-lib/res/values-iw/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"חיפוש…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"גלילה למטה"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"גלילה למעלה"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"חזרה"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"חיפוש"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"הגדרות"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"אפשרויות נוספות"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"פועל"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"כבוי"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"התכונה לא זמינה בזמן הנהיגה"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ja/strings.xml b/car-ui-lib/res/values-ja/strings.xml
new file mode 100644
index 0000000..b80bef6
--- /dev/null
+++ b/car-ui-lib/res/values-ja/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"検索…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"下にスクロール"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"上にスクロール"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"戻る"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"検索"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"設定"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"オーバーフロー"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ON"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"OFF"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"この機能は運転中は利用できません"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ka/strings.xml b/car-ui-lib/res/values-ka/strings.xml
new file mode 100644
index 0000000..3c90f08
--- /dev/null
+++ b/car-ui-lib/res/values-ka/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ძიება…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"ქვემოთ გადაადგილება"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ზემოთ გადაადგილება"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"უკან"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ძიება"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"პარამეტრები"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"გადავსება"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ჩართულია"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"გამორთულია"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ფუნქცია მიუწვდომელია მანქანის მართვისას"</string>
+</resources>
diff --git a/car-ui-lib/res/values-kk/strings.xml b/car-ui-lib/res/values-kk/strings.xml
new file mode 100644
index 0000000..80170fa
--- /dev/null
+++ b/car-ui-lib/res/values-kk/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Іздеу…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Төмен айналдыру"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Жоғары айналдыру"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Артқа"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Іздеу"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Параметрлер"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Қосымша мәзір"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Қосулы"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Өшірулі"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Көлік жүргізу кезінде бұл функция жұмыс істемейді."</string>
+</resources>
diff --git a/car-ui-lib/res/values-km/strings.xml b/car-ui-lib/res/values-km/strings.xml
new file mode 100644
index 0000000..044333c
--- /dev/null
+++ b/car-ui-lib/res/values-km/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ស្វែងរក…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"រំកិលចុះក្រោម"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"រំកិល​​ឡើង​លើ"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ថយក្រោយ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ស្វែងរក"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ការកំណត់"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ម៉ឺនុយបន្ថែម"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"បើក"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"បិទ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"មិនអាច​ប្រើមុខងារ​នេះបានទេ ខណៈពេល​កំពុង​បើកបរ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-kn/strings.xml b/car-ui-lib/res/values-kn/strings.xml
new file mode 100644
index 0000000..31e4e0c
--- /dev/null
+++ b/car-ui-lib/res/values-kn/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ಹುಡುಕಿ…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"ಕೆಳಗೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ಮೇಲೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ಹಿಂದಕ್ಕೆ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ಹುಡುಕಿ"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ಓವರ್‌ಫ್ಲೋ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ಆನ್ ಆಗಿದೆ"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ಡ್ರೈವ್ ಮಾಡುವಾಗ ಈ ವೈಶಿಷ್ಟ್ಯ ಲಭ್ಯವಿಲ್ಲ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ko/strings.xml b/car-ui-lib/res/values-ko/strings.xml
new file mode 100644
index 0000000..f8efa76
--- /dev/null
+++ b/car-ui-lib/res/values-ko/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"검색…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"아래로 스크롤"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"위로 스크롤"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"뒤로"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"검색"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"설정"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"더보기"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"사용 설정됨"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"사용 중지됨"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"운전 중에 사용할 수 없는 기능입니다."</string>
+</resources>
diff --git a/car-ui-lib/res/values-ky/strings.xml b/car-ui-lib/res/values-ky/strings.xml
new file mode 100644
index 0000000..5143048
--- /dev/null
+++ b/car-ui-lib/res/values-ky/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Издөө…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Төмөн сыдыруу"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Жогору сыдыруу"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Артка"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Издөө"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Жөндөөлөр"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Кошумча меню"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Күйүк"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Өчүк"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Унаа айдаганда бул функция жеткиликтүү эмес"</string>
+</resources>
diff --git a/car-ui-lib/res/values-lo/strings.xml b/car-ui-lib/res/values-lo/strings.xml
new file mode 100644
index 0000000..3c65459
--- /dev/null
+++ b/car-ui-lib/res/values-lo/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ຊອກຫາ…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"ເລື່ອນລົງ"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ເລື່ອນຂຶ້ນ"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ກັບຄືນ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ຊອກຫາ"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ການຕັ້ງຄ່າ"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ລົ້ນ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ເປີດ"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ປິດ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ຄຸນສົມບັດບໍ່ສາມາດໃຊ້ໄດ້ໃນເວລາຂັບລົດ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-lt/strings.xml b/car-ui-lib/res/values-lt/strings.xml
new file mode 100644
index 0000000..674e342
--- /dev/null
+++ b/car-ui-lib/res/values-lt/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Ieškoti…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Slinkti žemyn"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Slinkti aukštyn"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Atgal"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Paieška"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Nustatymai"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Perpildymas"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Įjungta"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Išjungta"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkcija nepasiekiama vairuojant"</string>
+</resources>
diff --git a/car-ui-lib/res/values-lv/strings.xml b/car-ui-lib/res/values-lv/strings.xml
new file mode 100644
index 0000000..fa02dd9
--- /dev/null
+++ b/car-ui-lib/res/values-lv/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Meklēt…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Ritināt uz leju"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Ritināt uz augšu"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Atpakaļ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Meklēšana"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Iestatījumi"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Pārpilde"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Ieslēgta"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Izslēgta"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkcija nav pieejama braukšanas laikā."</string>
+</resources>
diff --git a/car-ui-lib/res/values-mk/strings.xml b/car-ui-lib/res/values-mk/strings.xml
new file mode 100644
index 0000000..9905cd0
--- /dev/null
+++ b/car-ui-lib/res/values-mk/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Пребарувајте…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Оди надолу"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Оди нагоре"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Назад"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Пребарување"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Поставки"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Прелевање"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Вклучено"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Исклучено"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Функцијата не е достапна при возење"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ml/strings.xml b/car-ui-lib/res/values-ml/strings.xml
new file mode 100644
index 0000000..25c5631
--- /dev/null
+++ b/car-ui-lib/res/values-ml/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"തിരയുക…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"താഴോട്ട് സ്‌ക്രോൾ ചെയ്യുക"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"മുകളിലോട്ട് സ്‌ക്രോൾ ചെയ്യുക"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"മടങ്ങുക"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"തിരയുക"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ക്രമീകരണം"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ഓവർഫ്ലോ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ഓണാണ്"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ഓഫാണ്"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ഡ്രൈവ് ചെയ്യുമ്പോൾ ഫീച്ചർ ലഭ്യമല്ല"</string>
+</resources>
diff --git a/car-ui-lib/res/values-mn/strings.xml b/car-ui-lib/res/values-mn/strings.xml
new file mode 100644
index 0000000..ac81c8a
--- /dev/null
+++ b/car-ui-lib/res/values-mn/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Хайх..."</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Доош гүйлгэх"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Дээш гүйлгэх"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Буцах"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Хайлт"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Тохиргоо"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Халих"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Асаалттай"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Унтраалттай"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Жолоо барьж байх үед онцлог боломжгүй"</string>
+</resources>
diff --git a/car-ui-lib/res/values-mr/strings.xml b/car-ui-lib/res/values-mr/strings.xml
new file mode 100644
index 0000000..44e74df
--- /dev/null
+++ b/car-ui-lib/res/values-mr/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"शोधा…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"खाली स्क्रोल करा"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"वर स्क्रोल करा"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"मागे जा"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"शोधा"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"सेटिंग्ज"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ओव्हरफ्लो"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"सुरू आहे"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"बंद आहे"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ड्राइव्ह करताना वैशिष्ट्य उपलब्ध नाही"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ms/strings.xml b/car-ui-lib/res/values-ms/strings.xml
new file mode 100644
index 0000000..c5c780f
--- /dev/null
+++ b/car-ui-lib/res/values-ms/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Cari…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Tatal ke bawah"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Tatal ke atas"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Kembali"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Cari"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Tetapan"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Limpahan"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Hidup"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Mati"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Ciri tidak tersedia semasa anda memandu"</string>
+</resources>
diff --git a/car-ui-lib/res/values-my/strings.xml b/car-ui-lib/res/values-my/strings.xml
new file mode 100644
index 0000000..b1c9f63
--- /dev/null
+++ b/car-ui-lib/res/values-my/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ရှာဖွေရန်…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"အောက်သို့ လှိမ့်ရန်"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"အပေါ်သို့ လှိမ့်ရန်"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"နောက်သို့"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ရှာဖွေခြင်း"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ဆက်တင်များ"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"အပို"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ဖွင့်ထားသည်"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ပိတ်ထားသည်"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ကားမောင်းနေစဉ် ဝန်ဆောင်မှု မရနိုင်ပါ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-nb/strings.xml b/car-ui-lib/res/values-nb/strings.xml
new file mode 100644
index 0000000..ed93746
--- /dev/null
+++ b/car-ui-lib/res/values-nb/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Søk"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Rull ned"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Rull opp"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Tilbake"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Søk"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Innstillinger"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overflyt"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"På"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Av"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funksjonen er ikke tilgjengelig når du kjører"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ne/strings.xml b/car-ui-lib/res/values-ne/strings.xml
new file mode 100644
index 0000000..9e86b17
--- /dev/null
+++ b/car-ui-lib/res/values-ne/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"खोज्नुहोस्…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"तलतिर स्क्रोल गर्नुहोस्"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"माथितिर स्क्रोल गर्नु…"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"पछाडि"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"खोज्नुहोस्"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"सेटिङ"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ओभरफ्लो"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"सुचारू छ"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"बन्द छ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"सवारी साधन चलाइरहेका बेला यो सुविधा उपलब्ध हुँदैन"</string>
+</resources>
diff --git a/car-ui-lib/res/values-night/colors.xml b/car-ui-lib/res/values-night/colors.xml
new file mode 100644
index 0000000..4295f07
--- /dev/null
+++ b/car-ui-lib/res/values-night/colors.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <!-- Rotary focus -->
+    <color name="car_ui_rotary_focus_color">#2371cd</color>
+</resources>
diff --git a/car-ui-lib/res/values-nl/strings.xml b/car-ui-lib/res/values-nl/strings.xml
new file mode 100644
index 0000000..50418fc
--- /dev/null
+++ b/car-ui-lib/res/values-nl/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Zoeken…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Omlaag scrollen"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Omhoog scrollen"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Terug"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Zoeken"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Instellingen"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overloop"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Aan"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Uit"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Functie niet beschikbaar tijdens het rijden"</string>
+</resources>
diff --git a/car-ui-lib/res/values-or/strings.xml b/car-ui-lib/res/values-or/strings.xml
new file mode 100644
index 0000000..f49d810
--- /dev/null
+++ b/car-ui-lib/res/values-or/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ସନ୍ଧାନ କରନ୍ତୁ…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"ତଳକୁ ସ୍କ୍ରୋଲ୍ କରନ୍ତୁ"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ଉପରକୁ ସ୍କ୍ରୋଲ୍ କରନ୍ତୁ"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ପଛକୁ ଫେରନ୍ତୁ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ସେଟିଂସ୍"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ଓଭରଫ୍ଲୋ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ଚାଲୁ ଅଛି"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ବନ୍ଦ ଅଛି"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ଗାଡ଼ି ଚଲାଇବା ସମୟରେ ଫିଚର୍ ଉପଲବ୍ଧ ହେବ ନାହିଁ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-pa/strings.xml b/car-ui-lib/res/values-pa/strings.xml
new file mode 100644
index 0000000..251b8bb
--- /dev/null
+++ b/car-ui-lib/res/values-pa/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ਖੋਜ…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"ਹੇਠਾਂ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ਉੱਪਰ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ਪਿੱਛੇ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ਖੋਜ"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ਸੈਟਿੰਗਾਂ"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ਓਵਰਫ਼ਲੋ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ਚਾਲੂ"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ਬੰਦ"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ਚੱਲਦੀ ਗੱਡੀ ਵਿੱਚ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-pl/strings.xml b/car-ui-lib/res/values-pl/strings.xml
new file mode 100644
index 0000000..ec5388c
--- /dev/null
+++ b/car-ui-lib/res/values-pl/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Szukaj…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Przewiń w dół"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Przewiń w górę"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Wstecz"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Szukaj"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Ustawienia"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Rozszerzone menu"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Wł."</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Wył."</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkcja niedostępna podczas jazdy"</string>
+</resources>
diff --git a/car-ui-lib/referencedesign/res/values-port/bools.xml b/car-ui-lib/res/values-port/bools.xml
similarity index 100%
rename from car-ui-lib/referencedesign/res/values-port/bools.xml
rename to car-ui-lib/res/values-port/bools.xml
diff --git a/car-ui-lib/res/values-pt-rPT/strings.xml b/car-ui-lib/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..ec04d23
--- /dev/null
+++ b/car-ui-lib/res/values-pt-rPT/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Pesquisar…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Deslocar para baixo"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Deslocar para cima"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Anterior"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Pesquisar"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Definições"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Menu adicional"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Ativado"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Desativado"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funcionalidade não disponível durante a condução."</string>
+</resources>
diff --git a/car-ui-lib/res/values-pt/strings.xml b/car-ui-lib/res/values-pt/strings.xml
new file mode 100644
index 0000000..69fc9fe
--- /dev/null
+++ b/car-ui-lib/res/values-pt/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Pesquisar…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Rolar para baixo"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Rolar para cima"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Voltar"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Pesquisa"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Configurações"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Menu flutuante"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Ativada"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Desativada"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Recurso indisponível enquanto você dirige"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ro/strings.xml b/car-ui-lib/res/values-ro/strings.xml
new file mode 100644
index 0000000..32e31eb
--- /dev/null
+++ b/car-ui-lib/res/values-ro/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Căutați…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Derulați în jos"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Derulați în sus"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Înapoi"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Căutați"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Setări"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Suplimentar"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Activat"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Dezactivat"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funcția nu este disponibilă când conduceți"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ru/strings.xml b/car-ui-lib/res/values-ru/strings.xml
new file mode 100644
index 0000000..29373a6
--- /dev/null
+++ b/car-ui-lib/res/values-ru/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Поиск…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Прокрутить вниз"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Прокрутить вверх"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Назад"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Поиск"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Настройки"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Дополнительное меню"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Включено"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Выключено"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Функция недоступна во время вождения."</string>
+</resources>
diff --git a/car-ui-lib/res/values-si/strings.xml b/car-ui-lib/res/values-si/strings.xml
new file mode 100644
index 0000000..a0ea615
--- /dev/null
+++ b/car-ui-lib/res/values-si/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"සොයන්න…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"පහළට අනුචලනය කරන්න"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"ඉහළට අනුචලනය කරන්න"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"ආපසු"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"සෙවීම"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"සැකසීම්"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ඉතිරියනය"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ක්‍රියාත්මකයි"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ක්‍රියාවිරහිතයි"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"රිය පදවන අතරේ විශේෂාංගය නොමැත"</string>
+</resources>
diff --git a/car-ui-lib/res/values-sk/strings.xml b/car-ui-lib/res/values-sk/strings.xml
new file mode 100644
index 0000000..3925a81
--- /dev/null
+++ b/car-ui-lib/res/values-sk/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Vyhľadať…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Posunúť nadol"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Posunúť nahor"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Späť"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Hľadať"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Nastavenia"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Rozšírená ponuka"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Zap."</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Vyp."</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkcia nie je k dispozícii počas jazdy"</string>
+</resources>
diff --git a/car-ui-lib/res/values-sl/strings.xml b/car-ui-lib/res/values-sl/strings.xml
new file mode 100644
index 0000000..6333890
--- /dev/null
+++ b/car-ui-lib/res/values-sl/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Iskanje …"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Pomik navzdol"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Pomik navzgor"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Nazaj"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Išči"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Nastavitve"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Element menija z dodatnimi elementi"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Vklopljeno"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Izklopljeno"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funkcija med vožnjo ni na voljo"</string>
+</resources>
diff --git a/car-ui-lib/res/values-sq/strings.xml b/car-ui-lib/res/values-sq/strings.xml
new file mode 100644
index 0000000..fb50946
--- /dev/null
+++ b/car-ui-lib/res/values-sq/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Kërko…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Lëviz poshtë"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Lëviz lart"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Pas"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Kërko"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Cilësimet"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Tejkalo"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Aktiv"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Joaktiv"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Veçoria nuk ofrohet gjatë drejtimit të makinës"</string>
+</resources>
diff --git a/car-ui-lib/res/values-sr/strings.xml b/car-ui-lib/res/values-sr/strings.xml
new file mode 100644
index 0000000..fd83edf
--- /dev/null
+++ b/car-ui-lib/res/values-sr/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Претражите…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Померите надоле"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Померите нагоре"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Назад"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Претражи"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Подешавања"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Преклопни мени"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Укључено"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Искључено"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Функција није доступна током вожње"</string>
+</resources>
diff --git a/car-ui-lib/res/values-sv/strings.xml b/car-ui-lib/res/values-sv/strings.xml
new file mode 100644
index 0000000..1b31e43
--- /dev/null
+++ b/car-ui-lib/res/values-sv/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Sök …"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Scrolla nedåt"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Scrolla uppåt"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Tillbaka"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Sök"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Inställningar"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Fler menyalternativ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"På"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Av"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Funktionen är inte tillgänglig när du kör"</string>
+</resources>
diff --git a/car-ui-lib/res/values-sw/strings.xml b/car-ui-lib/res/values-sw/strings.xml
new file mode 100644
index 0000000..999ccb6
--- /dev/null
+++ b/car-ui-lib/res/values-sw/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Tafuta…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Sogeza chini"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Sogeza juu"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Nyuma"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Tafuta"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Mipangilio"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Vipengee vya ziada"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Imewashwa"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Imezimwa"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Kipengele hakipatikani unapoendesha gari"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ta/strings.xml b/car-ui-lib/res/values-ta/strings.xml
new file mode 100644
index 0000000..8598837
--- /dev/null
+++ b/car-ui-lib/res/values-ta/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"தேடுக…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"கீழே செல்லும்"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"மேலே செல்லும்"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"பின்செல்வதற்கான பட்டன்"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Search"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"அமைப்புகள்"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"ஓவர்ஃப்லோ"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ஆன்"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ஆஃப்"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"வாகனம் ஓட்டும்போது இந்த அம்சத்தைப் பயன்படுத்த இயலாது"</string>
+</resources>
diff --git a/car-ui-lib/res/values-te/strings.xml b/car-ui-lib/res/values-te/strings.xml
new file mode 100644
index 0000000..68e671f
--- /dev/null
+++ b/car-ui-lib/res/values-te/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"వెతకండి…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"కిందికి స్క్రోల్ చేయండి"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"పైకి స్క్రోల్ చేయండి"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"వెనుకకు"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"సెర్చ్"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"సెట్టింగ్‌లు"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"అతివ్యాప్తి అంశాలు"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"ఆన్‌లో ఉంది"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ఆఫ్‌లో ఉంది"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"డ్రైవింగ్ చేస్తున్నప్పుడు ఈ ఫీచర్ అందుబాటులో ఉండదు"</string>
+</resources>
diff --git a/car-ui-lib/res/values-th/strings.xml b/car-ui-lib/res/values-th/strings.xml
new file mode 100644
index 0000000..6557b2c
--- /dev/null
+++ b/car-ui-lib/res/values-th/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"ค้นหา…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"เลื่อนลง"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"เลื่อนขึ้น"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"กลับ"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"ค้นหา"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"การตั้งค่า"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"รายการเพิ่มเติม"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"เปิด"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"ปิด"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ฟีเจอร์ไม่พร้อมใช้งานขณะขับรถ"</string>
+</resources>
diff --git a/car-ui-lib/res/values-tl/strings.xml b/car-ui-lib/res/values-tl/strings.xml
new file mode 100644
index 0000000..b879f3b
--- /dev/null
+++ b/car-ui-lib/res/values-tl/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Maghanap…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Mag-scroll pababa"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Mag-scroll pataas"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Bumalik"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Paghahanap"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Mga Setting"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Overflow"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"I-on"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"I-off"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Hindi available ang feature habang nagmamaneho"</string>
+</resources>
diff --git a/car-ui-lib/res/values-tr/strings.xml b/car-ui-lib/res/values-tr/strings.xml
new file mode 100644
index 0000000..47a1978
--- /dev/null
+++ b/car-ui-lib/res/values-tr/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Ara…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Aşağı kaydır"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Yukarı kaydır"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Geri"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Ara"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Ayarlar"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Taşma"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Açık"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Kapalı"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Sürüş sırasında bu özellik kullanılamaz"</string>
+</resources>
diff --git a/car-ui-lib/res/values-uk/strings.xml b/car-ui-lib/res/values-uk/strings.xml
new file mode 100644
index 0000000..a18668d
--- /dev/null
+++ b/car-ui-lib/res/values-uk/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Пошук…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Прокрутити вниз"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Прокрутити вгору"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Назад"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Пошук"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Налаштування"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Додаткове меню"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Увімкнено"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Вимкнено"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Функція недоступна під час руху автомобіля"</string>
+</resources>
diff --git a/car-ui-lib/res/values-ur/strings.xml b/car-ui-lib/res/values-ur/strings.xml
new file mode 100644
index 0000000..efffbcd
--- /dev/null
+++ b/car-ui-lib/res/values-ur/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"تلاش کریں…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"نیچے اسکرول کریں"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"اوپر اسکرول کریں"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"پیچھے"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"تلاش کریں"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"ترتیبات"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"اوورفلو"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"آن ہے"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"آف ہے"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"ڈرائیونگ کے دوران یہ خصوصیت دستیاب نہیں ہے"</string>
+</resources>
diff --git a/car-ui-lib/res/values-uz/strings.xml b/car-ui-lib/res/values-uz/strings.xml
new file mode 100644
index 0000000..1dd26ac
--- /dev/null
+++ b/car-ui-lib/res/values-uz/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Qidirish…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Pastga surish"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Tepaga surish"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Orqaga"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Qidiruv"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Sozlamalar"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Kengaytirilgan"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Yoniq"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Yoqilmagan"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Avtomobilda harakatlanayotganda bu funksiya ishlamaydi"</string>
+</resources>
diff --git a/car-ui-lib/res/values-vi/strings.xml b/car-ui-lib/res/values-vi/strings.xml
new file mode 100644
index 0000000..39df5ce
--- /dev/null
+++ b/car-ui-lib/res/values-vi/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Tìm kiếm…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Cuộn xuống"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Cuộn lên"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Quay lại"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Tìm kiếm"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Cài đặt"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Trình đơn mục bổ sung"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Đang bật"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Đang tắt"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Bạn không sử dụng được tính năng này khi đang lái xe"</string>
+</resources>
diff --git a/car-ui-lib/res/values-zh-rCN/strings.xml b/car-ui-lib/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..a581718
--- /dev/null
+++ b/car-ui-lib/res/values-zh-rCN/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"搜索…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"向下滚动"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"向上滚动"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"返回"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"搜索"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"设置"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"溢出菜单"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"开启"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"关闭"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"驾车时无法使用此功能"</string>
+</resources>
diff --git a/car-ui-lib/res/values-zh-rHK/strings.xml b/car-ui-lib/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..dc5482d
--- /dev/null
+++ b/car-ui-lib/res/values-zh-rHK/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"搜尋…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"向下捲動"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"向上捲動"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"返回"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"搜尋"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"設定"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"展開式選單"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"已開啟"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"已關閉"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"無法在駕駛時使用此功能"</string>
+</resources>
diff --git a/car-ui-lib/res/values-zh-rTW/strings.xml b/car-ui-lib/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..0d28130
--- /dev/null
+++ b/car-ui-lib/res/values-zh-rTW/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"搜尋…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"向下捲動"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"向上捲動"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"返回"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"搜尋"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"設定"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"溢位"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"開啟"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"關閉"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"開車時無法使用這項功能"</string>
+</resources>
diff --git a/car-ui-lib/res/values-zu/strings.xml b/car-ui-lib/res/values-zu/strings.xml
new file mode 100644
index 0000000..a3066d0
--- /dev/null
+++ b/car-ui-lib/res/values-zu/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_ui_toolbar_default_search_hint" msgid="7807151740020494659">"Sesha…"</string>
+    <string name="car_ui_scrollbar_page_down_button" msgid="2419547312871553905">"Skrolela phansi"</string>
+    <string name="car_ui_scrollbar_page_up_button" msgid="4152120100101092092">"Skrolela phezulu"</string>
+    <string name="car_ui_toolbar_nav_icon_content_description" msgid="2689756063478650269">"Emuva"</string>
+    <string name="car_ui_toolbar_menu_item_search_title" msgid="8705757227447034030">"Sesha"</string>
+    <string name="car_ui_toolbar_menu_item_settings_title" msgid="6694060516340354337">"Izilungiselelo"</string>
+    <string name="car_ui_toolbar_menu_item_overflow_title" msgid="771643815366812499">"Ukuphuphuma"</string>
+    <string name="car_ui_preference_switch_on" msgid="5512335363135043642">"Vuliwe"</string>
+    <string name="car_ui_preference_switch_off" msgid="4393435896926380920">"Valiwe"</string>
+    <string name="car_ui_restricted_while_driving" msgid="8401317496175957541">"Isici asitholakali ngenkathi ushayela"</string>
+</resources>
diff --git a/car-ui-lib/res/values/attrs.xml b/car-ui-lib/res/values/attrs.xml
new file mode 100644
index 0000000..4b06a60
--- /dev/null
+++ b/car-ui-lib/res/values/attrs.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+    <!-- Global theme options for CarUi -->
+    <declare-styleable name="CarUi">
+        <!-- When set to true, the window decor will contain an OEM-customizable layout -->
+        <attr name="carUiBaseLayout" format="boolean"/>
+        <!-- When set to true, a CarUi Toolbar will be provided in the window decor -->
+        <attr name="carUiToolbar" format="boolean"/>
+    </declare-styleable>
+
+    <declare-styleable name="CarUiToolbar">
+        <!-- Title of the toolbar, only displayed in certain conditions -->
+        <attr name="title" format="string"/>
+        <!-- Logo drawable for the toolbar. Appears when there's no back/close button shown -->
+        <attr name="logo" format="reference"/>
+        <!-- Hint for the search bar in the toolbar -->
+        <attr name="searchHint" format="string"/>
+        <!-- Whether or not to show the MenuItems while searching. Default false. -->
+        <attr name="showMenuItemsWhileSearching" format="boolean"/>
+        <!-- Initial state of the toolbar. See the Toolbar.State enum for more information -->
+        <attr name="car_ui_state" format="enum">
+            <enum name="home" value="0"/>
+            <enum name="subpage" value="1"/>
+            <enum name="search" value="2"/>
+        </attr>
+        <!-- Whether or not the toolbar should have a background. Default true. -->
+        <attr name="showBackground" format="boolean"/>
+        <!-- Mode of the navigation button See the Toolbar.NavButtonMode enum for more information -->
+        <attr name="car_ui_navButtonMode" format="enum">
+            <enum name="back" value="0"/>
+            <enum name="close" value="1"/>
+            <enum name="down" value="2"/>
+        </attr>
+        <!-- XML resource of MenuItems. See Toolbar.setMenuItems(int) for more information. -->
+        <attr name="menuItems" format="reference"/>
+        <!-- Whether or not to show tabs in the SUBPAGE state. Default false -->
+        <attr name="showTabsInSubpage" format="boolean"/>
+    </declare-styleable>
+
+    <declare-styleable name="CarUiToolbarMenuItem">
+        <!-- Id of MenuItem, used to differentiate them -->
+        <attr name="id" format="reference"/>
+        <!-- Show/hide the MenuItem -->
+        <attr name="visible" format="boolean"/>
+        <!-- Set this to true to make a search MenuItem. This will override every other property except id, visible, and onclick. -->
+        <attr name="search" format="boolean"/>
+        <!-- Set this to true to make a settings MenuItem. This will override every other property except id, visible, and onclick. -->
+        <attr name="settings" format="boolean"/>
+        <!-- Title -->
+        <attr name="title"/>
+        <!-- Icon -->
+        <attr name="icon" format="reference"/>
+        <!-- True to tint the icon to a consistent color. Default true, all the other booleans default to false -->
+        <attr name="tinted" format="boolean"/>
+        <!-- Show both the icon and title at the same time -->
+        <attr name="showIconAndTitle" format="boolean"/>
+        <!-- True if this MenuItem should be a switch -->
+        <attr name="checkable" format="boolean"/>
+        <!-- Whether the switch should be checked or not. Setting this implies checkable=true -->
+        <attr name="checked" format="boolean"/>
+        <!-- True if this MenuItem should be activatable, in which case it will visually toggle states when clicked -->
+        <attr name="activatable" format="boolean"/>
+        <!-- Whether the MenuItem starts activated. Setting this implies activatable=true -->
+        <attr name="activated" format="boolean"/>
+        <!-- How to display the MenuItem. "always" means always show it on the toolbar, "never" means never show it on the toolbar and instead show it in the overflow menu -->
+        <attr name="displayBehavior" format="enum">
+            <enum name="always" value="0"/>
+            <enum name="never" value="1"/>
+        </attr>
+        <!-- Ux restrictions required to interact with this MenuItem -->
+        <attr name="uxRestrictions">
+            <!-- Values are copied from android.car.drivingstate.CarUxRestrictions. Note:
+            UX_RESTRICTIONS_BASELINE is not allowed here because it's useless and confusing. -->
+            <flag name="UX_RESTRICTIONS_NO_DIALPAD" value="1"/>
+            <flag name="UX_RESTRICTIONS_NO_FILTERING" value="2"/>
+            <flag name="UX_RESTRICTIONS_LIMIT_STRING_LENGTH" value="4"/>
+            <flag name="UX_RESTRICTIONS_NO_KEYBOARD" value="8"/>
+            <flag name="UX_RESTRICTIONS_NO_VIDEO" value="16"/>
+            <flag name="UX_RESTRICTIONS_LIMIT_CONTENT" value="32"/>
+            <flag name="UX_RESTRICTIONS_NO_SETUP" value="64"/>
+            <flag name="UX_RESTRICTIONS_NO_TEXT_MESSAGE" value="128"/>
+            <flag name="UX_RESTRICTIONS_NO_VOICE_TRANSCRIPTION" value="256"/>
+            <flag name="UX_RESTRICTIONS_FULLY_RESTRICTED" value="511"/>
+        </attr>
+        <!-- The name of a method that takes a MenuItem as an argument in you'r toolbar's Activity. Will be called when the MenuItem is clicked -->
+        <attr name="onClick" format="string"/>
+    </declare-styleable>
+
+    <!-- Theme attribute to specifying a default style for all CarUiToolbars -->
+    <attr name="CarUiToolbarStyle" format="reference"/>
+
+    <declare-styleable name="CarUiRecyclerView">
+        <!-- Whether to enable the dividers or not. Linear and grid layout uses
+        car_ui_recyclerview_divider.xml and car_ui_divider.xml drawables
+        respectively for styling dividers. -->
+        <attr name="enableDivider" format="boolean" />
+        <!-- Top offset for car ui recycler view. -->
+        <attr name="topOffset" format="integer" />
+        <!-- Bottom offset for car ui recycler view for linear layout. -->
+        <attr name="bottomOffset" format="integer" />
+
+        <!-- Number of columns in a grid layout. -->
+        <attr name="numOfColumns" format="integer" />
+
+        <!-- car ui recycler view layout. -->
+        <attr name="layoutStyle" format="enum">
+            <!-- linear layout -->
+            <enum name="linear" value="0" />
+            <!-- grid layout -->
+            <enum name="grid" value="1" />
+        </attr>
+    </declare-styleable>
+
+    <declare-styleable name="CarUiPreference">
+        <!-- Toggle for showing chevron -->
+        <attr name="showChevron" format="boolean" />
+        <!-- Show ripple when disabled preference is clicked -->
+        <attr name="showRippleOnDisabledPreference" format="boolean" />
+    </declare-styleable>
+
+    <declare-styleable name="CarUiTwoActionPreference">
+        <!-- Determines if the secondary action is initially shown -->
+        <attr name="actionShown" format="boolean"/>
+    </declare-styleable>
+
+    <!-- Theme attribute to specify a default style for all CarUiPreferences -->
+    <attr name="carUiPreferenceStyle" format="reference" />
+
+    <!-- Theme attribute to specify a default style for all CarUiRecyclerViews -->
+    <attr name="carUiRecyclerViewStyle" format="reference" />
+
+    <attr name="state_ux_restricted" format="boolean" />
+</resources>
diff --git a/car-ui-lib/res/values/bools.xml b/car-ui-lib/res/values/bools.xml
new file mode 100644
index 0000000..d85e840
--- /dev/null
+++ b/car-ui-lib/res/values/bools.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+    <!-- Toolbar -->
+
+    <!-- Whether tabs should use flex layout or not -->
+    <bool name="car_ui_toolbar_tab_flexible_layout">false</bool>
+    <!-- Whether the space for nav icon should be reserved, even if the nav icon is not visible -->
+    <bool name="car_ui_toolbar_nav_icon_reserve_space">true</bool>
+    <!-- Whether the logo (if provided) should be used in place of the nav icon when nav icon is
+         not visible -->
+    <bool name="car_ui_toolbar_logo_fills_nav_icon_space">true</bool>
+    <!-- Whether logo should be displayed. If set to false, logo won't be shown even if provided -->
+    <bool name="car_ui_toolbar_show_logo">true</bool>
+    <!-- Whether tabs should be displayed on a second row, or they should be placed in the first
+         row, replacing the title -->
+    <bool name="car_ui_toolbar_tabs_on_second_row">false</bool>
+
+    <!-- CarUiRecyclerView -->
+
+    <!-- Whether to display the Scroll Bar or not. Defaults to true. If this is set to false,
+         the CarUiRecyclerView will behave exactly like the RecyclerView. -->
+    <bool name="car_ui_scrollbar_enable">true</bool>
+
+    <!-- Preferences -->
+
+    <!-- Whether list, edit, dropdown and intent preferences should show a chevron or not -->
+    <bool name="car_ui_preference_show_chevron">false</bool>
+    <!-- whether list preference should be shown in full screen or as a dialog -->
+    <bool name="car_ui_preference_list_show_full_screen">true</bool>
+
+    <!-- List items -->
+
+    <bool name="car_ui_list_item_single_line_title">true</bool>
+
+    <!-- FocusArea -->
+
+    <!-- Whether to draw highlight (car_ui_focus_area_foreground_highlight) on top of the FocusArea
+         and its children when the FocusArea's descendant gets focused. -->
+    <bool name="car_ui_enable_focus_area_foreground_highlight">false</bool>
+    <!-- Whether to draw highlight (car_ui_focus_area_background_highlight) on top of the FocusArea
+         but behind its children when the FocusArea's descendant gets focused. -->
+    <bool name="car_ui_enable_focus_area_background_highlight">false</bool>
+</resources>
diff --git a/car-ui-lib/res/values/colors.xml b/car-ui-lib/res/values/colors.xml
new file mode 100644
index 0000000..db62ad2
--- /dev/null
+++ b/car-ui-lib/res/values/colors.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <!-- General -->
+
+    <!-- Background color to use on full screen activities -->
+    <color name="car_ui_activity_background_color">#000000</color>
+    <!-- The ripple color. -->
+    <color name="car_ui_ripple_color">#27ffffff</color>
+
+    <!-- Toolbar -->
+
+    <!-- Color used on the navigation icon -->
+    <color name="car_ui_toolbar_nav_icon_color">@color/car_ui_text_color_primary</color>
+    <!-- Text color applied to the hint displayed inside the search box -->
+    <color name="car_ui_toolbar_search_hint_text_color">@color/car_ui_text_color_hint</color>
+    <!-- Tab selected color -->
+    <color name="car_ui_toolbar_tab_selected_color">@color/car_ui_text_color_primary</color>
+    <!-- Tab normal color -->
+    <color name="car_ui_toolbar_tab_unselected_color">@color/car_ui_text_color_secondary</color>
+
+    <!-- Recycler View  -->
+
+    <!-- Color of the scroll bar indicator in the CarUiRecyclerView. -->
+    <color name="car_ui_scrollbar_thumb">#99ffffff</color>
+    <!-- Color of the divider views between CarUiRecyclerView items -->
+    <color name="car_ui_recyclerview_divider_color">@android:color/transparent</color>
+
+    <!-- Preferences -->
+
+    <color name="car_ui_preference_icon_color">@color/car_ui_text_color_primary</color>
+    <color name="car_ui_preference_two_action_divider_color">#1fffffff</color>
+
+    <!-- Rotary focus -->
+    <color name="car_ui_rotary_focus_color">#4b9eff</color>
+</resources>
diff --git a/car-ui-lib/res/values/dimens.xml b/car-ui-lib/res/values/dimens.xml
new file mode 100644
index 0000000..3910c60
--- /dev/null
+++ b/car-ui-lib/res/values/dimens.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+    <!-- General resources -->
+
+    <dimen name="car_ui_touch_target_size">76dp</dimen>
+    <dimen name="car_ui_touch_target_width">@dimen/car_ui_touch_target_size</dimen>
+    <dimen name="car_ui_touch_target_height">@dimen/car_ui_touch_target_size</dimen>
+
+    <dimen name="car_ui_primary_icon_size">44dp</dimen>
+
+    <!-- Horizontal margin between screen content and display border. In reference
+     implementation, this value matches the CarUiRecyclerView scrollbar width -->
+    <dimen name="car_ui_margin">112dp</dimen>
+
+    <!-- Paddings -->
+    <dimen name="car_ui_padding_0">4dp</dimen>
+    <dimen name="car_ui_padding_1">8dp</dimen>
+    <dimen name="car_ui_padding_2">16dp</dimen>
+    <dimen name="car_ui_padding_3">24dp</dimen>
+    <dimen name="car_ui_padding_4">32dp</dimen>
+    <dimen name="car_ui_padding_5">64dp</dimen>
+    <dimen name="car_ui_padding_6">96dp</dimen>
+
+    <!-- Type Sizings -->
+    <dimen name="car_ui_body1_size">32sp</dimen>
+    <dimen name="car_ui_body2_size">28sp</dimen>
+    <dimen name="car_ui_body3_size">24sp</dimen>
+    <dimen name="car_ui_sub1_size">22sp</dimen>
+    <dimen name="car_ui_sub2_size">20sp</dimen>
+    <dimen name="car_ui_sub3_size">18sp</dimen>
+
+    <!-- Tabs -->
+
+    <!-- Exact size of the tab textbox. Use @dimen/wrap_content if this must be flexible -->
+    <dimen name="car_ui_toolbar_tab_text_width">135dp</dimen>
+    <!-- Horizontal padding between tabs -->
+    <dimen name="car_ui_toolbar_tab_padding_x">12dp</dimen>
+    <!-- Tab icon width (if icons are enabled) -->
+    <dimen name="car_ui_toolbar_tab_icon_width">36dp</dimen>
+    <!-- Tab icon height (if icons are enabled) -->
+    <dimen name="car_ui_toolbar_tab_icon_height">36dp</dimen>
+
+    <!-- Toolbar -->
+
+    <!-- Default height for both toolbar rows. See car_ui_toolbar_first_row_height and
+     car_ui_toolbar_second_row_height -->
+    <dimen name="car_ui_toolbar_row_height">96dp</dimen>
+    <!-- Height of the top toolbar row. This can be customized independently. -->
+    <dimen name="car_ui_toolbar_first_row_height">@dimen/car_ui_toolbar_row_height</dimen>
+    <!-- Height of the bottom toolbar row (if the toolbar is used in two-rows mode. -->
+    <dimen name="car_ui_toolbar_second_row_height">@dimen/car_ui_toolbar_row_height</dimen>
+    <!-- Padding on the toolbar start (e.g.: distance between the container start and the start of
+    nav icon or logo) -->
+    <dimen name="car_ui_toolbar_start_inset">0dp</dimen>
+    <!-- End padding (e.g.: distance between the container end and the end of the menu items) -->
+    <dimen name="car_ui_toolbar_end_inset">0dp</dimen>
+    <!-- Top padding -->
+    <dimen name="car_ui_toolbar_top_inset">0dp</dimen>
+    <!-- Bottom padding -->
+    <dimen name="car_ui_toolbar_bottom_inset">0dp</dimen>
+    <!-- Toolbar title/tabs start margin. Toolbar navigation icon (or logo if no navigation icon is
+    used) will be centered in this space, and the title will start from here -->
+    <dimen name="car_ui_toolbar_margin">@dimen/car_ui_margin</dimen>
+    <!-- Navigation icon -->
+    <dimen name="car_ui_toolbar_nav_icon_size">@dimen/car_ui_primary_icon_size</dimen>
+    <!-- Logo -->
+    <dimen name="car_ui_toolbar_logo_size">@dimen/car_ui_primary_icon_size</dimen>
+    <!-- Margin between the logo and the title, when both logo and navigation icons are used -->
+    <dimen name="car_ui_toolbar_title_logo_padding">0dp</dimen>
+    <!-- Margin at the start of the title -->
+    <dimen name="car_ui_toolbar_title_margin_start">@dimen/car_ui_padding_2</dimen>
+    <!-- Margin at the start of the title when there is no logo present -->
+    <dimen name="car_ui_toolbar_title_no_logo_margin_start">0dp</dimen>
+    <!-- Space at the end and in between menu items -->
+    <dimen name="car_ui_toolbar_menu_item_margin">@dimen/car_ui_padding_2</dimen>
+    <!-- Ripple effect radius for icon menu items -->
+    <dimen name="car_ui_toolbar_menu_item_icon_ripple_radius">48dp</dimen>
+    <!-- Icon size for icon menu items -->
+    <dimen name="car_ui_toolbar_menu_item_icon_size">@dimen/car_ui_primary_icon_size</dimen>
+    <!-- Icon background size for icon menu items -->
+    <dimen name="car_ui_toolbar_menu_item_icon_background_size">54dp</dimen>
+    <!-- Height of the decoration view between the two rows of the toolbar (or below the toolbar
+    if this is a single row one -->
+    <!-- can't use 0dp for layout_height or the constraintlayout effect kicks in -->
+    <dimen name="car_ui_toolbar_separator_height">0.1dp</dimen>
+    <!-- Height of the decoration view below the toolbar -->
+    <!-- can't use 0dp for layout_height or the constraintlayout effect kicks in -->
+    <dimen name="car_ui_toolbar_bottom_view_height">0.1dp</dimen>
+    <!-- Height of the search box -->
+    <dimen name="car_ui_toolbar_search_height">0dp</dimen>
+    <!-- Space before the text search area, where the search icon is located -->
+    <dimen name="car_ui_toolbar_search_search_icon_container_width">@dimen/car_ui_touch_target_width</dimen>
+    <!-- Space after the text search area, where the cancel icon is located -->
+    <dimen name="car_ui_toolbar_search_close_icon_container_width">@dimen/car_ui_touch_target_width</dimen>
+    <!-- Size of the search icon inside the search box -->
+    <dimen name="car_ui_toolbar_search_search_icon_size">@dimen/car_ui_primary_icon_size</dimen>
+    <!-- Size of the close icon inside the search box -->
+    <dimen name="car_ui_toolbar_search_close_icon_size">@dimen/car_ui_primary_icon_size</dimen>
+
+    <!-- Internal artifacts. Do not overlay -->
+    <item name="wrap_content" format="integer" type="dimen">-2</item>
+
+    <!-- CarUiRecyclerView -->
+
+    <dimen name="car_ui_recyclerview_divider_height">0dp</dimen>
+    <dimen name="car_ui_recyclerview_divider_start_margin">0dp</dimen>
+    <dimen name="car_ui_recyclerview_divider_end_margin">0dp</dimen>
+    <dimen name="car_ui_recyclerview_divider_top_margin">0dp</dimen>
+    <dimen name="car_ui_recyclerview_divider_bottom_margin">0dp</dimen>
+
+    <!-- CarUiRecyclerView default scrollbar -->
+
+    <dimen name="car_ui_scrollbar_container_width">@dimen/car_ui_margin</dimen>
+    <dimen name="car_ui_scrollbar_button_size">@dimen/car_ui_touch_target_width</dimen>
+    <dimen name="car_ui_scrollbar_thumb_width">7dp</dimen>
+    <dimen name="car_ui_scrollbar_separator_margin">16dp</dimen>
+    <dimen name="car_ui_scrollbar_margin">@dimen/car_ui_margin</dimen>
+    <dimen name="car_ui_scrollbar_thumb_radius">100dp</dimen>
+
+    <item name="car_ui_button_disabled_alpha" format="float" type="dimen">0.2</item>
+    <item name="car_ui_scrollbar_milliseconds_per_inch" format="float" type="dimen">150.0</item>
+    <item name="car_ui_scrollbar_deceleration_times_divisor" format="float" type="dimen">0.45</item>
+    <item name="car_ui_scrollbar_decelerate_interpolator_factor" format="float" type="dimen">1.8</item>
+
+    <dimen name="car_ui_scrollbar_padding_top">0dp</dimen>
+    <dimen name="car_ui_scrollbar_padding_bottom">0dp</dimen>
+
+    <!-- Preferences -->
+
+    <dimen name="car_ui_divider_width">1dp</dimen>
+
+    <dimen name="car_ui_preference_content_margin_top">16dp</dimen>
+    <dimen name="car_ui_preference_content_margin_bottom">16dp</dimen>
+    <dimen name="car_ui_preference_icon_size">44dp</dimen>
+    <dimen name="car_ui_preference_icon_margin_end">16dp</dimen>
+
+    <dimen name="car_ui_preference_category_min_height">76dp</dimen>
+    <dimen name="car_ui_preference_category_icon_size">44dp</dimen>
+    <dimen name="car_ui_preference_category_icon_margin_end">16dp</dimen>
+
+    <dimen name="car_ui_preference_dropdown_padding_start">112dp</dimen>
+
+    <dimen name="car_ui_preference_edit_text_dialog_margin_top">32dp</dimen>
+    <dimen name="car_ui_preference_edit_text_dialog_margin_bottom">32dp</dimen>
+    <dimen name="car_ui_preference_edit_text_dialog_message_margin_bottom">32dp</dimen>
+    <dimen name="car_ui_preference_edit_text_dialog_message_margin_start">24dp</dimen>
+    <dimen name="car_ui_preference_edit_text_dialog_message_margin_end">24dp</dimen>
+    <dimen name="car_ui_preference_edit_text_dialog_text_margin_start">24dp</dimen>
+    <dimen name="car_ui_preference_edit_text_dialog_text_margin_end">24dp</dimen>
+
+    <!-- Alert dialog   -->
+
+    <dimen name="car_ui_dialog_edittext_height">50dp</dimen>
+    <dimen name="car_ui_dialog_edittext_margin_top">10dp</dimen>
+    <dimen name="car_ui_dialog_edittext_margin_bottom">10dp</dimen>
+    <dimen name="car_ui_dialog_edittext_margin_start">22dp</dimen>
+    <dimen name="car_ui_dialog_edittext_margin_end">22dp</dimen>
+    <dimen name="car_ui_dialog_icon_size">56dp</dimen>
+    <dimen name="car_ui_dialog_title_margin">24dp</dimen>
+
+    <!-- List item  -->
+
+    <dimen name="car_ui_list_item_height">116dp</dimen>
+    <dimen name="car_ui_list_item_header_height">76dp</dimen>
+    <dimen name="car_ui_list_item_header_start_inset">0dp</dimen>
+    <dimen name="car_ui_list_item_start_inset">0dp</dimen>
+    <dimen name="car_ui_list_item_end_inset">0dp</dimen>
+    <dimen name="car_ui_header_list_item_text_start_margin">0dp</dimen>
+    <dimen name="car_ui_list_item_text_start_margin">24dp</dimen>
+    <dimen name="car_ui_list_item_text_no_icon_start_margin">24dp</dimen>
+
+    <!-- List item icons  -->
+
+    <dimen name="car_ui_list_item_icon_size">@dimen/car_ui_primary_icon_size</dimen>
+    <dimen name="car_ui_list_item_content_icon_width">@dimen/car_ui_list_item_icon_container_width</dimen>
+    <dimen name="car_ui_list_item_content_icon_height">@dimen/car_ui_list_item_icon_container_width</dimen>
+    <dimen name="car_ui_list_item_avatar_icon_width">@dimen/car_ui_primary_icon_size</dimen>
+    <dimen name="car_ui_list_item_avatar_icon_height">@dimen/car_ui_primary_icon_size</dimen>
+    <dimen name="car_ui_list_item_supplemental_icon_size">@dimen/car_ui_primary_icon_size</dimen>
+    <dimen name="car_ui_list_item_icon_container_width">112dp</dimen>
+    <dimen name="car_ui_list_item_action_divider_width">1dp</dimen>
+    <dimen name="car_ui_list_item_action_divider_height">60dp</dimen>
+
+    <!-- List item actions  -->
+
+    <dimen name="car_ui_list_item_radio_button_height">@dimen/car_ui_list_item_height</dimen>
+    <dimen name="car_ui_list_item_radio_button_start_inset">@dimen/car_ui_list_item_start_inset</dimen>
+    <dimen name="car_ui_list_item_radio_button_end_inset">@dimen/car_ui_list_item_end_inset</dimen>
+    <dimen name="car_ui_list_item_radio_button_icon_container_width">@dimen/car_ui_list_item_icon_container_width</dimen>
+    <dimen name="car_ui_list_item_check_box_height">@dimen/car_ui_list_item_height</dimen>
+    <dimen name="car_ui_list_item_check_box_start_inset">@dimen/car_ui_list_item_start_inset</dimen>
+    <dimen name="car_ui_list_item_check_box_end_inset">@dimen/car_ui_list_item_end_inset</dimen>
+    <dimen name="car_ui_list_item_check_box_icon_container_width">@dimen/car_ui_list_item_icon_container_width</dimen>
+
+</resources>
diff --git a/car-ui-lib/res/values/drawables.xml b/car-ui-lib/res/values/drawables.xml
new file mode 100644
index 0000000..181846c
--- /dev/null
+++ b/car-ui-lib/res/values/drawables.xml
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <!-- General -->
+
+    <!-- Background drawable to use on full screen activities -->
+    <drawable name="car_ui_activity_background">@color/car_ui_activity_background_color</drawable>
+
+    <!-- Toolbar -->
+
+    <!-- Toolbar background color -->
+    <drawable name="car_ui_toolbar_background">#E0000000</drawable>
+    <!-- Search icon shown inside the search box in the toolbar -->
+    <drawable name="car_ui_toolbar_search_search_icon">@drawable/car_ui_icon_search</drawable>
+    <!-- Icon used for clearing the search box in toolbar -->
+    <drawable name="car_ui_toolbar_search_close_icon">@drawable/car_ui_icon_close</drawable>
+    <!-- Icon used for nav when the toolbar is in search state   -->
+    <drawable name="car_ui_icon_search_nav_icon">@drawable/car_ui_icon_arrow_back</drawable>
+
+    <!-- Preferences -->
+
+    <!-- Overlayable drawable to use for the preference chevron when preference is enabled -->
+    <item name="car_ui_preference_icon_chevron_enabled" type="drawable">@null</item>
+    <!-- Overlayable drawable to use for the preference chevron when preference is disabled -->
+    <item name="car_ui_preference_icon_chevron_disabled" type="drawable">@null</item>
+</resources>
diff --git a/car-ui-lib/res/values/ids.xml b/car-ui-lib/res/values/ids.xml
new file mode 100644
index 0000000..2c23ac3
--- /dev/null
+++ b/car-ui-lib/res/values/ids.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+    <!-- Id used for the search button when using Toolbar.createSearch() method -->
+    <item name="search" type="id"/>
+</resources>
diff --git a/car-ui-lib/res/values/integers.xml b/car-ui-lib/res/values/integers.xml
new file mode 100644
index 0000000..963c955
--- /dev/null
+++ b/car-ui-lib/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+    <!-- Default max string length -->
+    <integer name="car_ui_default_max_string_length">120</integer>
+    <integer name="car_ui_scrollbar_longpress_initial_delay">1000</integer>
+    <integer name="car_ui_scrollbar_longpress_repeat_interval">100</integer>
+</resources>
diff --git a/car-ui-lib/res/values/strings.xml b/car-ui-lib/res/values/strings.xml
new file mode 100644
index 0000000..ff101f7
--- /dev/null
+++ b/car-ui-lib/res/values/strings.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<resources>
+    <!--
+    Configuration for a default scrollbar for the CarUiRecyclerView. This component must inherit
+    abstract class ScrollBar. If the ScrollBar is enabled, the component will be initialized from
+    CarUiRecyclerView#createScrollBarFromConfig(). If no component is provided,
+    {@link DefaultScrollbar} class will be used.
+    -->
+    <string name="car_ui_scrollbar_component" translatable="false"/>
+    <!-- Search hint, displayed inside the search box [CHAR LIMIT=50] -->
+    <string name="car_ui_toolbar_default_search_hint">Search&#8230;</string>
+    <!-- CarUxRestrictions Utility -->
+    <string name="car_ui_ellipsis" translatable="false">&#8230;</string>
+    <!-- Content description for car ui recycler view scroll bar down arrow [CHAR LIMIT=30] -->
+    <string name="car_ui_scrollbar_page_down_button">Scroll down</string>
+    <!-- Content description for car ui recycler view scroll bar up arrow [CHAR LIMIT=30] -->
+    <string name="car_ui_scrollbar_page_up_button">Scroll up</string>
+    <!-- The content description on the toolbar back button -->
+    <string name="car_ui_toolbar_nav_icon_content_description">Back</string>
+    <!-- Title of the search menu item. Will be displayed if the button is in the overflow menu. [CHAR_LIMIT=50] -->
+    <string name="car_ui_toolbar_menu_item_search_title">Search</string>
+    <!-- Title of the settings menu item. Will be displayed if the button is in the overflow menu. [CHAR_LIMIT=50] -->
+    <string name="car_ui_toolbar_menu_item_settings_title">Settings</string>
+    <!-- Title of the overflow menu item. Only used for content descriptions. [CHAR_LIMIT=50] -->
+    <string name="car_ui_toolbar_menu_item_overflow_title">Overflow</string>
+
+    <!-- Positive option for a preference dialog. [CHAR_LIMIT=30] -->
+    <string name="car_ui_dialog_preference_positive" translatable="false">@android:string/ok</string>
+    <!-- Negative option for a preference dialog. [CHAR_LIMIT=30] -->
+    <string name="car_ui_dialog_preference_negative" translatable="false">@android:string/cancel</string>
+    <!-- Text to show when a preference switch is on. [CHAR_LIMIT=30] -->
+    <string name="car_ui_preference_switch_on">On</string>
+    <!-- Text to show when a preference switch is off. [CHAR_LIMIT=30] -->
+    <string name="car_ui_preference_switch_off">Off</string>
+
+    <!-- Text to show when no button is provided and a default button is used. -->
+    <string name="car_ui_alert_dialog_default_button" translatable="false">Close</string>
+
+    <!-- Shown in a toast when the user attempts to do something distracting while driving [CHAR_LIMIT=200] -->
+    <string name="car_ui_restricted_while_driving">Feature not available while driving</string>
+
+    <!-- Mostly used for GMSCore, this attribute is used to launch CarUiInstaller in a process -->
+    <!-- that can register to Application.ActivityLifecycleCallbacks. -->
+    <!-- Clients should override this value instead of changing the process name -->
+    <!-- from manifest file. -->
+    <string name="car_ui_installer_process_name" translatable="false"></string>
+</resources>
diff --git a/car-ui-lib/res/values/styles.xml b/car-ui-lib/res/values/styles.xml
new file mode 100644
index 0000000..00cb56e
--- /dev/null
+++ b/car-ui-lib/res/values/styles.xml
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- Styles for CarUi tab view -->
+
+    <style name="Widget.CarUi" parent="android:Widget.DeviceDefault"/>
+
+    <style name="Widget.CarUi.Button.Borderless.Colored"
+           parent="android:Widget.DeviceDefault.Button.Borderless.Colored"/>
+
+    <style name="Widget.CarUi.Button" parent="android:Widget.DeviceDefault.Button"/>
+
+    <style name="Widget.CarUi.Toolbar"/>
+
+    <style name="Widget.CarUi.SeekbarPreference"/>
+
+    <style name="Widget.CarUi.Toolbar.Container"/>
+
+    <style name="Widget.CarUi.Toolbar.NavIconContainer"/>
+
+    <style name="Widget.CarUi.Toolbar.Logo"/>
+
+    <style name="Widget.CarUi.Toolbar.LogoContainer">
+        <item name="android:paddingEnd">@dimen/car_ui_toolbar_title_logo_padding</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.ProgressBar"
+           parent="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal">
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.NavIcon">
+        <item name="android:tint">@color/car_ui_toolbar_nav_icon_color</item>
+        <item name="android:src">@drawable/car_ui_icon_arrow_back</item>
+        <item name="android:background">@drawable/car_ui_toolbar_menu_item_icon_ripple</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.Title">
+        <item name="android:textAppearance">@style/TextAppearance.CarUi.Widget.Toolbar.Title</item>
+        <item name="android:textAlignment">viewStart</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.Subtitle">
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:textAlignment">viewStart</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.TextButton" parent="Widget.CarUi.Button.Borderless.Colored">
+        <item name="android:drawableTint">@color/car_ui_toolbar_menu_item_icon_color</item>
+        <item name="android:drawablePadding">10dp</item>
+        <item name="android:maxWidth">350dp</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.TextButton.WithIcon">
+        <item name="android:textColor">@color/car_ui_toolbar_menu_item_icon_color</item>
+    </style>
+
+    <!-- Style applied to the seekbar widget within the seekbar preference -->
+    <style name="Widget.CarUi.SeekbarPreference.Seekbar">
+        <item name="android:background">@null</item>
+        <item name="android:clickable">false</item>
+        <item name="android:focusable">false</item>
+    </style>
+
+    <!-- Style applied to the decoration view between toolbar rows -->
+    <style name="Widget.CarUi.Toolbar.SeparatorView">
+        <item name="android:height">0.01dp</item>
+        <item name="android:background">@android:color/transparent</item>
+    </style>
+
+    <!-- Style applied to the decoration view below the toolbar -->
+    <style name="Widget.CarUi.Toolbar.BottomView">
+        <item name="android:height">0.01dp</item>
+        <item name="android:background">@android:color/transparent</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.MenuItem"/>
+
+    <style name="Widget.CarUi.Toolbar.MenuItem.Container">
+        <item name="android:divider">@drawable/car_ui_toolbar_menu_item_divider</item>
+        <item name="android:showDividers">beginning|middle|end</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.MenuItem.IndividualContainer">
+        <item name="android:minHeight">@dimen/car_ui_touch_target_height</item>
+        <item name="android:minWidth">@dimen/car_ui_touch_target_width</item>
+        <item name="android:layout_gravity">center_vertical</item>
+    </style>
+
+    <!-- Style applied to the edit box inside the toolbar search area -->
+    <style name="Widget.CarUi.Toolbar.Search.EditText"
+        parent="android:Widget.DeviceDefault.EditText"/>
+
+    <style name="Widget.CarUi.Toolbar.Search.SearchIcon" parent="Widget.CarUi.Toolbar"/>
+
+    <style name="Widget.CarUi.Toolbar.Search.CloseIcon" parent="Widget.CarUi.Toolbar">
+        <item name="android:background">@drawable/car_ui_toolbar_menu_item_icon_ripple</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.Tab"/>
+
+    <style name="Widget.CarUi.Toolbar.Tab.Container">
+        <item name="android:orientation">vertical</item>
+        <item name="android:paddingStart">@dimen/car_ui_toolbar_tab_padding_x</item>
+        <item name="android:paddingEnd">@dimen/car_ui_toolbar_tab_padding_x</item>
+        <item name="android:gravity">center</item>
+        <item name="android:background">?android:attr/selectableItemBackground</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.Tab.Icon">
+        <item name="android:scaleType">fitCenter</item>
+        <item name="android:tint">@color/car_ui_toolbar_tab_item_selector</item>
+        <item name="android:tintMode">src_in</item>
+    </style>
+
+    <style name="Widget.CarUi.Toolbar.Tab.Text">
+        <item name="android:singleLine">true</item>
+        <item name="android:gravity">center</item>
+        <item name="android:textAppearance">@style/TextAppearance.CarUi.Widget.Toolbar.Tab</item>
+    </style>
+
+    <style name="Widget.CarUi.CarUiRecyclerView">
+        <item name="android:scrollbars">vertical</item>
+    </style>
+
+    <style name="Widget.CarUi.AlertDialog"/>
+
+    <style name="Widget.CarUi.AlertDialog.HeaderContainer">
+        <item name="android:orientation">horizontal</item>
+        <item name="android:gravity">center_vertical|start</item>
+        <item name="android:paddingTop">18dp</item>
+        <item name="android:paddingBottom">18dp</item>
+    </style>
+
+    <style name="Widget.CarUi.AlertDialog.TitleContainer">
+        <item name="android:layout_marginStart">@dimen/car_ui_dialog_title_margin</item>
+        <item name="android:layout_marginEnd">@dimen/car_ui_dialog_title_margin</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+
+    <style name="Widget.CarUi.AlertDialog.Icon">
+        <item name="android:layout_marginStart">@dimen/car_ui_dialog_title_margin</item>
+        <item name="android:scaleType">fitCenter</item>
+    </style>
+
+    <!-- Preference Styles -->
+
+    <style name="Preference.CarUi">
+        <item name="allowDividerBelow">false</item>
+        <item name="allowDividerAbove">false</item>
+        <item name="android:layout">@layout/car_ui_preference</item>
+    </style>
+
+    <style name="Preference.CarUi.Category">
+        <item name="android:layout">@layout/car_ui_preference_category</item>
+        <!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
+        <item name="android:shouldDisableView">false</item>
+        <item name="android:selectable">false</item>
+    </style>
+
+    <style name="Preference.CarUi.CheckBoxPreference">
+        <item name="android:widgetLayout">@layout/car_ui_preference_widget_checkbox</item>
+    </style>
+
+    <style name="Preference.CarUi.DialogPreference">
+        <item name="android:positiveButtonText">@string/car_ui_dialog_preference_positive</item>
+        <item name="android:negativeButtonText">@string/car_ui_dialog_preference_negative</item>
+    </style>
+
+    <style name="Preference.CarUi.DialogPreference.EditTextPreference">
+        <item name="android:dialogLayout">@layout/car_ui_preference_dialog_edittext</item>
+    </style>
+
+    <style name="Preference.CarUi.Divider">
+        <item name="android:background">@color/car_ui_preference_two_action_divider_color</item>
+    </style>
+
+    <style name="Preference.CarUi.DropDown">
+        <item name="android:layout">@layout/car_ui_preference_dropdown</item>
+    </style>
+
+    <style name="Preference.CarUi.Icon"/>
+
+    <style name="Preference.CarUi.Information">
+        <item name="android:enabled">false</item>
+        <item name="android:shouldDisableView">false</item>
+    </style>
+
+    <style name="Preference.CarUi.Preference"/>
+
+    <style name="Preference.CarUi.PreferenceScreen"/>
+
+    <style name="Preference.CarUi.SeekBarPreference">
+        <item name="android:layout">@layout/car_ui_preference_widget_seekbar</item>
+        <item name="adjustable">true</item>
+        <item name="showSeekBarValue">false</item>
+    </style>
+
+    <style name="Preference.CarUi.DialogSeekBarPreference"/>
+
+    <style name="Preference.CarUi.DialogSeekBarPreference.Seekbar"/>
+
+    <style name="Preference.CarUi.DialogSeekBarPreference.TopText"/>
+    <style name="Preference.CarUi.DialogSeekBarPreference.RightText"/>
+    <style name="Preference.CarUi.DialogSeekBarPreference.LeftText"/>
+
+    <style name="Preference.CarUi.SwitchPreference">
+        <item name="android:widgetLayout">@layout/car_ui_preference_widget_switch</item>
+        <item name="android:switchTextOn">@string/car_ui_preference_switch_on</item>
+        <item name="android:switchTextOff">@string/car_ui_preference_switch_off</item>
+    </style>
+
+    <style name="PreferenceFragment.CarUi">
+        <item name="android:divider">?android:attr/listDivider</item>
+        <!-- TODO(b/150230923) change this to car_ui_preference_fragment -->
+        <item name="android:layout">@layout/car_ui_preference_fragment_with_toolbar</item>
+    </style>
+
+    <!-- TODO(b/150230923) remove this when other apps are ready -->
+    <style name="PreferenceFragment.CarUi.WithToolbar">
+        <item name="android:layout">@layout/car_ui_preference_fragment</item>
+    </style>
+
+    <style name="PreferenceFragmentList.CarUi">
+        <item name="android:paddingTop">0dp</item>
+        <item name="android:paddingBottom">0dp</item>
+        <item name="android:paddingLeft">0dp</item>
+        <item name="android:paddingStart">0dp</item>
+        <item name="android:paddingRight">0dp</item>
+        <item name="android:paddingEnd">0dp</item>
+    </style>
+
+    <!-- TextAppearance -->
+
+    <style name="TextAppearance.CarUi" parent="android:TextAppearance.DeviceDefault">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textAlignment">viewStart</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Body1">
+        <item name="android:textSize">@dimen/car_ui_body1_size</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Body2">
+        <item name="android:textSize">@dimen/car_ui_body2_size</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Body3">
+        <item name="android:textSize">@dimen/car_ui_body3_size</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Sub1">
+        <item name="android:textSize">@dimen/car_ui_sub1_size</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Sub2">
+        <item name="android:textSize">@dimen/car_ui_sub2_size</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Sub3">
+        <item name="android:textSize">@dimen/car_ui_sub3_size</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.PreferenceCategoryTitle" parent="TextAppearance.CarUi.Body3">
+        <item name="android:fontFamily">sans-serif-medium</item>
+        <item name="android:textColor">@color/car_ui_color_accent</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.PreferenceSummary" parent="TextAppearance.CarUi.Body3">
+        <item name="android:textColor">@color/car_ui_text_color_secondary</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.PreferenceTitle" parent="TextAppearance.CarUi.Body1"/>
+
+    <style name="TextAppearance.CarUi.PreferenceEditTextDialogMessage" parent="TextAppearance.CarUi.Body3"/>
+
+    <style name="TextAppearance.CarUi.AlertDialog.Title" parent="TextAppearance.CarUi.Body3"/>
+    <style name="TextAppearance.CarUi.AlertDialog.Subtitle" parent="TextAppearance.CarUi.Sub3"/>
+
+    <style name="TextAppearance.CarUi.Widget" parent="android:TextAppearance.DeviceDefault.Widget">
+        <item name="android:textAlignment">viewStart</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Widget.Toolbar"/>
+
+    <style name="TextAppearance.CarUi.Widget.Toolbar.Title" parent="TextAppearance.CarUi.Body1">
+        <item name="android:singleLine">true</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Widget.Toolbar.Tab" parent="TextAppearance.CarUi.Body3">
+        <item name="android:textColor">@color/car_ui_toolbar_tab_item_selector</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textFontWeight">400</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.Widget.Toolbar.Tab.Selected">
+        <item name="android:textFontWeight">500</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.ListItem.Header" parent="TextAppearance.CarUi.Body3">
+        <item name="android:fontFamily">sans-serif-medium</item>
+        <item name="android:textColor">@color/car_ui_color_accent</item>
+    </style>
+
+    <style name="TextAppearance.CarUi.ListItem" parent="TextAppearance.CarUi.Body1"/>
+
+    <style name="TextAppearance.CarUi.ListItem.Body" parent="TextAppearance.CarUi.Body3">
+        <item name="android:textColor">@color/car_ui_text_color_secondary</item>
+    </style>
+
+</resources>
diff --git a/car-ui-lib/res/values/themes.xml b/car-ui-lib/res/values/themes.xml
new file mode 100644
index 0000000..34bbf3c
--- /dev/null
+++ b/car-ui-lib/res/values/themes.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- TODO: for internal TODOs, expand theme/style to leaf resources as necessary -->
+    <style name="Theme.CarUi" parent="@android:style/Theme.DeviceDefault.NoActionBar">
+        <!-- TODO(b/150230923) change to true when other apps are ready -->
+        <item name="carUiBaseLayout">false</item>
+        <item name="carUiToolbar">false</item>
+
+        <!-- Attributes from: Base.V7.Theme.AppCompat -->
+
+        <item name="windowNoTitle">true</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowActionBarOverlay">false</item>
+        <item name="windowActionModeOverlay">false</item>
+        <item name="actionBarPopupTheme">@null</item>
+
+        <item name="colorBackgroundFloating">?android:attr/colorBackgroundFloating</item>
+
+        <!-- Used by MediaRouter -->
+        <item name="isLightTheme">false</item>
+
+        <item name="selectableItemBackground">?android:attr/selectableItemBackground</item>
+        <item name="selectableItemBackgroundBorderless">?android:attr/selectableItemBackgroundBorderless</item>
+        <item name="borderlessButtonStyle">?android:attr/borderlessButtonStyle</item>
+        <item name="homeAsUpIndicator">?android:attr/homeAsUpIndicator</item>
+
+        <item name="dividerVertical">?android:attr/dividerVertical</item>
+        <item name="dividerHorizontal">?android:attr/dividerHorizontal</item>
+
+        <!-- Action Bar Styles -->
+        <item name="actionBarTabStyle">?android:attr/actionBarTabStyle</item>
+        <item name="actionBarTabBarStyle">?android:attr/actionBarTabBarStyle</item>
+        <item name="actionBarTabTextStyle">?android:attr/actionBarTabTextStyle</item>
+        <item name="actionButtonStyle">?android:attr/actionButtonStyle</item>
+        <item name="actionOverflowButtonStyle">?android:attr/actionOverflowButtonStyle</item>
+        <item name="actionOverflowMenuStyle">?android:attr/actionOverflowMenuStyle</item>
+        <item name="actionBarStyle">?android:attr/actionBarStyle</item>
+        <item name="actionBarSplitStyle">?android:attr/actionBarSplitStyle</item>
+        <item name="actionBarWidgetTheme">?android:attr/actionBarWidgetTheme</item>
+        <item name="actionBarTheme">?android:attr/actionBarTheme</item>
+        <item name="actionBarSize">?android:attr/actionBarSize</item>
+        <item name="actionBarDivider">?android:attr/actionBarDivider</item>
+        <item name="actionBarItemBackground">?android:attr/actionBarItemBackground</item>
+        <item name="actionMenuTextAppearance">?android:attr/actionMenuTextAppearance</item>
+        <item name="actionMenuTextColor">?android:attr/actionMenuTextColor</item>
+
+        <!-- Dropdown Spinner Attributes -->
+        <item name="actionDropDownStyle">?android:attr/actionDropDownStyle</item>
+
+        <!-- Action Mode -->
+        <item name="actionModeStyle">?android:attr/actionModeStyle</item>
+        <item name="actionModeBackground">?android:attr/actionModeBackground</item>
+        <item name="actionModeSplitBackground">?android:attr/actionModeSplitBackground</item>
+        <item name="actionModeCloseDrawable">?android:attr/actionModeCloseDrawable</item>
+        <item name="actionModeCloseButtonStyle">?android:attr/actionModeCloseButtonStyle</item>
+
+        <item name="actionModeCutDrawable">?android:attr/actionModeCutDrawable</item>
+        <item name="actionModeCopyDrawable">?android:attr/actionModeCopyDrawable</item>
+        <item name="actionModePasteDrawable">?android:attr/actionModePasteDrawable</item>
+        <item name="actionModeSelectAllDrawable">?android:attr/actionModeSelectAllDrawable</item>
+        <item name="actionModeShareDrawable">?android:attr/actionModeShareDrawable</item>
+
+        <!-- Panel attributes -->
+        <!-- TODO: panelMenuListWidth -->
+        <item name="panelMenuListWidth">@dimen/abc_panel_menu_list_width</item>
+        <!-- TODO: panelMenuListTheme -->
+        <item name="panelMenuListTheme">@style/Theme.AppCompat.CompactMenu</item>
+        <item name="panelBackground">?android:attr/panelBackground</item>
+        <item name="listChoiceBackgroundIndicator">?android:attr/listChoiceBackgroundIndicator</item>
+
+        <!-- List attributes -->
+        <item name="textAppearanceListItem">?android:attr/textAppearanceListItem</item>
+        <item name="textAppearanceListItemSmall">?android:attr/textAppearanceListItemSmall</item>
+        <item name="textAppearanceListItemSecondary">?android:attr/textAppearanceListItemSecondary</item>
+        <item name="listPreferredItemHeight">?android:attr/listPreferredItemHeight</item>
+        <item name="listPreferredItemHeightSmall">?android:attr/listPreferredItemHeightSmall</item>
+        <item name="listPreferredItemHeightLarge">?android:attr/listPreferredItemHeightLarge</item>
+        <item name="listPreferredItemPaddingLeft">?android:attr/listPreferredItemPaddingLeft</item>
+        <item name="listPreferredItemPaddingRight">?android:attr/listPreferredItemPaddingRight</item>
+
+        <!-- Spinner styles -->
+        <item name="spinnerStyle">?android:attr/spinnerStyle</item>
+
+        <!-- Required for use of support_simple_spinner_dropdown_item.xml -->
+        <item name="spinnerDropDownItemStyle">?android:attr/spinnerDropDownItemStyle</item>
+        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
+
+        <!-- Popup Menu styles -->
+        <item name="popupMenuStyle">?android:attr/popupMenuStyle</item>
+        <item name="textAppearanceLargePopupMenu">?android:attr/textAppearanceLargePopupMenu</item>
+        <item name="textAppearanceSmallPopupMenu">?android:attr/textAppearanceSmallPopupMenu</item>
+        <item name="textAppearancePopupMenuHeader">?android:attr/textAppearancePopupMenuHeader</item>
+        <item name="listPopupWindowStyle">?android:attr/listPopupWindowStyle</item>
+        <item name="dropDownListViewStyle">?android:attr/dropDownListViewStyle</item>
+        <item name="listMenuViewStyle">?android:attr/listMenuViewStyle</item>
+
+        <!-- SearchView attributes -->
+        <item name="searchViewStyle">?android:attr/searchViewStyle</item>
+        <!-- TODO: textColorSearchUrl -->
+        <item name="textColorSearchUrl">@color/abc_search_url_text</item>
+        <item name="textAppearanceSearchResultTitle">?android:attr/textAppearanceSearchResultTitle</item>
+        <item name="textAppearanceSearchResultSubtitle">?android:attr/textAppearanceSearchResultSubtitle</item>
+
+        <!-- ShareActionProvider attributes -->
+        <!-- TODO: activityChooserViewStyle -->
+        <item name="activityChooserViewStyle">@style/Widget.AppCompat.ActivityChooserView</item>
+
+        <!-- Toolbar styles -->
+        <item name="toolbarStyle">?android:attr/toolbarStyle</item>
+        <!-- TODO: toolbarNavigationButtonStyle -->
+        <item name="toolbarNavigationButtonStyle">@style/Widget.AppCompat.Toolbar.Button.Navigation</item>
+
+        <item name="editTextStyle">?android:attr/editTextStyle</item>
+        <item name="editTextBackground">?android:attr/editTextBackground</item>
+        <item name="editTextColor">?android:attr/editTextColor</item>
+        <item name="autoCompleteTextViewStyle">?android:attr/autoCompleteTextViewStyle</item>
+
+        <!-- Color palette -->
+        <item name="colorPrimaryDark">?android:attr/colorPrimaryDark</item>
+        <item name="colorPrimary">?android:attr/colorPrimary</item>
+        <item name="colorAccent">?android:attr/colorAccent</item>
+
+        <item name="colorControlNormal">?android:attr/colorControlNormal</item>
+        <item name="colorControlActivated">?android:attr/colorControlActivated</item>
+        <item name="colorControlHighlight">?android:attr/colorControlHighlight</item>
+        <item name="colorButtonNormal">?android:attr/colorButtonNormal</item>
+        <!-- TODO: colorSwitchThumbNormal -->
+        <item name="colorSwitchThumbNormal">@color/switch_thumb_material_dark</item>
+        <item name="controlBackground">?attr/selectableItemBackgroundBorderless</item>
+
+        <!-- TODO: drawerArrowStyle -->
+        <item name="drawerArrowStyle">@style/Widget.AppCompat.DrawerArrowToggle</item>
+
+        <item name="checkboxStyle">?android:attr/checkboxStyle</item>
+        <item name="radioButtonStyle">?android:attr/radioButtonStyle</item>
+        <item name="switchStyle">?android:attr/switchStyle</item>
+
+        <item name="ratingBarStyle">?android:attr/ratingBarStyle</item>
+        <item name="ratingBarStyleIndicator">?android:attr/ratingBarStyleIndicator</item>
+        <item name="ratingBarStyleSmall">?android:attr/ratingBarStyleSmall</item>
+        <item name="seekBarStyle">?android:attr/seekBarStyle</item>
+
+        <!-- Button styles -->
+        <item name="buttonStyle">?android:attr/buttonStyle</item>
+        <item name="buttonStyleSmall">?android:attr/buttonStyleSmall</item>
+
+        <item name="imageButtonStyle">?android:attr/imageButtonStyle</item>
+
+        <item name="buttonBarStyle">?android:attr/buttonBarStyle</item>
+        <item name="buttonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
+        <item name="buttonBarPositiveButtonStyle">?android:attr/buttonBarPositiveButtonStyle</item>
+        <item name="buttonBarNegativeButtonStyle">?android:attr/buttonBarNegativeButtonStyle</item>
+        <item name="buttonBarNeutralButtonStyle">?android:attr/buttonBarNeutralButtonStyle</item>
+
+        <!-- Dialog attributes -->
+        <item name="dialogTheme">?android:attr/dialogTheme</item>
+        <item name="dialogPreferredPadding">?android:attr/dialogPreferredPadding</item>
+        <item name="dialogCornerRadius">?android:attr/dialogCornerRadius</item>
+
+        <item name="alertDialogTheme">?android:attr/alertDialogTheme</item>
+        <item name="alertDialogStyle">?android:attr/alertDialogStyle</item>
+        <item name="alertDialogCenterButtons">false</item>
+        <item name="textColorAlertDialogListItem">?android:attr/textColorAlertDialogListItem</item>
+        <item name="listDividerAlertDialog">?android:attr/listDividerAlertDialog</item>
+
+        <!-- Define these here; ContextThemeWrappers around themes that define them should
+             always clear these values. -->
+        <item name="windowFixedWidthMajor">@null</item>
+        <item name="windowFixedWidthMinor">@null</item>
+        <item name="windowFixedHeightMajor">@null</item>
+        <item name="windowFixedHeightMinor">@null</item>
+
+        <!-- Tooltip attributes -->
+        <!-- TODO: tooltipFrameBackground -->
+        <item name="tooltipFrameBackground">@drawable/tooltip_frame_light</item>
+        <!-- TODO: tooltipForegroundColor -->
+        <item name="tooltipForegroundColor">@color/foreground_material_light</item>
+
+        <item name="colorError">?android:attr/colorError</item>
+
+        <!-- Attributes from: Platform.AppCompat -->
+
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowActionBar">false</item>
+
+        <item name="listChoiceIndicatorSingleAnimated">?android:attr/listChoiceIndicatorSingle</item>
+        <item name="listChoiceIndicatorMultipleAnimated">?android:attr/listChoiceIndicatorMultiple</item>
+
+        <item name="preferenceTheme">@style/CarUiPreferenceTheme</item>
+
+        <!-- Used by CarUiRecyclerView -->
+        <item name="carUiRecyclerViewStyle">@style/Widget.CarUi.CarUiRecyclerView</item>
+    </style>
+
+    <!-- TODO(b/150230923) remove this when other apps are ready -->
+    <style name="Theme.CarUi.WithToolbar">
+        <item name="carUiBaseLayout">true</item>
+        <item name="carUiToolbar">true</item>
+        <item name="preferenceTheme">@style/CarUiPreferenceTheme.WithToolbar</item>
+    </style>
+
+    <style name="Theme.CarUi.NoToolbar">
+        <item name="carUiBaseLayout">true</item>
+        <item name="carUiToolbar">false</item>
+    </style>
+
+    <style name="CarUiPreferenceTheme">
+        <item name="checkBoxPreferenceStyle">@style/Preference.CarUi.CheckBoxPreference</item>
+        <item name="dialogPreferenceStyle">@style/Preference.CarUi.DialogPreference</item>
+        <item name="dropdownPreferenceStyle">@style/Preference.CarUi.DropDown</item>
+        <item name="editTextPreferenceStyle">@style/Preference.CarUi.DialogPreference.EditTextPreference</item>
+        <item name="preferenceCategoryStyle">@style/Preference.CarUi.Category</item>
+        <item name="preferenceFragmentCompatStyle">@style/PreferenceFragment.CarUi</item>
+        <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList.CarUi</item>
+        <item name="preferenceFragmentStyle">@style/PreferenceFragment.CarUi</item>
+        <item name="preferenceScreenStyle">@style/Preference.CarUi.PreferenceScreen</item>
+        <item name="preferenceStyle">@style/Preference.CarUi</item>
+        <item name="seekBarPreferenceStyle">@style/Preference.CarUi.SeekBarPreference</item>
+        <item name="switchPreferenceStyle">@style/Preference.CarUi.SwitchPreference</item>
+    </style>
+
+    <!-- TODO(b/150230923) remove this when other apps are ready -->
+    <style name="CarUiPreferenceTheme.WithToolbar">
+        <item name="preferenceFragmentCompatStyle">@style/PreferenceFragment.CarUi.WithToolbar</item>
+        <item name="preferenceFragmentStyle">@style/PreferenceFragment.CarUi.WithToolbar</item>
+    </style>
+
+</resources>
diff --git a/car-ui-lib/res/values/values.xml b/car-ui-lib/res/values/values.xml
new file mode 100644
index 0000000..82a4d65
--- /dev/null
+++ b/car-ui-lib/res/values/values.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <!-- Toolbar -->
+
+    <!-- Layout to be used for toolbar tabs -->
+    <item name="car_ui_toolbar_tab_item_layout" type="layout">@layout/car_ui_toolbar_tab_item</item>
+    <item name="car_ui_toolbar_tab_item_layout_flexible" type="layout">@layout/car_ui_toolbar_tab_item_flexible</item>
+</resources>
diff --git a/car-ui-lib/settings.gradle b/car-ui-lib/settings.gradle
index 43af7e0..50c2c6d 100644
--- a/car-ui-lib/settings.gradle
+++ b/car-ui-lib/settings.gradle
@@ -14,14 +14,11 @@
  * limitations under the License.
  */
 
-include ':car-ui-lib'
-project(':car-ui-lib').projectDir = new File('./car-ui-lib')
 include ':PaintBooth'
-project(':PaintBooth').projectDir = new File('./paintbooth')
-include ':oem-apis'
-project(':oem-apis').projectDir = new File('./oem-apis')
-include ':shared-library'
-project(':shared-library').projectDir = new File('./referencedesign/sharedlibrary')
+project(':PaintBooth').projectDir = new File('./tests/paintbooth')
+include ':RoboTests'
+project(':RoboTests').projectDir = new File('./tests/robotests')
+include ':InstrumentionTests'
+project(':InstrumentionTests').projectDir = new File('./tests/unit')
 
 rootProject.name='Chassis'
-include ':car-rotary-lib'
diff --git a/car-ui-lib/sharedlibrary/Android.bp b/car-ui-lib/sharedlibrary/Android.bp
new file mode 100644
index 0000000..1abaa30
--- /dev/null
+++ b/car-ui-lib/sharedlibrary/Android.bp
@@ -0,0 +1,31 @@
+
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_app {
+    name: "car-ui-lib-sharedlibrary",
+    visibility: [
+        "//packages/apps/Car/libs/car-ui-lib/tests/PaintBooth:__pkg__",
+    ],
+    platform_apis: true,
+    resource_dirs: ["res"],
+    aaptflags: ["--shared-lib"],
+    optimize: {
+        enabled: false,
+    },
+    static_libs: [
+        "car-ui-lib",
+    ],
+}
diff --git a/car-ui-lib/sharedlibrary/AndroidManifest.xml b/car-ui-lib/sharedlibrary/AndroidManifest.xml
new file mode 100644
index 0000000..61b4515
--- /dev/null
+++ b/car-ui-lib/sharedlibrary/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.car.ui.sharedlibrary">
+  <uses-sdk
+      android:minSdkVersion="28"
+      android:targetSdkVersion="28" />
+    <application>
+        <library android:name="com.android.car.ui.sharedlibrary" />
+    </application>
+</manifest>
diff --git a/car-ui-lib/sharedlibrary/README.md b/car-ui-lib/sharedlibrary/README.md
new file mode 100644
index 0000000..21c6172
--- /dev/null
+++ b/car-ui-lib/sharedlibrary/README.md
@@ -0,0 +1,5 @@
+# Android Automotive 'Chassis' shared library
+Please refer to [Android Automotive 'Chassiss' library](../README.md)
+
+**Required**
+This module needs to be, and is included in PRODUCT_PACKAGES in vendor/auto/embeded/products/car.mk. It needs to be pre-installed with the system image.
\ No newline at end of file
diff --git a/car-ui-lib/sharedlibrary/res/values/public.xml b/car-ui-lib/sharedlibrary/res/values/public.xml
new file mode 100644
index 0000000..80ea2e7
--- /dev/null
+++ b/car-ui-lib/sharedlibrary/res/values/public.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <!-- Any resource or attribute that is or can be referenced from RRO needs to be public go/rro-on-r -->
+
+    <!-- To add new resources to this file follow the following naming convention -->
+    <!-- 0cXXXX is used for styles -->
+    <!-- 0dXXXX is used for attributes -->
+    <!-- 0eXXXX is used for drawables -->
+    <!-- The first time that a resource type is seen, Android resource manager, assigns YY of the ID (0xXXYYXXXX) of the resouce to that type.
+         And you'll get a compile error if you use the same type with a different YY -->
+
+    <public type="style" name="Theme.CarUi" id="0x000c0000" />
+
+    <public type="attr" name="logo" id="0x000d0001" />
+    <public type="attr" name="car_ui_state" id="0x000d0002" />
+    <public type="attr" name="title" id="0x000d0003" />
+    <public type="attr" name="layoutStyle" id="0x000d0004" />
+    <public type="attr" name="numOfColumns" id="0x000d0005" />
+    <public type="attr" name="layout_constraintTop_toTopOf" id="0x000d0006" />
+    <public type="attr" name="layout_constraintTop_toBottomOf" id="0x000d0007" />
+    <public type="attr" name="layout_constraintLeft_toLeftOf" id="0x000d0008" />
+    <public type="attr" name="layout_constraintBottom_toTopOf" id="0x000d0009" />
+    <public type="attr" name="layout_constraintBottom_toBottomOf" id="0x000d0010" />
+    <public type="attr" name="layout_constraintRight_toRightOf" id="0x000d0011" />
+    <public type="attr" name="search" id="0x000d0012" />
+    <public type="attr" name="settings" id="0x000d0013" />
+    <public type="attr" name="id" id="0x000d0014" />
+    <public type="attr" name="icon" id="0x000d0015" />
+    <public type="attr" name="onClick" id="0x000d0016" />
+    <public type="attr" name="checkable" id="0x000d0017" />
+    <public type="attr" name="uxRestrictions" id="0x000d0018" />
+    <public type="attr" name="singleLineTitle" id="0x000d0019" />
+    <public type="attr" name="useSimpleSummaryProvider" id="0x000d0020" />
+    <public type="attr" name="initialExpandedChildrenCount" id="0x000d0021" />
+    <public type="attr" name="enableCopying" id="0x000d0022" />
+
+    <public type="drawable" name="car_ui_activity_background" id="0x000e0000" />
+
+</resources>
diff --git a/car-ui-lib/src/com/android/car/ui/AlertDialogBuilder.java b/car-ui-lib/src/com/android/car/ui/AlertDialogBuilder.java
new file mode 100644
index 0000000..a025e9e
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/AlertDialogBuilder.java
@@ -0,0 +1,702 @@
+/*
+ * 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.ui;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.text.InputFilter;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.LinkMovementMethod;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import androidx.annotation.ArrayRes;
+import androidx.annotation.AttrRes;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter;
+import com.android.car.ui.utils.CarUiUtils;
+
+/**
+ * Wrapper for AlertDialog.Builder
+ */
+public class AlertDialogBuilder {
+
+    private AlertDialog.Builder mBuilder;
+    private Context mContext;
+    private boolean mPositiveButtonSet;
+    private boolean mNeutralButtonSet;
+    private boolean mNegativeButtonSet;
+    private CharSequence mTitle;
+    private CharSequence mSubtitle;
+    private Drawable mIcon;
+    private boolean mIconTinted;
+
+    public AlertDialogBuilder(Context context) {
+        // Resource id specified as 0 uses the parent contexts resolved value for alertDialogTheme.
+        this(context, /* themeResId= */0);
+    }
+
+    public AlertDialogBuilder(Context context, int themeResId) {
+        mBuilder = new AlertDialog.Builder(context, themeResId);
+        mContext = context;
+    }
+
+    public Context getContext() {
+        return mBuilder.getContext();
+    }
+
+    /**
+     * Set the title using the given resource id.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setTitle(@StringRes int titleId) {
+        return setTitle(mContext.getText(titleId));
+    }
+
+    /**
+     * Set the title displayed in the {@link Dialog}.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setTitle(CharSequence title) {
+        mTitle = title;
+        mBuilder.setTitle(title);
+        return this;
+    }
+
+    /**
+     * Sets a subtitle to be displayed in the {@link Dialog}.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setSubtitle(@StringRes int subtitle) {
+        return setSubtitle(mContext.getString(subtitle));
+    }
+
+    /**
+     * Sets a subtitle to be displayed in the {@link Dialog}.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setSubtitle(CharSequence subtitle) {
+        mSubtitle = subtitle;
+        return this;
+    }
+
+    /**
+     * Set the message to display using the given resource id.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setMessage(@StringRes int messageId) {
+        mBuilder.setMessage(messageId);
+        return this;
+    }
+
+    /**
+     * Set the message to display.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setMessage(CharSequence message) {
+        mBuilder.setMessage(message);
+        return this;
+    }
+
+    /**
+     * Set the resource id of the {@link Drawable} to be used in the title.
+     * <p>
+     * Takes precedence over values set using {@link #setIcon(Drawable)}.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setIcon(@DrawableRes int iconId) {
+        return setIcon(mContext.getDrawable(iconId));
+    }
+
+    /**
+     * Set the {@link Drawable} to be used in the title.
+     * <p>
+     * <strong>Note:</strong> To ensure consistent styling, the drawable
+     * should be inflated or constructed using the alert dialog's themed
+     * context obtained via {@link #getContext()}.
+     *
+     * @return this Builder object to allow for chaining of calls to set
+     * methods
+     */
+    public AlertDialogBuilder setIcon(Drawable icon) {
+        mIcon = icon;
+        return this;
+    }
+
+    /**
+     * Whether the icon provided by {@link #setIcon(Drawable)} should be
+     * tinted with the default system color.
+     *
+     * @return this Builder object to allow for chaining of calls to set
+     * methods.
+     */
+    public AlertDialogBuilder setIconTinted(boolean tinted) {
+        mIconTinted = tinted;
+        return this;
+    }
+
+    /**
+     * Set an icon as supplied by a theme attribute. e.g.
+     * {@link android.R.attr#alertDialogIcon}.
+     * <p>
+     * Takes precedence over values set using {@link #setIcon(Drawable)}.
+     *
+     * @param attrId ID of a theme attribute that points to a drawable resource.
+     */
+    public AlertDialogBuilder setIconAttribute(@AttrRes int attrId) {
+        mBuilder.setIconAttribute(attrId);
+        return this;
+    }
+
+    /**
+     * Set a listener to be invoked when the positive button of the dialog is pressed.
+     *
+     * @param textId The resource id of the text to display in the positive button
+     * @param listener The {@link DialogInterface.OnClickListener} to use.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setPositiveButton(@StringRes int textId,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setPositiveButton(textId, listener);
+        mPositiveButtonSet = true;
+        return this;
+    }
+
+    /**
+     * Set a listener to be invoked when the positive button of the dialog is pressed.
+     *
+     * @param text The text to display in the positive button
+     * @param listener The {@link DialogInterface.OnClickListener} to use.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setPositiveButton(CharSequence text,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setPositiveButton(text, listener);
+        mPositiveButtonSet = true;
+        return this;
+    }
+
+    /**
+     * Set a listener to be invoked when the negative button of the dialog is pressed.
+     *
+     * @param textId The resource id of the text to display in the negative button
+     * @param listener The {@link DialogInterface.OnClickListener} to use.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setNegativeButton(@StringRes int textId,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setNegativeButton(textId, listener);
+        mNegativeButtonSet = true;
+        return this;
+    }
+
+    /**
+     * Set a listener to be invoked when the negative button of the dialog is pressed.
+     *
+     * @param text The text to display in the negative button
+     * @param listener The {@link DialogInterface.OnClickListener} to use.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setNegativeButton(CharSequence text,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setNegativeButton(text, listener);
+        mNegativeButtonSet = true;
+        return this;
+    }
+
+    /**
+     * Set a listener to be invoked when the neutral button of the dialog is pressed.
+     *
+     * @param textId The resource id of the text to display in the neutral button
+     * @param listener The {@link DialogInterface.OnClickListener} to use.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setNeutralButton(@StringRes int textId,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setNeutralButton(textId, listener);
+        mNeutralButtonSet = true;
+        return this;
+    }
+
+    /**
+     * Set a listener to be invoked when the neutral button of the dialog is pressed.
+     *
+     * @param text The text to display in the neutral button
+     * @param listener The {@link DialogInterface.OnClickListener} to use.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setNeutralButton(CharSequence text,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setNeutralButton(text, listener);
+        mNeutralButtonSet = true;
+        return this;
+    }
+
+    /**
+     * Sets whether the dialog is cancelable or not.  Default is true.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setCancelable(boolean cancelable) {
+        mBuilder.setCancelable(cancelable);
+        return this;
+    }
+
+    /**
+     * Sets the callback that will be called if the dialog is canceled.
+     *
+     * <p>Even in a cancelable dialog, the dialog may be dismissed for reasons other than
+     * being canceled or one of the supplied choices being selected.
+     * If you are interested in listening for all cases where the dialog is dismissed
+     * and not just when it is canceled, see
+     * {@link #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
+     * setOnDismissListener}.</p>
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     * @see #setCancelable(boolean)
+     * @see #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
+     */
+    public AlertDialogBuilder setOnCancelListener(
+            DialogInterface.OnCancelListener onCancelListener) {
+        mBuilder.setOnCancelListener(onCancelListener);
+        return this;
+    }
+
+    /**
+     * Sets the callback that will be called when the dialog is dismissed for any reason.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setOnDismissListener(
+            DialogInterface.OnDismissListener onDismissListener) {
+        mBuilder.setOnDismissListener(onDismissListener);
+        return this;
+    }
+
+    /**
+     * Sets the callback that will be called if a key is dispatched to the dialog.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setOnKeyListener(DialogInterface.OnKeyListener onKeyListener) {
+        mBuilder.setOnKeyListener(onKeyListener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content, you will be notified of the
+     * selected item via the supplied listener. This should be an array type i.e. R.array.foo
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setItems(@ArrayRes int itemsId,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setItems(itemsId, listener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content, you will be notified of the
+     * selected item via the supplied listener.
+     *
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setItems(CharSequence[] items,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setItems(items, listener);
+        return this;
+    }
+
+    /**
+     * This was not supposed to be in the Chassis API because it allows custom views.
+     *
+     * @deprecated Use {@link #setAdapter(CarUiListItemAdapter)} instead.
+     */
+    @Deprecated
+    public AlertDialogBuilder setAdapter(final ListAdapter adapter,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setAdapter(adapter, listener);
+        return this;
+    }
+
+    /**
+     * Display all the {@link com.android.car.ui.recyclerview.CarUiListItem CarUiListItems} in a
+     * {@link CarUiListItemAdapter}. You should set click listeners on the CarUiListItems as
+     * opposed to a callback in this function.
+     */
+    public AlertDialogBuilder setAdapter(final CarUiListItemAdapter adapter) {
+        setCustomList(adapter);
+        return this;
+    }
+
+    private void setCustomList(@NonNull CarUiListItemAdapter adapter) {
+        View customList = LayoutInflater.from(mContext).inflate(
+                R.layout.car_ui_alert_dialog_list, null);
+        RecyclerView mList = CarUiUtils.requireViewByRefId(customList, R.id.list);
+        mList.setLayoutManager(new LinearLayoutManager(mContext));
+        mList.setAdapter(adapter);
+        mBuilder.setView(customList);
+    }
+
+    /**
+     * Set a list of items, which are supplied by the given {@link Cursor}, to be
+     * displayed in the dialog as the content, you will be notified of the
+     * selected item via the supplied listener.
+     *
+     * @param cursor The {@link Cursor} to supply the list of items
+     * @param listener The listener that will be called when an item is clicked.
+     * @param labelColumn The column name on the cursor containing the string to display
+     * in the label.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setCursor(final Cursor cursor,
+            final DialogInterface.OnClickListener listener,
+            String labelColumn) {
+        mBuilder.setCursor(cursor, listener, labelColumn);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content,
+     * you will be notified of the selected item via the supplied listener.
+     * This should be an array type, e.g. R.array.foo. The list will have
+     * a check mark displayed to the right of the text for each checked
+     * item. Clicking on an item in the list will not dismiss the dialog.
+     * Clicking on a button will dismiss the dialog.
+     *
+     * @param itemsId the resource id of an array i.e. R.array.foo
+     * @param checkedItems specifies which items are checked. It should be null in which case no
+     * items are checked. If non null it must be exactly the same length as the array of
+     * items.
+     * @param listener notified when an item on the list is clicked. The dialog will not be
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setMultiChoiceItems(@ArrayRes int itemsId, boolean[] checkedItems,
+            final DialogInterface.OnMultiChoiceClickListener listener) {
+        mBuilder.setMultiChoiceItems(itemsId, checkedItems, listener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content,
+     * you will be notified of the selected item via the supplied listener.
+     * The list will have a check mark displayed to the right of the text
+     * for each checked item. Clicking on an item in the list will not
+     * dismiss the dialog. Clicking on a button will dismiss the dialog.
+     *
+     * @param items the text of the items to be displayed in the list.
+     * @param checkedItems specifies which items are checked. It should be null in which case no
+     * items are checked. If non null it must be exactly the same length as the array of
+     * items.
+     * @param listener notified when an item on the list is clicked. The dialog will not be
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,
+            final DialogInterface.OnMultiChoiceClickListener listener) {
+        mBuilder.setMultiChoiceItems(items, checkedItems, listener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content,
+     * you will be notified of the selected item via the supplied listener.
+     * The list will have a check mark displayed to the right of the text
+     * for each checked item. Clicking on an item in the list will not
+     * dismiss the dialog. Clicking on a button will dismiss the dialog.
+     *
+     * @param cursor the cursor used to provide the items.
+     * @param isCheckedColumn specifies the column name on the cursor to use to determine
+     * whether a checkbox is checked or not. It must return an integer value where 1
+     * means checked and 0 means unchecked.
+     * @param labelColumn The column name on the cursor containing the string to display in the
+     * label.
+     * @param listener notified when an item on the list is clicked. The dialog will not be
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setMultiChoiceItems(Cursor cursor, String isCheckedColumn,
+            String labelColumn,
+            final DialogInterface.OnMultiChoiceClickListener listener) {
+        mBuilder.setMultiChoiceItems(cursor, isCheckedColumn, labelColumn, listener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content, you will be notified of
+     * the selected item via the supplied listener. This should be an array type i.e.
+     * R.array.foo The list will have a check mark displayed to the right of the text for the
+     * checked item. Clicking on an item in the list will not dismiss the dialog. Clicking on a
+     * button will dismiss the dialog.
+     *
+     * @param itemsId the resource id of an array i.e. R.array.foo
+     * @param checkedItem specifies which item is checked. If -1 no items are checked.
+     * @param listener notified when an item on the list is clicked. The dialog will not be
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setSingleChoiceItems(@ArrayRes int itemsId, int checkedItem,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setSingleChoiceItems(itemsId, checkedItem, listener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content, you will be notified of
+     * the selected item via the supplied listener. The list will have a check mark displayed to
+     * the right of the text for the checked item. Clicking on an item in the list will not
+     * dismiss the dialog. Clicking on a button will dismiss the dialog.
+     *
+     * @param cursor the cursor to retrieve the items from.
+     * @param checkedItem specifies which item is checked. If -1 no items are checked.
+     * @param labelColumn The column name on the cursor containing the string to display in the
+     * label.
+     * @param listener notified when an item on the list is clicked. The dialog will not be
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setSingleChoiceItems(Cursor cursor, int checkedItem,
+            String labelColumn,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setSingleChoiceItems(cursor, checkedItem, labelColumn, listener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content, you will be notified of
+     * the selected item via the supplied listener. The list will have a check mark displayed to
+     * the right of the text for the checked item. Clicking on an item in the list will not
+     * dismiss the dialog. Clicking on a button will dismiss the dialog.
+     *
+     * @param items the items to be displayed.
+     * @param checkedItem specifies which item is checked. If -1 no items are checked.
+     * @param listener notified when an item on the list is clicked. The dialog will not be
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setSingleChoiceItems(CharSequence[] items, int checkedItem,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setSingleChoiceItems(items, checkedItem, listener);
+        return this;
+    }
+
+    /**
+     * This was not supposed to be in the Chassis API because it allows custom views.
+     *
+     * @deprecated Use {@link #setSingleChoiceItems(CarUiRadioButtonListItemAdapter,
+     * DialogInterface.OnClickListener)} instead.
+     */
+    @Deprecated
+    public AlertDialogBuilder setSingleChoiceItems(ListAdapter adapter, int checkedItem,
+            final DialogInterface.OnClickListener listener) {
+        mBuilder.setSingleChoiceItems(adapter, checkedItem, listener);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content, you will be notified of
+     * the selected item via the supplied listener. The list will have a check mark displayed to
+     * the right of the text for the checked item. Clicking on an item in the list will not
+     * dismiss the dialog. Clicking on a button will dismiss the dialog.
+     *
+     * @param adapter The {@link CarUiRadioButtonListItemAdapter} to supply the list of items
+     * @param listener notified when an item on the list is clicked. The dialog will not be
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     *
+     * @deprecated Use {@link #setSingleChoiceItems(CarUiRadioButtonListItemAdapter)} instead.
+     */
+    @Deprecated
+    public AlertDialogBuilder setSingleChoiceItems(CarUiRadioButtonListItemAdapter adapter,
+            final DialogInterface.OnClickListener listener) {
+        setCustomList(adapter);
+        return this;
+    }
+
+    /**
+     * Set a list of items to be displayed in the dialog as the content,The list will have a check
+     * mark displayed to the right of the text for the checked item. Clicking on an item in the list
+     * will not dismiss the dialog. Clicking on a button will dismiss the dialog.
+     *
+     * @param adapter The {@link CarUiRadioButtonListItemAdapter} to supply the list of items
+     * dismissed when an item is clicked. It will only be dismissed if clicked on a
+     * button, if no buttons are supplied it's up to the user to dismiss the dialog.
+     * @return This Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setSingleChoiceItems(CarUiRadioButtonListItemAdapter adapter) {
+        setCustomList(adapter);
+        return this;
+    }
+
+    /**
+     * Sets a listener to be invoked when an item in the list is selected.
+     *
+     * @param listener the listener to be invoked
+     * @return this Builder object to allow for chaining of calls to set methods
+     * @see AdapterView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener)
+     */
+    public AlertDialogBuilder setOnItemSelectedListener(
+            final AdapterView.OnItemSelectedListener listener) {
+        mBuilder.setOnItemSelectedListener(listener);
+        return this;
+    }
+
+    /**
+     * Sets a custom edit text box within the alert dialog.
+     *
+     * @param prompt the string that will be set on the edit text view
+     * @param textChangedListener textWatcher whose methods are called whenever this TextView's text
+     * changes {@link null} otherwise.
+     * @param inputFilters list of input filters, {@link null} if no filter is needed
+     * @param inputType See {@link EditText#setInputType(int)}, except
+     *                  {@link android.text.InputType#TYPE_NULL} will not be set.
+     * @return this Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setEditBox(String prompt, TextWatcher textChangedListener,
+            InputFilter[] inputFilters, int inputType) {
+        View contentView = LayoutInflater.from(mContext).inflate(
+                R.layout.car_ui_alert_dialog_edit_text, null);
+
+        EditText editText = CarUiUtils.requireViewByRefId(contentView, R.id.textbox);
+        editText.setText(prompt);
+
+        if (textChangedListener != null) {
+            editText.addTextChangedListener(textChangedListener);
+        }
+
+        if (inputFilters != null) {
+            editText.setFilters(inputFilters);
+        }
+
+        if (inputType != 0) {
+            editText.setInputType(inputType);
+        }
+
+        mBuilder.setView(contentView);
+        return this;
+    }
+
+    /**
+     * Sets a custom edit text box within the alert dialog.
+     *
+     * @param prompt the string that will be set on the edit text view
+     * @param textChangedListener textWatcher whose methods are called whenever this TextView's text
+     * changes {@link null} otherwise.
+     * @param inputFilters list of input filters, {@link null} if no filter is needed
+     * @return this Builder object to allow for chaining of calls to set methods
+     */
+    public AlertDialogBuilder setEditBox(String prompt, TextWatcher textChangedListener,
+            InputFilter[] inputFilters) {
+        return setEditBox(prompt, textChangedListener, inputFilters, 0);
+    }
+
+
+    /** Final steps common to both {@link #create()} and {@link #show()} */
+    private void prepareDialog() {
+        View customTitle = LayoutInflater.from(mContext).inflate(
+                R.layout.car_ui_alert_dialog_title_with_subtitle, null);
+
+        TextView mTitleView = CarUiUtils.requireViewByRefId(customTitle, R.id.car_ui_alert_title);
+        TextView mSubtitleView =
+                CarUiUtils.requireViewByRefId(customTitle, R.id.car_ui_alert_subtitle);
+        mSubtitleView.setMovementMethod(LinkMovementMethod.getInstance());
+        ImageView mIconView = CarUiUtils.requireViewByRefId(customTitle, R.id.car_ui_alert_icon);
+
+        mTitleView.setText(mTitle);
+        mTitleView.setVisibility(TextUtils.isEmpty(mTitle) ? View.GONE : View.VISIBLE);
+        mSubtitleView.setText(mSubtitle);
+        mSubtitleView.setVisibility(TextUtils.isEmpty(mSubtitle) ? View.GONE : View.VISIBLE);
+        mIconView.setImageDrawable(mIcon);
+        mIconView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
+        if (mIconTinted) {
+            mIconView.setImageTintList(
+                    mContext.getColorStateList(R.color.car_ui_dialog_icon_color));
+        }
+        mBuilder.setCustomTitle(customTitle);
+
+        if (!mNeutralButtonSet && !mNegativeButtonSet && !mPositiveButtonSet) {
+            String mDefaultButtonText = mContext.getString(
+                    R.string.car_ui_alert_dialog_default_button);
+            mBuilder.setNegativeButton(mDefaultButtonText, (dialog, which) -> {
+            });
+        }
+    }
+
+    /**
+     * Creates an {@link AlertDialog} with the arguments supplied to this
+     * builder.
+     * <p>
+     * Calling this method does not display the dialog. If no additional
+     * processing is needed, {@link #show()} may be called instead to both
+     * create and display the dialog.
+     */
+    public AlertDialog create() {
+        prepareDialog();
+        AlertDialog alertDialog = mBuilder.create();
+
+        // Put a FocusParkingView at the end of dialog window to prevent rotary controller
+        // wrap-around. Android will focus on the first view automatically when the dialog is shown,
+        // and we want it to focus on the title instead of the FocusParkingView, so we put the
+        // FocusParkingView at the end of dialog window.
+        ViewGroup root = (ViewGroup) alertDialog.getWindow().getDecorView().getRootView();
+        FocusParkingView fpv = new FocusParkingView(mContext);
+        root.addView(fpv);
+
+        return alertDialog;
+    }
+
+    /**
+     * Creates an {@link AlertDialog} with the arguments supplied to this
+     * builder and immediately displays the dialog.
+     */
+    public AlertDialog show() {
+        AlertDialog alertDialog = create();
+        alertDialog.show();
+        return alertDialog;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/FocusArea.java b/car-ui-lib/src/com/android/car/ui/FocusArea.java
new file mode 100644
index 0000000..f969380
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/FocusArea.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.annotation.Nullable;
+
+/**
+ * A {@link LinearLayout} used as a navigation block for the rotary controller.
+ * <p>
+ * The {@link com.android.car.rotary.RotaryService} looks for instances of {@link FocusArea} in the
+ * view hierarchy when handling rotate and nudge actions. When receiving a rotation event ({@link
+ * android.car.input.RotaryEvent}), RotaryService will move the focus to another {@link View} that
+ * can take focus within the same FocusArea. When receiving a nudge event ({@link
+ * KeyEvent#KEYCODE_SYSTEM_NAVIGATION_UP}, {@link KeyEvent#KEYCODE_SYSTEM_NAVIGATION_DOWN}, {@link
+ * KeyEvent#KEYCODE_SYSTEM_NAVIGATION_LEFT}, or {@link KeyEvent#KEYCODE_SYSTEM_NAVIGATION_RIGHT}),
+ * RotaryService will move the focus to another view that can take focus in another (typically
+ * adjacent) FocusArea.
+ * <p>
+ * If enabled, FocusArea can draw highlights when one of its descendants has focus.
+ * <p>
+ * When creating a navigation block in the layout file, if you intend to use a LinearLayout as a
+ * container for that block, just use a FocusArea instead; otherwise wrap the block in a FocusArea.
+ * <p>
+ * DO NOT nest a FocusArea inside another FocusArea because it will result in undefined navigation
+ * behavior.
+ */
+public class FocusArea extends LinearLayout {
+
+    /** Whether the FocusArea's descendant has focus (the FocusArea itself is not focusable). */
+    private boolean mHasFocus;
+
+    /**
+     * Whether to draw {@link #mForegroundHighlight} when one of the FocusArea's descendants has
+     * focus.
+     */
+    private boolean mEnableForegroundHighlight;
+
+    /**
+     * Whether to draw {@link #mBackgroundHighlight} when one of the FocusArea's descendants has
+     * focus.
+     */
+    private boolean mEnableBackgroundHighlight;
+
+    /**
+     * Highlight (typically outline of the FocusArea) drawn on top of the FocusArea and its
+     * descendants.
+     */
+    private Drawable mForegroundHighlight;
+
+    /**
+     * Highlight (typically a solid or gradient shape) drawn on top of the FocusArea but behind its
+     * descendants.
+     */
+    private Drawable mBackgroundHighlight;
+
+    /** The padding (in pixels) of the FocusArea highlight. */
+    private int mPaddingLeft;
+    private int mPaddingRight;
+    private int mPaddingTop;
+    private int mPaddingBottom;
+
+    public FocusArea(Context context) {
+        super(context);
+        init();
+    }
+
+    public FocusArea(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public FocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public FocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        mEnableForegroundHighlight = getContext().getResources().getBoolean(
+                R.bool.car_ui_enable_focus_area_foreground_highlight);
+        mEnableBackgroundHighlight = getContext().getResources().getBoolean(
+                R.bool.car_ui_enable_focus_area_background_highlight);
+        mForegroundHighlight = getContext().getResources().getDrawable(
+                R.drawable.car_ui_focus_area_foreground_highlight, getContext().getTheme());
+        mBackgroundHighlight = getContext().getResources().getDrawable(
+                R.drawable.car_ui_focus_area_background_highlight, getContext().getTheme());
+
+        // Ensure that an AccessibilityNodeInfo is created for this view.
+        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+
+        // By default all ViewGroup subclasses do not call their draw() and onDraw() methods. We
+        // should enable it since we override these methods.
+        setWillNotDraw(false);
+
+        // Update highlight of the FocusArea when the focus of its descendants has changed.
+        getViewTreeObserver().addOnGlobalFocusChangeListener(
+                (oldFocus, newFocus) -> {
+                    boolean hasFocus = hasFocus();
+                    if (mHasFocus != hasFocus) {
+                        mHasFocus = hasFocus;
+                        invalidate();
+                    }
+                });
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        // Draw highlight on top of this FocusArea (including its background and content) but
+        // behind its children.
+        if (mEnableBackgroundHighlight && mHasFocus) {
+            mBackgroundHighlight.setBounds(
+                    mPaddingLeft + getScrollX(),
+                    mPaddingTop + getScrollY(),
+                    getScrollX() + getWidth() - mPaddingRight,
+                    getScrollY() + getHeight() - mPaddingBottom);
+            mBackgroundHighlight.draw(canvas);
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+
+        // Draw highlight on top of this FocusArea (including its background and content) and its
+        // children (including background, content, focus highlight, etc).
+        if (mEnableForegroundHighlight && mHasFocus) {
+            mForegroundHighlight.setBounds(
+                    mPaddingLeft + getScrollX(),
+                    mPaddingTop + getScrollY(),
+                    getScrollX() + getWidth() - mPaddingRight,
+                    getScrollY() + getHeight() - mPaddingBottom);
+            mForegroundHighlight.draw(canvas);
+        }
+    }
+
+    @Override
+    public CharSequence getAccessibilityClassName() {
+        return FocusArea.class.getName();
+    }
+
+    /** Sets the padding (in pixels) of the FocusArea highlight. */
+    public void setHighlightPadding(int left, int top, int right, int bottom) {
+        if (mPaddingLeft == left && mPaddingTop == top && mPaddingRight == right
+                && mPaddingBottom == bottom) {
+            return;
+        }
+        mPaddingLeft = left;
+        mPaddingTop = top;
+        mPaddingRight = right;
+        mPaddingBottom = bottom;
+        invalidate();
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/FocusParkingView.java b/car-ui-lib/src/com/android/car/ui/FocusParkingView.java
new file mode 100644
index 0000000..1b4bd13
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/FocusParkingView.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui;
+
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_DISMISS;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+/**
+ * A transparent {@link View} that can take focus. It's used by {@link
+ * com.android.car.rotary.RotaryService} to support rotary controller navigation. Each {@link
+ * android.view.Window} must have at least one FocusParkingView. The {@link FocusParkingView} must
+ * be the first in Tab order, and outside of all {@link FocusArea}s.
+ *
+ * <p>
+ * Android doesn't clear focus automatically when focus is set in another window. If we try to clear
+ * focus in the previous window, Android will re-focus a view in that window, resulting in two
+ * windows being focused simultaneously. Adding this view to each window can fix this issue. This
+ * view is transparent and its default focus highlight is disabled, so it's invisible to the user no
+ * matter whether it's focused or not. It can take focus so that RotaryService can "park" the focus
+ * on it to remove the focus highlight.
+ * <p>
+ * If the focused view is scrolled off the screen, Android will refocus the first focusable view in
+ * the window. The FocusParkingView should be the first view so that it gets focus. The
+ * RotaryService detects this and moves focus to the scrolling container.
+ * <p>
+ * If there is only one focus area in the current window, rotating the controller within the focus
+ * area will cause RotaryService to move the focus around from the view on the right to the view on
+ * the left or vice versa. Adding this view to each window can fix this issue. When RotaryService
+ * finds out the focus target is a FocusParkingView, it will know a wrap-around is going to happen.
+ * Then it will avoid the wrap-around by not moving focus.
+ */
+public class FocusParkingView extends View {
+
+    public FocusParkingView(Context context) {
+        super(context);
+        init();
+    }
+
+    public FocusParkingView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public FocusParkingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public FocusParkingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        // This view is focusable, visible and enabled so it can take focus.
+        setFocusable(View.FOCUSABLE);
+        setVisibility(VISIBLE);
+        setEnabled(true);
+
+        // This view is not clickable so it won't affect the app's behavior when the user clicks on
+        // it by accident.
+        setClickable(false);
+
+        // This view is always transparent.
+        setAlpha(0f);
+
+        // Prevent Android from drawing the default focus highlight for this view when it's focused.
+        setDefaultFocusHighlightEnabled(false);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // This size of the view is always 1 x 1 pixel, no matter what value is set in the layout
+        // file (match_parent, wrap_content, 100dp, 0dp, etc). Small size is to ensure it has little
+        // impact on the layout, non-zero size is to ensure it can take focus.
+        setMeasuredDimension(1, 1);
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        if (!hasWindowFocus) {
+            // We need to clear the focus (by parking the focus on the FocusParkingView) once the
+            // current window goes to background. This can't be done by RotaryService because
+            // RotaryService sees the window as removed, thus can't perform any action (such as
+            // focus, clear focus) on the nodes in the window. So FocusParkingView has to grab the
+            // focus proactively.
+            requestFocus();
+        }
+        super.onWindowFocusChanged(hasWindowFocus);
+    }
+
+    @Override
+    public CharSequence getAccessibilityClassName() {
+        return FocusParkingView.class.getName();
+    }
+
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        if (action == ACTION_DISMISS) {
+            // Try to move focus to the default focus.
+            getRootView().restoreDefaultFocus();
+            // The action failed if the FocusParkingView is still focused.
+            return !isFocused();
+        }
+        return super.performAccessibilityAction(action, arguments);
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/baselayout/ClickBlockingView.java b/car-ui-lib/src/com/android/car/ui/baselayout/ClickBlockingView.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/baselayout/ClickBlockingView.java
rename to car-ui-lib/src/com/android/car/ui/baselayout/ClickBlockingView.java
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/baselayout/Insets.java b/car-ui-lib/src/com/android/car/ui/baselayout/Insets.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/baselayout/Insets.java
rename to car-ui-lib/src/com/android/car/ui/baselayout/Insets.java
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/baselayout/InsetsChangedListener.java b/car-ui-lib/src/com/android/car/ui/baselayout/InsetsChangedListener.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/baselayout/InsetsChangedListener.java
rename to car-ui-lib/src/com/android/car/ui/baselayout/InsetsChangedListener.java
diff --git a/car-ui-lib/src/com/android/car/ui/core/BaseLayoutController.java b/car-ui-lib/src/com/android/car/ui/core/BaseLayoutController.java
new file mode 100644
index 0000000..153b4e6
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/core/BaseLayoutController.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.core;
+
+import android.app.Activity;
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.car.ui.R;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.toolbar.ToolbarController;
+import com.android.car.ui.toolbar.ToolbarControllerImpl;
+import com.android.car.ui.utils.CarUiUtils;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * BaseLayoutController accepts an {@link Activity} and sets up the base layout inside of it.
+ * It also exposes a {@link ToolbarController} to access the toolbar. This may be null if
+ * used with a base layout without a Toolbar.
+ */
+class BaseLayoutController {
+
+    private static final Map<Activity, BaseLayoutController> sBaseLayoutMap = new WeakHashMap<>();
+
+    private InsetsUpdater mInsetsUpdater;
+
+    /**
+     * Gets a BaseLayoutController for the given {@link Activity}. Must have called
+     * {@link #build(Activity)} with the same activity earlier, otherwise will return null.
+     */
+    @Nullable
+    /* package */ static BaseLayoutController getBaseLayout(Activity activity) {
+        return sBaseLayoutMap.get(activity);
+    }
+
+    @Nullable
+    private ToolbarController mToolbarController;
+
+    private BaseLayoutController(Activity activity) {
+        installBaseLayout(activity);
+    }
+
+    /**
+     * Create a new BaseLayoutController for the given {@link Activity}.
+     *
+     * <p>You can get a reference to it by calling {@link #getBaseLayout(Activity)}.
+     */
+    /* package */
+    static void build(Activity activity) {
+        if (getThemeBoolean(activity, R.attr.carUiBaseLayout)) {
+            sBaseLayoutMap.put(activity, new BaseLayoutController(activity));
+        }
+    }
+
+    /**
+     * Destroy the BaseLayoutController for the given {@link Activity}.
+     */
+    /* package */
+    static void destroy(Activity activity) {
+        sBaseLayoutMap.remove(activity);
+    }
+
+    /**
+     * Gets the {@link ToolbarController} for activities created with carUiBaseLayout and
+     * carUiToolbar set to true.
+     */
+    @Nullable
+    /* package */ ToolbarController getToolbarController() {
+        return mToolbarController;
+    }
+
+    /* package */ Insets getInsets() {
+        return mInsetsUpdater.getInsets();
+    }
+
+    /* package */ void dispatchNewInsets(Insets insets) {
+        mInsetsUpdater.dispatchNewInsets(insets);
+    }
+
+    /* package */ void replaceInsetsChangedListenerWith(InsetsChangedListener listener) {
+        mInsetsUpdater.replaceInsetsChangedListenerWith(listener);
+    }
+
+    /**
+     * Installs the base layout into an activity, moving its content view under the base layout.
+     *
+     * <p>This function must be called during the onCreate() of the {@link Activity}.
+     *
+     * @param activity The {@link Activity} to install a base layout in.
+     */
+    private void installBaseLayout(Activity activity) {
+        boolean toolbarEnabled = getThemeBoolean(activity, R.attr.carUiToolbar);
+        boolean legacyToolbar = Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q;
+        @LayoutRes final int baseLayoutRes;
+
+        if (toolbarEnabled) {
+            baseLayoutRes = legacyToolbar
+                    ? R.layout.car_ui_base_layout_toolbar_legacy
+                    : R.layout.car_ui_base_layout_toolbar;
+        } else {
+            baseLayoutRes = R.layout.car_ui_base_layout;
+        }
+
+        View baseLayout = LayoutInflater.from(activity)
+                .inflate(baseLayoutRes, null, false);
+
+        // Replace windowContentView with baseLayout
+        ViewGroup windowContentView = CarUiUtils.findViewByRefId(
+                activity.getWindow().getDecorView(), android.R.id.content);
+        ViewGroup contentViewParent = (ViewGroup) windowContentView.getParent();
+        int contentIndex = contentViewParent.indexOfChild(windowContentView);
+        contentViewParent.removeView(windowContentView);
+        contentViewParent.addView(baseLayout, contentIndex, windowContentView.getLayoutParams());
+
+        // Add windowContentView to the baseLayout's content view
+        FrameLayout contentView = CarUiUtils.requireViewByRefId(baseLayout, R.id.content);
+        contentView.addView(windowContentView, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+
+        if (toolbarEnabled) {
+            if (legacyToolbar) {
+                mToolbarController = CarUiUtils.requireViewByRefId(baseLayout, R.id.car_ui_toolbar);
+            } else {
+                mToolbarController = new ToolbarControllerImpl(baseLayout);
+            }
+        }
+
+        mInsetsUpdater = new InsetsUpdater(activity, baseLayout, windowContentView);
+        mInsetsUpdater.installListeners();
+    }
+
+    /**
+     * Gets the boolean value of an Attribute from an {@link Activity Activity's}
+     * {@link android.content.res.Resources.Theme}.
+     */
+    private static boolean getThemeBoolean(Activity activity, int attr) {
+        TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{attr});
+
+        try {
+            return a.getBoolean(0, false);
+        } finally {
+            a.recycle();
+        }
+    }
+
+    /**
+     * InsetsUpdater waits for layout changes, and when there is one, calculates the appropriate
+     * insets into the content view.
+     *
+     * <p>It then calls {@link InsetsChangedListener#onCarUiInsetsChanged(Insets)} on the
+     * {@link Activity} and any {@link Fragment Fragments} the Activity might have. If
+     * none of the Activity/Fragments implement {@link InsetsChangedListener}, it will set
+     * padding on the content view equal to the insets.
+     */
+    private static class InsetsUpdater implements ViewTreeObserver.OnGlobalLayoutListener {
+        // These tags mark views that should overlay the content view in the base layout.
+        // OEMs should add them to views in their base layout, ie: android:tag="car_ui_left_inset"
+        // Apps will then be able to draw under these views, but will be encouraged to not put
+        // any user-interactable content there.
+        private static final String LEFT_INSET_TAG = "car_ui_left_inset";
+        private static final String RIGHT_INSET_TAG = "car_ui_right_inset";
+        private static final String TOP_INSET_TAG = "car_ui_top_inset";
+        private static final String BOTTOM_INSET_TAG = "car_ui_bottom_inset";
+
+        private final Activity mActivity;
+        private final View mLeftInsetView;
+        private final View mRightInsetView;
+        private final View mTopInsetView;
+        private final View mBottomInsetView;
+        private InsetsChangedListener mInsetsChangedListenerDelegate;
+
+        private boolean mInsetsDirty = true;
+        @NonNull
+        private Insets mInsets = new Insets();
+
+        /**
+         * Constructs an InsetsUpdater that calculates and dispatches insets to an {@link Activity}.
+         *
+         * @param activity    The activity that is using base layouts
+         * @param baseLayout  The root view of the base layout
+         * @param contentView The android.R.id.content View
+         */
+        InsetsUpdater(Activity activity, View baseLayout, View contentView) {
+            mActivity = activity;
+
+            mLeftInsetView = baseLayout.findViewWithTag(LEFT_INSET_TAG);
+            mRightInsetView = baseLayout.findViewWithTag(RIGHT_INSET_TAG);
+            mTopInsetView = baseLayout.findViewWithTag(TOP_INSET_TAG);
+            mBottomInsetView = baseLayout.findViewWithTag(BOTTOM_INSET_TAG);
+
+            final View.OnLayoutChangeListener layoutChangeListener =
+                    (View v, int left, int top, int right, int bottom,
+                            int oldLeft, int oldTop, int oldRight, int oldBottom) -> {
+                        if (left != oldLeft || top != oldTop
+                                || right != oldRight || bottom != oldBottom) {
+                            mInsetsDirty = true;
+                        }
+                    };
+
+            if (mLeftInsetView != null) {
+                mLeftInsetView.addOnLayoutChangeListener(layoutChangeListener);
+            }
+            if (mRightInsetView != null) {
+                mRightInsetView.addOnLayoutChangeListener(layoutChangeListener);
+            }
+            if (mTopInsetView != null) {
+                mTopInsetView.addOnLayoutChangeListener(layoutChangeListener);
+            }
+            if (mBottomInsetView != null) {
+                mBottomInsetView.addOnLayoutChangeListener(layoutChangeListener);
+            }
+            contentView.addOnLayoutChangeListener(layoutChangeListener);
+        }
+
+        /**
+         * Install a global layout listener, during which the insets will be recalculated and
+         * dispatched.
+         */
+        void installListeners() {
+            // The global layout listener will run after all the individual layout change listeners
+            // so that we only updateInsets once per layout, even if multiple inset views changed
+            mActivity.getWindow().getDecorView().getViewTreeObserver()
+                    .addOnGlobalLayoutListener(this);
+        }
+
+        @NonNull
+        Insets getInsets() {
+            return mInsets;
+        }
+
+        public void replaceInsetsChangedListenerWith(InsetsChangedListener listener) {
+            mInsetsChangedListenerDelegate = listener;
+        }
+
+        /**
+         * onGlobalLayout() should recalculate the amount of insets we need, and then dispatch them.
+         */
+        @Override
+        public void onGlobalLayout() {
+            if (!mInsetsDirty) {
+                return;
+            }
+
+            View content = CarUiUtils.requireViewByRefId(mActivity.getWindow().getDecorView(),
+                    android.R.id.content);
+
+            // Calculate how much each inset view overlays the content view
+            int top = 0;
+            int left = 0;
+            int right = 0;
+            int bottom = 0;
+            if (mTopInsetView != null) {
+                top = Math.max(0, getBottomOfView(mTopInsetView) - getTopOfView(content));
+            }
+            if (mBottomInsetView != null) {
+                bottom = Math.max(0, getBottomOfView(content) - getTopOfView(mBottomInsetView));
+            }
+            if (mLeftInsetView != null) {
+                left = Math.max(0, getRightOfView(mLeftInsetView) - getLeftOfView(content));
+            }
+            if (mRightInsetView != null) {
+                right = Math.max(0, getRightOfView(content) - getLeftOfView(mRightInsetView));
+            }
+            Insets insets = new Insets(left, top, right, bottom);
+
+            mInsetsDirty = false;
+            if (!insets.equals(mInsets)) {
+                mInsets = insets;
+                dispatchNewInsets(insets);
+            }
+        }
+
+        /**
+         * Dispatch the new {@link Insets} to the {@link Activity} and all of its
+         * {@link Fragment Fragments}. If none of those implement {@link InsetsChangedListener},
+         * we will set the value of the insets as padding on the content view.
+         *
+         * @param insets The newly-changed insets.
+         */
+        /* package */ void dispatchNewInsets(Insets insets) {
+            mInsets = insets;
+
+            boolean handled = false;
+
+            if (mInsetsChangedListenerDelegate != null) {
+                mInsetsChangedListenerDelegate.onCarUiInsetsChanged(insets);
+                handled = true;
+            } else {
+                // If an explicit InsetsChangedListener is not provided,
+                // pass the insets to activities and fragments
+                if (mActivity instanceof InsetsChangedListener) {
+                    ((InsetsChangedListener) mActivity).onCarUiInsetsChanged(insets);
+                    handled = true;
+                }
+
+                if (mActivity instanceof FragmentActivity) {
+                    for (Fragment fragment : ((FragmentActivity) mActivity)
+                            .getSupportFragmentManager().getFragments()) {
+                        if (fragment instanceof InsetsChangedListener) {
+                            ((InsetsChangedListener) fragment).onCarUiInsetsChanged(insets);
+                            handled = true;
+                        }
+                    }
+                }
+            }
+
+            if (!handled) {
+                CarUiUtils.requireViewByRefId(mActivity.getWindow().getDecorView(),
+                        android.R.id.content).setPadding(insets.getLeft(), insets.getTop(),
+                        insets.getRight(), insets.getBottom());
+            }
+        }
+
+        private static int getLeftOfView(View v) {
+            int[] position = new int[2];
+            v.getLocationOnScreen(position);
+            return position[0];
+        }
+
+        private static int getRightOfView(View v) {
+            int[] position = new int[2];
+            v.getLocationOnScreen(position);
+            return position[0] + v.getWidth();
+        }
+
+        private static int getTopOfView(View v) {
+            int[] position = new int[2];
+            v.getLocationOnScreen(position);
+            return position[1];
+        }
+
+        private static int getBottomOfView(View v) {
+            int[] position = new int[2];
+            v.getLocationOnScreen(position);
+            return position[1] + v.getHeight();
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/core/CarUi.java b/car-ui-lib/src/com/android/car/ui/core/CarUi.java
new file mode 100644
index 0000000..ad67121
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/core/CarUi.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.core;
+
+import android.app.Activity;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.toolbar.ToolbarController;
+
+import java.lang.reflect.Method;
+
+/**
+ * Public interface for general CarUi static functions.
+ */
+public class CarUi {
+
+    /** Prevent instantiating this class */
+    private CarUi() {}
+
+    /**
+     * Gets the {@link ToolbarController} for an activity. Requires that the Activity uses
+     * Theme.CarUi.WithToolbar, or otherwise sets carUiBaseLayout and carUiToolbar to true.
+     *
+     * See also: {@link #requireToolbar(Activity)}
+     */
+    @Nullable
+    public static ToolbarController getToolbar(Activity activity) {
+        BaseLayoutController controller = getBaseLayoutController(activity);
+        if (controller != null) {
+            return controller.getToolbarController();
+        }
+        return null;
+    }
+
+    /**
+     * Gets the {@link ToolbarController} for an activity. Requires that the Activity uses
+     * Theme.CarUi.WithToolbar, or otherwise sets carUiBaseLayout and carUiToolbar to true.
+     *
+     * <p>See also: {@link #getToolbar(Activity)}
+     *
+     * @throws IllegalArgumentException When the CarUi Toolbar cannot be found.
+     */
+    @NonNull
+    public static ToolbarController requireToolbar(Activity activity) {
+        ToolbarController result = getToolbar(activity);
+        if (result == null) {
+            throw new IllegalArgumentException("Activity " + activity
+                    + " does not have a CarUi Toolbar!"
+                    + " Are you using Theme.CarUi.WithToolbar?");
+        }
+
+        return result;
+    }
+
+    /**
+     * Registering a listener to receive the InsetsChanged updates instead of the Activity.
+     */
+    public static void replaceInsetsChangedListenerWith(Activity activity,
+            InsetsChangedListener listener) {
+        BaseLayoutController controller = getBaseLayoutController(activity);
+        if (controller != null) {
+            controller.replaceInsetsChangedListenerWith(listener);
+        }
+    }
+
+    /**
+     * Gets the current {@link Insets} of the given {@link Activity}. Only applies to Activities
+     * using the base layout, ie have the theme attribute "carUiBaseLayout" set to true.
+     *
+     * <p>Note that you likely don't want to use this without also using
+     * {@link com.android.car.ui.baselayout.InsetsChangedListener}, as without it the Insets
+     * will automatically be applied to your Activity's content view.
+     */
+    @Nullable
+    public static Insets getInsets(Activity activity) {
+        BaseLayoutController controller = getBaseLayoutController(activity);
+        if (controller != null) {
+            return controller.getInsets();
+        }
+        return null;
+    }
+
+    /**
+     * Gets the current {@link Insets} of the given {@link Activity}. Only applies to Activities
+     * using the base layout, ie have the theme attribute "carUiBaseLayout" set to true.
+     *
+     * <p>Note that you likely don't want to use this without also using
+     * {@link com.android.car.ui.baselayout.InsetsChangedListener}, as without it the Insets
+     * will automatically be applied to your Activity's content view.
+     *
+     * @throws IllegalArgumentException When the activity is not using base layouts.
+     */
+    @NonNull
+    public static Insets requireInsets(Activity activity) {
+        Insets result = getInsets(activity);
+        if (result == null) {
+            throw new IllegalArgumentException("Activity " + activity
+                    + " does not have a base layout!"
+                    + " Are you using Theme.CarUi.WithToolbar or Theme.CarUi.NoToolbar?");
+        }
+
+        return result;
+    }
+
+    /* package */ static BaseLayoutController getBaseLayoutController(Activity activity) {
+        if (activity.getClassLoader().equals(CarUi.class.getClassLoader())) {
+            return BaseLayoutController.getBaseLayout(activity);
+        } else {
+            // Note: (b/156532465)
+            // The usage of the alternate classloader is to accommodate GMSCore.
+            // Some activities are loaded dynamically from external modules.
+            try {
+                Class baseLayoutControllerClass = activity.getClassLoader()
+                        .loadClass(BaseLayoutController.class.getName());
+                Method method = baseLayoutControllerClass
+                        .getDeclaredMethod("getBaseLayout", Activity.class);
+                return (BaseLayoutController) method.invoke(null, activity);
+            } catch (ReflectiveOperationException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/core/CarUiInstaller.java b/car-ui-lib/src/com/android/car/ui/core/CarUiInstaller.java
new file mode 100644
index 0000000..e845979
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/core/CarUiInstaller.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.core;
+
+import static com.android.car.ui.core.CarUi.getBaseLayoutController;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.car.ui.baselayout.Insets;
+
+import java.lang.reflect.Method;
+import java.util.Locale;
+
+/**
+ * {@link ContentProvider ContentProvider's} onCreate() methods are "called for all registered
+ * content providers on the application main thread at application launch time." This means we
+ * can use a content provider to register for Activity lifecycle callbacks before any activities
+ * have started, for installing the CarUi base layout into all activities.
+ */
+public class CarUiInstaller extends ContentProvider {
+
+    private static final String TAG = "CarUiInstaller";
+    private static final String CAR_UI_INSET_LEFT = "CAR_UI_INSET_LEFT";
+    private static final String CAR_UI_INSET_RIGHT = "CAR_UI_INSET_RIGHT";
+    private static final String CAR_UI_INSET_TOP = "CAR_UI_INSET_TOP";
+    private static final String CAR_UI_INSET_BOTTOM = "CAR_UI_INSET_BOTTOM";
+
+    private static final boolean IS_DEBUG_DEVICE =
+            Build.TYPE.toLowerCase(Locale.ROOT).contains("debug")
+                    || Build.TYPE.toLowerCase(Locale.ROOT).equals("eng");
+
+    @Override
+    public boolean onCreate() {
+        Context context = getContext();
+        if (context == null) {
+            Log.e(TAG, "CarUiInstaller had a null context!");
+            return false;
+        }
+        Log.i(TAG, "CarUiInstaller started for " + context.getPackageName());
+
+        Application application = (Application) context.getApplicationContext();
+        application.registerActivityLifecycleCallbacks(
+                new Application.ActivityLifecycleCallbacks() {
+                    private Insets mInsets = null;
+                    private boolean mIsActivityStartedForFirstTime = false;
+
+                    @Override
+                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+                        if (activity.getClassLoader()
+                                .equals(CarUiInstaller.class.getClassLoader())) {
+                            BaseLayoutController.build(activity);
+                        } else {
+                            callBaseLayoutControllerMethod("build", activity);
+                        }
+
+                        if (savedInstanceState != null) {
+                            int inset_left = savedInstanceState.getInt(CAR_UI_INSET_LEFT);
+                            int inset_top = savedInstanceState.getInt(CAR_UI_INSET_TOP);
+                            int inset_right = savedInstanceState.getInt(CAR_UI_INSET_RIGHT);
+                            int inset_bottom = savedInstanceState.getInt(CAR_UI_INSET_BOTTOM);
+                            mInsets = new Insets(inset_left, inset_top, inset_right, inset_bottom);
+                        }
+
+                        mIsActivityStartedForFirstTime = true;
+                    }
+
+                    @Override
+                    public void onActivityPostStarted(Activity activity) {
+                        BaseLayoutController controller = getBaseLayoutController(activity);
+                        if (mInsets != null && controller != null
+                                && mIsActivityStartedForFirstTime) {
+                            controller.dispatchNewInsets(mInsets);
+                            mIsActivityStartedForFirstTime = false;
+                        }
+                    }
+
+                    @Override
+                    public void onActivityStarted(Activity activity) {
+                    }
+
+                    @Override
+                    public void onActivityResumed(Activity activity) {
+                    }
+
+                    @Override
+                    public void onActivityPaused(Activity activity) {
+                    }
+
+                    @Override
+                    public void onActivityStopped(Activity activity) {
+                    }
+
+                    @Override
+                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+                        BaseLayoutController controller = getBaseLayoutController(activity);
+                        if (controller != null) {
+                            Insets insets = controller.getInsets();
+                            outState.putInt(CAR_UI_INSET_LEFT, insets.getLeft());
+                            outState.putInt(CAR_UI_INSET_TOP, insets.getTop());
+                            outState.putInt(CAR_UI_INSET_RIGHT, insets.getRight());
+                            outState.putInt(CAR_UI_INSET_BOTTOM, insets.getBottom());
+                        }
+                    }
+
+                    @Override
+                    public void onActivityDestroyed(Activity activity) {
+                        if (activity.getClassLoader()
+                                .equals(CarUiInstaller.class.getClassLoader())) {
+                            BaseLayoutController.destroy(activity);
+                        } else {
+                            callBaseLayoutControllerMethod("destroy", activity);
+                        }
+                    }
+                });
+
+        // Check only if we are in debug mode.
+        if (IS_DEBUG_DEVICE) {
+            CheckCarUiComponents checkCarUiComponents = new CheckCarUiComponents(application);
+            application.registerActivityLifecycleCallbacks(checkCarUiComponents);
+        }
+
+        return true;
+    }
+
+    @Nullable
+    @Override
+    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
+            @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public String getType(@NonNull Uri uri) {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(@NonNull Uri uri, @Nullable String selection,
+            @Nullable String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
+            @Nullable String[] selectionArgs) {
+        return 0;
+    }
+
+    private static void callBaseLayoutControllerMethod(String methodName, Activity activity) {
+        // Note: (b/156532465)
+        // The usage of the alternate classloader is to accommodate GMSCore.
+        // Some activities are loaded dynamically from external modules.
+        try {
+            Class baseLayoutControllerClass =
+                    activity.getClassLoader()
+                            .loadClass(BaseLayoutController.class.getName());
+            Method method = baseLayoutControllerClass
+                    .getDeclaredMethod(methodName, Activity.class);
+            method.invoke(null, activity);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/core/CheckCarUiComponents.java b/car-ui-lib/src/com/android/car/ui/core/CheckCarUiComponents.java
new file mode 100644
index 0000000..b4fd358
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/core/CheckCarUiComponents.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.core;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.utils.CarUiUtils;
+
+/**
+ * Class used to traverse through the view hierarchy of the activity and check if carUI components
+ * are being used as expected.
+ *
+ * To check if the activity is using the CarUI components properly, navigate to the activity and
+ * run: adb shell am broadcast -a com.android.car.ui.intent.CHECK_CAR_UI_COMPONENTS. Filter
+ * the logs with "CheckCarUiComponents". This is ONLY available for debug and eng builds.
+ */
+class CheckCarUiComponents implements Application.ActivityLifecycleCallbacks {
+    private static final String TAG = CheckCarUiComponents.class.getSimpleName();
+    private static final String INTENT_FILTER = "com.android.car.ui.intent.CHECK_CAR_UI_COMPONENTS";
+    private View mRootView;
+    private boolean mIsScreenVisible;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!mIsScreenVisible) {
+                return;
+            }
+
+            CarUiComponents carUiComponents = new CarUiComponents();
+            checkForCarUiComponents(mRootView, carUiComponents);
+            if (carUiComponents.mIsUsingCarUiRecyclerView
+                    && !carUiComponents.mIsCarUiRecyclerViewUsingListItem) {
+                Log.e(TAG, "CarUiListItem are not used within CarUiRecyclerView: ");
+                showToast(context, "CarUiListItem are not used within CarUiRecyclerView");
+            }
+            if (carUiComponents.mIsUsingAndroidXRecyclerView) {
+                Log.e(TAG, "CarUiRecyclerView not used: ");
+                showToast(context, "CarUiRecycler is not used");
+            }
+            if (!carUiComponents.mIsUsingCarUiToolbar) {
+                Log.e(TAG, "CarUiToolbar is not used: ");
+                showToast(context, "CarUiToolbar is not used");
+            }
+            if (!carUiComponents.mIsUsingCarUiBaseLayoutToolbar
+                    && carUiComponents.mIsUsingCarUiToolbar) {
+                Log.e(TAG, "CarUiBaseLayoutToolbar is not used: ");
+                showToast(context, "CarUiBaseLayoutToolbar is not used");
+            }
+            if (carUiComponents.mIsUsingCarUiRecyclerViewForPreference
+                    && !carUiComponents.mIsUsingCarUiPreference) {
+                Log.e(TAG, "CarUiPreference is not used: ");
+                showToast(context, "CarUiPreference is not used");
+            }
+        }
+    };
+
+    CheckCarUiComponents(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(INTENT_FILTER);
+        context.registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+    }
+
+    @Override
+    public void onActivityStarted(Activity activity) {
+    }
+
+    @Override
+    public void onActivityResumed(Activity activity) {
+        mRootView = activity.getWindow().getDecorView().getRootView();
+        mIsScreenVisible = true;
+    }
+
+    @Override
+    public void onActivityPaused(Activity activity) {
+        mIsScreenVisible = false;
+    }
+
+    @Override
+    public void onActivityStopped(Activity activity) {
+    }
+
+    @Override
+    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+    }
+
+    @Override
+    public void onActivityDestroyed(Activity activity) {
+        if (mRootView != null
+                && CarUiUtils.getActivity(mRootView.getContext()) == activity) {
+            mRootView = null;
+        }
+    }
+
+    private void checkForCarUiComponents(View v, CarUiComponents carUiComponents) {
+        viewHasChildMatching(v, view -> {
+            if (isCarUiRecyclerView(view)) {
+                carUiComponents.mIsUsingCarUiRecyclerView = true;
+
+                if (viewHasChildMatching(view, CheckCarUiComponents::isCarUiPreference)) {
+                    carUiComponents.mIsUsingCarUiPreference = true;
+                    return false;
+                }
+
+                carUiComponents.mIsCarUiRecyclerViewUsingListItem = viewHasChildMatching(view,
+                        CheckCarUiComponents::isCarUiListItem);
+                return false;
+            }
+
+            if (isAndroidXRecyclerView(view)) {
+                carUiComponents.mIsUsingAndroidXRecyclerView = true;
+            }
+
+            if (isCarUiToolbar(view)) {
+                carUiComponents.mIsUsingCarUiToolbar = true;
+            }
+
+            if (isCarUiBaseLayoutToolbar(view)) {
+                carUiComponents.mIsUsingCarUiBaseLayoutToolbar = true;
+            }
+            return false;
+        });
+    }
+
+    private static boolean viewHasChildMatching(View view, Predicate<View> p) {
+        if (view == null) {
+            return false;
+        }
+        if (p.test(view)) {
+            return true;
+        }
+        if (view instanceof ViewGroup) {
+            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
+                if (viewHasChildMatching(((ViewGroup) view).getChildAt(i), p)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static boolean isCarUiRecyclerView(View view) {
+        return view.getTag() != null && view.getTag().toString().equals("carUiRecyclerView");
+    }
+
+    private static boolean isCarUiListItem(View view) {
+        return view.getTag() != null && view.getTag().toString().equals("carUiListItem");
+    }
+
+    private static boolean isCarUiPreference(View view) {
+        return view.getTag() != null && view.getTag().toString().equals("carUiPreference");
+    }
+
+    private static boolean isCarUiToolbar(View view) {
+        return view.getTag() != null && (view.getTag().toString().equals("carUiToolbar")
+                || view.getTag().toString().equals("CarUiBaseLayoutToolbar"));
+    }
+
+    private static boolean isCarUiBaseLayoutToolbar(View view) {
+        return view.getTag() != null && view.getTag().toString().equals("CarUiBaseLayoutToolbar");
+    }
+
+    private static boolean isAndroidXRecyclerView(View view) {
+        return view.getClass() == RecyclerView.class;
+    }
+
+    private static void showToast(Context context, String message) {
+        Toast.makeText(context, message, Toast.LENGTH_LONG).show();
+    }
+
+    private static class CarUiComponents {
+        boolean mIsUsingCarUiRecyclerView;
+        boolean mIsUsingCarUiRecyclerViewForPreference;
+        boolean mIsCarUiRecyclerViewUsingListItem;
+        boolean mIsUsingCarUiToolbar;
+        boolean mIsUsingCarUiBaseLayoutToolbar;
+        boolean mIsUsingCarUiPreference;
+        boolean mIsUsingAndroidXRecyclerView;
+    }
+
+    /**
+     * Dump's the view hierarchy.
+     */
+    private static void printViewHierarchy(String indent, View view) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("\n ");
+        sb.append(indent);
+        sb.append('{');
+
+        if (view == null) {
+            sb.append("viewNode= NULL, ");
+            sb.append('}');
+            return;
+        }
+
+        sb.append("viewNode= ").append(view.toString()).append(", ");
+        sb.append("id= ").append(view.getId()).append(", ");
+        sb.append("name= ").append(view.getAccessibilityClassName()).append(", ");
+
+        sb.append('}');
+        System.out.println(sb.toString());
+
+        indent += "  ";
+        if (!(view instanceof ViewGroup)) {
+            return;
+        }
+        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
+            printViewHierarchy(indent, ((ViewGroup) view).getChildAt(i));
+        }
+    }
+
+    private interface Predicate<T> {
+        boolean test(T input);
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiDialogFragment.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiDialogFragment.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/CarUiDialogFragment.java
rename to car-ui-lib/src/com/android/car/ui/preference/CarUiDialogFragment.java
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiDropDownPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiDropDownPreference.java
new file mode 100644
index 0000000..56134b3
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiDropDownPreference.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.preference.DropDownPreference;
+
+import com.android.car.ui.R;
+
+/**
+ * This class extends the base {@link DropDownPreference} class. Adds the drawable icon to
+ * the preference.
+ */
+public class CarUiDropDownPreference extends DropDownPreference {
+
+    private final Context mContext;
+
+    public CarUiDropDownPreference(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    public CarUiDropDownPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mContext = context;
+    }
+
+    public CarUiDropDownPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mContext = context;
+    }
+
+    public CarUiDropDownPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        mContext = context;
+    }
+
+    /**
+     * Instead of displaying a drop-down that is not car optimized, have drop-down preferences
+     * mirror the behavior of list preferences.
+     */
+    @Override
+    protected void onClick() {
+        getPreferenceManager().showDialog(this);
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+
+        boolean showChevron = mContext.getResources().getBoolean(
+                R.bool.car_ui_preference_show_chevron);
+
+        if (!showChevron) {
+            return;
+        }
+
+        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiEditTextPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiEditTextPreference.java
new file mode 100644
index 0000000..3882e03
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiEditTextPreference.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.EditTextPreference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+
+/**
+ * This class extends the base {@link EditTextPreference} class. Adds the drawable icon to
+ * the preference.
+ */
+public class CarUiEditTextPreference extends EditTextPreference {
+
+    private final Context mContext;
+    private boolean mShowChevron = true;
+
+    public CarUiEditTextPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        mContext = context;
+    }
+
+    public CarUiEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        mContext = context;
+    }
+
+    public CarUiEditTextPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mContext = context;
+    }
+
+    public CarUiEditTextPreference(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    protected void setTwoActionLayout() {
+        setLayoutResource(R.layout.car_ui_two_action_preference);
+    }
+
+    /**
+     * Returns the widget container if {@link #setTwoActionLayout) was called, otherwise null.
+     */
+    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+    public View getWidgetActionContainer(PreferenceViewHolder holder) {
+        return CarUiUtils.findViewByRefId(holder.itemView, R.id.action_widget_container);
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+
+        boolean allowChevron = mContext.getResources().getBoolean(
+                R.bool.car_ui_preference_show_chevron);
+
+        if (!allowChevron || !mShowChevron) {
+            return;
+        }
+
+        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
+    }
+
+    public void setShowChevron(boolean showChevron) {
+        mShowChevron = showChevron;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiListPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiListPreference.java
new file mode 100644
index 0000000..24d940c
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiListPreference.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.preference.ListPreference;
+
+import com.android.car.ui.R;
+
+/**
+ * This class extends the base {@link ListPreference} class. Adds the drawable icon to
+ * the preference.
+ */
+public class CarUiListPreference extends ListPreference {
+
+    private final Context mContext;
+
+    public CarUiListPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        mContext = context;
+    }
+
+    public CarUiListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        mContext = context;
+    }
+
+    public CarUiListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mContext = context;
+    }
+
+    public CarUiListPreference(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+
+        boolean showChevron = mContext.getResources().getBoolean(
+                R.bool.car_ui_preference_show_chevron);
+
+        if (!showChevron) {
+            return;
+        }
+
+        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiMultiSelectListPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiMultiSelectListPreference.java
new file mode 100644
index 0000000..bc626a0
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiMultiSelectListPreference.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.preference.MultiSelectListPreference;
+
+import com.android.car.ui.R;
+
+/**
+ * This class extends the base {@link CarUiMultiSelectListPreference} class. Adds the drawable icon
+ * to the preference.
+ */
+public class CarUiMultiSelectListPreference extends MultiSelectListPreference {
+
+    private final Context mContext;
+
+    public CarUiMultiSelectListPreference(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    public CarUiMultiSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mContext = context;
+    }
+
+    public CarUiMultiSelectListPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mContext = context;
+    }
+
+    public CarUiMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        mContext = context;
+    }
+
+    /**
+     * This is to make getSelectedItems() visible from other classes in
+     * com.android.car.ui.preference.
+     */
+    @Override
+    protected boolean[] getSelectedItems() {
+        return super.getSelectedItems();
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+
+        boolean showChevron = mContext.getResources().getBoolean(
+                R.bool.car_ui_preference_show_chevron);
+
+        if (!showChevron) {
+            return;
+        }
+
+        setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiPreference.java
new file mode 100644
index 0000000..111fbf5
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiPreference.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+
+/**
+ * This class extends the base {@link Preference} class. Adds the support to add a drawable icon to
+ * the preference if there is one of fragment, intent or onPreferenceClickListener set.
+ */
+public class CarUiPreference extends Preference implements DisabledPreferenceCallback {
+
+    private Context mContext;
+    private boolean mShowChevron;
+    private String mMessageToShowWhenDisabledPreferenceClicked;
+
+    private boolean mShouldShowRippleOnDisabledPreference;
+    private Drawable mBackground;
+    private View mPreference;
+
+    public CarUiPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public CarUiPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, R.style.Preference_CarUi_Preference);
+    }
+
+    public CarUiPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, R.attr.carUiPreferenceStyle);
+    }
+
+    public CarUiPreference(Context context) {
+        this(context, null);
+    }
+
+    public void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        mContext = context;
+
+        TypedArray a = getContext().obtainStyledAttributes(
+                attrs,
+                R.styleable.CarUiPreference,
+                defStyleAttr,
+                defStyleRes);
+
+        mShowChevron = a.getBoolean(R.styleable.CarUiPreference_showChevron, true);
+        mShouldShowRippleOnDisabledPreference = a.getBoolean(
+                R.styleable.CarUiPreference_showRippleOnDisabledPreference, false);
+
+        a.recycle();
+    }
+
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        boolean viewEnabled = isEnabled();
+        mPreference = holder.itemView;
+        mBackground = CarUiUtils.setPreferenceViewEnabled(viewEnabled, holder.itemView, mBackground,
+                mShouldShowRippleOnDisabledPreference);
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+
+        boolean allowChevron = mContext.getResources().getBoolean(
+                R.bool.car_ui_preference_show_chevron);
+
+        if (!allowChevron || !mShowChevron) {
+            return;
+        }
+
+        if (getOnPreferenceClickListener() != null || getIntent() != null
+                || getFragment() != null) {
+            setWidgetLayoutResource(R.layout.car_ui_preference_chevron);
+        }
+    }
+
+    /**
+     * This is similar to {@link Preference#performClick()} with the only difference that we do not
+     * return when view is not enabled.
+     */
+    @Override
+    @SuppressWarnings("RestrictTo")
+    public void performClick() {
+        if (isEnabled()) {
+            super.performClick();
+        } else if (mMessageToShowWhenDisabledPreferenceClicked != null
+                && !mMessageToShowWhenDisabledPreferenceClicked.isEmpty()) {
+            Toast.makeText(mContext, mMessageToShowWhenDisabledPreferenceClicked,
+                    Toast.LENGTH_LONG).show();
+        }
+    }
+
+    public void setShowChevron(boolean showChevron) {
+        mShowChevron = showChevron;
+    }
+
+    /**
+     * Sets the ripple on the disabled preference.
+     */
+    @Override
+    public void setShouldShowRippleOnDisabledPreference(boolean showRipple) {
+        mShouldShowRippleOnDisabledPreference = showRipple;
+        CarUiUtils.updateRippleStateOnDisabledPreference(isEnabled(),
+                mShouldShowRippleOnDisabledPreference, mBackground, mPreference);
+    }
+
+    @Override
+    public void setMessageToShowWhenDisabledPreferenceClicked(@NonNull String message) {
+        mMessageToShowWhenDisabledPreferenceClicked = message;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiRadioButtonPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiRadioButtonPreference.java
new file mode 100644
index 0000000..f02f105
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiRadioButtonPreference.java
@@ -0,0 +1,66 @@
+/*
+ * 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.ui.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioButton;
+
+import androidx.preference.PreferenceViewHolder;
+import androidx.preference.TwoStatePreference;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+
+/** A preference which shows a radio button at the start of the preference. */
+public class CarUiRadioButtonPreference extends TwoStatePreference {
+
+    public CarUiRadioButtonPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    public CarUiRadioButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public CarUiRadioButtonPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public CarUiRadioButtonPreference(Context context) {
+        super(context);
+        init();
+    }
+
+    private void init() {
+        setLayoutResource(R.layout.car_ui_preference);
+        setWidgetLayoutResource(R.layout.car_ui_radio_button_preference_widget);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        RadioButton radioButton = (RadioButton) CarUiUtils.findViewByRefId(holder.itemView,
+                R.id.radio_button);
+        radioButton.setChecked(isChecked());
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiSeekBarDialogPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiSeekBarDialogPreference.java
new file mode 100644
index 0000000..29e9e33
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiSeekBarDialogPreference.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.DialogPreference;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+
+/** A class implements some basic methods of a seekbar dialog preference. */
+public class CarUiSeekBarDialogPreference extends DialogPreference
+        implements DialogFragmentCallbacks {
+
+    private int mSeekBarProgress;
+    private SeekBar mSeekBar;
+
+    private int mSeekBarTopTextViewVisibility;
+    private TextView mSeekBarTopTextView;
+    private String mSeekBarTopText;
+
+    private int mSeekBarLeftTextViewVisibility;
+    private TextView mSeekBarLeftTextView;
+    private String mSeekBarLeftText;
+
+    private int mSeekBarRightTextViewVisibility;
+    private TextView mSeekBarRightTextView;
+    private String mSeekBarRightText;
+
+    private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
+    private int mMaxProgress = 100;
+
+    public CarUiSeekBarDialogPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    public CarUiSeekBarDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public CarUiSeekBarDialogPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public CarUiSeekBarDialogPreference(Context context) {
+        super(context);
+        init();
+    }
+
+    private void init() {
+        setDialogLayoutResource(R.layout.car_ui_seekbar_dialog);
+        setPositiveButtonText(R.string.car_ui_dialog_preference_positive);
+        setNegativeButtonText(R.string.car_ui_dialog_preference_negative);
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        mSeekBarProgress = getPersistedInt(0);
+    }
+
+    @Override
+    public void onBindDialogView(@NonNull View view) {
+        mSeekBar = CarUiUtils.findViewByRefId(view, R.id.seek_bar);
+        mSeekBarTopTextView = CarUiUtils.findViewByRefId(view, R.id.seek_bar_text_top);
+        mSeekBarLeftTextView = CarUiUtils.findViewByRefId(view, R.id.seek_bar_text_left);
+        mSeekBarRightTextView = CarUiUtils.findViewByRefId(view, R.id.seek_bar_text_right);
+
+        setProgress(mSeekBarProgress);
+
+        setSeekBarTopTextViewVisibility(mSeekBarTopTextViewVisibility);
+        setSeekBarTopTextViewText(mSeekBarTopText);
+
+        setSeekBarLeftTextViewVisibility(mSeekBarLeftTextViewVisibility);
+        setSeekBarLeftTextViewText(mSeekBarLeftText);
+
+        setSeekBarRightTextViewVisibility(mSeekBarRightTextViewVisibility);
+        setSeekBarRightTextViewText(mSeekBarRightText);
+
+        setMaxProgress(mMaxProgress);
+        setOnSeekBarChangeListener(mOnSeekBarChangeListener);
+    }
+
+    /**
+     * Get the progress bar's current level of progress. Return 0 when the progress bar is in
+     * indeterminate mode.
+     */
+    public int getProgress() {
+        if (mSeekBar != null) {
+            return mSeekBar.getProgress();
+        }
+        return mSeekBarProgress;
+    }
+
+    /**
+     * Sets the current progress to the specified value.
+     */
+    public void setProgress(int progress) {
+        if (mSeekBar != null) {
+            mSeekBar.setProgress(progress);
+        }
+        mSeekBarProgress = progress;
+    }
+
+    @Override
+    public void onDialogClosed(boolean positiveResult) {
+        if (positiveResult) {
+            mSeekBarProgress = mSeekBar.getProgress();
+            persistInt(mSeekBarProgress);
+            notifyChanged();
+        }
+
+        mSeekBarTopTextView = null;
+        mSeekBarRightTextView = null;
+        mSeekBarLeftTextView = null;
+        mSeekBar = null;
+    }
+
+    /**
+     * Sets the text view visibility on top of the seekbar.
+     */
+    public void setSeekBarTopTextViewVisibility(int visibility) {
+        if (mSeekBarTopTextView != null) {
+            mSeekBarTopTextView.setVisibility(visibility);
+        }
+        mSeekBarTopTextViewVisibility = visibility;
+    }
+
+    /**
+     * Gets the text on top of the seekbar.
+     */
+    @Nullable
+    public String getSeekBarTopTextViewText() {
+        if (mSeekBarTopTextView != null) {
+            return mSeekBarTopTextView.getText().toString();
+        }
+        return mSeekBarTopText;
+    }
+
+    /**
+     * Sets the text on top of the seekbar.
+     */
+    public void setSeekBarTopTextViewText(String text) {
+        if (mSeekBarTopTextView != null) {
+            mSeekBarTopTextView.setText(text);
+        }
+        mSeekBarTopText = text;
+    }
+
+    /**
+     * Sets the text view visibility on left of the seekbar.
+     */
+    public void setSeekBarLeftTextViewVisibility(int visibility) {
+        if (mSeekBarLeftTextView != null) {
+            mSeekBarLeftTextView.setVisibility(visibility);
+        }
+        mSeekBarLeftTextViewVisibility = visibility;
+    }
+
+    /**
+     * Gets the text on left of the seekbar.
+     */
+    @Nullable
+    public String getSeekBarLeftTextViewText() {
+        if (mSeekBarLeftTextView != null) {
+            return mSeekBarLeftTextView.getText().toString();
+        }
+        return mSeekBarLeftText;
+    }
+
+    /**
+     * Sets the text on Left of the seekbar.
+     */
+    public void setSeekBarLeftTextViewText(@Nullable String text) {
+        if (mSeekBarLeftTextView != null) {
+            mSeekBarLeftTextView.setText(text);
+        }
+        mSeekBarLeftText = text;
+    }
+
+
+    /**
+     * Sets the text view visibility on right of the seekbar.
+     */
+    public void setSeekBarRightTextViewVisibility(int visibility) {
+        if (mSeekBarRightTextView != null) {
+            mSeekBarRightTextView.setVisibility(visibility);
+        }
+        mSeekBarRightTextViewVisibility = visibility;
+    }
+
+    /**
+     * Gets the text on right of the seekbar.
+     */
+    @Nullable
+    public String getSeekBarRightTextViewText() {
+        if (mSeekBarRightTextView != null) {
+            return mSeekBarRightTextView.getText().toString();
+        }
+        return mSeekBarRightText;
+    }
+
+
+    /**
+     * Sets the text on right of the seekbar.
+     */
+    public void setSeekBarRightTextViewText(@Nullable String text) {
+        if (mSeekBarRightTextView != null) {
+            mSeekBarRightTextView.setText(text);
+        }
+        mSeekBarRightText = text;
+    }
+
+    /**
+     * Sets a listener to receive notifications of changes to the SeekBar's progress level. Also
+     * provides notifications of when the user starts and stops a touch gesture within the SeekBar.
+     *
+     * @param listener The seek bar notification listener
+     * @see SeekBar.OnSeekBarChangeListener
+     */
+    public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
+        if (mSeekBar != null) {
+            mSeekBar.setOnSeekBarChangeListener(listener);
+        }
+        mOnSeekBarChangeListener = listener;
+    }
+
+    /** Get the upper range of the progress bar */
+    public int getMaxProgress() {
+        if (mSeekBar != null) {
+            return mSeekBar.getMax();
+        }
+        return mMaxProgress;
+    }
+
+    /** Set the upper range of the progress bar */
+    public void setMaxProgress(int maxProgress) {
+        if (mSeekBar != null) {
+            mSeekBar.setMax(maxProgress);
+        }
+        mMaxProgress = maxProgress;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiSwitchPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiSwitchPreference.java
new file mode 100644
index 0000000..e2b141d
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiSwitchPreference.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceViewHolder;
+import androidx.preference.SwitchPreference;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+
+/**
+ * This class extends the base {@link SwitchPreference} class. Adds the functionality to show
+ * message when preference is disabled.
+ */
+public class CarUiSwitchPreference extends SwitchPreference implements DisabledPreferenceCallback {
+
+    private String mMessageToShowWhenDisabledPreferenceClicked;
+
+    private boolean mShouldShowRippleOnDisabledPreference;
+    private Drawable mBackground;
+    private View mPreference;
+    private Context mContext;
+
+    public CarUiSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init(context, attrs);
+    }
+
+    public CarUiSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context, attrs);
+    }
+
+    public CarUiSwitchPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context, attrs);
+    }
+
+    public CarUiSwitchPreference(Context context) {
+        super(context);
+        init(context, null);
+    }
+
+    private void init(Context context, AttributeSet attrs) {
+        mContext = context;
+        TypedArray preferenceAttributes = getContext().obtainStyledAttributes(attrs,
+                R.styleable.CarUiPreference);
+        mShouldShowRippleOnDisabledPreference = preferenceAttributes.getBoolean(
+                R.styleable.CarUiPreference_showRippleOnDisabledPreference, false);
+        preferenceAttributes.recycle();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        mPreference = holder.itemView;
+        mBackground = CarUiUtils.setPreferenceViewEnabled(isEnabled(), holder.itemView, mBackground,
+                mShouldShowRippleOnDisabledPreference);
+    }
+
+    /**
+     * This is similar to {@link Preference#performClick()} with the only difference that we do not
+     * return when view is not enabled.
+     */
+    @Override
+    @SuppressWarnings("RestrictTo")
+    public void performClick() {
+        if (isEnabled()) {
+            super.performClick();
+        } else if (mMessageToShowWhenDisabledPreferenceClicked != null
+                && !mMessageToShowWhenDisabledPreferenceClicked.isEmpty()) {
+            Toast.makeText(mContext, mMessageToShowWhenDisabledPreferenceClicked,
+                    Toast.LENGTH_LONG).show();
+        }
+    }
+
+    /**
+     * Sets the ripple on the disabled preference.
+     */
+    @Override
+    public void setShouldShowRippleOnDisabledPreference(boolean showRipple) {
+        mShouldShowRippleOnDisabledPreference = showRipple;
+        CarUiUtils.updateRippleStateOnDisabledPreference(isEnabled(),
+                mShouldShowRippleOnDisabledPreference, mBackground, mPreference);
+    }
+
+    @Override
+    public void setMessageToShowWhenDisabledPreferenceClicked(@NonNull String message) {
+        mMessageToShowWhenDisabledPreferenceClicked = message;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiTwoActionPreference.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiTwoActionPreference.java
new file mode 100644
index 0000000..3b9a583
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/CarUiTwoActionPreference.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 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.ui.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+
+/**
+ * A preference which can perform two actions. The secondary action is shown by default.
+ * {@link #showAction(boolean)} may be used to manually set the visibility of the action.
+ */
+public class CarUiTwoActionPreference extends CarUiPreference {
+
+    private boolean mIsActionShown;
+
+    public CarUiTwoActionPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init(attrs);
+    }
+
+    public CarUiTwoActionPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(attrs);
+    }
+
+    public CarUiTwoActionPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(attrs);
+    }
+
+    public CarUiTwoActionPreference(Context context) {
+        super(context);
+        init(/* attrs= */ null);
+    }
+
+    /**
+     * Sets the custom two action preference layout and attributes.
+     * Check {@link #setLayoutResource} for layout requirements.
+     */
+    private void init(AttributeSet attrs) {
+        setLayoutResource(R.layout.car_ui_two_action_preference);
+        TypedArray preferenceAttributes = getContext().obtainStyledAttributes(attrs,
+                R.styleable.CarUiTwoActionPreference);
+        mIsActionShown = preferenceAttributes.getBoolean(
+                R.styleable.CarUiTwoActionPreference_actionShown, true);
+        setShowChevron(false);
+        preferenceAttributes.recycle();
+    }
+
+    /**
+     * Sets whether the secondary action is visible in the preference.
+     *
+     * @param isShown {@code true} if the secondary action should be shown.
+     */
+    public void showAction(boolean isShown) {
+        mIsActionShown = isShown;
+        notifyChanged();
+    }
+
+    /** Returns {@code true} if action is shown. */
+    public boolean isActionShown() {
+        return mIsActionShown;
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        View actionContainer = CarUiUtils.findViewByRefId(holder.itemView,
+                R.id.action_widget_container);
+        View widgetFrame = CarUiUtils.findViewByRefId(holder.itemView, android.R.id.widget_frame);
+        if (mIsActionShown) {
+            actionContainer.setVisibility(View.VISIBLE);
+            onBindWidgetFrame(widgetFrame);
+        } else {
+            actionContainer.setVisibility(View.GONE);
+        }
+    }
+
+    /**
+     * Binds the created View for the second action.
+     *
+     * <p>This is a good place to set properties on any custom view.
+     *
+     * @param widgetFrame The widget frame which controls the 2nd action.
+     */
+    protected void onBindWidgetFrame(@NonNull View widgetFrame) {
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/DialogFragmentCallbacks.java b/car-ui-lib/src/com/android/car/ui/preference/DialogFragmentCallbacks.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/DialogFragmentCallbacks.java
rename to car-ui-lib/src/com/android/car/ui/preference/DialogFragmentCallbacks.java
diff --git a/car-ui-lib/src/com/android/car/ui/preference/DisabledPreferenceCallback.java b/car-ui-lib/src/com/android/car/ui/preference/DisabledPreferenceCallback.java
new file mode 100644
index 0000000..ea3585b
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/DisabledPreferenceCallback.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Interface for preferences to handle clicks when its disabled.
+ */
+public interface DisabledPreferenceCallback {
+
+    /**
+     * Sets if the ripple effect should be shown on disabled preference.
+     */
+    default void setShouldShowRippleOnDisabledPreference(boolean showRipple) {}
+
+    /**
+     * Sets the message to be displayed when the disabled preference is clicked.
+     */
+    default void setMessageToShowWhenDisabledPreferenceClicked(@NonNull String message) {}
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/EditTextPreferenceDialogFragment.java b/car-ui-lib/src/com/android/car/ui/preference/EditTextPreferenceDialogFragment.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/EditTextPreferenceDialogFragment.java
rename to car-ui-lib/src/com/android/car/ui/preference/EditTextPreferenceDialogFragment.java
diff --git a/car-ui-lib/src/com/android/car/ui/preference/ListPreferenceFragment.java b/car-ui-lib/src/com/android/car/ui/preference/ListPreferenceFragment.java
new file mode 100644
index 0000000..348ec54
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/ListPreferenceFragment.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import static com.android.car.ui.preference.PreferenceDialogFragment.ARG_KEY;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.preference.DialogPreference;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
+import com.android.car.ui.R;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+import com.android.car.ui.utils.CarUiUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A fragment that provides a layout with a list of options associated with a {@link
+ * ListPreference}.
+ */
+public class ListPreferenceFragment extends Fragment implements InsetsChangedListener {
+
+    private ToolbarController mToolbar;
+    private ListPreference mPreference;
+    private CarUiContentListItem mSelectedItem;
+    private int mSelectedIndex = -1;
+    private final Toolbar.OnBackListener mOnBackListener = () -> {
+        if (mSelectedIndex >= 0 && mPreference != null) {
+            String entryValue = mPreference.getEntryValues()[mSelectedIndex].toString();
+
+            if (mPreference.callChangeListener(entryValue)) {
+                mPreference.setValue(entryValue);
+            }
+        }
+
+        return false;
+    };
+
+    /**
+     * Returns a new instance of {@link ListPreferenceFragment} for the {@link ListPreference} with
+     * the given {@code key}.
+     */
+    @NonNull
+    static ListPreferenceFragment newInstance(String key) {
+        ListPreferenceFragment fragment = new ListPreferenceFragment();
+        Bundle b = new Bundle(/* capacity= */ 1);
+        b.putString(ARG_KEY, key);
+        fragment.setArguments(b);
+        return fragment;
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(
+            @NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        if (CarUi.getToolbar(getActivity()) == null) {
+            return inflater.inflate(R.layout.car_ui_list_preference_with_toolbar, container, false);
+        } else {
+            return inflater.inflate(R.layout.car_ui_list_preference, container, false);
+        }
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        final CarUiRecyclerView carUiRecyclerView = CarUiUtils.requireViewByRefId(view, R.id.list);
+        mToolbar = CarUi.getToolbar(getActivity());
+
+        // TODO(b/150230923) remove the code for the old toolbar height change when apps are ready
+        if (mToolbar == null) {
+            Toolbar toolbarView = CarUiUtils.requireViewByRefId(view, R.id.toolbar);
+            mToolbar = toolbarView;
+
+            carUiRecyclerView.setPadding(0, toolbarView.getHeight(), 0, 0);
+            toolbarView.registerToolbarHeightChangeListener(newHeight -> {
+                if (carUiRecyclerView.getPaddingTop() == newHeight) {
+                    return;
+                }
+
+                int oldHeight = carUiRecyclerView.getPaddingTop();
+                carUiRecyclerView.setPadding(0, newHeight, 0, 0);
+                carUiRecyclerView.scrollBy(0, oldHeight - newHeight);
+            });
+        }
+
+        carUiRecyclerView.setClipToPadding(false);
+        mPreference = getListPreference();
+        mToolbar.setTitle(mPreference.getTitle());
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+
+        CharSequence[] entries = mPreference.getEntries();
+        CharSequence[] entryValues = mPreference.getEntryValues();
+
+        if (entries == null || entryValues == null) {
+            throw new IllegalStateException(
+                    "ListPreference requires an entries array and an entryValues array.");
+        }
+
+        if (entries.length != entryValues.length) {
+            throw new IllegalStateException(
+                    "ListPreference entries array length does not match entryValues array length.");
+        }
+
+        mSelectedIndex = mPreference.findIndexOfValue(mPreference.getValue());
+        List<CarUiListItem> listItems = new ArrayList<>();
+        CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);
+
+        for (int i = 0; i < entries.length; i++) {
+            String entry = entries[i].toString();
+            CarUiContentListItem item = new CarUiContentListItem(
+                    CarUiContentListItem.Action.RADIO_BUTTON);
+            item.setTitle(entry);
+
+            if (i == mSelectedIndex) {
+                item.setChecked(true);
+                mSelectedItem = item;
+            }
+
+            item.setOnCheckedChangeListener((listItem, isChecked) -> {
+                if (mSelectedItem != null) {
+                    mSelectedItem.setChecked(false);
+                    adapter.notifyItemChanged(listItems.indexOf(mSelectedItem));
+                }
+                mSelectedItem = listItem;
+                mSelectedIndex = listItems.indexOf(mSelectedItem);
+            });
+
+            listItems.add(item);
+        }
+
+        carUiRecyclerView.setAdapter(adapter);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        mToolbar.registerOnBackListener(mOnBackListener);
+        Insets insets = CarUi.getInsets(getActivity());
+        if (insets != null) {
+            onCarUiInsetsChanged(insets);
+        }
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        mToolbar.unregisterOnBackListener(mOnBackListener);
+    }
+
+    private ListPreference getListPreference() {
+        if (getArguments() == null) {
+            throw new IllegalStateException("Preference arguments cannot be null");
+        }
+
+        String key = getArguments().getString(ARG_KEY);
+        DialogPreference.TargetFragment fragment =
+                (DialogPreference.TargetFragment) getTargetFragment();
+
+        if (key == null) {
+            throw new IllegalStateException(
+                    "ListPreference key not found in Fragment arguments");
+        }
+
+        if (fragment == null) {
+            throw new IllegalStateException(
+                    "Target fragment must be registered before displaying ListPreference "
+                            + "screen.");
+        }
+
+        Preference preference = fragment.findPreference(key);
+
+        if (!(preference instanceof ListPreference)) {
+            throw new IllegalStateException(
+                    "Cannot use ListPreferenceFragment with a preference that is not of type "
+                            + "ListPreference");
+        }
+
+        return (ListPreference) preference;
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        View view = requireView();
+        CarUiUtils.requireViewByRefId(view, R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        view.setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java b/car-ui-lib/src/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java
new file mode 100644
index 0000000..1d4a3a2
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import static com.android.car.ui.preference.PreferenceDialogFragment.ARG_KEY;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.preference.DialogPreference;
+import androidx.preference.Preference;
+
+import com.android.car.ui.R;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+import com.android.car.ui.utils.CarUiUtils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A fragment that provides a layout with a list of options associated with a {@link
+ * CarUiMultiSelectListPreference}.
+ */
+public class MultiSelectListPreferenceFragment extends Fragment implements InsetsChangedListener {
+
+    private CarUiMultiSelectListPreference mPreference;
+    private Set<String> mNewValues;
+    private ToolbarController mToolbar;
+    private final Toolbar.OnBackListener mOnBackListener = () -> {
+        if (mPreference.callChangeListener(mNewValues)) {
+            mPreference.setValues(mNewValues);
+        }
+
+        return false;
+    };
+
+    /**
+     * Returns a new instance of {@link MultiSelectListPreferenceFragment} for the {@link
+     * CarUiMultiSelectListPreference} with the given {@code key}.
+     */
+    @NonNull
+    static MultiSelectListPreferenceFragment newInstance(String key) {
+        MultiSelectListPreferenceFragment fragment = new MultiSelectListPreferenceFragment();
+        Bundle b = new Bundle(/* capacity= */ 1);
+        b.putString(ARG_KEY, key);
+        fragment.setArguments(b);
+        return fragment;
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(
+            @NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        if (CarUi.getToolbar(getActivity()) == null) {
+            return inflater.inflate(R.layout.car_ui_list_preference_with_toolbar, container, false);
+        } else {
+            return inflater.inflate(R.layout.car_ui_list_preference, container, false);
+        }
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        final CarUiRecyclerView recyclerView = CarUiUtils.requireViewByRefId(view, R.id.list);
+        mToolbar = CarUi.getToolbar(requireActivity());
+
+        // TODO(b/150230923) remove the code for the old toolbar height change when apps are ready
+        if (mToolbar == null) {
+            Toolbar toolbarView = CarUiUtils.requireViewByRefId(view, R.id.toolbar);
+            mToolbar = toolbarView;
+
+            recyclerView.setPadding(0, toolbarView.getHeight(), 0, 0);
+            toolbarView.registerToolbarHeightChangeListener(newHeight -> {
+                if (recyclerView.getPaddingTop() == newHeight) {
+                    return;
+                }
+
+                int oldHeight = recyclerView.getPaddingTop();
+                recyclerView.setPadding(0, newHeight, 0, 0);
+                recyclerView.scrollBy(0, oldHeight - newHeight);
+            });
+        }
+
+        mPreference = getPreference();
+
+        recyclerView.setClipToPadding(false);
+        mToolbar.setTitle(mPreference.getTitle());
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+
+        mNewValues = new HashSet<>(mPreference.getValues());
+        CharSequence[] entries = mPreference.getEntries();
+        CharSequence[] entryValues = mPreference.getEntryValues();
+
+        if (entries == null || entryValues == null) {
+            throw new IllegalStateException(
+                    "MultiSelectListPreference requires an entries array and an entryValues array"
+                            + ".");
+        }
+
+        if (entries.length != entryValues.length) {
+            throw new IllegalStateException(
+                    "MultiSelectListPreference entries array length does not match entryValues "
+                            + "array length.");
+        }
+
+        List<CarUiListItem> listItems = new ArrayList<>();
+        boolean[] selectedItems = mPreference.getSelectedItems();
+
+        for (int i = 0; i < entries.length; i++) {
+            String entry = entries[i].toString();
+            String entryValue = entryValues[i].toString();
+            CarUiContentListItem item = new CarUiContentListItem(
+                    CarUiContentListItem.Action.CHECK_BOX);
+            item.setTitle(entry);
+            item.setChecked(selectedItems[i]);
+            item.setOnCheckedChangeListener((listItem, isChecked) -> {
+                if (isChecked) {
+                    mNewValues.add(entryValue);
+                } else {
+                    mNewValues.remove(entryValue);
+                }
+            });
+
+            listItems.add(item);
+        }
+
+        CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);
+        recyclerView.setAdapter(adapter);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        mToolbar.registerOnBackListener(mOnBackListener);
+        Insets insets = CarUi.getInsets(getActivity());
+        if (insets != null) {
+            onCarUiInsetsChanged(insets);
+        }
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        mToolbar.unregisterOnBackListener(mOnBackListener);
+    }
+
+    private CarUiMultiSelectListPreference getPreference() {
+        if (getArguments() == null) {
+            throw new IllegalStateException("Preference arguments cannot be null");
+        }
+
+        String key = getArguments().getString(ARG_KEY);
+        DialogPreference.TargetFragment fragment =
+                (DialogPreference.TargetFragment) getTargetFragment();
+
+        if (key == null) {
+            throw new IllegalStateException(
+                    "MultiSelectListPreference key not found in Fragment arguments");
+        }
+
+        if (fragment == null) {
+            throw new IllegalStateException(
+                    "Target fragment must be registered before displaying "
+                            + "MultiSelectListPreference screen.");
+        }
+
+        Preference preference = fragment.findPreference(key);
+
+        if (!(preference instanceof CarUiMultiSelectListPreference)) {
+            throw new IllegalStateException(
+                    "Cannot use MultiSelectListPreferenceFragment with a preference that is "
+                            + "not of type CarUiMultiSelectListPreference");
+        }
+
+        return (CarUiMultiSelectListPreference) preference;
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        View view = requireView();
+        CarUiUtils.requireViewByRefId(view, R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        view.setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/PreferenceDialogFragment.java b/car-ui-lib/src/com/android/car/ui/preference/PreferenceDialogFragment.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/PreferenceDialogFragment.java
rename to car-ui-lib/src/com/android/car/ui/preference/PreferenceDialogFragment.java
diff --git a/car-ui-lib/src/com/android/car/ui/preference/PreferenceFragment.java b/car-ui-lib/src/com/android/car/ui/preference/PreferenceFragment.java
new file mode 100644
index 0000000..8b66b8e
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/preference/PreferenceFragment.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.preference;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.util.Pair;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.preference.DialogPreference;
+import androidx.preference.DropDownPreference;
+import androidx.preference.EditTextPreference;
+import androidx.preference.ListPreference;
+import androidx.preference.MultiSelectListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+import com.android.car.ui.utils.CarUiUtils;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A PreferenceFragmentCompat is the entry point to using the Preference library.
+ *
+ * <p>Using this fragment will replace regular Preferences with CarUi equivalents. Because of this,
+ * certain properties that cannot be read out of Preferences will be lost upon calling
+ * {@link #setPreferenceScreen(PreferenceScreen)}. These include the preference viewId,
+ * defaultValue, and enabled state.
+ */
+public abstract class PreferenceFragment extends PreferenceFragmentCompat implements
+        InsetsChangedListener {
+
+    private static final String TAG = "CarUiPreferenceFragment";
+    private static final String DIALOG_FRAGMENT_TAG =
+            "com.android.car.ui.PreferenceFragment.DIALOG";
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        ToolbarController baseLayoutToolbar = CarUi.getToolbar(getActivity());
+        if (baseLayoutToolbar != null) {
+            baseLayoutToolbar.setState(Toolbar.State.SUBPAGE);
+            if (getPreferenceScreen() != null) {
+                baseLayoutToolbar.setTitle(getPreferenceScreen().getTitle());
+            }
+        }
+
+        // TODO(b/150230923) remove the code for the old toolbar height change when apps are ready
+        final RecyclerView recyclerView = CarUiUtils.findViewByRefId(view, R.id.recycler_view);
+        final Toolbar toolbar = CarUiUtils.findViewByRefId(view, R.id.toolbar);
+        if (recyclerView == null || toolbar == null) {
+            return;
+        }
+
+        recyclerView.setPadding(0, toolbar.getHeight(), 0, 0);
+        toolbar.registerToolbarHeightChangeListener(newHeight -> {
+            if (recyclerView.getPaddingTop() == newHeight) {
+                return;
+            }
+
+            int oldHeight = recyclerView.getPaddingTop();
+            recyclerView.setPadding(0, newHeight, 0, 0);
+            recyclerView.scrollBy(0, oldHeight - newHeight);
+        });
+
+        recyclerView.setClipToPadding(false);
+        if (getPreferenceScreen() != null) {
+            toolbar.setTitle(getPreferenceScreen().getTitle());
+        }
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Insets insets = CarUi.getInsets(getActivity());
+        if (insets != null) {
+            onCarUiInsetsChanged(insets);
+        }
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        View view = requireView();
+        CarUiUtils.requireViewByRefId(view, R.id.recycler_view)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        view.setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+
+    /**
+     * Called when a preference in the tree requests to display a dialog. Subclasses should override
+     * this method to display custom dialogs or to handle dialogs for custom preference classes.
+     *
+     * <p>Note: this is borrowed as-is from androidx.preference.PreferenceFragmentCompat with
+     * updates to launch Car UI library {@link DialogFragment} instead of the ones in the
+     * support library.
+     *
+     * @param preference The {@link Preference} object requesting the dialog
+     */
+    @Override
+    public void onDisplayPreferenceDialog(Preference preference) {
+
+        if (getActivity() instanceof OnPreferenceDisplayDialogCallback
+                && ((OnPreferenceDisplayDialogCallback) getActivity())
+                .onPreferenceDisplayDialog(this, preference)) {
+            return;
+        }
+
+        // check if dialog is already showing
+        if (requireFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
+            return;
+        }
+
+        final Fragment f;
+        if (preference instanceof EditTextPreference) {
+            f = EditTextPreferenceDialogFragment.newInstance(preference.getKey());
+        } else if (preference instanceof ListPreference) {
+            f = ListPreferenceFragment.newInstance(preference.getKey());
+        } else if (preference instanceof MultiSelectListPreference) {
+            f = MultiSelectListPreferenceFragment.newInstance(preference.getKey());
+        } else if (preference instanceof CarUiSeekBarDialogPreference) {
+            f = SeekbarPreferenceDialogFragment.newInstance(preference.getKey());
+        } else {
+            throw new IllegalArgumentException(
+                    "Cannot display dialog for an unknown Preference type: "
+                            + preference.getClass().getSimpleName()
+                            + ". Make sure to implement onPreferenceDisplayDialog() to handle "
+                            + "displaying a custom dialog for this Preference.");
+        }
+
+        f.setTargetFragment(this, 0);
+
+        if (f instanceof DialogFragment) {
+            ((DialogFragment) f).show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+        } else {
+            if (getActivity() == null) {
+                throw new IllegalStateException(
+                        "Preference fragment is not attached to an Activity.");
+            }
+
+            if (getView() == null) {
+                throw new IllegalStateException(
+                        "Preference fragment must have a layout.");
+            }
+
+            Context context = getContext();
+            getActivity().getSupportFragmentManager().beginTransaction()
+                    .setCustomAnimations(
+                            CarUiUtils.getAttrResourceId(context,
+                                    android.R.attr.fragmentOpenEnterAnimation),
+                            CarUiUtils.getAttrResourceId(context,
+                                    android.R.attr.fragmentOpenExitAnimation),
+                            CarUiUtils.getAttrResourceId(context,
+                                    android.R.attr.fragmentCloseEnterAnimation),
+                            CarUiUtils.getAttrResourceId(context,
+                                    android.R.attr.fragmentCloseExitAnimation))
+                    .replace(((ViewGroup) getView().getParent()).getId(), f)
+                    .addToBackStack(null)
+                    .commit();
+        }
+    }
+
+    /**
+     * This override of setPreferenceScreen replaces preferences with their CarUi versions first.
+     */
+    @Override
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        // We do a search of the tree and every time we see a PreferenceGroup we remove
+        // all it's children, replace them with CarUi versions, and then re-add them
+
+        Map<Preference, String> dependencies = new HashMap<>();
+        List<Preference> children = new ArrayList<>();
+
+        // Stack of preferences to process
+        Deque<Preference> stack = new ArrayDeque<>();
+        stack.addFirst(preferenceScreen);
+
+        while (!stack.isEmpty()) {
+            Preference preference = stack.removeFirst();
+
+            if (preference instanceof PreferenceGroup) {
+                PreferenceGroup pg = (PreferenceGroup) preference;
+
+                children.clear();
+                for (int i = 0; i < pg.getPreferenceCount(); i++) {
+                    children.add(pg.getPreference(i));
+                }
+
+                pg.removeAll();
+
+                for (Preference child : children) {
+                    Preference replacement = getReplacementFor(child);
+
+                    dependencies.put(replacement, child.getDependency());
+                    pg.addPreference(replacement);
+                    stack.addFirst(replacement);
+                }
+            }
+        }
+
+        super.setPreferenceScreen(preferenceScreen);
+
+        // Set the dependencies after all the swapping has been done and they've been
+        // associated with this fragment, or we could potentially fail to find preferences
+        // or use the wrong preferenceManager
+        for (Map.Entry<Preference, String> entry : dependencies.entrySet()) {
+            entry.getKey().setDependency(entry.getValue());
+        }
+    }
+
+    // Mapping from regular preferences to CarUi preferences.
+    // Order is important, subclasses must come before their base classes
+    private static final List<Pair<Class<? extends Preference>, Class<? extends Preference>>>
+            sPreferenceMapping = Arrays.asList(
+            new Pair<>(DropDownPreference.class, CarUiDropDownPreference.class),
+            new Pair<>(ListPreference.class, CarUiListPreference.class),
+            new Pair<>(MultiSelectListPreference.class, CarUiMultiSelectListPreference.class),
+            new Pair<>(EditTextPreference.class, CarUiEditTextPreference.class),
+            new Pair<>(SwitchPreference.class, CarUiSwitchPreference.class),
+            new Pair<>(Preference.class, CarUiPreference.class)
+    );
+
+    /**
+     * Gets the CarUi version of the passed in preference. If there is no suitable replacement, this
+     * method will return it's input.
+     *
+     * <p>When given a Preference that extends a replaceable preference, we log a warning instead
+     * of replacing it so that we don't remove any functionality.
+     */
+    private static Preference getReplacementFor(Preference preference) {
+        Class<? extends Preference> clazz = preference.getClass();
+
+        for (Pair<Class<? extends Preference>, Class<? extends Preference>> replacement
+                : sPreferenceMapping) {
+            Class<? extends Preference> source = replacement.first;
+            Class<? extends Preference> target = replacement.second;
+            if (source.isAssignableFrom(clazz)) {
+                if (clazz == source) {
+                    try {
+                        return copyPreference(preference, (Preference) target
+                                .getDeclaredConstructor(Context.class)
+                                .newInstance(preference.getContext()));
+                    } catch (ReflectiveOperationException e) {
+                        throw new RuntimeException(e);
+                    }
+                } else if (clazz == target || source == Preference.class) {
+                    // Don't warn about subclasses of Preference because there are many legitimate
+                    // uses for non-carui Preference subclasses, like Preference groups.
+                    return preference;
+                } else {
+                    Log.w(TAG, "Subclass of " + source.getSimpleName() + " was used, "
+                            + "preventing us from substituting it with " + target.getSimpleName());
+                    return preference;
+                }
+            }
+        }
+
+        return preference;
+    }
+
+    /**
+     * Copies all the properties of one preference to another.
+     *
+     * @return the {@code to} parameter
+     */
+    private static Preference copyPreference(Preference from, Preference to) {
+        // viewId and defaultValue don't have getters
+        // isEnabled() is not completely symmetrical with setEnabled(), so we can't use it.
+        to.setTitle(from.getTitle());
+        to.setOnPreferenceClickListener(from.getOnPreferenceClickListener());
+        to.setOnPreferenceChangeListener(from.getOnPreferenceChangeListener());
+        to.setIcon(from.getIcon());
+        to.setFragment(from.getFragment());
+        to.setIntent(from.getIntent());
+        to.setKey(from.getKey());
+        to.setOrder(from.getOrder());
+        to.setSelectable(from.isSelectable());
+        to.setPersistent(from.isPersistent());
+        to.setIconSpaceReserved(from.isIconSpaceReserved());
+        to.setWidgetLayoutResource(from.getWidgetLayoutResource());
+        to.setPreferenceDataStore(from.getPreferenceDataStore());
+        to.setShouldDisableView(from.getShouldDisableView());
+        to.setSingleLineTitle(from.isSingleLineTitle());
+        to.setVisible(from.isVisible());
+        to.setLayoutResource(from.getLayoutResource());
+        to.setCopyingEnabled(from.isCopyingEnabled());
+
+        if (from.getSummaryProvider() != null) {
+            to.setSummaryProvider(from.getSummaryProvider());
+        } else {
+            to.setSummary(from.getSummary());
+        }
+
+        if (from.peekExtras() != null) {
+            to.getExtras().putAll(from.peekExtras());
+        }
+
+        if (from instanceof DialogPreference) {
+            DialogPreference fromDialog = (DialogPreference) from;
+            DialogPreference toDialog = (DialogPreference) to;
+            toDialog.setDialogTitle(fromDialog.getDialogTitle());
+            toDialog.setDialogIcon(fromDialog.getDialogIcon());
+            toDialog.setDialogMessage(fromDialog.getDialogMessage());
+            toDialog.setDialogLayoutResource(fromDialog.getDialogLayoutResource());
+            toDialog.setNegativeButtonText(fromDialog.getNegativeButtonText());
+            toDialog.setPositiveButtonText(fromDialog.getPositiveButtonText());
+        }
+
+        // DropDownPreference extends ListPreference and doesn't add any extra api surface,
+        // so we don't need a case for it
+        if (from instanceof ListPreference) {
+            ListPreference fromList = (ListPreference) from;
+            ListPreference toList = (ListPreference) to;
+            toList.setEntries(fromList.getEntries());
+            toList.setEntryValues(fromList.getEntryValues());
+            toList.setValue(fromList.getValue());
+        } else if (from instanceof EditTextPreference) {
+            EditTextPreference fromText = (EditTextPreference) from;
+            EditTextPreference toText = (EditTextPreference) to;
+            toText.setText(fromText.getText());
+        } else if (from instanceof MultiSelectListPreference) {
+            MultiSelectListPreference fromMulti = (MultiSelectListPreference) from;
+            MultiSelectListPreference toMulti = (MultiSelectListPreference) to;
+            toMulti.setEntries(fromMulti.getEntries());
+            toMulti.setEntryValues(fromMulti.getEntryValues());
+            toMulti.setValues(fromMulti.getValues());
+        }
+
+        // We don't need to add checks for things that we will never replace,
+        // like PreferenceGroup or CheckBoxPreference
+
+        return to;
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/SeekbarPreferenceDialogFragment.java b/car-ui-lib/src/com/android/car/ui/preference/SeekbarPreferenceDialogFragment.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/preference/SeekbarPreferenceDialogFragment.java
rename to car-ui-lib/src/com/android/car/ui/preference/SeekbarPreferenceDialogFragment.java
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiCheckBoxListItem.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiCheckBoxListItem.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiCheckBoxListItem.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/CarUiCheckBoxListItem.java
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiContentListItem.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiContentListItem.java
new file mode 100644
index 0000000..71f5d1a
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiContentListItem.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Definition of list items that can be inserted into {@link CarUiListItemAdapter}.
+ */
+public class CarUiContentListItem extends CarUiListItem {
+
+    /**
+     * Callback to be invoked when the checked state of a list item changed.
+     */
+    public interface OnCheckedChangeListener {
+        /**
+         * Called when the checked state of a list item has changed.
+         *
+         * @param item      whose checked state changed.
+         * @param isChecked new checked state of list item.
+         */
+        void onCheckedChanged(@NonNull CarUiContentListItem item, boolean isChecked);
+    }
+
+    /**
+     * Callback to be invoked when an item is clicked.
+     */
+    public interface OnClickListener {
+        /**
+         * Called when the item has been clicked.
+         *
+         * @param item whose checked state changed.
+         */
+        void onClick(@NonNull CarUiContentListItem item);
+    }
+
+    public enum IconType {
+        /**
+         * For an icon type of CONTENT, the primary icon is a larger than {@code STANDARD}.
+         */
+        CONTENT,
+        /**
+         * For an icon type of STANDARD, the primary icon is the standard size.
+         */
+        STANDARD,
+        /**
+         * For an icon type of AVATAR, the primary icon is masked to provide an icon with a modified
+         * shape.
+         */
+        AVATAR
+    }
+
+    /**
+     * Enum of secondary action types of a list item.
+     */
+    public enum Action {
+        /**
+         * For an action value of NONE, no action element is shown for a list item.
+         */
+        NONE,
+        /**
+         * For an action value of SWITCH, a switch is shown for the action element of the list item.
+         */
+        SWITCH,
+        /**
+         * For an action value of CHECK_BOX, a checkbox is shown for the action element of the list
+         * item.
+         */
+        CHECK_BOX,
+        /**
+         * For an action value of RADIO_BUTTON, a radio button is shown for the action element of
+         * the list item.
+         */
+        RADIO_BUTTON,
+        /**
+         * For an action value of ICON, an icon is shown for the action element of the list item.
+         */
+        ICON,
+        /**
+         * For an action value CHEVRON, a chevron is shown for the action element of the list
+         * item.
+         */
+        CHEVRON
+    }
+
+    private Drawable mIcon;
+    @Nullable
+    private Drawable mSupplementalIcon;
+    private CharSequence mTitle;
+    private CharSequence mBody;
+    private final Action mAction;
+    private IconType mPrimaryIconType;
+    private boolean mIsActionDividerVisible;
+    private boolean mIsChecked;
+    private boolean mIsEnabled = true;
+    private boolean mIsActivated;
+    private OnClickListener mOnClickListener;
+    private OnCheckedChangeListener mOnCheckedChangeListener;
+    private View.OnClickListener mSupplementalIconOnClickListener;
+
+
+    public CarUiContentListItem(Action action) {
+        mAction = action;
+        mPrimaryIconType = IconType.STANDARD;
+    }
+
+    /**
+     * Returns the title of the item.
+     */
+    @Nullable
+    public CharSequence getTitle() {
+        return mTitle;
+    }
+
+    /**
+     * Sets the title of the item.
+     *
+     * @param title text to display as title.
+     */
+    public void setTitle(@NonNull CharSequence title) {
+        mTitle = title;
+    }
+
+    /**
+     * Returns the body text of the item.
+     */
+    @Nullable
+    public CharSequence getBody() {
+        return mBody;
+    }
+
+    /**
+     * Sets the body of the item.
+     *
+     * @param body text to display as body text.
+     */
+    public void setBody(@NonNull CharSequence body) {
+        mBody = body;
+    }
+
+    /**
+     * Returns the icon of the item.
+     */
+    @Nullable
+    public Drawable getIcon() {
+        return mIcon;
+    }
+
+    /**
+     * Sets the icon of the item.
+     *
+     * @param icon the icon to display.
+     */
+    public void setIcon(@Nullable Drawable icon) {
+        mIcon = icon;
+    }
+
+    /**
+     * Returns the primary icon type for the item.
+     */
+    public IconType getPrimaryIconType() {
+        return mPrimaryIconType;
+    }
+
+    /**
+     * Sets the primary icon type for the item.
+     *
+     * @param icon the icon type for the item.
+     */
+    public void setPrimaryIconType(IconType icon) {
+        mPrimaryIconType = icon;
+    }
+
+    /**
+     * Returns {@code true} if the item is activated.
+     */
+    public boolean isActivated() {
+        return mIsActivated;
+    }
+
+    /**
+     * Sets the activated state of the item.
+     *
+     * @param activated the activated state for the item.
+     */
+    public void setActivated(boolean activated) {
+        mIsActivated = activated;
+    }
+
+    /**
+     * Returns {@code true} if the item is enabled.
+     */
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    /**
+     * Sets the enabled state of the item.
+     *
+     * @param enabled the enabled state for the item.
+     */
+    public void setEnabled(boolean enabled) {
+        mIsEnabled = enabled;
+    }
+
+    /**
+     * Returns {@code true} if the item is checked. Will always return {@code false} when the action
+     * type for the item is {@code Action.NONE}.
+     */
+    public boolean isChecked() {
+        return mIsChecked;
+    }
+
+    /**
+     * Sets the checked state of the item.
+     *
+     * @param checked the checked state for the item.
+     */
+    public void setChecked(boolean checked) {
+        if (checked == mIsChecked) {
+            return;
+        }
+
+        // Checked state can only be set when action type is checkbox, radio button or switch.
+        if (mAction == Action.CHECK_BOX || mAction == Action.SWITCH
+                || mAction == Action.RADIO_BUTTON) {
+            mIsChecked = checked;
+
+            if (mOnCheckedChangeListener != null) {
+                mOnCheckedChangeListener.onCheckedChanged(this, mIsChecked);
+            }
+        }
+    }
+
+    /**
+     * Sets the visibility of the action divider.
+     *
+     * @param visible visibility of the action divider.
+     */
+    public void setActionDividerVisible(boolean visible) {
+        mIsActionDividerVisible = visible;
+    }
+
+    /**
+     * Returns {@code true} if the action divider is visible.
+     */
+    public boolean isActionDividerVisible() {
+        return mIsActionDividerVisible;
+    }
+
+    /**
+     * Returns the action type for the item.
+     */
+    public Action getAction() {
+        return mAction;
+    }
+
+    /**
+     * Returns the supplemental icon for the item.
+     */
+    @Nullable
+    public Drawable getSupplementalIcon() {
+        if (mAction != Action.ICON) {
+            return null;
+        }
+
+        return mSupplementalIcon;
+    }
+
+    /**
+     * Sets supplemental icon to be displayed in a list item.
+     *
+     * @param icon the Drawable to set as the icon, or null to clear the content.
+     */
+    public void setSupplementalIcon(@Nullable Drawable icon) {
+        setSupplementalIcon(icon, null);
+    }
+
+    /**
+     * Sets supplemental icon to be displayed in a list item.
+     *
+     * @param icon     the Drawable to set as the icon, or null to clear the content.
+     * @param listener the callback that is invoked when the icon is clicked.
+     */
+    public void setSupplementalIcon(@Nullable Drawable icon,
+            @Nullable View.OnClickListener listener) {
+        if (mAction != Action.ICON) {
+            throw new IllegalStateException(
+                    "Cannot set supplemental icon on list item that does not have an action of "
+                            + "type ICON");
+        }
+
+        mSupplementalIcon = icon;
+        mSupplementalIconOnClickListener = listener;
+    }
+
+    @Nullable
+    public View.OnClickListener getSupplementalIconOnClickListener() {
+        return mSupplementalIconOnClickListener;
+    }
+
+    /**
+     * Registers a callback to be invoked when the item is clicked.
+     *
+     * @param listener callback to be invoked when item is clicked.
+     */
+    public void setOnItemClickedListener(@Nullable OnClickListener listener) {
+        mOnClickListener = listener;
+    }
+
+    /**
+     * Returns the {@link OnClickListener} registered for this item.
+     */
+    @Nullable
+    public OnClickListener getOnClickListener() {
+        return mOnClickListener;
+    }
+
+    /**
+     * Registers a callback to be invoked when the checked state of list item changes.
+     *
+     * <p>Checked state changes can take place when the action type is {@code Action.SWITCH} or
+     * {@code Action.CHECK_BOX}.
+     *
+     * @param listener callback to be invoked when the checked state shown in the UI changes.
+     */
+    public void setOnCheckedChangeListener(
+            @Nullable OnCheckedChangeListener listener) {
+        mOnCheckedChangeListener = listener;
+    }
+
+    /**
+     * Returns the {@link OnCheckedChangeListener} registered for this item.
+     */
+    @Nullable
+    public OnCheckedChangeListener getOnCheckedChangeListener() {
+        return mOnCheckedChangeListener;
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiHeaderListItem.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiHeaderListItem.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiHeaderListItem.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/CarUiHeaderListItem.java
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItem.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItem.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiListItem.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItem.java
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItemAdapter.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItemAdapter.java
new file mode 100644
index 0000000..eac856a
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItemAdapter.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
+
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+
+import java.util.List;
+
+/**
+ * Adapter for {@link CarUiRecyclerView} to display {@link CarUiContentListItem} and {@link
+ * CarUiHeaderListItem}.
+ *
+ * <ul>
+ * <li> Implements {@link CarUiRecyclerView.ItemCap} - defaults to unlimited item count.
+ * </ul>
+ */
+public class CarUiListItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
+        CarUiRecyclerView.ItemCap {
+
+    static final int VIEW_TYPE_LIST_ITEM = 1;
+    static final int VIEW_TYPE_LIST_HEADER = 2;
+
+    private final List<? extends CarUiListItem> mItems;
+    private int mMaxItems = CarUiRecyclerView.ItemCap.UNLIMITED;
+
+    public CarUiListItemAdapter(List<? extends CarUiListItem> items) {
+        this.mItems = items;
+    }
+
+    @NonNull
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(
+            @NonNull ViewGroup parent, int viewType) {
+        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+
+        switch (viewType) {
+            case VIEW_TYPE_LIST_ITEM:
+                return new ListItemViewHolder(
+                        inflater.inflate(R.layout.car_ui_list_item, parent, false));
+            case VIEW_TYPE_LIST_HEADER:
+                return new HeaderViewHolder(
+                        inflater.inflate(R.layout.car_ui_header_list_item, parent, false));
+            default:
+                throw new IllegalStateException("Unknown item type.");
+        }
+    }
+
+    /**
+     * Returns the data set held by the adapter.
+     *
+     * <p>Any changes performed to this mutable list must be followed with an invocation of the
+     * appropriate notify method for the adapter.
+     */
+    @NonNull
+    public List<? extends CarUiListItem> getItems() {
+        return mItems;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (mItems.get(position) instanceof CarUiContentListItem) {
+            return VIEW_TYPE_LIST_ITEM;
+        } else if (mItems.get(position) instanceof CarUiHeaderListItem) {
+            return VIEW_TYPE_LIST_HEADER;
+        }
+
+        throw new IllegalStateException("Unknown view type.");
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
+        switch (holder.getItemViewType()) {
+            case VIEW_TYPE_LIST_ITEM:
+                if (!(holder instanceof ListItemViewHolder)) {
+                    throw new IllegalStateException("Incorrect view holder type for list item.");
+                }
+
+                CarUiListItem item = mItems.get(position);
+                if (!(item instanceof CarUiContentListItem)) {
+                    throw new IllegalStateException(
+                            "Expected item to be bound to viewHolder to be instance of "
+                                    + "CarUiContentListItem.");
+                }
+
+                ((ListItemViewHolder) holder).bind((CarUiContentListItem) item);
+                break;
+            case VIEW_TYPE_LIST_HEADER:
+                if (!(holder instanceof HeaderViewHolder)) {
+                    throw new IllegalStateException("Incorrect view holder type for list item.");
+                }
+
+                CarUiListItem header = mItems.get(position);
+                if (!(header instanceof CarUiHeaderListItem)) {
+                    throw new IllegalStateException(
+                            "Expected item to be bound to viewHolder to be instance of "
+                                    + "CarUiHeaderListItem.");
+                }
+
+                ((HeaderViewHolder) holder).bind((CarUiHeaderListItem) header);
+                break;
+            default:
+                throw new IllegalStateException("Unknown item view type.");
+        }
+    }
+
+    @Override
+    public int getItemCount() {
+        return mMaxItems == CarUiRecyclerView.ItemCap.UNLIMITED
+                ? mItems.size()
+                : Math.min(mItems.size(), mMaxItems);
+    }
+
+    @Override
+    public void setMaxItems(int maxItems) {
+        mMaxItems = maxItems;
+    }
+
+    /**
+     * Holds views of {@link CarUiContentListItem}.
+     */
+    static class ListItemViewHolder extends RecyclerView.ViewHolder {
+
+        final TextView mTitle;
+        final TextView mBody;
+        final ImageView mIcon;
+        final ImageView mContentIcon;
+        final ImageView mAvatarIcon;
+        final ViewGroup mIconContainer;
+        final ViewGroup mActionContainer;
+        final View mActionDivider;
+        final Switch mSwitch;
+        final CheckBox mCheckBox;
+        final RadioButton mRadioButton;
+        final ImageView mSupplementalIcon;
+        final View mTouchInterceptor;
+        final View mReducedTouchInterceptor;
+        final View mActionContainerTouchInterceptor;
+
+        ListItemViewHolder(@NonNull View itemView) {
+            super(itemView);
+            mTitle = requireViewByRefId(itemView, R.id.title);
+            mBody = requireViewByRefId(itemView, R.id.body);
+            mIcon = requireViewByRefId(itemView, R.id.icon);
+            mContentIcon = requireViewByRefId(itemView, R.id.content_icon);
+            mAvatarIcon = requireViewByRefId(itemView, R.id.avatar_icon);
+            mIconContainer = requireViewByRefId(itemView, R.id.icon_container);
+            mActionContainer = requireViewByRefId(itemView, R.id.action_container);
+            mActionDivider = requireViewByRefId(itemView, R.id.action_divider);
+            mSwitch = requireViewByRefId(itemView, R.id.switch_widget);
+            mCheckBox = requireViewByRefId(itemView, R.id.checkbox_widget);
+            mRadioButton = requireViewByRefId(itemView, R.id.radio_button_widget);
+            mSupplementalIcon = requireViewByRefId(itemView, R.id.supplemental_icon);
+            mReducedTouchInterceptor = requireViewByRefId(itemView, R.id.reduced_touch_interceptor);
+            mTouchInterceptor = requireViewByRefId(itemView, R.id.touch_interceptor);
+            mActionContainerTouchInterceptor = requireViewByRefId(itemView,
+                    R.id.action_container_touch_interceptor);
+        }
+
+        void bind(@NonNull CarUiContentListItem item) {
+            CharSequence title = item.getTitle();
+            CharSequence body = item.getBody();
+            Drawable icon = item.getIcon();
+
+            if (!TextUtils.isEmpty(title)) {
+                mTitle.setText(title);
+                mTitle.setVisibility(View.VISIBLE);
+            } else {
+                mTitle.setVisibility(View.GONE);
+            }
+
+            if (!TextUtils.isEmpty(body)) {
+                mBody.setText(body);
+                mBody.setVisibility(View.VISIBLE);
+            } else {
+                mBody.setVisibility(View.GONE);
+            }
+
+            mIcon.setVisibility(View.GONE);
+            mContentIcon.setVisibility(View.GONE);
+            mAvatarIcon.setVisibility(View.GONE);
+
+            if (icon != null) {
+                mIconContainer.setVisibility(View.VISIBLE);
+
+                switch (item.getPrimaryIconType()) {
+                    case CONTENT:
+                        mContentIcon.setVisibility(View.VISIBLE);
+                        mContentIcon.setImageDrawable(icon);
+                        break;
+                    case STANDARD:
+                        mIcon.setVisibility(View.VISIBLE);
+                        mIcon.setImageDrawable(icon);
+                        break;
+                    case AVATAR:
+                        mAvatarIcon.setVisibility(View.VISIBLE);
+                        mAvatarIcon.setImageDrawable(icon);
+                        mAvatarIcon.setClipToOutline(true);
+                        break;
+                }
+            } else {
+                mIconContainer.setVisibility(View.GONE);
+            }
+
+            mActionDivider.setVisibility(
+                    item.isActionDividerVisible() ? View.VISIBLE : View.GONE);
+            mSwitch.setVisibility(View.GONE);
+            mCheckBox.setVisibility(View.GONE);
+            mRadioButton.setVisibility(View.GONE);
+            mSupplementalIcon.setVisibility(View.GONE);
+
+            CarUiContentListItem.OnClickListener itemOnClickListener = item.getOnClickListener();
+
+            switch (item.getAction()) {
+                case NONE:
+                    mActionContainer.setVisibility(View.GONE);
+
+                    // Display ripple effects across entire item when clicked by using full-sized
+                    // touch interceptor.
+                    mTouchInterceptor.setVisibility(View.VISIBLE);
+                    mTouchInterceptor.setOnClickListener(v -> {
+                        if (itemOnClickListener != null) {
+                            itemOnClickListener.onClick(item);
+                        }
+                    });
+                    mReducedTouchInterceptor.setVisibility(View.GONE);
+                    mActionContainerTouchInterceptor.setVisibility(View.GONE);
+                    break;
+                case SWITCH:
+                    bindCompoundButton(item, mSwitch, itemOnClickListener);
+                    break;
+                case CHECK_BOX:
+                    bindCompoundButton(item, mCheckBox, itemOnClickListener);
+                    break;
+                case RADIO_BUTTON:
+                    bindCompoundButton(item, mRadioButton, itemOnClickListener);
+                    break;
+                case CHEVRON:
+                    mSupplementalIcon.setVisibility(View.VISIBLE);
+                    mSupplementalIcon.setImageDrawable(itemView.getContext().getDrawable(
+                            R.drawable.car_ui_preference_icon_chevron));
+                    mActionContainer.setVisibility(View.VISIBLE);
+                    mTouchInterceptor.setVisibility(View.VISIBLE);
+                    mTouchInterceptor.setOnClickListener(v -> {
+                        if (itemOnClickListener != null) {
+                            itemOnClickListener.onClick(item);
+                        }
+                    });
+                    mReducedTouchInterceptor.setVisibility(View.GONE);
+                    mActionContainerTouchInterceptor.setVisibility(View.GONE);
+                    break;
+                case ICON:
+                    mSupplementalIcon.setVisibility(View.VISIBLE);
+                    mSupplementalIcon.setImageDrawable(item.getSupplementalIcon());
+                    mActionContainer.setVisibility(View.VISIBLE);
+
+                    // If the icon has a click listener, use a reduced touch interceptor to create
+                    // two distinct touch area; the action container and the remainder of the list
+                    // item. Each touch area will have its own ripple effect. If the icon has no
+                    // click listener, it shouldn't be clickable.
+                    if (item.getSupplementalIconOnClickListener() == null) {
+                        mTouchInterceptor.setVisibility(View.VISIBLE);
+                        mTouchInterceptor.setOnClickListener(v -> {
+                            if (itemOnClickListener != null) {
+                                itemOnClickListener.onClick(item);
+                            }
+                        });
+                        mReducedTouchInterceptor.setVisibility(View.GONE);
+                        mActionContainerTouchInterceptor.setVisibility(View.GONE);
+                    } else {
+                        mReducedTouchInterceptor.setVisibility(View.VISIBLE);
+                        mReducedTouchInterceptor.setOnClickListener(v -> {
+                            if (itemOnClickListener != null) {
+                                itemOnClickListener.onClick(item);
+                            }
+                        });
+                        mActionContainerTouchInterceptor.setVisibility(View.VISIBLE);
+                        mActionContainerTouchInterceptor.setOnClickListener(
+                                (container) -> {
+                                    if (item.getSupplementalIconOnClickListener() != null) {
+                                        item.getSupplementalIconOnClickListener().onClick(mIcon);
+                                    }
+                                    if (itemOnClickListener != null) {
+                                        itemOnClickListener.onClick(item);
+                                    }
+                                });
+                        mTouchInterceptor.setVisibility(View.GONE);
+                    }
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown secondary action type.");
+            }
+
+            itemView.setActivated(item.isActivated());
+            setEnabled(itemView, item.isEnabled());
+        }
+
+        void setEnabled(View view, boolean enabled) {
+            view.setEnabled(enabled);
+            if (view instanceof ViewGroup) {
+                ViewGroup group = (ViewGroup) view;
+
+                for (int i = 0; i < group.getChildCount(); i++) {
+                    setEnabled(group.getChildAt(i), enabled);
+                }
+            }
+        }
+
+        void bindCompoundButton(@NonNull CarUiContentListItem item,
+                @NonNull CompoundButton compoundButton,
+                @Nullable CarUiContentListItem.OnClickListener itemOnClickListener) {
+            compoundButton.setVisibility(View.VISIBLE);
+            compoundButton.setOnCheckedChangeListener(null);
+            compoundButton.setChecked(item.isChecked());
+            compoundButton.setOnCheckedChangeListener(
+                    (buttonView, isChecked) -> item.setChecked(isChecked));
+
+            // Clicks anywhere on the item should toggle the checkbox state. Use full touch
+            // interceptor.
+            mTouchInterceptor.setVisibility(View.VISIBLE);
+            mTouchInterceptor.setOnClickListener(v -> {
+                compoundButton.toggle();
+                if (itemOnClickListener != null) {
+                    itemOnClickListener.onClick(item);
+                }
+            });
+            mReducedTouchInterceptor.setVisibility(View.GONE);
+            mActionContainerTouchInterceptor.setVisibility(View.GONE);
+
+            mActionContainer.setVisibility(View.VISIBLE);
+            mActionContainer.setClickable(false);
+        }
+    }
+
+    /**
+     * Holds views of {@link CarUiHeaderListItem}.
+     */
+    static class HeaderViewHolder extends RecyclerView.ViewHolder {
+
+        private final TextView mTitle;
+        private final TextView mBody;
+
+        HeaderViewHolder(@NonNull View itemView) {
+            super(itemView);
+            mTitle = requireViewByRefId(itemView, R.id.title);
+            mBody = requireViewByRefId(itemView, R.id.body);
+        }
+
+        private void bind(@NonNull CarUiHeaderListItem item) {
+            mTitle.setText(item.getTitle());
+
+            CharSequence body = item.getBody();
+            if (!TextUtils.isEmpty(body)) {
+                mBody.setText(body);
+            } else {
+                mBody.setVisibility(View.GONE);
+            }
+        }
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRadioButtonListItem.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRadioButtonListItem.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRadioButtonListItem.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRadioButtonListItem.java
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRadioButtonListItemAdapter.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRadioButtonListItemAdapter.java
new file mode 100644
index 0000000..9485678
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRadioButtonListItemAdapter.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+
+import java.util.List;
+
+/**
+ * Adapter for {@link CarUiRecyclerView} to display {@link CarUiRadioButtonListItem}. This adapter
+ * allows for at most one item to be selected at a time.
+ *
+ * <ul>
+ * <li> Implements {@link CarUiRecyclerView.ItemCap} - defaults to unlimited item count.
+ * </ul>
+ */
+public class CarUiRadioButtonListItemAdapter extends CarUiListItemAdapter {
+
+    private int mSelectedIndex = -1;
+
+    public CarUiRadioButtonListItemAdapter(List<CarUiRadioButtonListItem> items) {
+        super(items);
+        for (int i = 0; i < items.size(); i++) {
+            CarUiRadioButtonListItem item = items.get(i);
+            if (item.isChecked() && mSelectedIndex >= 0) {
+                throw new IllegalStateException(
+                        "At most one item in a CarUiRadioButtonListItemAdapter can be checked");
+            }
+
+            if (item.isChecked()) {
+                mSelectedIndex = i;
+            }
+        }
+    }
+
+    @NonNull
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(
+            @NonNull ViewGroup parent, int viewType) {
+        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+
+        if (viewType == VIEW_TYPE_LIST_ITEM) {
+            return new RadioButtonListItemViewHolder(
+                    inflater.inflate(R.layout.car_ui_list_item, parent, false));
+        }
+        return super.onCreateViewHolder(parent, viewType);
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
+        if (holder.getItemViewType() == VIEW_TYPE_LIST_ITEM) {
+            if (!(holder instanceof RadioButtonListItemViewHolder)) {
+                throw new IllegalStateException("Incorrect view holder type for list item.");
+            }
+
+            CarUiListItem item = getItems().get(position);
+            if (!(item instanceof CarUiRadioButtonListItem)) {
+                throw new IllegalStateException(
+                        "Expected item to be bound to viewHolder to be instance of "
+                                + "CarUiRadioButtonListItem.");
+            }
+
+            RadioButtonListItemViewHolder actualHolder = ((RadioButtonListItemViewHolder) holder);
+            actualHolder.bind((CarUiRadioButtonListItem) item);
+            actualHolder.setOnCheckedChangeListener(isChecked -> {
+                if (isChecked && mSelectedIndex >= 0) {
+                    CarUiRadioButtonListItem previousSelectedItem =
+                            (CarUiRadioButtonListItem) getItems().get(mSelectedIndex);
+                    previousSelectedItem.setChecked(false);
+                    notifyItemChanged(mSelectedIndex);
+                }
+
+                if (isChecked) {
+                    mSelectedIndex = position;
+                    CarUiRadioButtonListItem currentSelectedItem =
+                            (CarUiRadioButtonListItem) getItems().get(mSelectedIndex);
+                    currentSelectedItem.setChecked(true);
+                    notifyItemChanged(mSelectedIndex);
+                }
+            });
+
+        } else {
+            super.onBindViewHolder(holder, position);
+        }
+    }
+
+    static class RadioButtonListItemViewHolder extends ListItemViewHolder {
+        /**
+         * Callback to be invoked when the checked state of a {@link RadioButtonListItemViewHolder}
+         * changed.
+         */
+        public interface OnCheckedChangeListener {
+            /**
+             * Called when the checked state of a {@link RadioButtonListItemViewHolder} has changed.
+             *
+             * @param isChecked new checked state of list item.
+             */
+            void onCheckedChanged(boolean isChecked);
+        }
+
+        @Nullable
+        private OnCheckedChangeListener mListener;
+
+        RadioButtonListItemViewHolder(@NonNull View itemView) {
+            super(itemView);
+        }
+
+        void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {
+            mListener = listener;
+        }
+
+        @Override
+        void bind(@NonNull CarUiContentListItem item) {
+            super.bind(item);
+            mRadioButton.setOnCheckedChangeListener(
+                    (buttonView, isChecked) -> {
+                        item.setChecked(isChecked);
+                        if (mListener != null) {
+                            mListener.onCheckedChanged(isChecked);
+                        }
+                    });
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRecyclerView.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRecyclerView.java
new file mode 100644
index 0000000..8f2cb7d
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRecyclerView.java
@@ -0,0 +1,545 @@
+/*
+ * 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.ui.recyclerview;
+
+import static com.android.car.ui.utils.CarUiUtils.findViewByRefId;
+import static com.android.car.ui.utils.RotaryConstants.ROTARY_HORIZONTALLY_SCROLLABLE;
+import static com.android.car.ui.utils.RotaryConstants.ROTARY_VERTICALLY_SCROLLABLE;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.car.drivingstate.CarUxRestrictions;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+import com.android.car.ui.recyclerview.decorations.grid.GridDividerItemDecoration;
+import com.android.car.ui.recyclerview.decorations.grid.GridOffsetItemDecoration;
+import com.android.car.ui.recyclerview.decorations.linear.LinearDividerItemDecoration;
+import com.android.car.ui.recyclerview.decorations.linear.LinearOffsetItemDecoration;
+import com.android.car.ui.recyclerview.decorations.linear.LinearOffsetItemDecoration.OffsetPosition;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.utils.CarUxRestrictionsUtil;
+
+import java.lang.annotation.Retention;
+import java.util.Objects;
+
+/**
+ * View that extends a {@link RecyclerView} and wraps itself into a {@link LinearLayout} which
+ * could potentially include a scrollbar that has page up and down arrows. Interaction with this
+ * view is similar to a {@code RecyclerView} as it takes the same adapter and the layout manager.
+ */
+public final class CarUiRecyclerView extends RecyclerView implements
+        Toolbar.OnHeightChangedListener {
+
+    private static final String TAG = "CarUiRecyclerView";
+
+    private final CarUxRestrictionsUtil.OnUxRestrictionsChangedListener mListener =
+            new UxRestrictionChangedListener();
+
+    @NonNull
+    private final CarUxRestrictionsUtil mCarUxRestrictionsUtil;
+    private boolean mScrollBarEnabled;
+    @Nullable
+    private String mScrollBarClass;
+    private int mScrollBarPaddingTop;
+    private int mScrollBarPaddingBottom;
+    private boolean mHasScrolledToTop = false;
+
+    @Nullable
+    private ScrollBar mScrollBar;
+    private int mInitialTopPadding;
+
+    @Nullable
+    private GridOffsetItemDecoration mOffsetItemDecoration;
+    @NonNull
+    private GridDividerItemDecoration mDividerItemDecorationGrid;
+    @NonNull
+    private RecyclerView.ItemDecoration mDividerItemDecorationLinear;
+    private int mNumOfColumns;
+    private boolean mInstallingExtScrollBar = false;
+    private int mContainerVisibility = View.VISIBLE;
+    @Nullable
+    private Rect mContainerPadding;
+    @Nullable
+    private Rect mContainerPaddingRelative;
+    @Nullable
+    private LinearLayout mContainer;
+
+
+    /**
+     * The possible values for setScrollBarPosition. The default value is actually {@link
+     * CarUiRecyclerViewLayout#LINEAR}.
+     */
+    @IntDef({
+            CarUiRecyclerViewLayout.LINEAR,
+            CarUiRecyclerViewLayout.GRID,
+    })
+    @Retention(SOURCE)
+    public @interface CarUiRecyclerViewLayout {
+        /**
+         * Arranges items either horizontally in a single row or vertically in a single column.
+         * This is default.
+         */
+        int LINEAR = 0;
+
+        /** Arranges items in a Grid. */
+        int GRID = 2;
+    }
+
+    /**
+     * Interface for a {@link RecyclerView.Adapter} to cap the number of items.
+     *
+     * <p>NOTE: it is still up to the adapter to use maxItems in {@link
+     * RecyclerView.Adapter#getItemCount()}.
+     *
+     * <p>the recommended way would be with:
+     *
+     * <pre>{@code
+     * {@literal@}Override
+     * public int getItemCount() {
+     *   return Math.min(super.getItemCount(), mMaxItems);
+     * }
+     * }</pre>
+     */
+    public interface ItemCap {
+
+        /**
+         * A value to pass to {@link #setMaxItems(int)} that indicates there should be no limit.
+         */
+        int UNLIMITED = -1;
+
+        /**
+         * Sets the maximum number of items available in the adapter. A value less than '0' means
+         * the
+         * list should not be capped.
+         */
+        void setMaxItems(int maxItems);
+    }
+
+    public CarUiRecyclerView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CarUiRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, R.attr.carUiRecyclerViewStyle);
+    }
+
+    public CarUiRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs,
+            int defStyle) {
+        super(context, attrs, defStyle);
+        mCarUxRestrictionsUtil = CarUxRestrictionsUtil.getInstance(context);
+        init(context, attrs, defStyle);
+    }
+
+    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
+        initRotaryScroll(context, attrs, defStyleAttr);
+        setClipToPadding(false);
+        TypedArray a = context.obtainStyledAttributes(
+                attrs,
+                R.styleable.CarUiRecyclerView,
+                defStyleAttr,
+                R.style.Widget_CarUi_CarUiRecyclerView);
+
+        mScrollBarEnabled = context.getResources().getBoolean(R.bool.car_ui_scrollbar_enable);
+
+        mScrollBarPaddingTop = context.getResources()
+                .getDimensionPixelSize(R.dimen.car_ui_scrollbar_padding_top);
+        mScrollBarPaddingBottom = context.getResources()
+                .getDimensionPixelSize(R.dimen.car_ui_scrollbar_padding_bottom);
+
+        @CarUiRecyclerViewLayout int carUiRecyclerViewLayout =
+                a.getInt(R.styleable.CarUiRecyclerView_layoutStyle, CarUiRecyclerViewLayout.LINEAR);
+        mNumOfColumns = a.getInt(R.styleable.CarUiRecyclerView_numOfColumns, /* defValue= */ 2);
+        boolean enableDivider =
+                a.getBoolean(R.styleable.CarUiRecyclerView_enableDivider, /* defValue= */ false);
+
+        mDividerItemDecorationLinear = new LinearDividerItemDecoration(
+                context.getDrawable(R.drawable.car_ui_recyclerview_divider));
+
+        mDividerItemDecorationGrid =
+                new GridDividerItemDecoration(
+                        context.getDrawable(R.drawable.car_ui_divider),
+                        context.getDrawable(R.drawable.car_ui_divider),
+                        mNumOfColumns);
+
+        int topOffset = a.getInteger(R.styleable.CarUiRecyclerView_topOffset, /* defValue= */0);
+        int bottomOffset = a.getInteger(
+                R.styleable.CarUiRecyclerView_bottomOffset, /* defValue= */0);
+        if (carUiRecyclerViewLayout == CarUiRecyclerViewLayout.LINEAR) {
+
+            if (enableDivider) {
+                addItemDecoration(mDividerItemDecorationLinear);
+            }
+            RecyclerView.ItemDecoration topOffsetItemDecoration =
+                    new LinearOffsetItemDecoration(topOffset, OffsetPosition.START);
+
+            RecyclerView.ItemDecoration bottomOffsetItemDecoration =
+                    new LinearOffsetItemDecoration(bottomOffset, OffsetPosition.END);
+
+            addItemDecoration(topOffsetItemDecoration);
+            addItemDecoration(bottomOffsetItemDecoration);
+            setLayoutManager(new LinearLayoutManager(getContext()));
+        } else {
+
+            if (enableDivider) {
+                addItemDecoration(mDividerItemDecorationGrid);
+            }
+
+            mOffsetItemDecoration =
+                    new GridOffsetItemDecoration(topOffset, mNumOfColumns,
+                            OffsetPosition.START);
+
+            GridOffsetItemDecoration bottomOffsetItemDecoration =
+                    new GridOffsetItemDecoration(bottomOffset, mNumOfColumns,
+                            OffsetPosition.END);
+
+            addItemDecoration(mOffsetItemDecoration);
+            addItemDecoration(bottomOffsetItemDecoration);
+            setLayoutManager(new GridLayoutManager(getContext(), mNumOfColumns));
+            setNumOfColumns(mNumOfColumns);
+        }
+
+        a.recycle();
+        if (!mScrollBarEnabled) {
+            return;
+        }
+
+        setVerticalScrollBarEnabled(false);
+        setHorizontalScrollBarEnabled(false);
+
+        mScrollBarClass = context.getResources().getString(R.string.car_ui_scrollbar_component);
+        this.getViewTreeObserver()
+                .addOnGlobalLayoutListener(() -> {
+                    if (!mHasScrolledToTop && getLayoutManager() != null) {
+                        // Scroll to the top after the first global layout, so that
+                        // we can set padding for the insets and still have the
+                        // recyclerview start at the top.
+                        new Handler(Objects.requireNonNull(Looper.myLooper())).post(() ->
+                                getLayoutManager().scrollToPosition(0));
+                        mHasScrolledToTop = true;
+                    }
+
+                    if (mInitialTopPadding == 0) {
+                        mInitialTopPadding = getPaddingTop();
+                    }
+                });
+    }
+
+    /**
+     * If this view's content description isn't set to opt out of scrolling via the rotary
+     * controller, initialize it accordingly.
+     */
+    private void initRotaryScroll(Context context, AttributeSet attrs, int defStyleAttr) {
+        CharSequence contentDescription = getContentDescription();
+        if (contentDescription == null) {
+            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView,
+                    defStyleAttr, /* defStyleRes= */ 0);
+            int orientation = a.getInt(R.styleable.RecyclerView_android_orientation,
+                    LinearLayout.VERTICAL);
+            setContentDescription(
+                    orientation == LinearLayout.HORIZONTAL
+                            ? ROTARY_HORIZONTALLY_SCROLLABLE
+                            : ROTARY_VERTICALLY_SCROLLABLE);
+        } else if (!ROTARY_HORIZONTALLY_SCROLLABLE.contentEquals(contentDescription)
+                && !ROTARY_VERTICALLY_SCROLLABLE.contentEquals(contentDescription)) {
+            return;
+        }
+
+        // Convert SOURCE_ROTARY_ENCODER scroll events into SOURCE_MOUSE scroll events that
+        // RecyclerView knows how to handle.
+        setOnGenericMotionListener((v, event) -> {
+            if (event.getAction() == MotionEvent.ACTION_SCROLL) {
+                if (event.getSource() == InputDevice.SOURCE_ROTARY_ENCODER) {
+                    MotionEvent mouseEvent = MotionEvent.obtain(event);
+                    mouseEvent.setSource(InputDevice.SOURCE_MOUSE);
+                    CarUiRecyclerView.super.onGenericMotionEvent(mouseEvent);
+                    return true;
+                }
+            }
+            return false;
+        });
+
+        // Mark this view as focusable. This view will be focused when no focusable elements are
+        // visible.
+        setFocusable(true);
+
+        // Focus this view before descendants so that the RotaryService can focus this view when it
+        // wants to.
+        setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+
+        // Disable the default focus highlight. No highlight should appear when this view is
+        // focused.
+        setDefaultFocusHighlightEnabled(false);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        super.onRestoreInstanceState(state);
+
+        // If we're restoring an existing RecyclerView, we don't want
+        // to do the initial scroll to top
+        mHasScrolledToTop = true;
+    }
+
+    @Override
+    public void requestLayout() {
+        super.requestLayout();
+        if (mScrollBar != null) {
+            mScrollBar.requestLayout();
+        }
+    }
+
+    @Override
+    public void onHeightChanged(int height) {
+        setPaddingRelative(getPaddingStart(), mInitialTopPadding + height,
+                getPaddingEnd(), getPaddingBottom());
+    }
+
+    /**
+     * Sets the number of columns in which grid needs to be divided.
+     */
+    public void setNumOfColumns(int numberOfColumns) {
+        mNumOfColumns = numberOfColumns;
+        if (mOffsetItemDecoration != null) {
+            mOffsetItemDecoration.setNumOfColumns(mNumOfColumns);
+        }
+        if (mDividerItemDecorationGrid != null) {
+            mDividerItemDecorationGrid.setNumOfColumns(mNumOfColumns);
+        }
+    }
+
+    @Override
+    public void setVisibility(int visibility) {
+        super.setVisibility(visibility);
+        mContainerVisibility = visibility;
+        if (mContainer != null) {
+            mContainer.setVisibility(visibility);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mCarUxRestrictionsUtil.register(mListener);
+        if (mInstallingExtScrollBar || !mScrollBarEnabled) {
+            return;
+        }
+        // When CarUiRV is detached from the current parent and attached to the container with
+        // the scrollBar, onAttachedToWindow() will get called immediately when attaching the
+        // CarUiRV to the container. This flag will help us keep track of this state and avoid
+        // recursion. We also want to reset the state of this flag as soon as the container is
+        // successfully attached to the CarUiRV's original parent.
+        mInstallingExtScrollBar = true;
+        installExternalScrollBar();
+        mInstallingExtScrollBar = false;
+    }
+
+    /**
+     * This method will detach the current recycler view from its parent and attach it to the
+     * container which is a LinearLayout. Later the entire container is attached to the
+     * parent where the recycler view was set with the same layout params.
+     */
+    private void installExternalScrollBar() {
+        mContainer = new LinearLayout(getContext());
+        LayoutInflater inflater = LayoutInflater.from(getContext());
+        inflater.inflate(R.layout.car_ui_recycler_view, mContainer, true);
+        mContainer.setVisibility(mContainerVisibility);
+
+        if (mContainerPadding != null) {
+            mContainer.setPadding(mContainerPadding.left, mContainerPadding.top,
+                    mContainerPadding.right, mContainerPadding.bottom);
+        } else if (mContainerPaddingRelative != null) {
+            mContainer.setPaddingRelative(mContainerPaddingRelative.left,
+                    mContainerPaddingRelative.top, mContainerPaddingRelative.right,
+                    mContainerPaddingRelative.bottom);
+        } else {
+            mContainer.setPadding(getPaddingLeft(), /* top= */ 0,
+                    getPaddingRight(), /* bottom= */ 0);
+            setPadding(/* left= */ 0, getPaddingTop(),
+                    /* right= */ 0, getPaddingBottom());
+        }
+
+        mContainer.setLayoutParams(getLayoutParams());
+        ViewGroup parent = (ViewGroup) getParent();
+        int index = parent.indexOfChild(this);
+        parent.removeViewInLayout(this);
+
+        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        ((CarUiRecyclerViewContainer) Objects.requireNonNull(
+                findViewByRefId(mContainer, R.id.car_ui_recycler_view)))
+                .addRecyclerView(this, params);
+        parent.addView(mContainer, index);
+
+        createScrollBarFromConfig(findViewByRefId(mContainer, R.id.car_ui_scroll_bar));
+    }
+
+    private void createScrollBarFromConfig(View scrollView) {
+        Class<?> cls;
+        try {
+            cls = !TextUtils.isEmpty(mScrollBarClass)
+                    ? getContext().getClassLoader().loadClass(mScrollBarClass)
+                    : DefaultScrollBar.class;
+        } catch (Throwable t) {
+            throw andLog("Error loading scroll bar component: " + mScrollBarClass, t);
+        }
+        try {
+            mScrollBar = (ScrollBar) cls.getDeclaredConstructor().newInstance();
+        } catch (Throwable t) {
+            throw andLog("Error creating scroll bar component: " + mScrollBarClass, t);
+        }
+
+        mScrollBar.initialize(this, scrollView);
+
+        setScrollBarPadding(mScrollBarPaddingTop, mScrollBarPaddingBottom);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mCarUxRestrictionsUtil.unregister(mListener);
+    }
+
+    @Override
+    public void setPadding(int left, int top, int right, int bottom) {
+        mContainerPaddingRelative = null;
+        if (mScrollBarEnabled) {
+            super.setPadding(0, top, 0, bottom);
+            mContainerPadding = new Rect(left, 0, right, 0);
+            if (mContainer != null) {
+                mContainer.setPadding(left, 0, right, 0);
+            }
+            setScrollBarPadding(mScrollBarPaddingTop, mScrollBarPaddingBottom);
+        } else {
+            super.setPadding(left, top, right, bottom);
+        }
+    }
+
+    @Override
+    public void setPaddingRelative(int start, int top, int end, int bottom) {
+        mContainerPadding = null;
+        if (mScrollBarEnabled) {
+            super.setPaddingRelative(0, top, 0, bottom);
+            mContainerPaddingRelative = new Rect(start, 0, end, 0);
+            if (mContainer != null) {
+                mContainer.setPaddingRelative(start, 0, end, 0);
+            }
+            setScrollBarPadding(mScrollBarPaddingTop, mScrollBarPaddingBottom);
+        } else {
+            super.setPaddingRelative(start, top, end, bottom);
+        }
+    }
+
+    /**
+     * Sets the scrollbar's padding top and bottom.
+     * This padding is applied in addition to the padding of the RecyclerView.
+     */
+    public void setScrollBarPadding(int paddingTop, int paddingBottom) {
+        if (mScrollBarEnabled) {
+            mScrollBarPaddingTop = paddingTop;
+            mScrollBarPaddingBottom = paddingBottom;
+
+            if (mScrollBar != null) {
+                mScrollBar.setPadding(paddingTop + getPaddingTop(),
+                        paddingBottom + getPaddingBottom());
+            }
+        }
+    }
+
+    /**
+     * Sets divider item decoration for linear layout.
+     */
+    public void setLinearDividerItemDecoration(boolean enableDividers) {
+        if (enableDividers) {
+            addItemDecoration(mDividerItemDecorationLinear);
+            return;
+        }
+        removeItemDecoration(mDividerItemDecorationLinear);
+    }
+
+    /**
+     * Sets divider item decoration for grid layout.
+     */
+    public void setGridDividerItemDecoration(boolean enableDividers) {
+        if (enableDividers) {
+            addItemDecoration(mDividerItemDecorationGrid);
+            return;
+        }
+        removeItemDecoration(mDividerItemDecorationGrid);
+    }
+
+    private static RuntimeException andLog(String msg, Throwable t) {
+        Log.e(TAG, msg, t);
+        throw new RuntimeException(msg, t);
+    }
+
+    private class UxRestrictionChangedListener implements
+            CarUxRestrictionsUtil.OnUxRestrictionsChangedListener {
+
+        @Override
+        public void onRestrictionsChanged(@NonNull CarUxRestrictions carUxRestrictions) {
+            Adapter<?> adapter = getAdapter();
+            // If the adapter does not implement ItemCap, then the max items on it cannot be
+            // updated.
+            if (!(adapter instanceof ItemCap)) {
+                return;
+            }
+
+            int maxItems = ItemCap.UNLIMITED;
+            if ((carUxRestrictions.getActiveRestrictions()
+                    & CarUxRestrictions.UX_RESTRICTIONS_LIMIT_CONTENT)
+                    != 0) {
+                maxItems = carUxRestrictions.getMaxCumulativeContentItems();
+            }
+
+            int originalCount = adapter.getItemCount();
+            ((ItemCap) adapter).setMaxItems(maxItems);
+            int newCount = adapter.getItemCount();
+
+            if (newCount == originalCount) {
+                return;
+            }
+
+            if (newCount < originalCount) {
+                adapter.notifyItemRangeRemoved(newCount, originalCount - newCount);
+            } else {
+                adapter.notifyItemRangeInserted(originalCount, newCount - originalCount);
+            }
+        }
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerViewAdapter.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRecyclerViewAdapter.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerViewAdapter.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRecyclerViewAdapter.java
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerViewContainer.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRecyclerViewContainer.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiRecyclerViewContainer.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/CarUiRecyclerViewContainer.java
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiSmoothScroller.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiSmoothScroller.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/CarUiSmoothScroller.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/CarUiSmoothScroller.java
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiSnapHelper.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiSnapHelper.java
new file mode 100644
index 0000000..136dc6e
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiSnapHelper.java
@@ -0,0 +1,425 @@
+/*
+ * 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.ui.recyclerview;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearSnapHelper;
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.LayoutManager;
+
+import java.util.Objects;
+
+/**
+ * Inspired by {@link androidx.car.widget.PagedSnapHelper}
+ *
+ * <p>Extension of a {@link LinearSnapHelper} that will snap to the start of the target child view
+ * to the start of the attached {@link RecyclerView}. The start of the view is defined as the top if
+ * the RecyclerView is scrolling vertically; it is defined as the left (or right if RTL) if the
+ * RecyclerView is scrolling horizontally.
+ */
+public class CarUiSnapHelper extends LinearSnapHelper {
+    /**
+     * The percentage of a View that needs to be completely visible for it to be a viable snap
+     * target.
+     */
+    private static final float VIEW_VISIBLE_THRESHOLD = 0.5f;
+
+    /**
+     * When a View is longer than containing RecyclerView, the percentage of the end of this View
+     * that needs to be completely visible to prevent the rest of views to be a viable snap target.
+     *
+     * <p>In other words, if a longer-than-screen View takes more than threshold screen space on its
+     * end, do not snap to any View.
+     */
+    private static final float LONG_ITEM_END_VISIBLE_THRESHOLD = 0.3f;
+
+    private final Context mContext;
+    private RecyclerView mRecyclerView;
+
+    public CarUiSnapHelper(Context context) {
+        mContext = context;
+    }
+
+    // Orientation helpers are lazily created per LayoutManager.
+    @Nullable
+    private OrientationHelper mVerticalHelper;
+    @Nullable
+    private OrientationHelper mHorizontalHelper;
+
+    @Override
+    public int[] calculateDistanceToFinalSnap(
+            @NonNull LayoutManager layoutManager, @NonNull View targetView) {
+        int[] out = new int[2];
+
+        // Don't snap when not in touch mode, i.e. when using rotary.
+        if (!mRecyclerView.isInTouchMode()) {
+            return out;
+        }
+
+        if (layoutManager.canScrollHorizontally()) {
+            out[0] = distanceToTopMargin(targetView, getHorizontalHelper(layoutManager));
+        }
+
+        if (layoutManager.canScrollVertically()) {
+            out[1] = distanceToTopMargin(targetView, getVerticalHelper(layoutManager));
+        }
+
+        return out;
+    }
+
+    /**
+     * Finds the view to snap to. The view to snap to is the child of the LayoutManager that is
+     * closest to the start of the RecyclerView. The "start" depends on if the LayoutManager
+     * is scrolling horizontally or vertically. If it is horizontally scrolling, then the
+     * start is the view on the left (right if RTL). Otherwise, it is the top-most view.
+     *
+     * @param layoutManager The current {@link LayoutManager} for the attached RecyclerView.
+     * @return The View closest to the start of the RecyclerView. Returns {@code null}when:
+     * <ul>
+     *     <li>there is no item; or
+     *     <li>no visible item can fully fit in the containing RecyclerView; or
+     *     <li>an item longer than containing RecyclerView is about to scroll out.
+     * </ul>
+     */
+    @Override
+    @Nullable
+    public View findSnapView(LayoutManager layoutManager) {
+        int childCount = layoutManager.getChildCount();
+        if (childCount == 0) {
+            return null;
+        }
+
+        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
+
+        // If there's only one child, then that will be the snap target.
+        if (childCount == 1) {
+            View firstChild = layoutManager.getChildAt(0);
+            return isValidSnapView(firstChild, orientationHelper) ? firstChild : null;
+        }
+
+        if (mRecyclerView == null) {
+            return null;
+        }
+
+        // If the top child view is longer than the RecyclerView (long item), and it's not yet
+        // scrolled out - meaning the screen it takes up is more than threshold,
+        // do not snap to any view.
+        // This way avoids next View snapping to top "pushes" out the end of a long item.
+        View firstChild = mRecyclerView.getChildAt(0);
+        if (firstChild.getHeight() > mRecyclerView.getHeight()
+                // Long item start is scrolled past screen;
+                && orientationHelper.getDecoratedStart(firstChild) < 0
+                // and it takes up more than threshold screen size.
+                && orientationHelper.getDecoratedEnd(firstChild) > (
+                mRecyclerView.getHeight() * LONG_ITEM_END_VISIBLE_THRESHOLD)) {
+            return null;
+        }
+
+        @NonNull View lastVisibleChild = Objects.requireNonNull(
+                layoutManager.getChildAt(childCount - 1));
+
+        // Check if the last child visible is the last item in the list.
+        boolean lastItemVisible =
+                layoutManager.getPosition(lastVisibleChild) == layoutManager.getItemCount() - 1;
+
+        // If it is, then check how much of that view is visible.
+        float lastItemPercentageVisible = lastItemVisible
+                ? getPercentageVisible(lastVisibleChild, orientationHelper) : 0;
+
+        View closestChild = null;
+        int closestDistanceToStart = Integer.MAX_VALUE;
+        float closestPercentageVisible = 0.f;
+
+        // Iterate to find the child closest to the top and more than half way visible.
+        for (int i = 0; i < childCount; i++) {
+            View child = layoutManager.getChildAt(i);
+            int startOffset = orientationHelper.getDecoratedStart(child);
+
+            if (Math.abs(startOffset) < closestDistanceToStart) {
+                float percentageVisible = getPercentageVisible(child, orientationHelper);
+
+                if (percentageVisible > VIEW_VISIBLE_THRESHOLD
+                        && percentageVisible > closestPercentageVisible) {
+                    closestDistanceToStart = startOffset;
+                    closestChild = child;
+                    closestPercentageVisible = percentageVisible;
+                }
+            }
+        }
+
+        View childToReturn = closestChild;
+
+        // If closestChild is null, then that means we were unable to find a closest child that
+        // is over the VIEW_VISIBLE_THRESHOLD. This could happen if the views are larger than
+        // the given area. In this case, consider returning the lastVisibleChild so that the screen
+        // scrolls. Also, check if the last item should be displayed anyway if it is mostly visible.
+        if ((childToReturn == null
+                || (lastItemVisible && lastItemPercentageVisible > closestPercentageVisible))) {
+            childToReturn = lastVisibleChild;
+        }
+
+        // Return null if the childToReturn is not valid. This allows the user to scroll freely
+        // with no snapping. This can allow them to see the entire view.
+        return isValidSnapView(childToReturn, orientationHelper) ? childToReturn : null;
+    }
+
+    private static int distanceToTopMargin(@NonNull View targetView, OrientationHelper helper) {
+        final int childTop = helper.getDecoratedStart(targetView);
+        final int containerTop = helper.getStartAfterPadding();
+        return childTop - containerTop;
+    }
+
+    /**
+     * Finds the view to snap to. The view to snap to is the child of the LayoutManager that is
+     * closest to the start of the RecyclerView. The "start" depends on if the LayoutManager is
+     * scrolling horizontally or vertically. If it is horizontally scrolling, then the start is the
+     * view on the left (right if RTL). Otherwise, it is the top-most view.
+     *
+     * @param layoutManager The current {@link RecyclerView.LayoutManager} for the attached
+     *                      RecyclerView.
+     * @return The View closest to the start of the RecyclerView.
+     */
+    private static View findTopView(LayoutManager layoutManager, OrientationHelper helper) {
+        int childCount = layoutManager.getChildCount();
+        if (childCount == 0) {
+            return null;
+        }
+
+        View closestChild = null;
+        int absClosest = Integer.MAX_VALUE;
+
+        for (int i = 0; i < childCount; i++) {
+            View child = layoutManager.getChildAt(i);
+            if (child == null) {
+                continue;
+            }
+            int absDistance = Math.abs(distanceToTopMargin(child, helper));
+
+            /* if child top is closer than previous closest, set it as closest */
+            if (absDistance < absClosest) {
+                absClosest = absDistance;
+                closestChild = child;
+            }
+        }
+        return closestChild;
+    }
+
+    /**
+     * Returns whether or not the given View is a valid snapping view. A view is considered valid
+     * for snapping if it can fit entirely within the height of the RecyclerView it is contained
+     * within.
+     *
+     * <p>If the view is larger than the RecyclerView, then it might not want to be snapped to
+     * to allow the user to scroll and see the rest of the View.
+     *
+     * @param view   The view to determine the snapping potential.
+     * @param helper The {@link OrientationHelper} associated with the current RecyclerView.
+     * @return {@code true} if the given view is a valid snapping view; {@code false} otherwise.
+     */
+    private static boolean isValidSnapView(View view, OrientationHelper helper) {
+        return helper.getDecoratedMeasurement(view) <= helper.getTotalSpace();
+    }
+
+    /**
+     * Returns the percentage of the given view that is visible, relative to its containing
+     * RecyclerView.
+     *
+     * @param view   The View to get the percentage visible of.
+     * @param helper An {@link OrientationHelper} to aid with calculation.
+     * @return A float indicating the percentage of the given view that is visible.
+     */
+    private static float getPercentageVisible(View view, OrientationHelper helper) {
+        int start = helper.getStartAfterPadding();
+        int end = helper.getEndAfterPadding();
+
+        int viewStart = helper.getDecoratedStart(view);
+        int viewEnd = helper.getDecoratedEnd(view);
+
+        if (viewStart >= start && viewEnd <= end) {
+            // The view is within the bounds of the RecyclerView, so it's fully visible.
+            return 1.f;
+        } else if (viewEnd <= start) {
+            // The view is above the visible area of the RecyclerView.
+            return 0;
+        } else if (viewStart >= end) {
+            // The view is below the visible area of the RecyclerView.
+            return 0;
+        } else if (viewStart <= start && viewEnd >= end) {
+            // The view is larger than the height of the RecyclerView.
+            return ((float) end - start) / helper.getDecoratedMeasurement(view);
+        } else if (viewStart < start) {
+            // The view is above the start of the RecyclerView.
+            return ((float) viewEnd - start) / helper.getDecoratedMeasurement(view);
+        } else {
+            // The view is below the end of the RecyclerView.
+            return ((float) end - viewStart) / helper.getDecoratedMeasurement(view);
+        }
+    }
+
+    @Override
+    public void attachToRecyclerView(@Nullable RecyclerView recyclerView) {
+        super.attachToRecyclerView(recyclerView);
+        mRecyclerView = recyclerView;
+    }
+
+    /**
+     * Returns a scroller specific to this {@code PagedSnapHelper}. This scroller is used for all
+     * smooth scrolling operations, including flings.
+     *
+     * @param layoutManager The {@link LayoutManager} associated with the attached
+     *                      {@link RecyclerView}.
+     * @return a {@link RecyclerView.SmoothScroller} which will handle the scrolling.
+     */
+    @Override
+    protected RecyclerView.SmoothScroller createScroller(@NonNull LayoutManager layoutManager) {
+        return new CarUiSmoothScroller(mContext);
+    }
+
+    /**
+     * Calculate the estimated scroll distance in each direction given velocities on both axes.
+     * This method will clamp the maximum scroll distance so that a single fling will never scroll
+     * more than one page.
+     *
+     * @param velocityX Fling velocity on the horizontal axis.
+     * @param velocityY Fling velocity on the vertical axis.
+     * @return An array holding the calculated distances in x and y directions respectively.
+     */
+    @Override
+    public int[] calculateScrollDistance(int velocityX, int velocityY) {
+        int[] outDist = super.calculateScrollDistance(velocityX, velocityY);
+
+        if (mRecyclerView == null) {
+            return outDist;
+        }
+
+        LayoutManager layoutManager = mRecyclerView.getLayoutManager();
+        if (layoutManager == null || layoutManager.getChildCount() == 0) {
+            return outDist;
+        }
+
+        int lastChildPosition = isAtEnd(layoutManager) ? 0 : layoutManager.getChildCount() - 1;
+
+        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
+        @NonNull View lastChild = Objects.requireNonNull(
+                layoutManager.getChildAt(lastChildPosition));
+        float percentageVisible = getPercentageVisible(lastChild, orientationHelper);
+
+        int maxDistance = layoutManager.getHeight();
+        if (percentageVisible > 0.f) {
+            // The max and min distance is the total height of the RecyclerView minus the height of
+            // the last child. This ensures that each scroll will never scroll more than a single
+            // page on the RecyclerView. That is, the max scroll will make the last child the
+            // first child and vice versa when scrolling the opposite way.
+            maxDistance -= layoutManager.getDecoratedMeasuredHeight(lastChild);
+        }
+
+        int minDistance = -maxDistance;
+
+        outDist[0] = clamp(outDist[0], minDistance, maxDistance);
+        outDist[1] = clamp(outDist[1], minDistance, maxDistance);
+
+        return outDist;
+    }
+
+    /**
+     * Returns {@code true} if the RecyclerView is completely displaying the first item.
+     */
+    public boolean isAtStart(@Nullable LayoutManager layoutManager) {
+        if (layoutManager == null || layoutManager.getChildCount() == 0) {
+            return true;
+        }
+
+        @NonNull View firstChild = Objects.requireNonNull(layoutManager.getChildAt(0));
+        OrientationHelper orientationHelper =
+                layoutManager.canScrollVertically() ? getVerticalHelper(layoutManager)
+                        : getHorizontalHelper(layoutManager);
+
+        // Check that the first child is completely visible and is the first item in the list.
+        return orientationHelper.getDecoratedStart(firstChild)
+                >= orientationHelper.getStartAfterPadding() && layoutManager.getPosition(firstChild)
+                == 0;
+    }
+
+    /**
+     * Returns {@code true} if the RecyclerView is completely displaying the last item.
+     */
+    public boolean isAtEnd(@Nullable LayoutManager layoutManager) {
+        if (layoutManager == null || layoutManager.getChildCount() == 0) {
+            return true;
+        }
+
+        int childCount = layoutManager.getChildCount();
+        OrientationHelper orientationHelper =
+                layoutManager.canScrollVertically() ? getVerticalHelper(layoutManager)
+                        : getHorizontalHelper(layoutManager);
+
+        @NonNull View lastVisibleChild = Objects.requireNonNull(
+                layoutManager.getChildAt(childCount - 1));
+
+        // The list has reached the bottom if the last child that is visible is the last item
+        // in the list and it's fully shown.
+        return layoutManager.getPosition(lastVisibleChild) == (layoutManager.getItemCount() - 1)
+                && layoutManager.getDecoratedBottom(lastVisibleChild)
+                <= orientationHelper.getEndAfterPadding();
+    }
+
+    /**
+     * Returns an {@link OrientationHelper} that corresponds to the current scroll direction of the
+     * given {@link LayoutManager}.
+     */
+    @NonNull
+    private OrientationHelper getOrientationHelper(@NonNull LayoutManager layoutManager) {
+        return layoutManager.canScrollVertically()
+                ? getVerticalHelper(layoutManager)
+                : getHorizontalHelper(layoutManager);
+    }
+
+    @NonNull
+    private OrientationHelper getVerticalHelper(@NonNull LayoutManager layoutManager) {
+        if (mVerticalHelper == null || mVerticalHelper.getLayoutManager() != layoutManager) {
+            mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
+        }
+        return mVerticalHelper;
+    }
+
+    @NonNull
+    private OrientationHelper getHorizontalHelper(@NonNull LayoutManager layoutManager) {
+        if (mHorizontalHelper == null || mHorizontalHelper.getLayoutManager() != layoutManager) {
+            mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
+        }
+        return mHorizontalHelper;
+    }
+
+    /**
+     * Ensures that the given value falls between the range given by the min and max values. This
+     * method does not check that the min value is greater than or equal to the max value. If the
+     * parameters are not well-formed, this method's behavior is undefined.
+     *
+     * @param value The value to clamp.
+     * @param min   The minimum value the given value can be.
+     * @param max   The maximum value the given value can be.
+     * @return A number that falls between {@code min} or {@code max} or one of those values if the
+     * given value is less than or greater than {@code min} and {@code max} respectively.
+     */
+    private static int clamp(int value, int min, int max) {
+        return Math.max(min, Math.min(max, value));
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/DefaultScrollBar.java b/car-ui-lib/src/com/android/car/ui/recyclerview/DefaultScrollBar.java
new file mode 100644
index 0000000..a643f6d
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/DefaultScrollBar.java
@@ -0,0 +1,418 @@
+/*
+ * 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.ui.recyclerview;
+
+import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
+
+import android.content.res.Resources;
+import android.os.Handler;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+
+/**
+ * The default scroll bar widget for the {@link CarUiRecyclerView}.
+ *
+ * <p>Inspired by {@link androidx.car.widget.PagedListView}. Most pagination and scrolling logic has
+ * been ported from the PLV with minor updates.
+ */
+class DefaultScrollBar implements ScrollBar {
+
+    private float mButtonDisabledAlpha;
+    private CarUiSnapHelper mSnapHelper;
+
+    private View mScrollView;
+    private View mScrollTrack;
+    private View mScrollThumb;
+    private View mUpButton;
+    private View mDownButton;
+
+    private RecyclerView mRecyclerView;
+
+    private final Interpolator mPaginationInterpolator = new AccelerateDecelerateInterpolator();
+
+    private final Handler mHandler = new Handler();
+
+    private OrientationHelper mOrientationHelper;
+
+    @Override
+    public void initialize(RecyclerView rv, View scrollView) {
+        mRecyclerView = rv;
+
+        mScrollView = scrollView;
+
+        Resources res = rv.getContext().getResources();
+
+        mButtonDisabledAlpha = CarUiUtils.getFloat(res, R.dimen.car_ui_button_disabled_alpha);
+
+        getRecyclerView().addOnScrollListener(mRecyclerViewOnScrollListener);
+        getRecyclerView().getRecycledViewPool().setMaxRecycledViews(0, 12);
+
+        mUpButton = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_page_up);
+        View.OnClickListener paginateUpButtonOnClickListener = v -> pageUp();
+        mUpButton.setOnClickListener(paginateUpButtonOnClickListener);
+        mUpButton.setOnTouchListener(
+                new OnContinuousScrollListener(rv.getContext(), paginateUpButtonOnClickListener));
+
+        mDownButton = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_page_down);
+        View.OnClickListener paginateDownButtonOnClickListener = v -> pageDown();
+        mDownButton.setOnClickListener(paginateDownButtonOnClickListener);
+        mDownButton.setOnTouchListener(
+                new OnContinuousScrollListener(rv.getContext(), paginateDownButtonOnClickListener));
+
+        mScrollTrack = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_track);
+        mScrollThumb = requireViewByRefId(mScrollView, R.id.car_ui_scrollbar_thumb);
+
+        mSnapHelper = new CarUiSnapHelper(rv.getContext());
+        getRecyclerView().setOnFlingListener(null);
+        mSnapHelper.attachToRecyclerView(getRecyclerView());
+
+        // enables fast scrolling.
+        FastScroller fastScroller = new FastScroller(mRecyclerView, mScrollTrack, mScrollView);
+        fastScroller.enable();
+
+        mScrollView.setVisibility(View.INVISIBLE);
+        mScrollView.addOnLayoutChangeListener(
+                (View v,
+                        int left,
+                        int top,
+                        int right,
+                        int bottom,
+                        int oldLeft,
+                        int oldTop,
+                        int oldRight,
+                        int oldBottom) -> mHandler.post(this::updatePaginationButtons));
+    }
+
+    public RecyclerView getRecyclerView() {
+        return mRecyclerView;
+    }
+
+    @Override
+    public void requestLayout() {
+        mScrollView.requestLayout();
+    }
+
+    @Override
+    public void setPadding(int paddingStart, int paddingEnd) {
+        mScrollView.setPadding(mScrollView.getPaddingLeft(), paddingStart,
+                mScrollView.getPaddingRight(), paddingEnd);
+    }
+
+    /**
+     * Sets whether or not the up button on the scroll bar is clickable.
+     *
+     * @param enabled {@code true} if the up button is enabled.
+     */
+    private void setUpEnabled(boolean enabled) {
+        mUpButton.setEnabled(enabled);
+        mUpButton.setAlpha(enabled ? 1f : mButtonDisabledAlpha);
+    }
+
+    /**
+     * Sets whether or not the down button on the scroll bar is clickable.
+     *
+     * @param enabled {@code true} if the down button is enabled.
+     */
+    private void setDownEnabled(boolean enabled) {
+        mDownButton.setEnabled(enabled);
+        mDownButton.setAlpha(enabled ? 1f : mButtonDisabledAlpha);
+    }
+
+    /**
+     * Returns whether or not the down button on the scroll bar is clickable.
+     *
+     * @return {@code true} if the down button is enabled. {@code false} otherwise.
+     */
+    private boolean isDownEnabled() {
+        return mDownButton.isEnabled();
+    }
+
+    /**
+     * Sets the range, offset and extent of the scroll bar. The range represents the size of a
+     * container for the scrollbar thumb; offset is the distance from the start of the container to
+     * where the thumb should be; and finally, extent is the size of the thumb.
+     *
+     * <p>These values can be expressed in arbitrary units, so long as they share the same units.
+     * The
+     * values should also be positive.
+     *
+     * @param range  The range of the scrollbar's thumb
+     * @param offset The offset of the scrollbar's thumb
+     * @param extent The extent of the scrollbar's thumb
+     */
+    private void setParameters(
+            @IntRange(from = 0) int range,
+            @IntRange(from = 0) int offset,
+            @IntRange(from = 0) int extent) {
+        // Not laid out yet, so values cannot be calculated.
+        if (!mScrollView.isLaidOut()) {
+            return;
+        }
+
+        // If the scroll bars aren't visible, then no need to update.
+        if (mScrollView.getVisibility() == View.GONE || range == 0) {
+            return;
+        }
+
+        int thumbLength = calculateScrollThumbLength(range, extent);
+        int thumbOffset = calculateScrollThumbOffset(range, offset, thumbLength);
+
+        // Sets the size of the thumb and request a redraw if needed.
+        ViewGroup.LayoutParams lp = mScrollThumb.getLayoutParams();
+
+        if (lp.height != thumbLength) {
+            lp.height = thumbLength;
+            mScrollThumb.requestLayout();
+        }
+
+        moveY(mScrollThumb, thumbOffset);
+    }
+
+    /**
+     * Calculates and returns how big the scroll bar thumb should be based on the given range and
+     * extent.
+     *
+     * @param range  The total amount of space the scroll bar is allowed to roam over.
+     * @param extent The amount of space that the scroll bar takes up relative to the range.
+     * @return The height of the scroll bar thumb in pixels.
+     */
+    private int calculateScrollThumbLength(int range, int extent) {
+        // Scale the length by the available space that the thumb can fill.
+        return Math.round(((float) extent / range) * mScrollTrack.getHeight());
+    }
+
+    /**
+     * Calculates and returns how much the scroll thumb should be offset from the top of where it
+     * has
+     * been laid out.
+     *
+     * @param range       The total amount of space the scroll bar is allowed to roam over.
+     * @param offset      The amount the scroll bar should be offset, expressed in the same units as
+     *                    the
+     *                    given range.
+     * @param thumbLength The current length of the thumb in pixels.
+     * @return The amount the thumb should be offset in pixels.
+     */
+    private int calculateScrollThumbOffset(int range, int offset, int thumbLength) {
+        // Ensure that if the user has reached the bottom of the list, then the scroll bar is
+        // aligned to the bottom as well. Otherwise, scale the offset appropriately.
+        // This offset will be a value relative to the parent of this scrollbar, so start by where
+        // the top of scrollbar track is.
+        return mScrollTrack.getTop()
+                + (isDownEnabled()
+                ? Math.round(((float) offset / range) * mScrollTrack.getHeight())
+                : mScrollTrack.getHeight() - thumbLength);
+    }
+
+    /** Moves the given view to the specified 'y' position. */
+    private void moveY(final View view, float newPosition) {
+        view.animate()
+                .y(newPosition)
+                .setDuration(/* duration= */ 0)
+                .setInterpolator(mPaginationInterpolator)
+                .start();
+    }
+
+    private final RecyclerView.OnScrollListener mRecyclerViewOnScrollListener =
+            new RecyclerView.OnScrollListener() {
+                @Override
+                public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+                    updatePaginationButtons();
+                }
+            };
+
+    private OrientationHelper getOrientationHelper(RecyclerView.LayoutManager layoutManager) {
+        if (mOrientationHelper == null || mOrientationHelper.getLayoutManager() != layoutManager) {
+            // CarUiRecyclerView is assumed to be a list that always vertically scrolls.
+            mOrientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
+        }
+        return mOrientationHelper;
+    }
+
+    /**
+     * Scrolls the contents of the RecyclerView up a page. A page is defined as the height of the
+     * {@code CarUiRecyclerView}.
+     *
+     * <p>The resulting first item in the list will be snapped to so that it is completely visible.
+     * If
+     * this is not possible due to the first item being taller than the containing {@code
+     * CarUiRecyclerView}, then the snapping will not occur.
+     */
+    void pageUp() {
+        int currentOffset = getRecyclerView().computeVerticalScrollOffset();
+        if (getRecyclerView().getLayoutManager() == null
+                || getRecyclerView().getChildCount() == 0
+                || currentOffset == 0) {
+            return;
+        }
+
+        // Use OrientationHelper to calculate scroll distance in order to match snapping behavior.
+        OrientationHelper orientationHelper =
+                getOrientationHelper(getRecyclerView().getLayoutManager());
+        int screenSize = orientationHelper.getTotalSpace();
+        int scrollDistance = screenSize;
+        // The iteration order matters. In case where there are 2 items longer than screen size, we
+        // want to focus on upcoming view.
+        for (int i = 0; i < getRecyclerView().getChildCount(); i++) {
+            /*
+             * We treat child View longer than screen size differently:
+             * 1) When it enters screen, next pageUp will align its bottom with parent bottom;
+             * 2) When it leaves screen, next pageUp will align its top with parent top.
+             */
+            View child = getRecyclerView().getChildAt(i);
+            if (child.getHeight() > screenSize) {
+                if (orientationHelper.getDecoratedEnd(child) < screenSize) {
+                    // Child view bottom is entering screen. Align its bottom with parent bottom.
+                    scrollDistance = screenSize - orientationHelper.getDecoratedEnd(child);
+                } else if (-screenSize < orientationHelper.getDecoratedStart(child)
+                        && orientationHelper.getDecoratedStart(child) < 0) {
+                    // Child view top is about to enter screen - its distance to parent top
+                    // is less than a full scroll. Align child top with parent top.
+                    scrollDistance = Math.abs(orientationHelper.getDecoratedStart(child));
+                }
+                // There can be two items that are longer than the screen. We stop at the first one.
+                // This is affected by the iteration order.
+                break;
+            }
+        }
+        // Distance should always be positive. Negate its value to scroll up.
+        mRecyclerView.smoothScrollBy(0, -scrollDistance);
+    }
+
+    /**
+     * Scrolls the contents of the RecyclerView down a page. A page is defined as the height of the
+     * {@code CarUiRecyclerView}.
+     *
+     * <p>This method will attempt to bring the last item in the list as the first item. If the
+     * current first item in the list is taller than the {@code CarUiRecyclerView}, then it will be
+     * scrolled the length of a page, but not snapped to.
+     */
+    void pageDown() {
+        if (getRecyclerView().getLayoutManager() == null
+                || getRecyclerView().getChildCount() == 0) {
+            return;
+        }
+
+        OrientationHelper orientationHelper =
+                getOrientationHelper(getRecyclerView().getLayoutManager());
+        int screenSize = orientationHelper.getTotalSpace();
+        int scrollDistance = screenSize;
+
+        // If the last item is partially visible, page down should bring it to the top.
+        View lastChild = getRecyclerView().getChildAt(getRecyclerView().getChildCount() - 1);
+        if (getRecyclerView().getLayoutManager().isViewPartiallyVisible(lastChild,
+                /* completelyVisible= */ false, /* acceptEndPointInclusion= */ false)) {
+            scrollDistance = orientationHelper.getDecoratedStart(lastChild);
+            if (scrollDistance <= 0) {
+                // - Scroll value is zero if the top of last item is aligned with top of the screen;
+                // - Scroll value can be negative if the child is longer than the screen size and
+                //   the visible area of the screen does not show the start of the child.
+                // Scroll to the next screen in both cases.
+                scrollDistance = screenSize;
+            }
+        }
+
+        // The iteration order matters. In case where there are 2 items longer than screen size, we
+        // want to focus on upcoming view (the one at the bottom of screen).
+        for (int i = getRecyclerView().getChildCount() - 1; i >= 0; i--) {
+            /* We treat child View longer than screen size differently:
+             * 1) When it enters screen, next pageDown will align its top with parent top;
+             * 2) When it leaves screen, next pageDown will align its bottom with parent bottom.
+             */
+            View child = getRecyclerView().getChildAt(i);
+            if (child.getHeight() > screenSize) {
+                if (orientationHelper.getDecoratedStart(child) > 0) {
+                    // Child view top is entering screen. Align its top with parent top.
+                    scrollDistance = orientationHelper.getDecoratedStart(child);
+                } else if (screenSize < orientationHelper.getDecoratedEnd(child)
+                        && orientationHelper.getDecoratedEnd(child) < 2 * screenSize) {
+                    // Child view bottom is about to enter screen - its distance to parent bottom
+                    // is less than a full scroll. Align child bottom with parent bottom.
+                    scrollDistance = orientationHelper.getDecoratedEnd(child) - screenSize;
+                }
+                // There can be two items that are longer than the screen. We stop at the first one.
+                // This is affected by the iteration order.
+                break;
+            }
+        }
+
+        mRecyclerView.smoothScrollBy(0, scrollDistance);
+    }
+
+    /**
+     * Determines if scrollbar should be visible or not and shows/hides it accordingly. If this is
+     * being called as a result of adapter changes, it should be called after the new layout has
+     * been
+     * calculated because the method of determining scrollbar visibility uses the current layout.
+     * If
+     * this is called after an adapter change but before the new layout, the visibility
+     * determination
+     * may not be correct.
+     */
+    private void updatePaginationButtons() {
+
+        boolean isAtStart = isAtStart();
+        boolean isAtEnd = isAtEnd();
+        RecyclerView.LayoutManager layoutManager = getRecyclerView().getLayoutManager();
+
+        // enable/disable the button before the view is shown. So there is no flicker.
+        setUpEnabled(!isAtStart);
+        setDownEnabled(!isAtEnd);
+        if ((isAtStart && isAtEnd) || layoutManager == null || layoutManager.getItemCount() == 0) {
+            mScrollView.setVisibility(View.INVISIBLE);
+        } else {
+            mScrollView.setVisibility(View.VISIBLE);
+        }
+
+        if (layoutManager == null) {
+            return;
+        }
+
+        if (layoutManager.canScrollVertically()) {
+            setParameters(
+                    getRecyclerView().computeVerticalScrollRange(),
+                    getRecyclerView().computeVerticalScrollOffset(),
+                    getRecyclerView().computeVerticalScrollExtent());
+        } else {
+            setParameters(
+                    getRecyclerView().computeHorizontalScrollRange(),
+                    getRecyclerView().computeHorizontalScrollOffset(),
+                    getRecyclerView().computeHorizontalScrollExtent());
+        }
+
+        mScrollView.invalidate();
+    }
+
+    /** Returns {@code true} if the RecyclerView is completely displaying the first item. */
+    boolean isAtStart() {
+        return mSnapHelper.isAtStart(getRecyclerView().getLayoutManager());
+    }
+
+    /** Returns {@code true} if the RecyclerView is completely displaying the last item. */
+    boolean isAtEnd() {
+        return mSnapHelper.isAtEnd(getRecyclerView().getLayoutManager());
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/FastScroller.java b/car-ui-lib/src/com/android/car/ui/recyclerview/FastScroller.java
new file mode 100644
index 0000000..9a44110
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/FastScroller.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
+
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+
+/**
+ * Class responsible for fast scrolling. This class offers two functionalities.
+ * <ul>
+ *     <li>User can hold the thumb and drag.</li>
+ *     <li>User can click anywhere on the track and thumb will scroll to that position.</li>
+ * </ul>
+ */
+class FastScroller implements View.OnTouchListener {
+
+    private float mTouchDownY = -1;
+
+    private View mScrollTrackView;
+    private boolean mIsDragging;
+    private View mScrollThumb;
+    private RecyclerView mRecyclerView;
+
+    FastScroller(@NonNull RecyclerView recyclerView, @NonNull View scrollTrackView,
+            @NonNull View scrollView) {
+        mRecyclerView = recyclerView;
+        mScrollTrackView = scrollTrackView;
+        mScrollThumb = requireViewByRefId(scrollView, R.id.car_ui_scrollbar_thumb);
+    }
+
+    void enable() {
+        if (mRecyclerView != null) {
+            mScrollTrackView.setOnTouchListener(this);
+        }
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent me) {
+        switch (me.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mTouchDownY = me.getY();
+                mIsDragging = false;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                mIsDragging = true;
+                float thumbBottom = mScrollThumb.getY() + mScrollThumb.getHeight();
+                // check if the move coordinates are within the bounds of the thumb. i.e user is
+                // holding and dragging the thumb.
+                if (!(me.getY() + mScrollTrackView.getY() < thumbBottom
+                        && me.getY() + mScrollTrackView.getY() > mScrollThumb.getY())) {
+                    // don't do anything if touch is detected outside the thumb
+                    return true;
+                }
+                // calculate where the center of the thumb is on the screen.
+                float thumbCenter = mScrollThumb.getY() + mScrollThumb.getHeight() / 2.0f;
+                // me.getY() returns the coordinates relative to the view. For example, if we
+                // click the top left of the scroll track the coordinates will be 0,0. Hence, we
+                // need to add the relative coordinates to the actual coordinates computed by the
+                // thumb center and add them to get the final Y coordinate. "(me.getY() -
+                // mTouchDownY)" calculates the distance that is moved from the previous touch
+                // event.
+                verticalScrollTo(thumbCenter + (me.getY() - mTouchDownY));
+                mTouchDownY = me.getY();
+                break;
+            case MotionEvent.ACTION_UP:
+            default:
+                mTouchDownY = -1;
+                // if not dragged then it's a click. When a click is detected on the track and
+                // within the range we want to move the center of the thumb to the Y coordinate
+                // of the clicked position.
+                if (!mIsDragging) {
+                    verticalScrollTo(me.getY() + mScrollTrackView.getY());
+                }
+        }
+        return true;
+    }
+
+    private void verticalScrollTo(float y) {
+        int scrollingBy = calculateScrollDistance(y);
+        if (scrollingBy != 0) {
+            mRecyclerView.scrollBy(0, scrollingBy);
+        }
+    }
+
+    private int calculateScrollDistance(float newDragPos) {
+        final int[] scrollbarRange = getVerticalRange();
+        int scrollbarLength = scrollbarRange[1] - scrollbarRange[0];
+
+        float thumbCenter = mScrollThumb.getY() + mScrollThumb.getHeight() / 2.0f;
+
+        if (scrollbarLength == 0) {
+            return 0;
+        }
+        // percentage of data to be scrolled.
+        float percentage = ((newDragPos - thumbCenter) / (float) scrollbarLength);
+        int totalPossibleOffset =
+                mRecyclerView.computeVerticalScrollRange() - mRecyclerView.getHeight();
+        int scrollingBy = (int) (percentage * totalPossibleOffset);
+        int absoluteOffset = mRecyclerView.computeVerticalScrollOffset() + scrollingBy;
+        if (absoluteOffset < 0) {
+            return 0;
+        }
+        return scrollingBy;
+    }
+
+    /**
+     * Gets the (min, max) vertical positions of the vertical scroll bar. The range starts from the
+     * center of thumb when thumb is top aligned to center of the thumb when thumb is bottom
+     * aligned.
+     */
+    private int[] getVerticalRange() {
+        int[] verticalRange = new int[2];
+        verticalRange[0] = (int) mScrollTrackView.getY() + mScrollThumb.getHeight() / 2;
+        verticalRange[1] = (int) mScrollTrackView.getY() + mScrollTrackView.getHeight()
+                - mScrollThumb.getHeight() / 2;
+        return verticalRange;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/OnContinuousScrollListener.java b/car-ui-lib/src/com/android/car/ui/recyclerview/OnContinuousScrollListener.java
new file mode 100644
index 0000000..4fafc8d
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/OnContinuousScrollListener.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnTouchListener;
+
+import androidx.annotation.NonNull;
+
+import com.android.car.ui.R;
+
+/**
+ * A class, that can be used as a TouchListener on any view (e.g. a Button).
+ * It periodically calls the provided clickListener. The first callback is fired after the
+ * initial Delay, and subsequent ones after the defined interval.
+ */
+public class OnContinuousScrollListener implements OnTouchListener {
+
+    private Handler mHandler = new Handler();
+
+    private int mInitialDelay;
+    private int mRepeatInterval;
+    private final OnClickListener mOnClickListener;
+    private View mTouchedView;
+    private boolean mIsLongPressed;
+
+    /**
+     * Notifies listener and self schedules to be re-run at next callback interval.
+     */
+    private Runnable mPeriodicRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (mTouchedView.isEnabled()) {
+                mHandler.postDelayed(this, mRepeatInterval);
+                mOnClickListener.onClick(mTouchedView);
+                mIsLongPressed = true;
+            } else {
+                mIsLongPressed = false;
+            }
+        }
+    };
+
+    /**
+     * @param clickListener The OnClickListener, that will be called
+     *                      periodically
+     */
+    public OnContinuousScrollListener(@NonNull Context context,
+            @NonNull OnClickListener clickListener) {
+        this.mInitialDelay = context.getResources().getInteger(
+                R.integer.car_ui_scrollbar_longpress_initial_delay);
+
+        this.mRepeatInterval = context.getResources().getInteger(
+                R.integer.car_ui_scrollbar_longpress_repeat_interval);
+
+        if (mInitialDelay < 0 || mRepeatInterval < 0) {
+            throw new IllegalArgumentException("negative intervals are not allowed");
+        }
+        this.mOnClickListener = clickListener;
+    }
+
+    @Override
+    public boolean onTouch(View view, MotionEvent motionEvent) {
+        mTouchedView = view;
+        switch (motionEvent.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mHandler.removeCallbacks(mPeriodicRunnable);
+                mHandler.postDelayed(mPeriodicRunnable, mInitialDelay);
+                mTouchedView.setPressed(true);
+                return true;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                if (!mIsLongPressed) {
+                    mOnClickListener.onClick(view);
+                }
+                mHandler.removeCallbacks(mPeriodicRunnable);
+                mTouchedView.setPressed(false);
+                mIsLongPressed = false;
+                return true;
+        }
+        return false;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/ScrollBar.java b/car-ui-lib/src/com/android/car/ui/recyclerview/ScrollBar.java
new file mode 100644
index 0000000..8e127f0
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/ScrollBar.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.recyclerview;
+
+import android.view.View;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * An abstract class that defines required contract for a custom scroll bar for the {@link
+ * CarUiRecyclerView}. All custom scroll bar must inherit from this class.
+ */
+public interface ScrollBar {
+    /**
+     * The concrete class should implement this method to initialize configuration of a scrollbar
+     * view.
+     */
+    void initialize(RecyclerView recyclerView, View scrollView);
+
+    /**
+     * Requests layout of the scrollbar. Should be called when there's been a change that will
+     * affect
+     * the size of the scrollbar view.
+     */
+    void requestLayout();
+
+    /** Sets the padding of the scrollbar, relative to the padding of the RecyclerView. */
+    void setPadding(int paddingStart, int paddingEnd);
+}
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/grid/GridDividerItemDecoration.java b/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/grid/GridDividerItemDecoration.java
new file mode 100644
index 0000000..abb90ca
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/grid/GridDividerItemDecoration.java
@@ -0,0 +1,164 @@
+/*
+ * 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.ui.recyclerview.decorations.grid;
+
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+
+/** Adds interior dividers to a RecyclerView with a GridLayoutManager. */
+public class GridDividerItemDecoration extends RecyclerView.ItemDecoration {
+
+    private final Drawable mHorizontalDivider;
+    private final Drawable mVerticalDivider;
+    private int mNumColumns;
+
+    /**
+     * Sole constructor. Takes in {@link Drawable} objects to be used as horizontal and vertical
+     * dividers.
+     *
+     * @param horizontalDivider A divider {@code Drawable} to be drawn on the rows of the grid of
+     *                          the
+     *                          RecyclerView
+     * @param verticalDivider   A divider {@code Drawable} to be drawn on the columns of the grid of
+     *                          the
+     *                          RecyclerView
+     * @param numColumns        The number of columns in the grid of the RecyclerView
+     */
+    public GridDividerItemDecoration(
+            Drawable horizontalDivider, Drawable verticalDivider, int numColumns) {
+        this.mHorizontalDivider = horizontalDivider;
+        this.mVerticalDivider = verticalDivider;
+        this.mNumColumns = numColumns;
+    }
+
+    /**
+     * Draws horizontal and/or vertical dividers onto the parent RecyclerView.
+     *
+     * @param canvas The {@link Canvas} onto which dividers will be drawn
+     * @param parent The RecyclerView onto which dividers are being added
+     * @param state  The current RecyclerView.State of the RecyclerView
+     */
+    @Override
+    public void onDrawOver(@NonNull Canvas canvas, @NonNull RecyclerView parent,
+            @NonNull RecyclerView.State state) {
+        drawVerticalDividers(canvas, parent);
+        drawHorizontalDividers(canvas, parent);
+    }
+
+    /**
+     * Determines the size and location of offsets between items in the parent RecyclerView.
+     *
+     * @param outRect The {@link Rect} of offsets to be added around the child view
+     * @param view    The child view to be decorated with an offset
+     * @param parent  The RecyclerView onto which dividers are being added
+     * @param state   The current RecyclerView.State of the RecyclerView
+     */
+    @Override
+    public void getItemOffsets(
+            Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
+            @NonNull RecyclerView.State state) {
+        outRect.set(
+                0, 0, mHorizontalDivider.getIntrinsicWidth(),
+                mHorizontalDivider.getIntrinsicHeight());
+    }
+
+    /**
+     * Adds horizontal dividers to a RecyclerView with a GridLayoutManager or its subclass.
+     *
+     * @param canvas The {@link Canvas} onto which dividers will be drawn
+     * @param parent The RecyclerView onto which dividers are being added
+     */
+    private void drawHorizontalDividers(Canvas canvas, RecyclerView parent) {
+        int childCount = parent.getChildCount();
+        int rowCount = childCount / mNumColumns;
+        int lastRowChildCount = childCount % mNumColumns;
+        int lastColumn = Math.min(childCount, mNumColumns);
+
+        for (int i = 1; i < lastColumn; i++) {
+            int lastRowChildIndex;
+            if (i < lastRowChildCount) {
+                lastRowChildIndex = i + (rowCount * mNumColumns);
+            } else {
+                lastRowChildIndex = i + ((rowCount - 1) * mNumColumns);
+            }
+
+            View firstRowChild = parent.getChildAt(i);
+            View lastRowChild = parent.getChildAt(lastRowChildIndex);
+
+            int dividerTop =
+                    firstRowChild.getTop() + (int) parent.getContext().getResources().getDimension(
+                            R.dimen.car_ui_recyclerview_divider_top_margin);
+            int dividerRight = firstRowChild.getLeft();
+            int dividerLeft = dividerRight - mHorizontalDivider.getIntrinsicWidth();
+            int dividerBottom = lastRowChild.getBottom()
+                    - (int) parent.getContext().getResources().getDimension(
+                    R.dimen.car_ui_recyclerview_divider_bottom_margin);
+
+            mHorizontalDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
+            mHorizontalDivider.draw(canvas);
+        }
+    }
+
+    public void setNumOfColumns(int numberOfColumns) {
+        mNumColumns = numberOfColumns;
+    }
+
+    /**
+     * Adds vertical dividers to a RecyclerView with a GridLayoutManager or its subclass.
+     *
+     * @param canvas The {@link Canvas} onto which dividers will be drawn
+     * @param parent The RecyclerView onto which dividers are being added
+     */
+    private void drawVerticalDividers(Canvas canvas, RecyclerView parent) {
+        double childCount = parent.getChildCount();
+        double rowCount = Math.ceil(childCount / mNumColumns);
+        int rightmostChildIndex;
+        for (int i = 1; i <= rowCount; i++) {
+            // we don't want the divider on top of first row.
+            if (i == 1) {
+                continue;
+            }
+            if (i == rowCount) {
+                rightmostChildIndex = ((i - 1) * mNumColumns) - 1;
+            } else {
+                rightmostChildIndex = (i * mNumColumns) - 1;
+            }
+
+            View leftmostChild = parent.getChildAt(mNumColumns * (i - 1));
+            View rightmostChild = parent.getChildAt(rightmostChildIndex);
+
+            // draws on top of each row.
+            int dividerLeft =
+                    leftmostChild.getLeft() + (int) parent.getContext().getResources().getDimension(
+                            R.dimen.car_ui_recyclerview_divider_start_margin);
+            int dividerBottom = leftmostChild.getTop();
+            int dividerTop = dividerBottom - mVerticalDivider.getIntrinsicHeight();
+            int dividerRight = rightmostChild.getRight()
+                    - (int) parent.getContext().getResources().getDimension(
+                    R.dimen.car_ui_recyclerview_divider_end_margin);
+
+            mVerticalDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
+            mVerticalDivider.draw(canvas);
+        }
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/grid/GridOffsetItemDecoration.java b/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/grid/GridOffsetItemDecoration.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/decorations/grid/GridOffsetItemDecoration.java
rename to car-ui-lib/src/com/android/car/ui/recyclerview/decorations/grid/GridOffsetItemDecoration.java
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/linear/LinearDividerItemDecoration.java b/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/linear/LinearDividerItemDecoration.java
new file mode 100644
index 0000000..4d5e6bd
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/linear/LinearDividerItemDecoration.java
@@ -0,0 +1,149 @@
+/*
+ * 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.ui.recyclerview.decorations.linear;
+
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+
+import java.util.Objects;
+
+/** Adds interior dividers to a RecyclerView with a LinearLayoutManager or its subclass. */
+public class LinearDividerItemDecoration extends RecyclerView.ItemDecoration {
+
+    private final Drawable mDivider;
+    private int mOrientation;
+
+    /**
+     * Sole constructor. Takes in a {@link Drawable} to be used as the interior
+     * car_ui_recyclerview_divider.
+     *
+     * @param divider A car_ui_recyclerview_divider {@code Drawable} to be drawn on the
+     *                RecyclerView
+     */
+    public LinearDividerItemDecoration(Drawable divider) {
+        this.mDivider = divider;
+    }
+
+    /**
+     * Draws horizontal or vertical dividers onto the parent RecyclerView.
+     *
+     * @param canvas The {@link Canvas} onto which dividers will be drawn
+     * @param parent The RecyclerView onto which dividers are being added
+     * @param state  The current RecyclerView.State of the RecyclerView
+     */
+    @Override
+    public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent,
+            @NonNull RecyclerView.State state) {
+        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
+            drawHorizontalDividers(canvas, parent);
+        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
+            drawVerticalDividers(canvas, parent);
+        }
+    }
+
+    /**
+     * Determines the size and location of offsets between items in the parent RecyclerView.
+     *
+     * @param outRect The {@link Rect} of offsets to be added around the child view
+     * @param view    The child view to be decorated with an offset
+     * @param parent  The RecyclerView onto which dividers are being added
+     * @param state   The current RecyclerView.State of the RecyclerView
+     */
+    @Override
+    public void getItemOffsets(
+            @NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
+            @NonNull RecyclerView.State state) {
+        super.getItemOffsets(outRect, view, parent, state);
+
+        if (parent.getChildAdapterPosition(view) == 0) {
+            return;
+        }
+
+        mOrientation = ((LinearLayoutManager) Objects.requireNonNull(
+                parent.getLayoutManager())).getOrientation();
+        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
+            outRect.left = mDivider.getIntrinsicWidth();
+        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
+            outRect.top = mDivider.getIntrinsicHeight();
+        }
+    }
+
+    /**
+     * Adds dividers to a RecyclerView with a LinearLayoutManager or its subclass oriented
+     * horizontally.
+     *
+     * @param canvas The {@link Canvas} onto which horizontal dividers will be drawn
+     * @param parent The RecyclerView onto which horizontal dividers are being added
+     */
+    private void drawHorizontalDividers(Canvas canvas, RecyclerView parent) {
+        int parentTop =
+                parent.getPaddingTop() + (int) parent.getContext().getResources().getDimension(
+                        R.dimen.car_ui_recyclerview_divider_top_margin);
+        int parentBottom = parent.getHeight() - parent.getPaddingBottom()
+                - (int) parent.getContext().getResources().getDimension(
+                R.dimen.car_ui_recyclerview_divider_bottom_margin);
+
+        int childCount = parent.getChildCount();
+        for (int i = 0; i < childCount - 1; i++) {
+            View child = parent.getChildAt(i);
+
+            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
+
+            int parentLeft = child.getRight() + params.rightMargin;
+            int parentRight = parentLeft + mDivider.getIntrinsicWidth();
+
+            mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
+            mDivider.draw(canvas);
+        }
+    }
+
+    /**
+     * Adds dividers to a RecyclerView with a LinearLayoutManager or its subclass oriented
+     * vertically.
+     *
+     * @param canvas The {@link Canvas} onto which vertical dividers will be drawn
+     * @param parent The RecyclerView onto which vertical dividers are being added
+     */
+    private void drawVerticalDividers(Canvas canvas, RecyclerView parent) {
+        int parentLeft =
+                parent.getPaddingLeft() + (int) parent.getContext().getResources().getDimension(
+                        R.dimen.car_ui_recyclerview_divider_start_margin);
+        int parentRight = parent.getWidth() - parent.getPaddingRight()
+                - (int) parent.getContext().getResources().getDimension(
+                R.dimen.car_ui_recyclerview_divider_end_margin);
+
+        int childCount = parent.getChildCount();
+        for (int i = 0; i < childCount - 1; i++) {
+            View child = parent.getChildAt(i);
+
+            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
+
+            int parentTop = child.getBottom() + params.bottomMargin;
+            int parentBottom = parentTop + mDivider.getIntrinsicHeight();
+
+            mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
+            mDivider.draw(canvas);
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/linear/LinearOffsetItemDecoration.java b/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/linear/LinearOffsetItemDecoration.java
new file mode 100644
index 0000000..33e14db
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/decorations/linear/LinearOffsetItemDecoration.java
@@ -0,0 +1,203 @@
+/*
+ * 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.ui.recyclerview.decorations.linear;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.lang.annotation.Retention;
+import java.util.Objects;
+
+/**
+ * Adds an offset to the start of a RecyclerView using a LinearLayoutManager or its subclass.
+ *
+ * <p>If the RecyclerView.LayoutManager is oriented vertically, the offset will be added to the top
+ * of the RecyclerView. If the LayoutManager is oriented horizontally, the offset will be added to
+ * the left of the RecyclerView.
+ */
+public class LinearOffsetItemDecoration extends RecyclerView.ItemDecoration {
+
+    private int mOffsetPx;
+    private Drawable mOffsetDrawable;
+    private int mOrientation;
+    @OffsetPosition
+    private int mOffsetPosition;
+
+    /** The possible values for setScrollbarPosition. */
+    @IntDef({
+            OffsetPosition.START,
+            OffsetPosition.END,
+    })
+    @Retention(SOURCE)
+    public @interface OffsetPosition {
+        /** Position the offset to the start of the screen. */
+        int START = 0;
+
+        /** Position offset to the end of the screen. */
+        int END = 1;
+    }
+
+    /**
+     * Constructor that takes in the size of the offset to be added to the start of the
+     * RecyclerView.
+     *
+     * @param offsetPx       The size of the offset to be added to the start of the RecyclerView in
+     *                       pixels
+     * @param offsetPosition Position where offset needs to be applied.
+     */
+    public LinearOffsetItemDecoration(int offsetPx, int offsetPosition) {
+        this.mOffsetPx = offsetPx;
+        this.mOffsetPosition = offsetPosition;
+    }
+
+    /**
+     * Constructor that takes in a {@link Drawable} to be drawn at the start of the RecyclerView.
+     *
+     * @param offsetDrawable The {@code Drawable} to be added to the start of the RecyclerView
+     */
+    public LinearOffsetItemDecoration(Drawable offsetDrawable) {
+        this.mOffsetDrawable = offsetDrawable;
+    }
+
+    /**
+     * Determines the size and location of the offset to be added to the start of the RecyclerView.
+     *
+     * @param outRect The {@link Rect} of offsets to be added around the child view
+     * @param view    The child view to be decorated with an offset
+     * @param parent  The RecyclerView onto which dividers are being added
+     * @param state   The current RecyclerView.State of the RecyclerView
+     */
+    @Override
+    public void getItemOffsets(
+            @NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
+            @NonNull RecyclerView.State state) {
+        super.getItemOffsets(outRect, view, parent, state);
+
+        if (mOffsetPosition == OffsetPosition.START && parent.getChildAdapterPosition(view) > 0) {
+            return;
+        }
+
+        int itemCount = state.getItemCount();
+        if (mOffsetPosition == OffsetPosition.END
+                && parent.getChildAdapterPosition(view) != itemCount - 1) {
+            return;
+        }
+
+        mOrientation = ((LinearLayoutManager) Objects.requireNonNull(
+                parent.getLayoutManager())).getOrientation();
+        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
+            if (mOffsetPx > 0) {
+                if (mOffsetPosition == OffsetPosition.START) {
+                    outRect.left = mOffsetPx;
+                } else {
+                    outRect.right = mOffsetPx;
+                }
+            } else if (mOffsetDrawable != null) {
+                if (mOffsetPosition == OffsetPosition.START) {
+                    outRect.left = mOffsetDrawable.getIntrinsicWidth();
+                } else {
+                    outRect.right = mOffsetDrawable.getIntrinsicWidth();
+                }
+            }
+        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
+            if (mOffsetPx > 0) {
+                if (mOffsetPosition == OffsetPosition.START) {
+                    outRect.top = mOffsetPx;
+                } else {
+                    outRect.bottom = mOffsetPx;
+                }
+            } else if (mOffsetDrawable != null) {
+                if (mOffsetPosition == OffsetPosition.START) {
+                    outRect.top = mOffsetDrawable.getIntrinsicHeight();
+                } else {
+                    outRect.bottom = mOffsetDrawable.getIntrinsicHeight();
+                }
+            }
+        }
+    }
+
+    /**
+     * Draws horizontal or vertical offset onto the start of the parent RecyclerView.
+     *
+     * @param c      The {@link Canvas} onto which an offset will be drawn
+     * @param parent The RecyclerView onto which an offset is being added
+     * @param state  The current RecyclerView.State of the RecyclerView
+     */
+    @Override
+    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent,
+            @NonNull RecyclerView.State state) {
+        super.onDraw(c, parent, state);
+        if (mOffsetDrawable == null) {
+            return;
+        }
+
+        if (mOrientation == LinearLayoutManager.HORIZONTAL) {
+            drawOffsetHorizontal(c, parent);
+        } else if (mOrientation == LinearLayoutManager.VERTICAL) {
+            drawOffsetVertical(c, parent);
+        }
+    }
+
+    private void drawOffsetHorizontal(Canvas canvas, RecyclerView parent) {
+        int parentTop = parent.getPaddingTop();
+        int parentBottom = parent.getHeight() - parent.getPaddingBottom();
+        int parentLeft;
+        int offsetDrawableRight;
+
+        if (mOffsetPosition == OffsetPosition.START) {
+            parentLeft = parent.getPaddingLeft();
+        } else {
+            View lastChild = parent.getChildAt(parent.getChildCount() - 1);
+            RecyclerView.LayoutParams lastChildLayoutParams =
+                    (RecyclerView.LayoutParams) lastChild.getLayoutParams();
+            parentLeft = lastChild.getRight() + lastChildLayoutParams.rightMargin;
+        }
+        offsetDrawableRight = parentLeft + mOffsetDrawable.getIntrinsicWidth();
+
+        mOffsetDrawable.setBounds(parentLeft, parentTop, offsetDrawableRight, parentBottom);
+        mOffsetDrawable.draw(canvas);
+    }
+
+    private void drawOffsetVertical(Canvas canvas, RecyclerView parent) {
+        int parentLeft = parent.getPaddingLeft();
+        int parentRight = parent.getWidth() - parent.getPaddingRight();
+
+        int parentTop;
+        int offsetDrawableBottom;
+
+        if (mOffsetPosition == OffsetPosition.START) {
+            parentTop = parent.getPaddingTop();
+        } else {
+            View lastChild = parent.getChildAt(parent.getChildCount() - 1);
+            RecyclerView.LayoutParams lastChildLayoutParams =
+                    (RecyclerView.LayoutParams) lastChild.getLayoutParams();
+            parentTop = lastChild.getBottom() + lastChildLayoutParams.bottomMargin;
+        }
+        offsetDrawableBottom = parentTop + mOffsetDrawable.getIntrinsicHeight();
+
+        mOffsetDrawable.setBounds(parentLeft, parentTop, parentRight, offsetDrawableBottom);
+        mOffsetDrawable.draw(canvas);
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/MenuItem.java b/car-ui-lib/src/com/android/car/ui/toolbar/MenuItem.java
new file mode 100644
index 0000000..6ee35d3
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/MenuItem.java
@@ -0,0 +1,613 @@
+/*
+ * 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.ui.toolbar;
+
+import android.car.drivingstate.CarUxRestrictions;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUxRestrictionsUtil;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Represents a button to display in the {@link Toolbar}.
+ *
+ * <p>There are currently 3 types of buttons: icon, text, and switch. Using
+ * {@link Builder#setCheckable()} will ensure that you get a switch, after that
+ * {@link Builder#setIcon(int)} will ensure an icon, and anything left just requires
+ * {@link Builder#setTitle(int)}.
+ *
+ * <p>Each MenuItem has a {@link DisplayBehavior} that controls if it appears on the {@link Toolbar}
+ * itself, or it's overflow menu.
+ *
+ * <p>If you require a search or settings button, you should use
+ * {@link Builder#setToSearch()} or
+ * {@link Builder#setToSettings()}.
+ *
+ * <p>Some properties can be changed after the creating a MenuItem, but others require being set
+ * with a {@link Builder}.
+ */
+public class MenuItem {
+
+    private final Context mContext;
+    private final boolean mIsCheckable;
+    private final boolean mIsActivatable;
+    private final boolean mIsSearch;
+    private final boolean mShowIconAndTitle;
+    private final boolean mIsTinted;
+    @CarUxRestrictions.CarUxRestrictionsInfo
+
+    private int mId;
+    private CarUxRestrictions mCurrentRestrictions;
+    // This is a WeakReference to allow the Toolbar (and by extension, the whole screen
+    // the toolbar is on) to be garbage-collected if the MenuItem is held past the
+    // lifecycle of the toolbar.
+    private WeakReference<Listener> mListener = new WeakReference<>(null);
+    private CharSequence mTitle;
+    private Drawable mIcon;
+    private OnClickListener mOnClickListener;
+    private DisplayBehavior mDisplayBehavior;
+    private int mUxRestrictions;
+    private boolean mIsEnabled;
+    private boolean mIsChecked;
+    private boolean mIsVisible;
+    private boolean mIsActivated;
+
+    private MenuItem(Builder builder) {
+        mContext = builder.mContext;
+        mId = builder.mId;
+        mIsCheckable = builder.mIsCheckable;
+        mIsActivatable = builder.mIsActivatable;
+        mTitle = builder.mTitle;
+        mIcon = builder.mIcon;
+        mOnClickListener = builder.mOnClickListener;
+        mDisplayBehavior = builder.mDisplayBehavior;
+        mIsEnabled = builder.mIsEnabled;
+        mIsChecked = builder.mIsChecked;
+        mIsVisible = builder.mIsVisible;
+        mIsActivated = builder.mIsActivated;
+        mIsSearch = builder.mIsSearch;
+        mShowIconAndTitle = builder.mShowIconAndTitle;
+        mIsTinted = builder.mIsTinted;
+        mUxRestrictions = builder.mUxRestrictions;
+
+        mCurrentRestrictions = CarUxRestrictionsUtil.getInstance(mContext).getCurrentRestrictions();
+    }
+
+    private void update() {
+        Listener listener = mListener.get();
+        if (listener != null) {
+            listener.onMenuItemChanged(this);
+        }
+    }
+
+    /** Sets the id, which is purely for the client to distinguish MenuItems with.  */
+    public void setId(int id) {
+        mId = id;
+        update();
+    }
+
+    /** Gets the id, which is purely for the client to distinguish MenuItems with. */
+    public int getId() {
+        return mId;
+    }
+
+    /** Returns whether the MenuItem is enabled */
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    /** Sets whether the MenuItem is enabled */
+    public void setEnabled(boolean enabled) {
+        mIsEnabled = enabled;
+
+        update();
+    }
+
+    /** Returns whether the MenuItem is checkable. If it is, it will be displayed as a switch. */
+    public boolean isCheckable() {
+        return mIsCheckable;
+    }
+
+    /**
+     * Returns whether the MenuItem is currently checked. Only valid if {@link #isCheckable()}
+     * is true.
+     */
+    public boolean isChecked() {
+        return mIsChecked;
+    }
+
+    /**
+     * Sets whether or not the MenuItem is checked.
+     * @throws IllegalStateException When {@link #isCheckable()} is false.
+     */
+    public void setChecked(boolean checked) {
+        if (!isCheckable()) {
+            throw new IllegalStateException("Cannot call setChecked() on a non-checkable MenuItem");
+        }
+
+        mIsChecked = checked;
+
+        update();
+    }
+
+    public boolean isTinted() {
+        return mIsTinted;
+    }
+
+    /** Returns whether or not the MenuItem is visible */
+    public boolean isVisible() {
+        return mIsVisible;
+    }
+
+    /** Sets whether or not the MenuItem is visible */
+    public void setVisible(boolean visible) {
+        mIsVisible = visible;
+
+        update();
+    }
+
+    /**
+     * Returns whether the MenuItem is activatable. If it is, it's every click will toggle
+     * the MenuItem's View to appear activated or not.
+     */
+    public boolean isActivatable() {
+        return mIsActivatable;
+    }
+
+    /** Returns whether or not this view is selected. Toggles after every click */
+    public boolean isActivated() {
+        return mIsActivated;
+    }
+
+    /** Sets the MenuItem as activated and updates it's View to the activated state */
+    public void setActivated(boolean activated) {
+        if (!isActivatable()) {
+            throw new IllegalStateException(
+                    "Cannot call setActivated() on a non-activatable MenuItem");
+        }
+
+        mIsActivated = activated;
+
+        update();
+    }
+
+    /** Gets the title of this MenuItem. */
+    public CharSequence getTitle() {
+        return mTitle;
+    }
+
+    /** Sets the title of this MenuItem. */
+    public void setTitle(CharSequence title) {
+        mTitle = title;
+
+        update();
+    }
+
+    /** Sets the title of this MenuItem to a string resource. */
+    public void setTitle(int resId) {
+        setTitle(mContext.getString(resId));
+    }
+
+    /** Sets the UxRestrictions of this MenuItem. */
+    public void setUxRestrictions(@CarUxRestrictions.CarUxRestrictionsInfo int uxRestrictions) {
+        if (mUxRestrictions != uxRestrictions) {
+            mUxRestrictions = uxRestrictions;
+            update();
+        }
+    }
+
+    @CarUxRestrictions.CarUxRestrictionsInfo
+    public int getUxRestrictions() {
+        return mUxRestrictions;
+    }
+
+    /** Gets the current {@link OnClickListener} */
+    public OnClickListener getOnClickListener() {
+        return mOnClickListener;
+    }
+
+    public boolean isShowingIconAndTitle() {
+        return mShowIconAndTitle;
+    }
+
+    /** Sets the {@link OnClickListener} */
+    public void setOnClickListener(OnClickListener listener) {
+        mOnClickListener = listener;
+
+        update();
+    }
+
+    /* package */ void setCarUxRestrictions(CarUxRestrictions restrictions) {
+        boolean wasRestricted = isRestricted();
+        mCurrentRestrictions = restrictions;
+
+        if (isRestricted() != wasRestricted) {
+            update();
+        }
+    }
+
+    /* package */ boolean isRestricted() {
+        return CarUxRestrictionsUtil.isRestricted(mUxRestrictions, mCurrentRestrictions);
+    }
+
+    /** Calls the {@link OnClickListener}. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public void performClick() {
+        if (!isEnabled() || !isVisible()) {
+            return;
+        }
+
+        if (isRestricted()) {
+            Toast.makeText(mContext,
+                    R.string.car_ui_restricted_while_driving, Toast.LENGTH_LONG).show();
+            return;
+        }
+
+        if (isActivatable()) {
+            setActivated(!isActivated());
+        }
+
+        if (isCheckable()) {
+            setChecked(!isChecked());
+        }
+
+        if (mOnClickListener != null) {
+            mOnClickListener.onClick(this);
+        }
+    }
+
+    /** Gets the current {@link DisplayBehavior} */
+    public DisplayBehavior getDisplayBehavior() {
+        return mDisplayBehavior;
+    }
+
+    /** Gets the current Icon */
+    public Drawable getIcon() {
+        return mIcon;
+    }
+
+    /** Sets the Icon of this MenuItem. */
+    public void setIcon(Drawable icon) {
+        mIcon = icon;
+
+        update();
+    }
+
+    /** Sets the Icon of this MenuItem to a drawable resource. */
+    public void setIcon(int resId) {
+        setIcon(resId == 0
+                ? null
+                : mContext.getDrawable(resId));
+    }
+
+    /** Returns if this is the search MenuItem, which has special behavior when searching */
+    boolean isSearch() {
+        return mIsSearch;
+    }
+
+    /** Builder class */
+    public static final class Builder {
+        private final Context mContext;
+
+        private String mSearchTitle;
+        private String mSettingsTitle;
+        private Drawable mSearchIcon;
+        private Drawable mSettingsIcon;
+
+        private int mId = View.NO_ID;
+        private CharSequence mTitle;
+        private Drawable mIcon;
+        private OnClickListener mOnClickListener;
+        private DisplayBehavior mDisplayBehavior = DisplayBehavior.ALWAYS;
+        private boolean mIsTinted = true;
+        private boolean mShowIconAndTitle = false;
+        private boolean mIsEnabled = true;
+        private boolean mIsCheckable = false;
+        private boolean mIsChecked = false;
+        private boolean mIsVisible = true;
+        private boolean mIsActivatable = false;
+        private boolean mIsActivated = false;
+        private boolean mIsSearch = false;
+        private boolean mIsSettings = false;
+        @CarUxRestrictions.CarUxRestrictionsInfo
+        private int mUxRestrictions = CarUxRestrictions.UX_RESTRICTIONS_BASELINE;
+
+        public Builder(Context c) {
+            // Must use getApplicationContext to avoid leaking activities when the MenuItem
+            // is held onto for longer than the Activity's lifecycle
+            mContext = c.getApplicationContext();
+        }
+
+        /** Builds a {@link MenuItem} from the current state of the Builder */
+        public MenuItem build() {
+            if (mIsActivatable && (mShowIconAndTitle || mIcon == null)) {
+                throw new IllegalStateException("Only simple icons can be activatable");
+            }
+            if (mIsCheckable && (mShowIconAndTitle || mIsActivatable)) {
+                throw new IllegalStateException("Unsupported options for a checkable MenuItem");
+            }
+            if (mIsSearch && mIsSettings) {
+                throw new IllegalStateException("Can't have both a search and settings MenuItem");
+            }
+            if (mIsActivatable && mDisplayBehavior == DisplayBehavior.NEVER) {
+                throw new IllegalStateException("Activatable MenuItems not supported as Overflow");
+            }
+
+            if (mIsSearch && (!mSearchTitle.contentEquals(mTitle)
+                    || !mSearchIcon.equals(mIcon)
+                    || mIsCheckable
+                    || mIsActivatable
+                    || !mIsTinted
+                    || mShowIconAndTitle
+                    || mDisplayBehavior != DisplayBehavior.ALWAYS)) {
+                throw new IllegalStateException("Invalid search MenuItem");
+            }
+
+            if (mIsSettings && (!mSettingsTitle.contentEquals(mTitle)
+                    || !mSettingsIcon.equals(mIcon)
+                    || mIsCheckable
+                    || mIsActivatable
+                    || !mIsTinted
+                    || mShowIconAndTitle
+                    || mDisplayBehavior != DisplayBehavior.ALWAYS)) {
+                throw new IllegalStateException("Invalid settings MenuItem");
+            }
+
+            return new MenuItem(this);
+        }
+
+        /** Sets the id, which is purely for the client to distinguish MenuItems with. */
+        public Builder setId(int id) {
+            mId = id;
+            return this;
+        }
+
+        /** Sets the title to a string resource id */
+        public Builder setTitle(int resId) {
+            setTitle(mContext.getString(resId));
+            return this;
+        }
+
+        /** Sets the title */
+        public Builder setTitle(CharSequence title) {
+            mTitle = title;
+            return this;
+        }
+
+        /**
+         * Sets the icon to a drawable resource id.
+         *
+         * <p>The icon's color and size will be changed to match the other MenuItems.
+         */
+        public Builder setIcon(int resId) {
+            mIcon = resId == 0
+                    ? null
+                    : mContext.getDrawable(resId);
+            return this;
+        }
+
+        /**
+         * Sets the icon to a drawable.
+         *
+         * <p>The icon's color and size will be changed to match the other MenuItems.
+         */
+        public Builder setIcon(Drawable icon) {
+            mIcon = icon;
+            return this;
+        }
+
+        /**
+         * Sets whether to tint the icon, true by default.
+         *
+         * <p>Try not to use this, it should only be used if the MenuItem is displaying some
+         * kind of logo or avatar and should be colored.
+         */
+        public Builder setTinted(boolean tinted) {
+            mIsTinted = tinted;
+            return this;
+        }
+
+        /** Sets whether the MenuItem is visible or not. Default true. */
+        public Builder setVisible(boolean visible) {
+            mIsVisible = visible;
+            return this;
+        }
+
+        /**
+         * Makes the MenuItem activatable, which means it will toggle it's visual state after
+         * every click.
+         */
+        public Builder setActivatable() {
+            mIsActivatable = true;
+            return this;
+        }
+
+        /**
+         * Sets whether or not the MenuItem is selected. If it is,
+         * {@link View#setSelected(boolean)} will be called on its View.
+         */
+        public Builder setActivated(boolean activated) {
+            setActivatable();
+            mIsActivated = activated;
+            return this;
+        }
+
+        /** Sets the {@link OnClickListener} */
+        public Builder setOnClickListener(OnClickListener listener) {
+            mOnClickListener = listener;
+            return this;
+        }
+
+        /**
+         * Used to show both the icon and title when displayed on the toolbar. If this
+         * is false, only the icon while be displayed when the MenuItem is in the toolbar
+         * and only the title will be displayed when the MenuItem is in the overflow menu.
+         *
+         * <p>Defaults to false.
+         */
+        public Builder setShowIconAndTitle(boolean showIconAndTitle) {
+            mShowIconAndTitle = showIconAndTitle;
+            return this;
+        }
+
+        /**
+         * Sets the {@link DisplayBehavior}.
+         *
+         * <p>If the DisplayBehavior is {@link DisplayBehavior#NEVER}, the MenuItem must not be
+         * {@link #setCheckable() checkable}.
+         */
+        public Builder setDisplayBehavior(DisplayBehavior behavior) {
+            mDisplayBehavior = behavior;
+            return this;
+        }
+
+        /** Sets whether the MenuItem is enabled or not. Default true. */
+        public Builder setEnabled(boolean enabled) {
+            mIsEnabled = enabled;
+            return this;
+        }
+
+        /**
+         * Makes the MenuItem checkable, meaning it will be displayed as a
+         * switch.
+         *
+         * <p>The MenuItem is not checkable by default.
+         */
+        public Builder setCheckable() {
+            mIsCheckable = true;
+            return this;
+        }
+
+        /**
+         * Sets whether the MenuItem is checked or not. This will imply {@link #setCheckable()}.
+         */
+        public Builder setChecked(boolean checked) {
+            setCheckable();
+            mIsChecked = checked;
+            return this;
+        }
+
+        /**
+         * Sets under what {@link android.car.drivingstate.CarUxRestrictions.CarUxRestrictionsInfo}
+         * the MenuItem should be restricted.
+         */
+        public Builder setUxRestrictions(
+                @CarUxRestrictions.CarUxRestrictionsInfo int restrictions) {
+            mUxRestrictions = restrictions;
+            return this;
+        }
+
+        /**
+         * Creates a search MenuItem.
+         *
+         * <p>The advantage of using this over creating your own is getting an OEM-styled search
+         * icon, and this button will always disappear while searching, even when the
+         * {@link Toolbar Toolbar's} showMenuItemsWhileSearching is true.
+         *
+         * <p>If using this, you should only change the id, visibility, or onClickListener.
+         */
+        public Builder setToSearch() {
+            mSearchTitle = mContext.getString(R.string.car_ui_toolbar_menu_item_search_title);
+            mSearchIcon = mContext.getDrawable(R.drawable.car_ui_icon_search);
+            mIsSearch = true;
+            setTitle(mSearchTitle);
+            setIcon(mSearchIcon);
+            return this;
+        }
+
+        /**
+         * Creates a settings MenuItem.
+         *
+         * <p>The advantage of this over creating your own is getting an OEM-styled settings icon,
+         * and that the MenuItem will be restricted based on
+         * {@link CarUxRestrictions#UX_RESTRICTIONS_NO_SETUP}
+         *
+         * <p>If using this, you should only change the id, visibility, or onClickListener.
+         */
+        public Builder setToSettings() {
+            mSettingsTitle = mContext.getString(R.string.car_ui_toolbar_menu_item_settings_title);
+            mSettingsIcon = mContext.getDrawable(R.drawable.car_ui_icon_settings);
+            mIsSettings = true;
+            setTitle(mSettingsTitle);
+            setIcon(mSettingsIcon);
+            setUxRestrictions(CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP);
+            return this;
+        }
+
+        /** @deprecated Use {@link #setToSearch()} instead. */
+        @Deprecated
+        public static MenuItem createSearch(Context c, OnClickListener listener) {
+            return MenuItem.builder(c)
+                    .setToSearch()
+                    .setOnClickListener(listener)
+                    .build();
+        }
+
+        /** @deprecated Use {@link #setToSettings()} instead. */
+        @Deprecated
+        public static MenuItem createSettings(Context c, OnClickListener listener) {
+            return MenuItem.builder(c)
+                    .setToSettings()
+                    .setOnClickListener(listener)
+                    .build();
+        }
+    }
+
+    /** Get a new {@link Builder}. */
+    public static Builder builder(Context context) {
+        return new Builder(context);
+    }
+
+    /**
+     * OnClickListener for a MenuItem.
+     */
+    public interface OnClickListener {
+        /** Called when the MenuItem is clicked */
+        void onClick(MenuItem item);
+    }
+
+    /**
+     * DisplayBehavior controls how the MenuItem is presented in the Toolbar
+     */
+    public enum DisplayBehavior {
+        /** Always show the MenuItem on the toolbar instead of the overflow menu */
+        ALWAYS,
+        /** Never show the MenuItem in the toolbar, always put it in the overflow menu */
+        NEVER
+    }
+
+    /** Listener for {@link Toolbar} to update when this MenuItem changes */
+    interface Listener {
+        /** Called when the MenuItem is changed. For use only by {@link Toolbar} */
+        void onMenuItemChanged(MenuItem item);
+    }
+
+    /**
+     * Sets a listener for changes to this MenuItem. Note that the MenuItem will only hold
+     * weak references to the Listener, so that the listener is not held if the MenuItem
+     * outlives the toolbar.
+     */
+    void setListener(Listener listener) {
+        mListener = new WeakReference<>(listener);
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/MenuItemRenderer.java b/car-ui-lib/src/com/android/car/ui/toolbar/MenuItemRenderer.java
new file mode 100644
index 0000000..7bf9025
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/MenuItemRenderer.java
@@ -0,0 +1,299 @@
+/*
+ * 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.ui.toolbar;
+
+import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
+
+import android.app.Activity;
+import android.car.drivingstate.CarUxRestrictions;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Xml;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.annotation.XmlRes;
+import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
+import androidx.core.util.Consumer;
+
+import com.android.car.ui.R;
+import com.android.car.ui.utils.CarUiUtils;
+import com.android.car.ui.uxr.DrawableStateView;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+class MenuItemRenderer implements MenuItem.Listener {
+
+    private static final int[] RESTRICTED_STATE = new int[] {R.attr.state_ux_restricted};
+
+    private final int mMenuItemIconSize;
+
+    private Toolbar.State mToolbarState;
+
+    private final MenuItem mMenuItem;
+    private final ViewGroup mParentView;
+    private View mView;
+    private View mIconContainer;
+    private ImageView mIconView;
+    private Switch mSwitch;
+    private TextView mTextView;
+    private TextView mTextWithIconView;
+
+    MenuItemRenderer(MenuItem item, ViewGroup parentView) {
+        mMenuItem = item;
+        mParentView = parentView;
+        mMenuItem.setListener(this);
+
+        mMenuItemIconSize = parentView.getContext().getResources()
+                .getDimensionPixelSize(R.dimen.car_ui_toolbar_menu_item_icon_size);
+    }
+
+    void setToolbarState(Toolbar.State state) {
+        mToolbarState = state;
+
+        if (mMenuItem.isSearch()) {
+            updateView();
+        }
+    }
+
+    void setCarUxRestrictions(CarUxRestrictions restrictions) {
+        mMenuItem.setCarUxRestrictions(restrictions);
+    }
+
+    @Override
+    public void onMenuItemChanged(MenuItem changedItem) {
+        updateView();
+    }
+
+    void createView(Consumer<View> callback) {
+        AsyncLayoutInflater inflater = new AsyncLayoutInflater(mParentView.getContext());
+        inflater.inflate(R.layout.car_ui_toolbar_menu_item, mParentView, (View view, int resid,
+                ViewGroup parent) -> {
+            mView = view;
+
+            mIconContainer =
+                    requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_icon_container);
+            mIconView = requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_icon);
+            mSwitch = requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_switch);
+            mTextView = requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_text);
+            mTextWithIconView =
+                    requireViewByRefId(mView, R.id.car_ui_toolbar_menu_item_text_with_icon);
+
+            updateView();
+            callback.accept(mView);
+        });
+    }
+
+    private void updateView() {
+        if (mView == null) {
+            return;
+        }
+
+        mView.setId(mMenuItem.getId());
+
+        boolean hasIcon = mMenuItem.getIcon() != null;
+        boolean hasText = !TextUtils.isEmpty(mMenuItem.getTitle());
+        boolean textAndIcon = mMenuItem.isShowingIconAndTitle();
+        boolean checkable = mMenuItem.isCheckable();
+
+        if (!mMenuItem.isVisible()
+                || (mMenuItem.isSearch() && mToolbarState == Toolbar.State.SEARCH)
+                || (!checkable && !hasIcon && !hasText)) {
+            mView.setVisibility(View.GONE);
+            return;
+        }
+        mView.setVisibility(View.VISIBLE);
+        mView.setContentDescription(mMenuItem.getTitle());
+
+        mIconContainer.setVisibility(View.GONE);
+        mTextView.setVisibility(View.GONE);
+        mTextWithIconView.setVisibility(View.GONE);
+        mSwitch.setVisibility(View.GONE);
+        if (checkable) {
+            mSwitch.setChecked(mMenuItem.isChecked());
+            mSwitch.setVisibility(View.VISIBLE);
+        } else if (hasText && hasIcon && textAndIcon) {
+            mMenuItem.getIcon().setBounds(0, 0, mMenuItemIconSize, mMenuItemIconSize);
+            mTextWithIconView.setCompoundDrawables(mMenuItem.getIcon(), null, null, null);
+            mTextWithIconView.setText(mMenuItem.getTitle());
+            mTextWithIconView.setVisibility(View.VISIBLE);
+        } else if (hasIcon) {
+            mIconView.setImageDrawable(mMenuItem.getIcon());
+            mIconContainer.setVisibility(View.VISIBLE);
+        } else { // hasText will be true
+            mTextView.setText(mMenuItem.getTitle());
+            mTextView.setVisibility(View.VISIBLE);
+        }
+
+        if (!mMenuItem.isTinted() && hasIcon) {
+            mMenuItem.getIcon().setTintList(null);
+        }
+
+        recursiveSetEnabledAndDrawableState(mView);
+        mView.setActivated(mMenuItem.isActivated());
+
+        if (mMenuItem.getOnClickListener() != null
+                || mMenuItem.isCheckable()
+                || mMenuItem.isActivatable()) {
+            mView.setOnClickListener(v -> mMenuItem.performClick());
+        } else {
+            mView.setOnClickListener(null);
+            mView.setClickable(false);
+        }
+    }
+
+    private void recursiveSetEnabledAndDrawableState(View view) {
+        view.setEnabled(mMenuItem.isEnabled());
+
+        int[] drawableState = mMenuItem.isRestricted() ? RESTRICTED_STATE : null;
+        if (view instanceof ImageView) {
+            ((ImageView) view).setImageState(drawableState, true);
+        } else if (view instanceof DrawableStateView) {
+            ((DrawableStateView) view).setDrawableState(drawableState);
+        }
+
+        if (view instanceof ViewGroup) {
+            ViewGroup viewGroup = ((ViewGroup) view);
+            for (int i = 0; i < viewGroup.getChildCount(); i++) {
+                recursiveSetEnabledAndDrawableState(viewGroup.getChildAt(i));
+            }
+        }
+    }
+
+    static List<MenuItem> readMenuItemList(Context c, @XmlRes int resId) {
+        if (resId == 0) {
+            return new ArrayList<>();
+        }
+
+        try (XmlResourceParser parser = c.getResources().getXml(resId)) {
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+            List<MenuItem> menuItems = new ArrayList<>();
+
+            parser.next();
+            parser.next();
+            parser.require(XmlPullParser.START_TAG, null, "MenuItems");
+            while (parser.next() != XmlPullParser.END_TAG) {
+                menuItems.add(readMenuItem(c, parser, attrs));
+            }
+
+            return menuItems;
+        } catch (XmlPullParserException | IOException e) {
+            throw new RuntimeException("Unable to parse Menu Items", e);
+        }
+    }
+
+    private static MenuItem readMenuItem(Context c, XmlResourceParser parser, AttributeSet attrs)
+            throws XmlPullParserException, IOException {
+
+        parser.require(XmlPullParser.START_TAG, null, "MenuItem");
+
+        TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.CarUiToolbarMenuItem);
+        try {
+            int id = a.getResourceId(R.styleable.CarUiToolbarMenuItem_id, View.NO_ID);
+            String title = a.getString(R.styleable.CarUiToolbarMenuItem_title);
+            Drawable icon = a.getDrawable(R.styleable.CarUiToolbarMenuItem_icon);
+            boolean isSearch = a.getBoolean(R.styleable.CarUiToolbarMenuItem_search, false);
+            boolean isSettings = a.getBoolean(R.styleable.CarUiToolbarMenuItem_settings, false);
+            boolean tinted = a.getBoolean(R.styleable.CarUiToolbarMenuItem_tinted, true);
+            boolean visible = a.getBoolean(R.styleable.CarUiToolbarMenuItem_visible, true);
+            boolean showIconAndTitle = a.getBoolean(
+                    R.styleable.CarUiToolbarMenuItem_showIconAndTitle, false);
+            boolean checkable = a.getBoolean(R.styleable.CarUiToolbarMenuItem_checkable, false);
+            boolean checked = a.getBoolean(R.styleable.CarUiToolbarMenuItem_checked, false);
+            boolean checkedExists = a.hasValue(R.styleable.CarUiToolbarMenuItem_checked);
+            boolean activatable = a.getBoolean(R.styleable.CarUiToolbarMenuItem_activatable, false);
+            boolean activated = a.getBoolean(R.styleable.CarUiToolbarMenuItem_activated, false);
+            boolean activatedExists = a.hasValue(R.styleable.CarUiToolbarMenuItem_activated);
+            int displayBehaviorInt = a.getInt(R.styleable.CarUiToolbarMenuItem_displayBehavior, 0);
+            int uxRestrictions = a.getInt(R.styleable.CarUiToolbarMenuItem_uxRestrictions, 0);
+            String onClickMethod = a.getString(R.styleable.CarUiToolbarMenuItem_onClick);
+            MenuItem.OnClickListener onClickListener = null;
+
+            if (onClickMethod != null) {
+                Activity activity = CarUiUtils.getActivity(c);
+                if (activity == null) {
+                    throw new RuntimeException("Couldn't find an activity for the MenuItem");
+                }
+
+                try {
+                    Method m = activity.getClass().getMethod(onClickMethod, MenuItem.class);
+                    onClickListener = i -> {
+                        try {
+                            m.invoke(activity, i);
+                        } catch (InvocationTargetException | IllegalAccessException e) {
+                            throw new RuntimeException("Couldn't call the MenuItem's listener", e);
+                        }
+                    };
+                } catch (NoSuchMethodException e) {
+                    throw new RuntimeException("OnClick method "
+                            + onClickMethod + "(MenuItem) not found in your activity", e);
+                }
+            }
+
+            MenuItem.DisplayBehavior displayBehavior = displayBehaviorInt == 0
+                    ? MenuItem.DisplayBehavior.ALWAYS
+                    : MenuItem.DisplayBehavior.NEVER;
+
+            parser.next();
+            parser.require(XmlPullParser.END_TAG, null, "MenuItem");
+
+            MenuItem.Builder builder = MenuItem.builder(c)
+                    .setId(id)
+                    .setTitle(title)
+                    .setIcon(icon)
+                    .setOnClickListener(onClickListener)
+                    .setUxRestrictions(uxRestrictions)
+                    .setTinted(tinted)
+                    .setVisible(visible)
+                    .setShowIconAndTitle(showIconAndTitle)
+                    .setDisplayBehavior(displayBehavior);
+
+            if (isSearch) {
+                builder.setToSearch();
+            }
+
+            if (isSettings) {
+                builder.setToSettings();
+            }
+
+            if (checkable || checkedExists) {
+                builder.setChecked(checked);
+            }
+
+            if (activatable || activatedExists) {
+                builder.setActivated(activated);
+            }
+
+            return builder.build();
+        } finally {
+            a.recycle();
+        }
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ProgressBarController.java b/car-ui-lib/src/com/android/car/ui/toolbar/ProgressBarController.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ProgressBarController.java
rename to car-ui-lib/src/com/android/car/ui/toolbar/ProgressBarController.java
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ProgressBarControllerImpl.java b/car-ui-lib/src/com/android/car/ui/toolbar/ProgressBarControllerImpl.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/ProgressBarControllerImpl.java
rename to car-ui-lib/src/com/android/car/ui/toolbar/ProgressBarControllerImpl.java
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/SearchView.java b/car-ui-lib/src/com/android/car/ui/toolbar/SearchView.java
new file mode 100644
index 0000000..7f7eb80
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/SearchView.java
@@ -0,0 +1,241 @@
+/*
+ * 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.ui.toolbar;
+
+import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.android.car.ui.R;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * A search view used by {@link Toolbar}.
+ */
+public class SearchView extends ConstraintLayout {
+    private final InputMethodManager mInputMethodManager;
+    private final ImageView mIcon;
+    private final EditText mSearchText;
+    private final View mCloseIcon;
+    private final int mStartPaddingWithoutIcon;
+    private final int mStartPadding;
+    private final int mEndPadding;
+    private Set<Toolbar.OnSearchListener> mSearchListeners = Collections.emptySet();
+    private Set<Toolbar.OnSearchCompletedListener> mSearchCompletedListeners =
+            Collections.emptySet();
+    private final TextWatcher mTextWatcher = new TextWatcher() {
+        @Override
+        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+        }
+
+        @Override
+        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+        }
+
+        @Override
+        public void afterTextChanged(Editable editable) {
+            onSearch(editable.toString());
+        }
+    };
+
+    private boolean mIsPlainText = false;
+
+    public SearchView(Context context) {
+        this(context, null);
+    }
+
+    public SearchView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SearchView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        mInputMethodManager = (InputMethodManager)
+            getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+
+        LayoutInflater inflater = LayoutInflater.from(context);
+        inflater.inflate(R.layout.car_ui_toolbar_search_view, this, true);
+
+        mSearchText = requireViewByRefId(this, R.id.car_ui_toolbar_search_bar);
+        mIcon = requireViewByRefId(this, R.id.car_ui_toolbar_search_icon);
+        mCloseIcon = requireViewByRefId(this, R.id.car_ui_toolbar_search_close);
+
+        mCloseIcon.setOnClickListener(view -> mSearchText.getText().clear());
+        mCloseIcon.setVisibility(View.GONE);
+
+        mStartPaddingWithoutIcon = mSearchText.getPaddingStart();
+        mStartPadding = context.getResources().getDimensionPixelSize(
+                R.dimen.car_ui_toolbar_search_search_icon_container_width);
+        mEndPadding = context.getResources().getDimensionPixelSize(
+                R.dimen.car_ui_toolbar_search_close_icon_container_width);
+
+        mSearchText.setSaveEnabled(false);
+        mSearchText.setPaddingRelative(mStartPadding, 0, mEndPadding, 0);
+
+        mSearchText.setOnFocusChangeListener(
+                (view, hasFocus) -> {
+                    if (hasFocus) {
+                        mInputMethodManager.showSoftInput(view, 0);
+                    } else {
+                        mInputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
+                    }
+                });
+
+        mSearchText.addTextChangedListener(mTextWatcher);
+
+        mSearchText.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE
+                    || actionId == EditorInfo.IME_ACTION_SEARCH) {
+                mSearchText.clearFocus();
+                for (Toolbar.OnSearchCompletedListener listener : mSearchCompletedListeners) {
+                    listener.onSearchCompleted();
+                }
+            }
+            return false;
+        });
+    }
+
+    private boolean mWasShown = false;
+
+    @Override
+    public void onVisibilityChanged(@NonNull View changedView, int visibility) {
+        super.onVisibilityChanged(changedView, visibility);
+
+        boolean isShown = isShown();
+        if (isShown && !mWasShown) {
+            boolean hasQuery = mSearchText.getText().length() > 0;
+            mCloseIcon.setVisibility(hasQuery ? View.VISIBLE : View.GONE);
+            mSearchText.requestFocus();
+        }
+        mWasShown = isShown;
+    }
+
+    /**
+     * Adds a listener for the search text changing.
+     * See also {@link #unregisterOnSearchListener(Toolbar.OnSearchListener)}
+     */
+    public void setSearchListeners(Set<Toolbar.OnSearchListener> listeners) {
+        mSearchListeners = listeners;
+    }
+
+    /**
+     * Removes a search listener.
+     * See also {@link #registerOnSearchListener(Toolbar.OnSearchListener)}
+     */
+    public void setSearchCompletedListeners(Set<Toolbar.OnSearchCompletedListener> listeners) {
+        mSearchCompletedListeners = listeners;
+    }
+
+    /**
+     * Sets the search hint.
+     *
+     * @param resId A string resource id of the search hint.
+     */
+    public void setHint(int resId) {
+        mSearchText.setHint(resId);
+    }
+
+    /**
+     * Sets the search hint
+     *
+     * @param hint A CharSequence of the search hint.
+     */
+    public void setHint(CharSequence hint) {
+        mSearchText.setHint(hint);
+    }
+
+    /** Gets the search hint */
+    public CharSequence getHint() {
+        return mSearchText.getHint();
+    }
+
+    /**
+     * Sets a custom icon to display in the search box.
+     */
+    public void setIcon(Drawable d) {
+        if (d == null) {
+            mIcon.setImageResource(R.drawable.car_ui_icon_search);
+        } else {
+            mIcon.setImageDrawable(d);
+        }
+    }
+
+    /**
+     * Sets a custom icon to display in the search box.
+     */
+    public void setIcon(int resId) {
+        if (resId == 0) {
+            mIcon.setImageResource(R.drawable.car_ui_icon_search);
+        } else {
+            mIcon.setImageResource(resId);
+        }
+    }
+
+    /**
+     * Sets whether or not the search bar should look like a regular text box
+     * instead of a search box.
+     */
+    public void setPlainText(boolean plainText) {
+        if (plainText != mIsPlainText) {
+            if (plainText) {
+                mSearchText.setPaddingRelative(mStartPaddingWithoutIcon, 0, mEndPadding, 0);
+                mSearchText.setImeOptions(EditorInfo.IME_ACTION_DONE);
+                mIcon.setVisibility(View.GONE);
+            } else {
+                mSearchText.setPaddingRelative(mStartPadding, 0, mEndPadding, 0);
+                mSearchText.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
+                mIcon.setVisibility(View.VISIBLE);
+            }
+            mIsPlainText = plainText;
+
+            // Needed to detect changes to imeOptions
+            mInputMethodManager.restartInput(mSearchText);
+        }
+    }
+
+    private void onSearch(String query) {
+        mCloseIcon.setVisibility(TextUtils.isEmpty(query) ? View.GONE : View.VISIBLE);
+
+        for (Toolbar.OnSearchListener listener : mSearchListeners) {
+            listener.onSearch(query);
+        }
+    }
+
+    /**
+     * Sets the text being searched.
+     */
+    public void setSearchQuery(String query) {
+        mSearchText.setText(query);
+        mSearchText.setSelection(mSearchText.getText().length());
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/TabLayout.java b/car-ui-lib/src/com/android/car/ui/toolbar/TabLayout.java
new file mode 100644
index 0000000..1f973d2
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/TabLayout.java
@@ -0,0 +1,303 @@
+/*
+ * 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.ui.toolbar;
+
+import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.util.ArraySet;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.car.ui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Custom tab layout which supports adding tabs dynamically
+ *
+ * <p>It supports two layout modes:
+ * <ul><li>Flexible layout which will fill the width
+ * <li>Non-flexible layout which wraps content with a minimum tab width. By setting tab gravity,
+ * it can left aligned, right aligned or center aligned.
+ *
+ * <p>Scrolling function is not supported. If a tab item runs out of the tab layout bound, there
+ * is no way to access it. It's better to set the layout mode to flexible in this case.
+ *
+ * <p>Default tab item inflates from R.layout.car_ui_tab_item, but it also supports custom layout
+ * id, by overlaying R.layout.car_ui_tab_item_layout. By doing this, appearance of tab item view
+ * can be customized.
+ *
+ * <p>Touch feedback is using @android:attr/selectableItemBackground.
+ */
+public class TabLayout extends LinearLayout {
+
+    /**
+     * Listener that listens the tab selection change.
+     */
+    public interface Listener {
+        /** Callback triggered when a tab is selected. */
+        default void onTabSelected(Tab tab) {
+        }
+
+        /** Callback triggered when a tab is unselected. */
+        default void onTabUnselected(Tab tab) {
+        }
+
+        /** Callback triggered when a tab is reselected. */
+        default void onTabReselected(Tab tab) {
+        }
+    }
+
+    private final Set<Listener> mListeners = new ArraySet<>();
+
+    private final TabAdapter mTabAdapter;
+
+    public TabLayout(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        Resources resources = context.getResources();
+
+        boolean tabFlexibleLayout = resources.getBoolean(R.bool.car_ui_toolbar_tab_flexible_layout);
+        @LayoutRes int tabLayoutRes = tabFlexibleLayout
+                ? R.layout.car_ui_toolbar_tab_item_layout_flexible
+                : R.layout.car_ui_toolbar_tab_item_layout;
+        mTabAdapter = new TabAdapter(context, tabLayoutRes, this);
+    }
+
+    /**
+     * Add a tab to this layout. The tab will be added at the end of the list. If this is the first
+     * tab to be added it will become the selected tab.
+     */
+    public void addTab(Tab tab) {
+        mTabAdapter.add(tab);
+        // If there is only one tab in the group, set it to be selected.
+        if (mTabAdapter.getCount() == 1) {
+            mTabAdapter.selectTab(0);
+        }
+    }
+
+    /** Set the tab as the current selected tab. */
+    public void selectTab(Tab tab) {
+        mTabAdapter.selectTab(tab);
+    }
+
+    /** Set the tab at given position as the current selected tab. */
+    public void selectTab(int position) {
+        mTabAdapter.selectTab(position);
+    }
+
+    /** Returns how tab items it has. */
+    public int getTabCount() {
+        return mTabAdapter.getCount();
+    }
+
+    /** Returns the position of the given tab. */
+    public int getTabPosition(Tab tab) {
+        return mTabAdapter.getPosition(tab);
+    }
+
+    /** Return the tab at the given position. */
+    public Tab get(int position) {
+        return mTabAdapter.getItem(position);
+    }
+
+    /** Clear all tabs. */
+    public void clearAllTabs() {
+        mTabAdapter.clear();
+    }
+
+    /** Register a {@link Listener}. Same listener will only be registered once. */
+    public void addListener(@NonNull Listener listener) {
+        mListeners.add(listener);
+    }
+
+    /** Unregister a {@link Listener} */
+    public void removeListener(@NonNull Listener listener) {
+        mListeners.remove(listener);
+    }
+
+    private void dispatchOnTabSelected(Tab tab) {
+        for (Listener listener : mListeners) {
+            listener.onTabSelected(tab);
+        }
+    }
+
+    private void dispatchOnTabUnselected(Tab tab) {
+        for (Listener listener : mListeners) {
+            listener.onTabUnselected(tab);
+        }
+    }
+
+    private void dispatchOnTabReselected(Tab tab) {
+        for (Listener listener : mListeners) {
+            listener.onTabReselected(tab);
+        }
+    }
+
+    private void addTabView(View tabView, int position) {
+        addView(tabView, position);
+    }
+
+    private static class TabAdapter extends BaseAdapter {
+        private final Context mContext;
+        private final TabLayout mTabLayout;
+        @LayoutRes
+        private final int mTabItemLayoutRes;
+        private final List<Tab> mTabList;
+
+        private TabAdapter(Context context, @LayoutRes int res, TabLayout tabLayout) {
+            mTabList = new ArrayList<>();
+            mContext = context;
+            mTabItemLayoutRes = res;
+            mTabLayout = tabLayout;
+        }
+
+        private void add(@NonNull Tab tab) {
+            mTabList.add(tab);
+            notifyItemInserted(mTabList.size() - 1);
+        }
+
+        private void clear() {
+            mTabList.clear();
+            mTabLayout.removeAllViews();
+        }
+
+        private int getPosition(Tab tab) {
+            return mTabList.indexOf(tab);
+        }
+
+        @Override
+        public int getCount() {
+            return mTabList.size();
+        }
+
+        @Override
+        public Tab getItem(int position) {
+            return mTabList.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        @NonNull
+        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+            View tabItemView = LayoutInflater.from(mContext)
+                    .inflate(mTabItemLayoutRes, parent, false);
+
+            presentTabItemView(position, tabItemView);
+            return tabItemView;
+        }
+
+        private void selectTab(Tab tab) {
+            selectTab(getPosition(tab));
+        }
+
+        private void selectTab(int position) {
+            if (position < 0 || position >= getCount()) {
+                throw new IndexOutOfBoundsException("Invalid position");
+            }
+
+            for (int i = 0; i < getCount(); i++) {
+                Tab tab = mTabList.get(i);
+                boolean isTabSelected = position == i;
+                if (tab.mIsSelected != isTabSelected) {
+                    tab.mIsSelected = isTabSelected;
+                    notifyItemChanged(i);
+                    if (tab.mIsSelected) {
+                        mTabLayout.dispatchOnTabSelected(tab);
+                    } else {
+                        mTabLayout.dispatchOnTabUnselected(tab);
+                    }
+                } else if (tab.mIsSelected) {
+                    mTabLayout.dispatchOnTabReselected(tab);
+                }
+            }
+        }
+
+        /** Represent the tab item at given position without destroying and recreating UI. */
+        private void notifyItemChanged(int position) {
+            View tabItemView = mTabLayout.getChildAt(position);
+            presentTabItemView(position, tabItemView);
+        }
+
+        private void notifyItemInserted(int position) {
+            View insertedView = getView(position, null, mTabLayout);
+            mTabLayout.addTabView(insertedView, position);
+        }
+
+        private void presentTabItemView(int position, @NonNull View tabItemView) {
+            Tab tab = mTabList.get(position);
+
+            ImageView iconView = requireViewByRefId(tabItemView, R.id.car_ui_toolbar_tab_item_icon);
+            TextView textView = requireViewByRefId(tabItemView, R.id.car_ui_toolbar_tab_item_text);
+
+            tabItemView.setOnClickListener(view -> selectTab(tab));
+            tab.bindText(textView);
+            tab.bindIcon(iconView);
+            tabItemView.setActivated(tab.mIsSelected);
+            textView.setTextAppearance(tab.mIsSelected
+                    ? R.style.TextAppearance_CarUi_Widget_Toolbar_Tab_Selected
+                    : R.style.TextAppearance_CarUi_Widget_Toolbar_Tab);
+        }
+    }
+
+    /** Tab entity. */
+    public static class Tab {
+        private final Drawable mIcon;
+        private final CharSequence mText;
+        private boolean mIsSelected;
+
+        public Tab(@Nullable Drawable icon, @Nullable CharSequence text) {
+            mIcon = icon;
+            mText = text;
+        }
+
+        /** Set tab text. */
+        protected void bindText(TextView textView) {
+            textView.setText(mText);
+        }
+
+        /** Set icon drawable. TODO(b/139444064): revise this api.*/
+        protected void bindIcon(ImageView imageView) {
+            imageView.setImageDrawable(mIcon);
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java b/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
new file mode 100644
index 0000000..b069fb0
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/Toolbar.java
@@ -0,0 +1,660 @@
+/*
+ * 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.ui.toolbar;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.widget.FrameLayout;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.annotation.XmlRes;
+
+import com.android.car.ui.R;
+
+import java.util.List;
+
+/**
+ * A toolbar for Android Automotive OS apps.
+ *
+ * <p>This isn't a toolbar in the android framework sense, it's merely a custom view that can be
+ * added to a layout. (You can't call
+ * {@link android.app.Activity#setActionBar(android.widget.Toolbar)} with it)
+ *
+ * <p>The toolbar supports a navigation button, title, tabs, search, and {@link MenuItem MenuItems}
+ */
+public class Toolbar extends FrameLayout implements ToolbarController {
+
+    /** Callback that will be issued whenever the height of toolbar is changed. */
+    public interface OnHeightChangedListener {
+        /**
+         * Will be called when the height of the toolbar is changed.
+         *
+         * @param height new height of the toolbar
+         */
+        void onHeightChanged(int height);
+    }
+
+    /** Back button listener */
+    public interface OnBackListener {
+        /**
+         * Invoked when the user clicks on the back button. By default, the toolbar will call
+         * the Activity's {@link android.app.Activity#onBackPressed()}. Returning true from
+         * this method will absorb the back press and prevent that behavior.
+         */
+        boolean onBack();
+    }
+
+    /** Tab selection listener */
+    public interface OnTabSelectedListener {
+        /** Called when a {@link TabLayout.Tab} is selected */
+        void onTabSelected(TabLayout.Tab tab);
+    }
+
+    /** Search listener */
+    public interface OnSearchListener {
+        /**
+         * Invoked when the user edits a search query.
+         *
+         * <p>This is called for every letter the user types, and also empty strings if the user
+         * erases everything.
+         */
+        void onSearch(String query);
+    }
+
+    /** Search completed listener */
+    public interface OnSearchCompletedListener {
+        /**
+         * Invoked when the user submits a search query by clicking the keyboard's search / done
+         * button.
+         */
+        void onSearchCompleted();
+    }
+
+    private static final String TAG = "CarUiToolbar";
+
+    /** Enum of states the toolbar can be in. Controls what elements of the toolbar are displayed */
+    public enum State {
+        /**
+         * In the HOME state, the logo will be displayed if there is one, and no navigation icon
+         * will be displayed. The tab bar will be visible. The title will be displayed if there
+         * is space. MenuItems will be displayed.
+         */
+        HOME,
+        /**
+         * In the SUBPAGE state, the logo will be replaced with a back button, the tab bar won't
+         * be visible. The title and MenuItems will be displayed.
+         */
+        SUBPAGE,
+        /**
+         * In the SEARCH state, only the back button and the search bar will be visible.
+         */
+        SEARCH,
+        /**
+         * In the EDIT state, the search bar will look like a regular text box, but will be
+         * functionally identical to the SEARCH state.
+         */
+        EDIT,
+    }
+
+    private ToolbarControllerImpl mController;
+    private boolean mEatingTouch = false;
+    private boolean mEatingHover = false;
+
+    public Toolbar(Context context) {
+        this(context, null);
+    }
+
+    public Toolbar(Context context, AttributeSet attrs) {
+        this(context, attrs, R.attr.CarUiToolbarStyle);
+    }
+
+    public Toolbar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public Toolbar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        LayoutInflater inflater = (LayoutInflater) context
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(getToolbarLayout(), this, true);
+
+        mController = new ToolbarControllerImpl(this);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.CarUiToolbar, defStyleAttr, defStyleRes);
+
+        try {
+            setShowTabsInSubpage(a.getBoolean(R.styleable.CarUiToolbar_showTabsInSubpage, false));
+            setTitle(a.getString(R.styleable.CarUiToolbar_title));
+            setLogo(a.getResourceId(R.styleable.CarUiToolbar_logo, 0));
+            setBackgroundShown(a.getBoolean(R.styleable.CarUiToolbar_showBackground, true));
+            setMenuItems(a.getResourceId(R.styleable.CarUiToolbar_menuItems, 0));
+            String searchHint = a.getString(R.styleable.CarUiToolbar_searchHint);
+            if (searchHint != null) {
+                setSearchHint(searchHint);
+            }
+
+            switch (a.getInt(R.styleable.CarUiToolbar_car_ui_state, 0)) {
+                case 0:
+                    setState(State.HOME);
+                    break;
+                case 1:
+                    setState(State.SUBPAGE);
+                    break;
+                case 2:
+                    setState(State.SEARCH);
+                    break;
+                default:
+                    if (Log.isLoggable(TAG, Log.WARN)) {
+                        Log.w(TAG, "Unknown initial state");
+                    }
+                    break;
+            }
+
+            switch (a.getInt(R.styleable.CarUiToolbar_car_ui_navButtonMode, 0)) {
+                case 0:
+                    setNavButtonMode(NavButtonMode.BACK);
+                    break;
+                case 1:
+                    setNavButtonMode(NavButtonMode.CLOSE);
+                    break;
+                case 2:
+                    setNavButtonMode(NavButtonMode.DOWN);
+                    break;
+                default:
+                    if (Log.isLoggable(TAG, Log.WARN)) {
+                        Log.w(TAG, "Unknown navigation button style");
+                    }
+                    break;
+            }
+        } finally {
+            a.recycle();
+        }
+    }
+
+    /**
+     * Override this in a subclass to allow for different toolbar layouts within a single app.
+     *
+     * <p>Non-system apps should not use this, as customising the layout isn't possible with RROs
+     */
+    protected int getToolbarLayout() {
+        if (getContext().getResources().getBoolean(
+                R.bool.car_ui_toolbar_tabs_on_second_row)) {
+            return R.layout.car_ui_toolbar_two_row;
+        }
+
+        return R.layout.car_ui_toolbar;
+    }
+
+    /**
+     * Returns {@code true} if a two row layout in enabled for the toolbar.
+     */
+    @Override
+    public boolean isTabsInSecondRow() {
+        return mController.isTabsInSecondRow();
+    }
+
+    /**
+     * Sets the title of the toolbar to a string resource.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setTitle(@StringRes int title) {
+        mController.setTitle(title);
+    }
+
+    /**
+     * Sets the title of the toolbar to a CharSequence.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setTitle(CharSequence title) {
+        mController.setTitle(title);
+    }
+
+    @Override
+    public CharSequence getTitle() {
+        return mController.getTitle();
+    }
+
+    /**
+     * Sets the subtitle of the toolbar to a string resource.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setSubtitle(@StringRes int title) {
+        mController.setSubtitle(title);
+    }
+
+    /**
+     * Sets the subtitle of the toolbar to a CharSequence.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setSubtitle(CharSequence title) {
+        mController.setSubtitle(title);
+    }
+
+    @Override
+    public CharSequence getSubtitle() {
+        return mController.getSubtitle();
+    }
+
+    /**
+     * Gets the {@link TabLayout} for this toolbar.
+     */
+    @Override
+    public TabLayout getTabLayout() {
+        return mController.getTabLayout();
+    }
+
+    /**
+     * Adds a tab to this toolbar. You can listen for when it is selected via
+     * {@link #registerOnTabSelectedListener(OnTabSelectedListener)}.
+     */
+    @Override
+    public void addTab(TabLayout.Tab tab) {
+        mController.addTab(tab);
+    }
+
+    /** Removes all the tabs. */
+    @Override
+    public void clearAllTabs() {
+        mController.clearAllTabs();
+    }
+
+    /**
+     * Gets a tab added to this toolbar. See
+     * {@link #addTab(TabLayout.Tab)}.
+     */
+    @Override
+    public TabLayout.Tab getTab(int position) {
+        return mController.getTab(position);
+    }
+
+    /**
+     * Selects a tab added to this toolbar. See
+     * {@link #addTab(TabLayout.Tab)}.
+     */
+    @Override
+    public void selectTab(int position) {
+        mController.selectTab(position);
+    }
+
+    /**
+     * Sets whether or not tabs should also be shown in the SUBPAGE {@link State}.
+     */
+    @Override
+    public void setShowTabsInSubpage(boolean showTabs) {
+        mController.setShowTabsInSubpage(showTabs);
+    }
+
+    /**
+     * Gets whether or not tabs should also be shown in the SUBPAGE {@link State}.
+     */
+    @Override
+    public boolean getShowTabsInSubpage() {
+        return mController.getShowTabsInSubpage();
+    }
+
+    /**
+     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
+     * will be displayed next to the title.
+     */
+    @Override
+    public void setLogo(@DrawableRes int resId) {
+        mController.setLogo(resId);
+    }
+
+    /**
+     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
+     * will be displayed next to the title.
+     */
+    @Override
+    public void setLogo(Drawable drawable) {
+        mController.setLogo(drawable);
+    }
+
+    /** Sets the hint for the search bar. */
+    @Override
+    public void setSearchHint(@StringRes int resId) {
+        mController.setSearchHint(resId);
+    }
+
+    /** Sets the hint for the search bar. */
+    @Override
+    public void setSearchHint(CharSequence hint) {
+        mController.setSearchHint(hint);
+    }
+
+    /** Gets the search hint */
+    @Override
+    public CharSequence getSearchHint() {
+        return mController.getSearchHint();
+    }
+
+    /**
+     * Sets the icon to display in the search box.
+     *
+     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
+     * a similar place.
+     */
+    @Override
+    public void setSearchIcon(@DrawableRes int resId) {
+        mController.setSearchIcon(resId);
+    }
+
+    /**
+     * Sets the icon to display in the search box.
+     *
+     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
+     * a similar place.
+     */
+    @Override
+    public void setSearchIcon(Drawable d) {
+        mController.setSearchIcon(d);
+    }
+
+    /**
+     * An enum of possible styles the nav button could be in. All styles will still call
+     * {@link OnBackListener#onBack()}.
+     */
+    public enum NavButtonMode {
+        /** A back button */
+        BACK,
+        /** A close button */
+        CLOSE,
+        /** A down button, used to indicate that the page will animate down when navigating away */
+        DOWN
+    }
+
+    /** Sets the {@link NavButtonMode} */
+    @Override
+    public void setNavButtonMode(NavButtonMode style) {
+        mController.setNavButtonMode(style);
+    }
+
+    /** Gets the {@link NavButtonMode} */
+    @Override
+    public NavButtonMode getNavButtonMode() {
+        return mController.getNavButtonMode();
+    }
+
+    /**
+     * setBackground is disallowed, to prevent apps from deviating from the intended style too much.
+     */
+    @Override
+    public void setBackground(Drawable d) {
+        throw new UnsupportedOperationException(
+                "You can not change the background of a CarUi toolbar, use "
+                        + "setBackgroundShown(boolean) or an RRO instead.");
+    }
+
+    /** Show/hide the background. When hidden, the toolbar is completely transparent. */
+    @Override
+    public void setBackgroundShown(boolean shown) {
+        mController.setBackgroundShown(shown);
+    }
+
+    /** Returns true is the toolbar background is shown */
+    @Override
+    public boolean getBackgroundShown() {
+        return mController.getBackgroundShown();
+    }
+
+    /**
+     * Sets the {@link MenuItem Menuitems} to display.
+     */
+    @Override
+    public void setMenuItems(@Nullable List<MenuItem> items) {
+        mController.setMenuItems(items);
+    }
+
+    /**
+     * Sets the {@link MenuItem Menuitems} to display to a list defined in XML.
+     *
+     * <p>If this method is called twice with the same argument (and {@link #setMenuItems(List)}
+     * wasn't called), nothing will happen the second time, even if the MenuItems were changed.
+     *
+     * <p>The XML file must have one <MenuItems> tag, with a variable number of <MenuItem>
+     * child tags. See CarUiToolbarMenuItem in CarUi's attrs.xml for a list of available attributes.
+     *
+     * Example:
+     * <pre>
+     * <MenuItems>
+     *     <MenuItem
+     *         app:title="Foo"/>
+     *     <MenuItem
+     *         app:title="Bar"
+     *         app:icon="@drawable/ic_tracklist"
+     *         app:onClick="xmlMenuItemClicked"/>
+     *     <MenuItem
+     *         app:title="Bar"
+     *         app:checkable="true"
+     *         app:uxRestrictions="FULLY_RESTRICTED"
+     *         app:onClick="xmlMenuItemClicked"/>
+     * </MenuItems>
+     * </pre>
+     *
+     * @return The MenuItems that were loaded from XML.
+     * @see #setMenuItems(List)
+     */
+    @Override
+    public List<MenuItem> setMenuItems(@XmlRes int resId) {
+        return mController.setMenuItems(resId);
+    }
+
+    /** Gets the {@link MenuItem MenuItems} currently displayed */
+    @Override
+    @NonNull
+    public List<MenuItem> getMenuItems() {
+        return mController.getMenuItems();
+    }
+
+    /** Gets a {@link MenuItem} by id. */
+    @Override
+    @Nullable
+    public MenuItem findMenuItemById(int id) {
+        return mController.findMenuItemById(id);
+    }
+
+    /** Gets a {@link MenuItem} by id. Will throw an exception if not found. */
+    @Override
+    @NonNull
+    public MenuItem requireMenuItemById(int id) {
+        return mController.requireMenuItemById(id);
+    }
+
+    /**
+     * Set whether or not to show the {@link MenuItem MenuItems} while searching. Default false.
+     * Even if this is set to true, the {@link MenuItem} created by
+     * {@link MenuItem.Builder#setToSearch()} will still be hidden.
+     */
+    @Override
+    public void setShowMenuItemsWhileSearching(boolean showMenuItems) {
+        mController.setShowMenuItemsWhileSearching(showMenuItems);
+    }
+
+    /** Returns if {@link MenuItem MenuItems} are shown while searching */
+    @Override
+    public boolean getShowMenuItemsWhileSearching() {
+        return mController.getShowMenuItemsWhileSearching();
+    }
+
+    /**
+     * Sets the search query.
+     */
+    @Override
+    public void setSearchQuery(String query) {
+        mController.setSearchQuery(query);
+    }
+
+    /**
+     * Sets the state of the toolbar. This will show/hide the appropriate elements of the toolbar
+     * for the desired state.
+     */
+    @Override
+    public void setState(State state) {
+        mController.setState(state);
+    }
+
+    /** Gets the current {@link State} of the toolbar. */
+    @Override
+    public State getState() {
+        return mController.getState();
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        // Copied from androidx.appcompat.widget.Toolbar
+
+        // Toolbars always eat touch events, but should still respect the touch event dispatch
+        // contract. If the normal View implementation doesn't want the events, we'll just silently
+        // eat the rest of the gesture without reporting the events to the default implementation
+        // since that's what it expects.
+
+        final int action = ev.getActionMasked();
+        if (action == MotionEvent.ACTION_DOWN) {
+            mEatingTouch = false;
+        }
+
+        if (!mEatingTouch) {
+            final boolean handled = super.onTouchEvent(ev);
+            if (action == MotionEvent.ACTION_DOWN && !handled) {
+                mEatingTouch = true;
+            }
+        }
+
+        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+            mEatingTouch = false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean onHoverEvent(MotionEvent ev) {
+        // Copied from androidx.appcompat.widget.Toolbar
+
+        // Same deal as onTouchEvent() above. Eat all hover events, but still
+        // respect the touch event dispatch contract.
+
+        final int action = ev.getActionMasked();
+        if (action == MotionEvent.ACTION_HOVER_ENTER) {
+            mEatingHover = false;
+        }
+
+        if (!mEatingHover) {
+            final boolean handled = super.onHoverEvent(ev);
+            if (action == MotionEvent.ACTION_HOVER_ENTER && !handled) {
+                mEatingHover = true;
+            }
+        }
+
+        if (action == MotionEvent.ACTION_HOVER_EXIT || action == MotionEvent.ACTION_CANCEL) {
+            mEatingHover = false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Registers a new {@link OnHeightChangedListener} to the list of listeners. Register a
+     * {@link com.android.car.ui.recyclerview.CarUiRecyclerView} only if there is a toolbar at
+     * the top and a {@link com.android.car.ui.recyclerview.CarUiRecyclerView} in the view and
+     * nothing else. {@link com.android.car.ui.recyclerview.CarUiRecyclerView} will
+     * automatically adjust its height according to the height of the Toolbar.
+     */
+    @Override
+    public void registerToolbarHeightChangeListener(
+            OnHeightChangedListener listener) {
+        mController.registerToolbarHeightChangeListener(listener);
+    }
+
+    /** Unregisters an existing {@link OnHeightChangedListener} from the list of listeners. */
+    @Override
+    public boolean unregisterToolbarHeightChangeListener(
+            OnHeightChangedListener listener) {
+        return mController.unregisterToolbarHeightChangeListener(listener);
+    }
+
+    /** Registers a new {@link OnTabSelectedListener} to the list of listeners. */
+    @Override
+    public void registerOnTabSelectedListener(OnTabSelectedListener listener) {
+        mController.registerOnTabSelectedListener(listener);
+    }
+
+    /** Unregisters an existing {@link OnTabSelectedListener} from the list of listeners. */
+    @Override
+    public boolean unregisterOnTabSelectedListener(OnTabSelectedListener listener) {
+        return mController.unregisterOnTabSelectedListener(listener);
+    }
+
+    /** Registers a new {@link OnSearchListener} to the list of listeners. */
+    @Override
+    public void registerOnSearchListener(OnSearchListener listener) {
+        mController.registerOnSearchListener(listener);
+    }
+
+    /** Unregisters an existing {@link OnSearchListener} from the list of listeners. */
+    @Override
+    public boolean unregisterOnSearchListener(OnSearchListener listener) {
+        return mController.unregisterOnSearchListener(listener);
+    }
+
+    /** Registers a new {@link OnSearchCompletedListener} to the list of listeners. */
+    @Override
+    public void registerOnSearchCompletedListener(OnSearchCompletedListener listener) {
+        mController.registerOnSearchCompletedListener(listener);
+    }
+
+    /** Unregisters an existing {@link OnSearchCompletedListener} from the list of listeners. */
+    @Override
+    public boolean unregisterOnSearchCompletedListener(OnSearchCompletedListener listener) {
+        return mController.unregisterOnSearchCompletedListener(listener);
+    }
+
+    /** Registers a new {@link OnBackListener} to the list of listeners. */
+    @Override
+    public void registerOnBackListener(OnBackListener listener) {
+        mController.registerOnBackListener(listener);
+    }
+
+    /** Unregisters an existing {@link OnBackListener} from the list of listeners. */
+    @Override
+    public boolean unregisterOnBackListener(OnBackListener listener) {
+        return mController.unregisterOnBackListener(listener);
+    }
+
+    /** Returns the progress bar */
+    @Override
+    public ProgressBarController getProgressBar() {
+        return mController.getProgressBar();
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/ToolbarController.java b/car-ui-lib/src/com/android/car/ui/toolbar/ToolbarController.java
new file mode 100644
index 0000000..4eb009d
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/ToolbarController.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.toolbar;
+
+import android.graphics.drawable.Drawable;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.annotation.XmlRes;
+
+import java.util.List;
+
+/**
+ * An interface for accessing a Chassis Toolbar, regardless of how the underlying
+ * views are represented.
+ */
+public interface ToolbarController {
+
+    /**
+     * Returns {@code true} if a two row layout in enabled for the toolbar.
+     */
+    boolean isTabsInSecondRow();
+
+    /**
+     * Sets the title of the toolbar to a string resource.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    void setTitle(@StringRes int title);
+
+    /**
+     * Sets the title of the toolbar to a CharSequence.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    void setTitle(CharSequence title);
+
+    /**
+     * Gets the current toolbar title.
+     */
+    CharSequence getTitle();
+
+    /**
+     * Sets the subtitle of the toolbar to a string resource.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    void setSubtitle(@StringRes int title);
+
+    /**
+     * Sets the subtitle of the toolbar to a CharSequence.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    void setSubtitle(CharSequence title);
+
+    /**
+     * Gets the current toolbar subtitle.
+     */
+    CharSequence getSubtitle();
+
+    /**
+     * Gets the {@link TabLayout} for this toolbar.
+     */
+    TabLayout getTabLayout();
+
+    /**
+     * Adds a tab to this toolbar. You can listen for when it is selected via
+     * {@link #registerOnTabSelectedListener(Toolbar.OnTabSelectedListener)}.
+     */
+    void addTab(TabLayout.Tab tab);
+
+    /** Removes all the tabs. */
+    void clearAllTabs();
+
+    /**
+     * Gets a tab added to this toolbar. See
+     * {@link #addTab(TabLayout.Tab)}.
+     */
+    TabLayout.Tab getTab(int position);
+
+    /**
+     * Selects a tab added to this toolbar. See
+     * {@link #addTab(TabLayout.Tab)}.
+     */
+    void selectTab(int position);
+
+    /**
+     * Sets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
+     */
+    void setShowTabsInSubpage(boolean showTabs);
+
+    /**
+     * Gets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
+     */
+    boolean getShowTabsInSubpage();
+
+    /**
+     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
+     * will be displayed next to the title.
+     */
+    void setLogo(@DrawableRes int resId);
+
+    /**
+     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
+     * will be displayed next to the title.
+     */
+    void setLogo(Drawable drawable);
+
+    /** Sets the hint for the search bar. */
+    void setSearchHint(@StringRes int resId);
+
+    /** Sets the hint for the search bar. */
+    void setSearchHint(CharSequence hint);
+
+    /** Gets the search hint */
+    CharSequence getSearchHint();
+
+    /**
+     * Sets the icon to display in the search box.
+     *
+     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
+     * a similar place.
+     */
+    void setSearchIcon(@DrawableRes int resId);
+
+    /**
+     * Sets the icon to display in the search box.
+     *
+     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
+     * a similar place.
+     */
+    void setSearchIcon(Drawable d);
+
+
+    /** Sets the {@link Toolbar.NavButtonMode} */
+    void setNavButtonMode(Toolbar.NavButtonMode style);
+
+    /** Gets the {@link Toolbar.NavButtonMode} */
+    Toolbar.NavButtonMode getNavButtonMode();
+
+    /** Show/hide the background. When hidden, the toolbar is completely transparent. */
+    void setBackgroundShown(boolean shown);
+
+    /** Returns true is the toolbar background is shown */
+    boolean getBackgroundShown();
+
+    /**
+     * Sets the {@link MenuItem Menuitems} to display.
+     */
+    void setMenuItems(@Nullable List<MenuItem> items);
+
+    /**
+     * Sets the {@link MenuItem Menuitems} to display to a list defined in XML.
+     *
+     * <p>If this method is called twice with the same argument (and {@link #setMenuItems(List)}
+     * wasn't called), nothing will happen the second time, even if the MenuItems were changed.
+     *
+     * <p>The XML file must have one <MenuItems> tag, with a variable number of <MenuItem>
+     * child tags. See CarUiToolbarMenuItem in CarUi's attrs.xml for a list of available attributes.
+     *
+     * Example:
+     * <pre>
+     * <MenuItems>
+     *     <MenuItem
+     *         app:title="Foo"/>
+     *     <MenuItem
+     *         app:title="Bar"
+     *         app:icon="@drawable/ic_tracklist"
+     *         app:onClick="xmlMenuItemClicked"/>
+     *     <MenuItem
+     *         app:title="Bar"
+     *         app:checkable="true"
+     *         app:uxRestrictions="FULLY_RESTRICTED"
+     *         app:onClick="xmlMenuItemClicked"/>
+     * </MenuItems>
+     * </pre>
+     *
+     * @return The MenuItems that were loaded from XML.
+     * @see #setMenuItems(List)
+     */
+    List<MenuItem> setMenuItems(@XmlRes int resId);
+
+    /** Gets the {@link MenuItem MenuItems} currently displayed */
+    @NonNull
+    List<MenuItem> getMenuItems();
+
+    /** Gets a {@link MenuItem} by id. */
+    @Nullable
+    MenuItem findMenuItemById(int id);
+
+    /** Gets a {@link MenuItem} by id. Will throw an IllegalArgumentException if not found. */
+    @NonNull
+    MenuItem requireMenuItemById(int id);
+
+    /**
+     * Set whether or not to show the {@link MenuItem MenuItems} while searching. Default false.
+     * Even if this is set to true, the {@link MenuItem} created by
+     * {@link MenuItem.Builder#setToSearch()} will still be hidden.
+     */
+    void setShowMenuItemsWhileSearching(boolean showMenuItems);
+
+    /** Returns if {@link MenuItem MenuItems} are shown while searching */
+    boolean getShowMenuItemsWhileSearching();
+
+    /**
+     * Sets the search query.
+     */
+    void setSearchQuery(String query);
+
+    /**
+     * Sets the state of the toolbar. This will show/hide the appropriate elements of the toolbar
+     * for the desired state.
+     */
+    void setState(Toolbar.State state);
+
+    /** Gets the current {@link Toolbar.State} of the toolbar. */
+    Toolbar.State getState();
+
+    /**
+     * Registers a new {@link Toolbar.OnHeightChangedListener} to the list of listeners. Register a
+     * {@link com.android.car.ui.recyclerview.CarUiRecyclerView} only if there is a toolbar at
+     * the top and a {@link com.android.car.ui.recyclerview.CarUiRecyclerView} in the view and
+     * nothing else. {@link com.android.car.ui.recyclerview.CarUiRecyclerView} will
+     * automatically adjust its height according to the height of the Toolbar.
+     */
+    void registerToolbarHeightChangeListener(Toolbar.OnHeightChangedListener listener);
+
+    /** Unregisters an existing {@link Toolbar.OnHeightChangedListener} from the list of
+     * listeners. */
+    boolean unregisterToolbarHeightChangeListener(Toolbar.OnHeightChangedListener listener);
+
+    /** Registers a new {@link Toolbar.OnTabSelectedListener} to the list of listeners. */
+    void registerOnTabSelectedListener(Toolbar.OnTabSelectedListener listener);
+
+    /** Unregisters an existing {@link Toolbar.OnTabSelectedListener} from the list of listeners. */
+    boolean unregisterOnTabSelectedListener(Toolbar.OnTabSelectedListener listener);
+
+    /** Registers a new {@link Toolbar.OnSearchListener} to the list of listeners. */
+    void registerOnSearchListener(Toolbar.OnSearchListener listener);
+
+    /** Unregisters an existing {@link Toolbar.OnSearchListener} from the list of listeners. */
+    boolean unregisterOnSearchListener(Toolbar.OnSearchListener listener);
+
+    /** Registers a new {@link Toolbar.OnSearchCompletedListener} to the list of listeners. */
+    void registerOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener);
+
+    /** Unregisters an existing {@link Toolbar.OnSearchCompletedListener} from the list of
+     * listeners. */
+    boolean unregisterOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener);
+
+    /** Registers a new {@link Toolbar.OnBackListener} to the list of listeners. */
+    void registerOnBackListener(Toolbar.OnBackListener listener);
+
+    /** Unregisters an existing {@link Toolbar.OnBackListener} from the list of listeners. */
+    boolean unregisterOnBackListener(Toolbar.OnBackListener listener);
+
+    /** Gets a {@link ProgressBarController} */
+    ProgressBarController getProgressBar();
+}
diff --git a/car-ui-lib/src/com/android/car/ui/toolbar/ToolbarControllerImpl.java b/car-ui-lib/src/com/android/car/ui/toolbar/ToolbarControllerImpl.java
new file mode 100644
index 0000000..1ef9f4a
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/toolbar/ToolbarControllerImpl.java
@@ -0,0 +1,867 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.toolbar;
+
+import static android.view.View.GONE;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+
+import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.annotation.XmlRes;
+
+import com.android.car.ui.AlertDialogBuilder;
+import com.android.car.ui.R;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+import com.android.car.ui.utils.CarUiUtils;
+import com.android.car.ui.utils.CarUxRestrictionsUtil;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * The implementation of {@link ToolbarController}. This class takes a ViewGroup, and looks
+ * in the ViewGroup to find all the toolbar-related views to control.
+ */
+public class ToolbarControllerImpl implements ToolbarController {
+    private static final String TAG = "CarUiToolbarController";
+
+    private View mBackground;
+    private ImageView mNavIcon;
+    private ImageView mLogoInNavIconSpace;
+    private ViewGroup mNavIconContainer;
+    private ViewGroup mTitleContainer;
+    private TextView mTitle;
+    private TextView mSubtitle;
+    private ImageView mTitleLogo;
+    private ViewGroup mTitleLogoContainer;
+    private TabLayout mTabLayout;
+    private ViewGroup mMenuItemsContainer;
+    private FrameLayout mSearchViewContainer;
+    private SearchView mSearchView;
+
+
+    // Cached values that we will send to views when they are inflated
+    private CharSequence mSearchHint;
+    private Drawable mSearchIcon;
+    private String mSearchQuery;
+    private final Context mContext;
+    private final Set<Toolbar.OnSearchListener> mOnSearchListeners = new HashSet<>();
+    private final Set<Toolbar.OnSearchCompletedListener> mOnSearchCompletedListeners =
+            new HashSet<>();
+
+    private final Set<Toolbar.OnBackListener> mOnBackListeners = new HashSet<>();
+    private final Set<Toolbar.OnTabSelectedListener> mOnTabSelectedListeners = new HashSet<>();
+    private final Set<Toolbar.OnHeightChangedListener> mOnHeightChangedListeners = new HashSet<>();
+
+    private final MenuItem mOverflowButton;
+    private final boolean mIsTabsInSecondRow;
+    private boolean mShowTabsInSubpage = false;
+    private boolean mHasLogo = false;
+    private boolean mShowMenuItemsWhileSearching;
+    private Toolbar.State mState = Toolbar.State.HOME;
+    private Toolbar.NavButtonMode mNavButtonMode = Toolbar.NavButtonMode.BACK;
+    @NonNull
+    private List<MenuItem> mMenuItems = Collections.emptyList();
+    private List<MenuItem> mOverflowItems = new ArrayList<>();
+    private final List<CarUiListItem> mUiOverflowItems = new ArrayList<>();
+    private final CarUiListItemAdapter mOverflowAdapter;
+    private final List<MenuItemRenderer> mMenuItemRenderers = new ArrayList<>();
+    private View[] mMenuItemViews;
+    private int mMenuItemsXmlId = 0;
+    private AlertDialog mOverflowDialog;
+    private boolean mNavIconSpaceReserved;
+    private boolean mLogoFillsNavIconSpace;
+    private boolean mShowLogo;
+    private final ProgressBarController mProgressBar;
+    private final MenuItem.Listener mOverflowItemListener = item -> {
+        updateOverflowDialog(item);
+        setState(getState());
+    };
+
+    // Despite the warning, this has to be a field so it's not garbage-collected.
+    // The only other reference to it is a weak reference
+    private final CarUxRestrictionsUtil.OnUxRestrictionsChangedListener
+            mOnUxRestrictionsChangedListener = restrictions -> {
+                for (MenuItemRenderer renderer : mMenuItemRenderers) {
+                    renderer.setCarUxRestrictions(restrictions);
+                }
+            };
+
+
+    public ToolbarControllerImpl(View view) {
+        mContext = view.getContext();
+        mOverflowButton = MenuItem.builder(getContext())
+                .setIcon(R.drawable.car_ui_icon_overflow_menu)
+                .setTitle(R.string.car_ui_toolbar_menu_item_overflow_title)
+                .setOnClickListener(v -> {
+                    if (mOverflowDialog == null) {
+                        if (Log.isLoggable(TAG, Log.ERROR)) {
+                            Log.e(TAG, "Overflow dialog was null when trying to show it!");
+                        }
+                    } else {
+                        mOverflowDialog.show();
+                    }
+                })
+                .build();
+
+        mIsTabsInSecondRow = getContext().getResources().getBoolean(
+                R.bool.car_ui_toolbar_tabs_on_second_row);
+        mNavIconSpaceReserved = getContext().getResources().getBoolean(
+                R.bool.car_ui_toolbar_nav_icon_reserve_space);
+        mLogoFillsNavIconSpace = getContext().getResources().getBoolean(
+                R.bool.car_ui_toolbar_logo_fills_nav_icon_space);
+        mShowLogo = getContext().getResources().getBoolean(
+                R.bool.car_ui_toolbar_show_logo);
+        mSearchHint = getContext().getString(R.string.car_ui_toolbar_default_search_hint);
+
+        mBackground = requireViewByRefId(view, R.id.car_ui_toolbar_background);
+        mTabLayout = requireViewByRefId(view, R.id.car_ui_toolbar_tabs);
+        mNavIcon = requireViewByRefId(view, R.id.car_ui_toolbar_nav_icon);
+        mLogoInNavIconSpace = requireViewByRefId(view, R.id.car_ui_toolbar_logo);
+        mNavIconContainer = requireViewByRefId(view, R.id.car_ui_toolbar_nav_icon_container);
+        mMenuItemsContainer = requireViewByRefId(view, R.id.car_ui_toolbar_menu_items_container);
+        mTitleContainer = requireViewByRefId(view, R.id.car_ui_toolbar_title_container);
+        mSubtitle = requireViewByRefId(view, R.id.car_ui_toolbar_subtitle);
+        mTitle = requireViewByRefId(view, R.id.car_ui_toolbar_title);
+        mTitleLogoContainer = requireViewByRefId(view, R.id.car_ui_toolbar_title_logo_container);
+        mTitleLogo = requireViewByRefId(view, R.id.car_ui_toolbar_title_logo);
+        mSearchViewContainer = requireViewByRefId(view, R.id.car_ui_toolbar_search_view_container);
+        mProgressBar = new ProgressBarControllerImpl(
+                requireViewByRefId(view, R.id.car_ui_toolbar_progress_bar));
+
+        mTabLayout.addListener(new TabLayout.Listener() {
+            @Override
+            public void onTabSelected(TabLayout.Tab tab) {
+                for (Toolbar.OnTabSelectedListener listener : mOnTabSelectedListeners) {
+                    listener.onTabSelected(tab);
+                }
+            }
+        });
+
+        mBackground.addOnLayoutChangeListener((v, left, top, right, bottom,
+                oldLeft, oldTop, oldRight, oldBottom) -> {
+            if (oldBottom - oldTop != bottom - top) {
+                for (Toolbar.OnHeightChangedListener listener : mOnHeightChangedListeners) {
+                    listener.onHeightChanged(mBackground.getHeight());
+                }
+            }
+        });
+
+        setBackgroundShown(true);
+
+        mOverflowAdapter = new CarUiListItemAdapter(mUiOverflowItems);
+
+        // This holds weak references so we don't need to unregister later
+        CarUxRestrictionsUtil.getInstance(getContext())
+                .register(mOnUxRestrictionsChangedListener);
+    }
+
+    private Context getContext() {
+        return mContext;
+    }
+
+    /**
+     * Returns {@code true} if a two row layout in enabled for the toolbar.
+     */
+    @Override
+    public boolean isTabsInSecondRow() {
+        return mIsTabsInSecondRow;
+    }
+
+    /**
+     * Sets the title of the toolbar to a string resource.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setTitle(@StringRes int title) {
+        mTitle.setText(title);
+        setState(getState());
+    }
+
+    /**
+     * Sets the title of the toolbar to a CharSequence.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setTitle(CharSequence title) {
+        mTitle.setText(title);
+        setState(getState());
+    }
+
+    @Override
+    public CharSequence getTitle() {
+        return mTitle.getText();
+    }
+
+    /**
+     * Sets the subtitle of the toolbar to a string resource.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setSubtitle(@StringRes int title) {
+        mSubtitle.setText(title);
+        setState(getState());
+    }
+
+    /**
+     * Sets the subtitle of the toolbar to a CharSequence.
+     *
+     * <p>The title may not always be shown, for example with one row layout with tabs.
+     */
+    @Override
+    public void setSubtitle(CharSequence title) {
+        mSubtitle.setText(title);
+        setState(getState());
+    }
+
+    @Override
+    public CharSequence getSubtitle() {
+        return mSubtitle.getText();
+    }
+
+    /**
+     * Gets the {@link TabLayout} for this toolbar.
+     */
+    @Override
+    public TabLayout getTabLayout() {
+        return mTabLayout;
+    }
+
+    /**
+     * Adds a tab to this toolbar. You can listen for when it is selected via
+     * {@link #registerOnTabSelectedListener(Toolbar.OnTabSelectedListener)}.
+     */
+    @Override
+    public void addTab(TabLayout.Tab tab) {
+        mTabLayout.addTab(tab);
+        setState(getState());
+    }
+
+    /** Removes all the tabs. */
+    @Override
+    public void clearAllTabs() {
+        mTabLayout.clearAllTabs();
+        setState(getState());
+    }
+
+    /**
+     * Gets a tab added to this toolbar. See
+     * {@link #addTab(TabLayout.Tab)}.
+     */
+    @Override
+    public TabLayout.Tab getTab(int position) {
+        return mTabLayout.get(position);
+    }
+
+    /**
+     * Selects a tab added to this toolbar. See
+     * {@link #addTab(TabLayout.Tab)}.
+     */
+    @Override
+    public void selectTab(int position) {
+        mTabLayout.selectTab(position);
+    }
+
+    /**
+     * Sets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
+     */
+    @Override
+    public void setShowTabsInSubpage(boolean showTabs) {
+        if (showTabs != mShowTabsInSubpage) {
+            mShowTabsInSubpage = showTabs;
+            setState(getState());
+        }
+    }
+
+    /**
+     * Gets whether or not tabs should also be shown in the SUBPAGE {@link Toolbar.State}.
+     */
+    @Override
+    public boolean getShowTabsInSubpage() {
+        return mShowTabsInSubpage;
+    }
+
+    /**
+     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
+     * will be displayed next to the title.
+     */
+    @Override
+    public void setLogo(@DrawableRes int resId) {
+        setLogo(resId != 0 ? getContext().getDrawable(resId) : null);
+    }
+
+    /**
+     * Sets the logo to display in this toolbar. If navigation icon is being displayed, this logo
+     * will be displayed next to the title.
+     */
+    @Override
+    public void setLogo(Drawable drawable) {
+        if (!mShowLogo) {
+            // If no logo should be shown then we act as if we never received one.
+            return;
+        }
+        if (drawable != null) {
+            mLogoInNavIconSpace.setImageDrawable(drawable);
+            mTitleLogo.setImageDrawable(drawable);
+            mHasLogo = true;
+        } else {
+            mHasLogo = false;
+        }
+        setState(mState);
+    }
+
+    /** Sets the hint for the search bar. */
+    @Override
+    public void setSearchHint(@StringRes int resId) {
+        setSearchHint(getContext().getString(resId));
+    }
+
+    /** Sets the hint for the search bar. */
+    public void setSearchHint(CharSequence hint) {
+        mSearchHint = hint;
+        if (mSearchView != null) {
+            mSearchView.setHint(mSearchHint);
+        }
+    }
+
+    /** Gets the search hint */
+    @Override
+    public CharSequence getSearchHint() {
+        return mSearchHint;
+    }
+
+    /**
+     * Sets the icon to display in the search box.
+     *
+     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
+     * a similar place.
+     */
+    @Override
+    public void setSearchIcon(@DrawableRes int resId) {
+        setSearchIcon(getContext().getDrawable(resId));
+    }
+
+    /**
+     * Sets the icon to display in the search box.
+     *
+     * <p>The icon will be lost on configuration change, make sure to set it in onCreate() or
+     * a similar place.
+     */
+    @Override
+    public void setSearchIcon(Drawable d) {
+        if (!Objects.equals(d, mSearchIcon)) {
+            mSearchIcon = d;
+            if (mSearchView != null) {
+                mSearchView.setIcon(mSearchIcon);
+            }
+        }
+    }
+
+
+    /** Sets the {@link Toolbar.NavButtonMode} */
+    @Override
+    public void setNavButtonMode(Toolbar.NavButtonMode style) {
+        if (style != mNavButtonMode) {
+            mNavButtonMode = style;
+            setState(mState);
+        }
+    }
+
+    /** Gets the {@link Toolbar.NavButtonMode} */
+    @Override
+    public Toolbar.NavButtonMode getNavButtonMode() {
+        return mNavButtonMode;
+    }
+
+    /** Show/hide the background. When hidden, the toolbar is completely transparent. */
+    @Override
+    public void setBackgroundShown(boolean shown) {
+        if (shown) {
+            mBackground.setBackground(
+                    getContext().getDrawable(R.drawable.car_ui_toolbar_background));
+        } else {
+            mBackground.setBackground(null);
+        }
+    }
+
+    /** Returns true is the toolbar background is shown */
+    @Override
+    public boolean getBackgroundShown() {
+        return mBackground.getBackground() != null;
+    }
+
+    private void setMenuItemsInternal(@Nullable List<MenuItem> items) {
+        if (items == null) {
+            items = Collections.emptyList();
+        }
+
+        List<MenuItem> visibleMenuItems = new ArrayList<>();
+        List<MenuItem> overflowItems = new ArrayList<>();
+        AtomicInteger loadedMenuItems = new AtomicInteger(0);
+
+        synchronized (this) {
+            if (items.equals(mMenuItems)) {
+                return;
+            }
+
+            for (MenuItem item : items) {
+                if (item.getDisplayBehavior() == MenuItem.DisplayBehavior.NEVER) {
+                    overflowItems.add(item);
+                    item.setListener(mOverflowItemListener);
+                } else {
+                    visibleMenuItems.add(item);
+                }
+            }
+
+            // Copy the list so that if the list is modified and setMenuItems is called again,
+            // the equals() check will fail. Note that the MenuItems are not copied here.
+            mMenuItems = new ArrayList<>(items);
+            mOverflowItems = overflowItems;
+            mMenuItemRenderers.clear();
+            mMenuItemsContainer.removeAllViews();
+
+            if (!overflowItems.isEmpty()) {
+                visibleMenuItems.add(mOverflowButton);
+                createOverflowDialog();
+            }
+
+            View[] menuItemViews = new View[visibleMenuItems.size()];
+            mMenuItemViews = menuItemViews;
+
+            for (int i = 0; i < visibleMenuItems.size(); ++i) {
+                int index = i;
+                MenuItem item = visibleMenuItems.get(i);
+                MenuItemRenderer renderer = new MenuItemRenderer(item, mMenuItemsContainer);
+                mMenuItemRenderers.add(renderer);
+                renderer.createView(view -> {
+                    synchronized (ToolbarControllerImpl.this) {
+                        if (menuItemViews != mMenuItemViews) {
+                            return;
+                        }
+
+                        menuItemViews[index] = view;
+                        if (loadedMenuItems.addAndGet(1) == menuItemViews.length) {
+                            for (View v : menuItemViews) {
+                                mMenuItemsContainer.addView(v);
+                            }
+                        }
+                    }
+                });
+            }
+        }
+
+        setState(mState);
+    }
+
+    /**
+     * Sets the {@link MenuItem Menuitems} to display.
+     */
+    @Override
+    public void setMenuItems(@Nullable List<MenuItem> items) {
+        mMenuItemsXmlId = 0;
+        setMenuItemsInternal(items);
+    }
+
+    /**
+     * Sets the {@link MenuItem Menuitems} to display to a list defined in XML.
+     *
+     * <p>If this method is called twice with the same argument (and {@link #setMenuItems(List)}
+     * wasn't called), nothing will happen the second time, even if the MenuItems were changed.
+     *
+     * <p>The XML file must have one <MenuItems> tag, with a variable number of <MenuItem>
+     * child tags. See CarUiToolbarMenuItem in CarUi's attrs.xml for a list of available attributes.
+     *
+     * Example:
+     * <pre>
+     * <MenuItems>
+     *     <MenuItem
+     *         app:title="Foo"/>
+     *     <MenuItem
+     *         app:title="Bar"
+     *         app:icon="@drawable/ic_tracklist"
+     *         app:onClick="xmlMenuItemClicked"/>
+     *     <MenuItem
+     *         app:title="Bar"
+     *         app:checkable="true"
+     *         app:uxRestrictions="FULLY_RESTRICTED"
+     *         app:onClick="xmlMenuItemClicked"/>
+     * </MenuItems>
+     * </pre>
+     *
+     * @return The MenuItems that were loaded from XML.
+     * @see #setMenuItems(List)
+     */
+    @Override
+    public List<MenuItem> setMenuItems(@XmlRes int resId) {
+        if (mMenuItemsXmlId != 0 && mMenuItemsXmlId == resId) {
+            return mMenuItems;
+        }
+
+        mMenuItemsXmlId = resId;
+        List<MenuItem> menuItems = MenuItemRenderer.readMenuItemList(getContext(), resId);
+        setMenuItemsInternal(menuItems);
+        return menuItems;
+    }
+
+    /** Gets the {@link MenuItem MenuItems} currently displayed */
+    @Override
+    @NonNull
+    public List<MenuItem> getMenuItems() {
+        return Collections.unmodifiableList(mMenuItems);
+    }
+
+    /** Gets a {@link MenuItem} by id. */
+    @Override
+    @Nullable
+    public MenuItem findMenuItemById(int id) {
+        for (MenuItem item : mMenuItems) {
+            if (item.getId() == id) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    /** Gets a {@link MenuItem} by id. Will throw an IllegalArgumentException if not found. */
+    @Override
+    @NonNull
+    public MenuItem requireMenuItemById(int id) {
+        MenuItem result = findMenuItemById(id);
+
+        if (result == null) {
+            throw new IllegalArgumentException("ID does not reference a MenuItem on this Toolbar");
+        }
+
+        return result;
+    }
+
+    private int countVisibleOverflowItems() {
+        int numVisibleItems = 0;
+        for (MenuItem item : mOverflowItems) {
+            if (item.isVisible()) {
+                numVisibleItems++;
+            }
+        }
+        return numVisibleItems;
+    }
+
+    private void createOverflowDialog() {
+        mUiOverflowItems.clear();
+        for (MenuItem menuItem : mOverflowItems) {
+            if (menuItem.isVisible()) {
+                mUiOverflowItems.add(toCarUiContentListItem(menuItem));
+            }
+        }
+
+        mOverflowDialog = new AlertDialogBuilder(getContext())
+                .setAdapter(mOverflowAdapter)
+                .create();
+    }
+
+    private void updateOverflowDialog(MenuItem changedItem) {
+        int itemIndex = mOverflowItems.indexOf(changedItem);
+        if (itemIndex >= 0) {
+            mUiOverflowItems.set(itemIndex, toCarUiContentListItem(changedItem));
+            mOverflowAdapter.notifyItemChanged(itemIndex);
+        } else {
+            createOverflowDialog();
+        }
+    }
+
+    private CarUiContentListItem toCarUiContentListItem(MenuItem menuItem) {
+        CarUiContentListItem carUiItem;
+        if (menuItem.isCheckable()) {
+            carUiItem = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
+        } else {
+            carUiItem = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        }
+        carUiItem.setIcon(menuItem.getIcon());
+        carUiItem.setActivated(menuItem.isActivated());
+        carUiItem.setChecked(menuItem.isChecked());
+        carUiItem.setEnabled(menuItem.isEnabled());
+        carUiItem.setTitle(menuItem.getTitle());
+        carUiItem.setOnItemClickedListener(item -> {
+            menuItem.performClick();
+            mOverflowDialog.hide();
+        });
+        return carUiItem;
+    }
+
+    /**
+     * Set whether or not to show the {@link MenuItem MenuItems} while searching. Default false.
+     * Even if this is set to true, the {@link MenuItem} created by
+     * {@link MenuItem.Builder#setToSearch()} will still be hidden.
+     */
+    @Override
+    public void setShowMenuItemsWhileSearching(boolean showMenuItems) {
+        mShowMenuItemsWhileSearching = showMenuItems;
+        setState(mState);
+    }
+
+    /** Returns if {@link MenuItem MenuItems} are shown while searching */
+    @Override
+    public boolean getShowMenuItemsWhileSearching() {
+        return mShowMenuItemsWhileSearching;
+    }
+
+    /**
+     * Sets the search query.
+     */
+    @Override
+    public void setSearchQuery(String query) {
+        if (mSearchView != null) {
+            mSearchView.setSearchQuery(query);
+        } else {
+            mSearchQuery = query;
+            for (Toolbar.OnSearchListener listener : mOnSearchListeners) {
+                listener.onSearch(query);
+            }
+        }
+    }
+
+    /**
+     * Sets the state of the toolbar. This will show/hide the appropriate elements of the toolbar
+     * for the desired state.
+     */
+    @Override
+    public void setState(Toolbar.State state) {
+        mState = state;
+
+        if (mSearchView == null && (state == Toolbar.State.SEARCH || state == Toolbar.State.EDIT)) {
+            SearchView searchView = new SearchView(getContext());
+            searchView.setHint(mSearchHint);
+            searchView.setIcon(mSearchIcon);
+            searchView.setSearchQuery(mSearchQuery);
+            searchView.setSearchListeners(mOnSearchListeners);
+            searchView.setSearchCompletedListeners(mOnSearchCompletedListeners);
+            searchView.setVisibility(GONE);
+
+            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.MATCH_PARENT);
+            mSearchViewContainer.addView(searchView, layoutParams);
+
+            mSearchView = searchView;
+        }
+
+        for (MenuItemRenderer renderer : mMenuItemRenderers) {
+            renderer.setToolbarState(mState);
+        }
+
+        View.OnClickListener backClickListener = (v) -> {
+            boolean absorbed = false;
+            List<Toolbar.OnBackListener> listenersCopy = new ArrayList<>(mOnBackListeners);
+            for (Toolbar.OnBackListener listener : listenersCopy) {
+                absorbed = absorbed || listener.onBack();
+            }
+
+            if (!absorbed) {
+                Activity activity = CarUiUtils.getActivity(getContext());
+                if (activity != null) {
+                    activity.onBackPressed();
+                }
+            }
+        };
+
+        if (state == Toolbar.State.SEARCH) {
+            mNavIcon.setImageResource(R.drawable.car_ui_icon_search_nav_icon);
+        } else {
+            switch (mNavButtonMode) {
+                case CLOSE:
+                    mNavIcon.setImageResource(R.drawable.car_ui_icon_close);
+                    break;
+                case DOWN:
+                    mNavIcon.setImageResource(R.drawable.car_ui_icon_down);
+                    break;
+                default:
+                    mNavIcon.setImageResource(R.drawable.car_ui_icon_arrow_back);
+                    break;
+            }
+        }
+
+        mNavIcon.setVisibility(state != Toolbar.State.HOME ? VISIBLE : GONE);
+
+        // Show the logo in the nav space if that's enabled, we have a logo,
+        // and we're in the Home state.
+        mLogoInNavIconSpace.setVisibility(mHasLogo
+                && state == Toolbar.State.HOME
+                && mLogoFillsNavIconSpace
+                ? VISIBLE : INVISIBLE);
+
+        // Show logo next to the title if we're in the subpage state or we're configured to not show
+        // the logo in the nav icon space.
+        mTitleLogoContainer.setVisibility(mHasLogo
+                && (state == Toolbar.State.SUBPAGE
+                || (state == Toolbar.State.HOME && !mLogoFillsNavIconSpace))
+                ? VISIBLE : GONE);
+
+        // Show the nav icon container if we're not in the home space or the logo fills the nav icon
+        // container. If car_ui_toolbar_nav_icon_reserve_space is true, hiding it will still reserve
+        // its space
+        mNavIconContainer.setVisibility(
+                state != Toolbar.State.HOME || (mHasLogo && mLogoFillsNavIconSpace)
+                        ? VISIBLE : (mNavIconSpaceReserved ? INVISIBLE : GONE));
+        mNavIconContainer.setOnClickListener(
+                state != Toolbar.State.HOME ? backClickListener : null);
+        mNavIconContainer.setClickable(state != Toolbar.State.HOME);
+        mNavIconContainer.setContentDescription(state != Toolbar.State.HOME
+                ? mContext.getString(R.string.car_ui_toolbar_nav_icon_content_description)
+                : null);
+
+        boolean hasTabs = mTabLayout.getTabCount() > 0
+                && (state == Toolbar.State.HOME
+                || (state == Toolbar.State.SUBPAGE && mShowTabsInSubpage));
+        // Show the title if we're in the subpage state, or in the home state with no tabs or tabs
+        // on the second row
+        int visibility = (state == Toolbar.State.SUBPAGE || state == Toolbar.State.HOME)
+                && (!hasTabs || mIsTabsInSecondRow)
+                ? VISIBLE : GONE;
+        mTitleContainer.setVisibility(visibility);
+        mSubtitle.setVisibility(
+                TextUtils.isEmpty(mSubtitle.getText()) ? GONE : VISIBLE);
+
+        mTabLayout.setVisibility(hasTabs ? VISIBLE : GONE);
+
+        if (mSearchView != null) {
+            if (state == Toolbar.State.SEARCH || state == Toolbar.State.EDIT) {
+                mSearchView.setPlainText(state == Toolbar.State.EDIT);
+                mSearchView.setVisibility(VISIBLE);
+            } else {
+                mSearchView.setVisibility(GONE);
+            }
+        }
+
+        boolean showButtons = (state != Toolbar.State.SEARCH && state != Toolbar.State.EDIT)
+                || mShowMenuItemsWhileSearching;
+        mMenuItemsContainer.setVisibility(showButtons ? VISIBLE : GONE);
+        mOverflowButton.setVisible(showButtons && countVisibleOverflowItems() > 0);
+    }
+
+    /** Gets the current {@link Toolbar.State} of the toolbar. */
+    @Override
+    public Toolbar.State getState() {
+        return mState;
+    }
+
+
+    /**
+     * Registers a new {@link Toolbar.OnHeightChangedListener} to the list of listeners. Register a
+     * {@link com.android.car.ui.recyclerview.CarUiRecyclerView} only if there is a toolbar at
+     * the top and a {@link com.android.car.ui.recyclerview.CarUiRecyclerView} in the view and
+     * nothing else. {@link com.android.car.ui.recyclerview.CarUiRecyclerView} will
+     * automatically adjust its height according to the height of the Toolbar.
+     */
+    @Override
+    public void registerToolbarHeightChangeListener(
+            Toolbar.OnHeightChangedListener listener) {
+        mOnHeightChangedListeners.add(listener);
+    }
+
+    /**
+     * Unregisters an existing {@link Toolbar.OnHeightChangedListener} from the list of
+     * listeners.
+     */
+    @Override
+    public boolean unregisterToolbarHeightChangeListener(
+            Toolbar.OnHeightChangedListener listener) {
+        return mOnHeightChangedListeners.remove(listener);
+    }
+
+    /** Registers a new {@link Toolbar.OnTabSelectedListener} to the list of listeners. */
+    @Override
+    public void registerOnTabSelectedListener(Toolbar.OnTabSelectedListener listener) {
+        mOnTabSelectedListeners.add(listener);
+    }
+
+    /** Unregisters an existing {@link Toolbar.OnTabSelectedListener} from the list of listeners. */
+    @Override
+    public boolean unregisterOnTabSelectedListener(Toolbar.OnTabSelectedListener listener) {
+        return mOnTabSelectedListeners.remove(listener);
+    }
+
+    /** Registers a new {@link Toolbar.OnSearchListener} to the list of listeners. */
+    @Override
+    public void registerOnSearchListener(Toolbar.OnSearchListener listener) {
+        mOnSearchListeners.add(listener);
+    }
+
+    /** Unregisters an existing {@link Toolbar.OnSearchListener} from the list of listeners. */
+    @Override
+    public boolean unregisterOnSearchListener(Toolbar.OnSearchListener listener) {
+        return mOnSearchListeners.remove(listener);
+    }
+
+    /** Registers a new {@link Toolbar.OnSearchCompletedListener} to the list of listeners. */
+    @Override
+    public void registerOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener) {
+        mOnSearchCompletedListeners.add(listener);
+    }
+
+    /**
+     * Unregisters an existing {@link Toolbar.OnSearchCompletedListener} from the list of
+     * listeners.
+     */
+    @Override
+    public boolean unregisterOnSearchCompletedListener(Toolbar.OnSearchCompletedListener listener) {
+        return mOnSearchCompletedListeners.remove(listener);
+    }
+
+    /** Registers a new {@link Toolbar.OnBackListener} to the list of listeners. */
+    @Override
+    public void registerOnBackListener(Toolbar.OnBackListener listener) {
+        mOnBackListeners.add(listener);
+    }
+
+    /** Unregisters an existing {@link Toolbar.OnBackListener} from the list of listeners. */
+    @Override
+    public boolean unregisterOnBackListener(Toolbar.OnBackListener listener) {
+        return mOnBackListeners.remove(listener);
+    }
+
+    /** Returns the progress bar */
+    @Override
+    public ProgressBarController getProgressBar() {
+        return mProgressBar;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/utils/CarUiUtils.java b/car-ui-lib/src/com/android/car/ui/utils/CarUiUtils.java
new file mode 100644
index 0000000..93cf868
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/utils/CarUiUtils.java
@@ -0,0 +1,191 @@
+/*
+ * 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.ui.utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.DimenRes;
+import androidx.annotation.IdRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StyleRes;
+import androidx.annotation.UiThread;
+import androidx.core.view.ViewCompat;
+
+/**
+ * Collection of utility methods
+ */
+public final class CarUiUtils {
+    /** This is a utility class */
+    private CarUiUtils() {
+    }
+
+    /**
+     * Reads a float value from a dimens resource. This is necessary as {@link Resources#getFloat}
+     * is not currently public.
+     *
+     * @param res {@link Resources} to read values from
+     * @param resId Id of the dimens resource to read
+     */
+    public static float getFloat(Resources res, @DimenRes int resId) {
+        TypedValue outValue = new TypedValue();
+        res.getValue(resId, outValue, true);
+        return outValue.getFloat();
+    }
+
+    /** Returns the identifier of the resolved resource assigned to the given attribute. */
+    public static int getAttrResourceId(Context context, int attr) {
+        return getAttrResourceId(context, /*styleResId=*/ 0, attr);
+    }
+
+    /**
+     * Returns the identifier of the resolved resource assigned to the given attribute defined in
+     * the given style.
+     */
+    public static int getAttrResourceId(Context context, @StyleRes int styleResId, int attr) {
+        TypedArray ta = context.obtainStyledAttributes(styleResId, new int[]{attr});
+        int resId = ta.getResourceId(0, 0);
+        ta.recycle();
+        return resId;
+    }
+
+    /**
+     * Gets the {@link Activity} for a certain {@link Context}.
+     *
+     * <p>It is possible the Context is not associated with an Activity, in which case
+     * this method will return null.
+     */
+    @Nullable
+    public static Activity getActivity(Context context) {
+        while (context instanceof ContextWrapper) {
+            if (context instanceof Activity) {
+                return (Activity) context;
+            }
+            context = ((ContextWrapper) context).getBaseContext();
+        }
+        return null;
+    }
+
+    /**
+     * Updates the preference view enabled state. If the view is disabled we just disable the child
+     * of preference like TextView, ImageView. The preference itself is always enabled to get the
+     * click events. Ripple effect in background is also removed by default. If the ripple is
+     * needed see
+     * {@link IDisabledPreferenceCallback#setShouldShowRippleOnDisabledPreference(boolean)}
+     */
+    public static Drawable setPreferenceViewEnabled(boolean viewEnabled, View itemView,
+            Drawable background, boolean shouldShowRippleOnDisabledPreference) {
+        if (viewEnabled) {
+            if (background != null) {
+                ViewCompat.setBackground(itemView, background);
+            }
+            setChildViewsEnabled(itemView, true, false);
+        } else {
+            itemView.setEnabled(true);
+            if (background == null) {
+                // store the original background.
+                background = itemView.getBackground();
+            }
+            updateRippleStateOnDisabledPreference(false, shouldShowRippleOnDisabledPreference,
+                    background, itemView);
+            setChildViewsEnabled(itemView, false, true);
+        }
+        return background;
+    }
+
+    /**
+     * Sets the enabled state on the views of the preference. If the view is being disabled we want
+     * only child views of preference to be disabled.
+     */
+    private static void setChildViewsEnabled(View view, boolean enabled, boolean isRootView) {
+        if (!isRootView) {
+            view.setEnabled(enabled);
+        }
+        if (view instanceof ViewGroup) {
+            ViewGroup grp = (ViewGroup) view;
+            for (int index = 0; index < grp.getChildCount(); index++) {
+                setChildViewsEnabled(grp.getChildAt(index), enabled, false);
+            }
+        }
+    }
+
+    /**
+     * Updates the ripple state on the given preference.
+     *
+     * @param isEnabled whether the preference is enabled or not
+     * @param shouldShowRippleOnDisabledPreference should ripple be displayed when the preference is
+     * clicked
+     * @param background drawable that represents the ripple
+     * @param preference preference on which drawable will be applied
+     */
+    public static void updateRippleStateOnDisabledPreference(boolean isEnabled,
+            boolean shouldShowRippleOnDisabledPreference, Drawable background, View preference) {
+        if (isEnabled || preference == null) {
+            return;
+        }
+        if (shouldShowRippleOnDisabledPreference && background != null) {
+            ViewCompat.setBackground(preference, background);
+        } else {
+            ViewCompat.setBackground(preference, null);
+        }
+    }
+
+    /**
+     * It behaves similar to @see View#findViewById, except it resolves the ID reference first.
+     *
+     * @param id the ID to search for
+     * @return a view with given ID if found, or {@code null} otherwise
+     * @see View#requireViewById(int)
+     */
+    @Nullable
+    @UiThread
+    public static <T extends View> T findViewByRefId(@NonNull View root, @IdRes int id) {
+        if (id == View.NO_ID) {
+            return null;
+        }
+
+        TypedValue value = new TypedValue();
+        root.getResources().getValue(id, value, true);
+        return root.findViewById(value.resourceId);
+    }
+
+    /**
+     * It behaves similar to @see View#requireViewById, except it resolves the ID reference first.
+     *
+     * @param id the ID to search for
+     * @return a view with given ID
+     * @see View#findViewById(int)
+     */
+    @NonNull
+    @UiThread
+    public static <T extends View> T requireViewByRefId(@NonNull View root, @IdRes int id) {
+        T view = findViewByRefId(root, id);
+        if (view == null) {
+            throw new IllegalArgumentException("ID "
+                    + root.getResources().getResourceName(id)
+                    + " does not reference a View inside this View");
+        }
+        return view;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/utils/CarUxRestrictionsUtil.java b/car-ui-lib/src/com/android/car/ui/utils/CarUxRestrictionsUtil.java
new file mode 100644
index 0000000..e5c7fc9
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/utils/CarUxRestrictionsUtil.java
@@ -0,0 +1,186 @@
+/*
+ * 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.ui.utils;
+
+import static android.car.drivingstate.CarUxRestrictions.UX_RESTRICTIONS_LIMIT_STRING_LENGTH;
+
+import android.car.Car;
+import android.car.drivingstate.CarUxRestrictions;
+import android.car.drivingstate.CarUxRestrictions.CarUxRestrictionsInfo;
+import android.car.drivingstate.CarUxRestrictionsManager;
+import android.content.Context;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.car.ui.R;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+// This can't be in the middle of the rest of the imports on gerrit or it will
+// fail our style checks
+// copybara:insert import android.car.CarNotConnectedException;
+
+/**
+ * Utility class to access Car Restriction Manager.
+ *
+ * <p>This class must be a singleton because only one listener can be registered with {@link
+ * CarUxRestrictionsManager} at a time, as documented in {@link
+ * CarUxRestrictionsManager#registerListener}.
+ */
+public class CarUxRestrictionsUtil {
+    private static final String TAG = "CarUxRestrictionsUtil";
+
+    /* copybara:insert
+    private final Car mCarApi;
+    private CarUxRestrictionsManager mCarUxRestrictionsManager;
+    */
+    @NonNull
+    private CarUxRestrictions mCarUxRestrictions = getDefaultRestrictions();
+
+    private final Set<OnUxRestrictionsChangedListener> mObservers =
+            Collections.newSetFromMap(new WeakHashMap<>());
+    private static CarUxRestrictionsUtil sInstance = null;
+
+    private CarUxRestrictionsUtil(Context context) {
+        CarUxRestrictionsManager.OnUxRestrictionsChangedListener listener =
+                (carUxRestrictions) -> {
+                    if (carUxRestrictions == null) {
+                        mCarUxRestrictions = getDefaultRestrictions();
+                    } else {
+                        mCarUxRestrictions = carUxRestrictions;
+                    }
+
+                    for (OnUxRestrictionsChangedListener observer : mObservers) {
+                        observer.onRestrictionsChanged(mCarUxRestrictions);
+                    }
+                };
+
+        // copybara:strip_begin
+        Car.createCar(context.getApplicationContext(), null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
+                (Car car, boolean ready) -> {
+                    if (ready) {
+                        CarUxRestrictionsManager carUxRestrictionsManager =
+                                (CarUxRestrictionsManager) car.getCarManager(
+                                        Car.CAR_UX_RESTRICTION_SERVICE);
+                        carUxRestrictionsManager.registerListener(listener);
+                        listener.onUxRestrictionsChanged(
+                                carUxRestrictionsManager.getCurrentCarUxRestrictions());
+                    } else {
+                        Log.w(TAG, "Car service disconnected, assuming fully restricted uxr");
+                        listener.onUxRestrictionsChanged(null);
+                    }
+                });
+        /* copybara:strip_end_and_replace
+        mCarApi = Car.createCar(context.getApplicationContext());
+
+        try {
+            mCarUxRestrictionsManager =
+                    (CarUxRestrictionsManager) mCarApi.getCarManager(
+                            Car.CAR_UX_RESTRICTION_SERVICE);
+            mCarUxRestrictionsManager.registerListener(listener);
+            listener.onUxRestrictionsChanged(
+                    mCarUxRestrictionsManager.getCurrentCarUxRestrictions());
+        } catch (CarNotConnectedException | NullPointerException e) {
+            Log.e(TAG, "Car not connected", e);
+            // mCarUxRestrictions will be the default
+        }
+        */
+    }
+
+    @NonNull
+    private static CarUxRestrictions getDefaultRestrictions() {
+        return new CarUxRestrictions.Builder(
+                true, CarUxRestrictions.UX_RESTRICTIONS_FULLY_RESTRICTED, 0)
+                .build();
+    }
+
+    /** Listener interface used to update clients on UxRestrictions changes */
+    public interface OnUxRestrictionsChangedListener {
+        /** Called when CarUxRestrictions changes */
+        void onRestrictionsChanged(@NonNull CarUxRestrictions carUxRestrictions);
+    }
+
+    /** Returns the singleton sInstance of this class */
+    @NonNull
+    public static CarUxRestrictionsUtil getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new CarUxRestrictionsUtil(context);
+        }
+
+        return sInstance;
+    }
+
+    /**
+     * Registers a listener on this class for updates to CarUxRestrictions. Multiple listeners may
+     * be registered. Note that this class will only hold a weak reference to the listener, you
+     * must maintain a strong reference to it elsewhere.
+     */
+    public void register(OnUxRestrictionsChangedListener listener) {
+        mObservers.add(listener);
+        listener.onRestrictionsChanged(mCarUxRestrictions);
+    }
+
+    /** Unregisters a registered listener */
+    public void unregister(OnUxRestrictionsChangedListener listener) {
+        mObservers.remove(listener);
+    }
+
+    @NonNull
+    public CarUxRestrictions getCurrentRestrictions() {
+        return mCarUxRestrictions;
+    }
+
+    /**
+     * Returns whether any of the given flags are blocked by the specified restrictions. If null is
+     * given, the method returns true for safety.
+     */
+    public static boolean isRestricted(
+            @CarUxRestrictionsInfo int restrictionFlags, @Nullable CarUxRestrictions uxr) {
+        return (uxr == null) || ((uxr.getActiveRestrictions() & restrictionFlags) != 0);
+    }
+
+    /**
+     * Complies the input string with the given UX restrictions. Returns the original string if
+     * already compliant, otherwise a shortened ellipsized string.
+     */
+    public static String complyString(Context context, String str, CarUxRestrictions uxr) {
+
+        if (isRestricted(UX_RESTRICTIONS_LIMIT_STRING_LENGTH, uxr)) {
+            int maxLength =
+                    uxr == null
+                            ? context.getResources().getInteger(
+                            R.integer.car_ui_default_max_string_length)
+                            : uxr.getMaxRestrictedStringLength();
+
+            if (str.length() > maxLength) {
+                return str.substring(0, maxLength) + context.getString(R.string.car_ui_ellipsis);
+            }
+        }
+
+        return str;
+    }
+
+    /** Sets car UX restrictions. Only used for testing. */
+    @VisibleForTesting
+    public void setUxRestrictions(CarUxRestrictions carUxRestrictions) {
+        mCarUxRestrictions = carUxRestrictions;
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/utils/DirectManipulationHelper.java b/car-ui-lib/src/com/android/car/ui/utils/DirectManipulationHelper.java
new file mode 100644
index 0000000..24a32d1
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/utils/DirectManipulationHelper.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.utils;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import androidx.annotation.NonNull;
+
+import java.lang.reflect.Method;
+
+/** Helper class to toggle direct manipulation mode. */
+public final class DirectManipulationHelper {
+
+    /**
+     * StateDescription for a {@link View} to support direct manipulation mode. It's also used as
+     * class name of {@link AccessibilityEvent} to indicate that the AccessibilityEvent represents
+     * a request to toggle direct manipulation mode.
+     */
+    private static final String DIRECT_MANIPULATION =
+            "com.android.car.ui.utils.DIRECT_MANIPULATION";
+
+    /** This is a utility class. */
+    private DirectManipulationHelper() {
+    }
+
+    /**
+     * Enables or disables direct manipulation mode. This method sends an {@link AccessibilityEvent}
+     * to tell {@link com.android.car.rotary.RotaryService} to enter or exit direct manipulation
+     * mode. Typically pressing the center button of the rotary controller with a direct
+     * manipulation view focused will enter direct manipulation mode, while pressing the Back button
+     * will exit direct manipulation mode.
+     *
+     * @param view   the direct manipulation view
+     * @param enable true to enter direct manipulation mode, false to exit direct manipulation mode
+     * @return whether the AccessibilityEvent was sent
+     */
+    public static boolean enableDirectManipulationMode(@NonNull View view, boolean enable) {
+        AccessibilityManager accessibilityManager = (AccessibilityManager)
+                view.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+        if (accessibilityManager == null || !accessibilityManager.isEnabled()) {
+            return false;
+        }
+        AccessibilityEvent event = AccessibilityEvent.obtain();
+        event.setClassName(DIRECT_MANIPULATION);
+        event.setSource(view);
+        event.setEventType(enable
+                ? AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
+                : AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+        accessibilityManager.sendAccessibilityEvent(event);
+        return true;
+    }
+
+    /** Returns whether the given {@code event} is for direct manipulation. */
+    public static boolean isDirectManipulation(@NonNull AccessibilityEvent event) {
+        return TextUtils.equals(DIRECT_MANIPULATION, event.getClassName());
+    }
+
+    /** Returns whether the given {@code node} supports direct manipulation. */
+    @TargetApi(30)
+    public static boolean supportDirectManipulation(@NonNull AccessibilityNodeInfo node) {
+        try {
+            // TODO(b/156115044): remove the reflection once Android R sdk is publicly released.
+            Method getStateDescription =
+                    AccessibilityNodeInfo.class.getMethod("getStateDescription");
+            CharSequence stateDescription = (CharSequence) getStateDescription.invoke(node);
+            return TextUtils.equals(DIRECT_MANIPULATION, stateDescription);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Sets whether the given {@code view} supports direct manipulation. */
+    @TargetApi(30)
+    public static void setSupportsDirectManipulation(@NonNull View view, boolean enable) {
+        try {
+            // TODO(b/156115044): remove the reflection once Android R sdk is publicly released.
+            Method setStateDescription =
+                    View.class.getMethod("setStateDescription", CharSequence.class);
+            CharSequence stateDescription = enable ? DIRECT_MANIPULATION : null;
+            setStateDescription.invoke(view, stateDescription);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/utils/RotaryConstants.java b/car-ui-lib/src/com/android/car/ui/utils/RotaryConstants.java
new file mode 100644
index 0000000..cb418bb
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/utils/RotaryConstants.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.utils;
+
+/** Constants for the rotary controller. */
+public final class RotaryConstants {
+    /**
+     * Content description indicating that the rotary controller should scroll this view
+     * horizontally.
+     */
+    public static final String ROTARY_HORIZONTALLY_SCROLLABLE =
+            "android.rotary.HORIZONTALLY_SCROLLABLE";
+
+    /**
+     * Content description indicating that the rotary controller should scroll this view
+     * vertically.
+     */
+    public static final String ROTARY_VERTICALLY_SCROLLABLE =
+            "android.rotary.VERTICALLY_SCROLLABLE";
+
+    /** Prevent instantiation. */
+    private RotaryConstants() {}
+}
diff --git a/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateButton.java b/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateButton.java
new file mode 100644
index 0000000..9e5e1ce
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateButton.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.uxr;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Button;
+
+import androidx.annotation.Nullable;
+
+/**
+ * A {@link Button} that implements {@link DrawableStateView}, for allowing additional states
+ * such as ux restriction.
+ */
+public class DrawableStateButton extends Button implements DrawableStateView {
+
+    private int[] mState;
+
+    public DrawableStateButton(Context context) {
+        super(context);
+    }
+
+    public DrawableStateButton(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public DrawableStateButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public DrawableStateButton(
+            Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public void setDrawableState(int[] state) {
+        mState = state;
+        refreshDrawableState();
+    }
+
+    @Override
+    public int[] onCreateDrawableState(int extraSpace) {
+        if (mState == null) {
+            return super.onCreateDrawableState(extraSpace);
+        } else {
+            return mergeDrawableStates(
+                    super.onCreateDrawableState(extraSpace + mState.length), mState);
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateSwitch.java b/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateSwitch.java
new file mode 100644
index 0000000..bfa018c
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateSwitch.java
@@ -0,0 +1,63 @@
+/*
+ * 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.ui.uxr;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Switch;
+
+import androidx.annotation.Nullable;
+
+/**
+ * A {@link Switch} that implements {@link DrawableStateView}, for allowing additional states
+ * such as ux restriction.
+ */
+public class DrawableStateSwitch extends Switch implements DrawableStateView {
+    private int[] mState;
+
+    public DrawableStateSwitch(Context context) {
+        super(context);
+    }
+
+    public DrawableStateSwitch(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public DrawableStateSwitch(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public DrawableStateSwitch(
+            Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public void setDrawableState(int[] state) {
+        mState = state;
+        refreshDrawableState();
+    }
+
+    @Override
+    public int[] onCreateDrawableState(int extraSpace) {
+        if (mState == null) {
+            return super.onCreateDrawableState(extraSpace);
+        } else {
+            return mergeDrawableStates(
+                    super.onCreateDrawableState(extraSpace + mState.length), mState);
+        }
+    }
+}
diff --git a/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateView.java b/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateView.java
new file mode 100644
index 0000000..a9cdb52
--- /dev/null
+++ b/car-ui-lib/src/com/android/car/ui/uxr/DrawableStateView.java
@@ -0,0 +1,28 @@
+/*
+ * 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.ui.uxr;
+
+/**
+ * An Interface to expose a view's drawable state.
+ *
+ * <p>Used by {@link com.android.car.ui.toolbar.Toolbar Toolbar's}
+ * {@link com.android.car.ui.toolbar.MenuItem MenuItems} to make the views display if they are ux
+ * restricted.
+ */
+public interface DrawableStateView {
+    /** Sets the drawable state. This should merge with existing drawable states */
+    void setDrawableState(int[] state);
+}
diff --git a/car-ui-lib/tests/apitest/auto-generate-resources.py b/car-ui-lib/tests/apitest/auto-generate-resources.py
index c48e04b..1fcd866 100755
--- a/car-ui-lib/tests/apitest/auto-generate-resources.py
+++ b/car-ui-lib/tests/apitest/auto-generate-resources.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # Copyright 2019, The Android Open Source Project
 #
@@ -17,36 +17,12 @@
 import argparse
 import os
 import sys
-import re
 from resource_utils import get_all_resources, get_resources_from_single_file, add_resource_to_set, Resource
 from git_utils import has_chassis_changes
-from datetime import datetime
-
-if sys.version_info[0] != 3:
-    print("Must use python 3")
-    sys.exit(1)
 
 # path to 'packages/apps/Car/libs/car-ui-lib/'
-ROOT_FOLDER = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
-OUTPUT_FILE_PATH = os.path.join(ROOT_FOLDER, 'tests/apitest/')
-
-
-COPYRIGHT_STR = """Copyright (C) %s 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.""" % (datetime.today().strftime("%Y"))
-
-
-AUTOGENERATION_NOTICE_STR = """ THIS FILE WAS AUTO GENERATED, DO NOT EDIT MANUALLY. """
+ROOT_FOLDER = os.path.dirname(os.path.abspath(__file__)) + '/../..'
+OUTPUT_FILE_PATH = ROOT_FOLDER + '/tests/apitest/'
 
 """
 Script used to update the 'current.xml' file. This is being used as part of pre-submits to
@@ -67,23 +43,14 @@
         # Don't run because there were no chassis changes
         return
 
-    resources = get_all_resources(os.path.join(ROOT_FOLDER, 'car-ui-lib/src/main/res'))
-    check_resource_names(resources, get_resources_from_single_file(os.path.join(OUTPUT_FILE_PATH, 'resource_name_allowed.xml')))
-
-    OVERLAYABLE_OUTPUT_FILE_PATH = os.path.join(ROOT_FOLDER, 'car-ui-lib/src/main/res-overlayable/values/overlayable.xml')
     output_file = args.file or 'current.xml'
     if args.compare:
-        old_mapping = get_resources_from_single_file(os.path.join(OUTPUT_FILE_PATH, 'current.xml'))
-        compare_resources(old_mapping, resources, os.path.join(OUTPUT_FILE_PATH, 'current.xml'))
-
-        old_mapping = get_resources_from_single_file(OVERLAYABLE_OUTPUT_FILE_PATH)
-        add_constraintlayout_resources(resources)
-        compare_resources(old_mapping, resources, OVERLAYABLE_OUTPUT_FILE_PATH)
+        compare_resources(ROOT_FOLDER+'/res', OUTPUT_FILE_PATH + 'current.xml')
     else:
-        generate_current_file(resources, output_file)
-        generate_overlayable_file(resources, OVERLAYABLE_OUTPUT_FILE_PATH)
+        generate_current_file(ROOT_FOLDER+'/res', output_file)
 
-def generate_current_file(resources, output_file='current.xml'):
+def generate_current_file(res_folder, output_file='current.xml'):
+    resources = get_all_resources(res_folder)
     resources = sorted(resources, key=lambda x: x.type + x.name)
 
     # defer importing lxml to here so that people who aren't editing chassis don't have to have
@@ -92,7 +59,7 @@
 
     root = etree.Element('resources')
 
-    root.addprevious(etree.Comment(AUTOGENERATION_NOTICE_STR))
+    root.addprevious(etree.Comment('This file is AUTO GENERATED, DO NOT EDIT MANUALLY.'))
     for resource in resources:
         item = etree.SubElement(root, 'public')
         item.set('type', resource.type)
@@ -100,11 +67,28 @@
 
     data = etree.ElementTree(root)
 
-    with open(os.path.join(OUTPUT_FILE_PATH, output_file), 'wb') as f:
+    with open(OUTPUT_FILE_PATH + output_file, 'w') as f:
         data.write(f, pretty_print=True, xml_declaration=True, encoding='utf-8')
 
-def generate_overlayable_file(resources, output_file='overlayable.xml'):
-    add_constraintlayout_resources(resources)
+def generate_overlayable_file(res_folder):
+    resources = get_all_resources(res_folder)
+    # We need these to be able to use base layouts in RROs
+    # This should become unnecessary in S
+    add_resource_to_set(resources, Resource('layout_constraintGuide_begin', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintGuide_end', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintHorizontal_bias', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintTop_toTopOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintTop_toBottomOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintBottom_toBottomOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintBottom_toTopOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintStart_toStartOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintStart_toEndOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintEnd_toEndOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintEnd_toStartOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintLeft_toLeftOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintLeft_toRightOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintRight_toRightOf', 'attr'))
+    add_resource_to_set(resources, Resource('layout_constraintRight_toLeftOf', 'attr'))
     resources = sorted(resources, key=lambda x: x.type + x.name)
 
     # defer importing lxml to here so that people who aren't editing chassis don't have to have
@@ -113,11 +97,22 @@
 
     root = etree.Element('resources')
 
-    root.addprevious(etree.Comment(COPYRIGHT_STR))
-    root.addprevious(etree.Comment(AUTOGENERATION_NOTICE_STR))
+    root.addprevious(etree.Comment(' Copyright (C) 2020 The Android Open Source Project\n\n' +
+
+                                   '     Licensed under the Apache License, Version 2.0 (the "License");\n' +
+                                   '     you may not use this file except in compliance with the License.\n' +
+                                   '     You may obtain a copy of the License at\n\n' +
+
+                                   '     http://www.apache.org/licenses/LICENSE-2.0\n\n'
+
+                                   '     Unless required by applicable law or agreed to in writing, software\n'
+                                   '     distributed under the License is distributed on an "AS IS" BASIS,\n'
+                                   '     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
+                                   '     See the License for the specific language governing permissions and\n'
+                                   '     limitations under the License.\n'))
 
     overlayable = etree.SubElement(root, 'overlayable')
-    overlayable.set('name', 'car-ui-lib')
+    overlayable.set('name', 'CarUiLibOverlayableResources')
 
     policy = etree.SubElement(overlayable, 'policy')
     policy.set('type', 'public')
@@ -129,83 +124,15 @@
 
     data = etree.ElementTree(root)
 
-    with open(output_file, 'wb') as f:
+    output_file=ROOT_FOLDER+'/res/values/overlayable.xml'
+    with open(output_file, 'w') as f:
         data.write(f, pretty_print=True, xml_declaration=True, encoding='utf-8')
 
-def add_constraintlayout_resources(resources):
-    # We need these to be able to use base layouts in RROs
-    # This should become unnecessary in S
-    # source: https://android.googlesource.com/platform/frameworks/opt/sherpa/+/studio-3.0/constraintlayout/src/main/res/values/attrs.xml
-    add_resource_to_set(resources, Resource('layout_optimizationLevel', 'attr'))
-    add_resource_to_set(resources, Resource('constraintSet', 'attr'))
-    add_resource_to_set(resources, Resource('barrierDirection', 'attr'))
-    add_resource_to_set(resources, Resource('constraint_referenced_ids', 'attr'))
-    add_resource_to_set(resources, Resource('chainUseRtl', 'attr'))
-    add_resource_to_set(resources, Resource('title', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintGuide_begin', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintGuide_end', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintGuide_percent', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintLeft_toLeftOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintLeft_toRightOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintRight_toLeftOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintRight_toRightOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintTop_toTopOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintTop_toBottomOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintBottom_toTopOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintBottom_toBottomOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintBaseline_toBaselineOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintStart_toEndOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintStart_toStartOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintEnd_toStartOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintEnd_toEndOf', 'attr'))
-    add_resource_to_set(resources, Resource('layout_goneMarginLeft', 'attr'))
-    add_resource_to_set(resources, Resource('layout_goneMarginTop', 'attr'))
-    add_resource_to_set(resources, Resource('layout_goneMarginRight', 'attr'))
-    add_resource_to_set(resources, Resource('layout_goneMarginBottom', 'attr'))
-    add_resource_to_set(resources, Resource('layout_goneMarginStart', 'attr'))
-    add_resource_to_set(resources, Resource('layout_goneMarginEnd', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintHorizontal_bias', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintVertical_bias', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintWidth_default', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintHeight_default', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintWidth_min', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintWidth_max', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintWidth_percent', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintHeight_min', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintHeight_max', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintHeight_percent', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintLeft_creator', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintTop_creator', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintRight_creator', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintBottom_creator', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintBaseline_creator', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintDimensionRatio', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintHorizontal_weight', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintVertical_weight', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintHorizontal_chainStyle', 'attr'))
-    add_resource_to_set(resources, Resource('layout_constraintVertical_chainStyle', 'attr'))
-    add_resource_to_set(resources, Resource('layout_editor_absoluteX', 'attr'))
-    add_resource_to_set(resources, Resource('layout_editor_absoluteY', 'attr'))
+def compare_resources(res_folder, res_public_file):
+    old_mapping = get_resources_from_single_file(res_public_file)
 
-def check_resource_names(resources, allowed):
-    newlist = resources.difference(allowed)
-    failed=False
-    for resource in newlist:
-        resourceType= resource.type
-        resourceName = resource.name
-        if resourceType == 'attr' and not re.match("^CarUi", resourceName, re.IGNORECASE):
-            print(f"Please consider changing {resourceType}/{resourceName} to something like CarUi{resourceName}")
-            failed=True
-        elif resourceType == 'style' and not re.search("CarUi", resourceName, re.IGNORECASE):
-            print(f"Please consider changing {resourceType}/{resourceName} to something like CarUi{resourceName}")
-            failed=True
-        elif resourceType != 'attr' and resourceType != 'style' and not re.match("^car_ui_", resourceName, re.IGNORECASE):
-            print(f"Please consider changing {resourceType}/{resourceName} to something like car_ui_{resourceName}")
-            failed=True
-    if failed:
-        sys.exit(1)
+    new_mapping = get_all_resources(res_folder)
 
-def compare_resources(old_mapping, new_mapping, res_public_file):
     removed = old_mapping.difference(new_mapping)
     added = new_mapping.difference(old_mapping)
     if len(removed) > 0:
@@ -215,8 +142,7 @@
 
     if len(added) + len(removed) > 0:
         print("Some resource have been modified. If this is intentional please " +
-              "run 'python3 $ANDROID_BUILD_TOP/packages/apps/Car/libs/car-ui-lib/tests/apitest/" +
-              "auto-generate-resources.py' again and submit the new %s" % res_public_file)
+              "run 'python auto-generate-resources.py' again and submit the new current.xml")
         sys.exit(1)
 
 if __name__ == '__main__':
diff --git a/car-ui-lib/tests/apitest/current.xml b/car-ui-lib/tests/apitest/current.xml
index a34d2f5..0731374 100644
--- a/car-ui-lib/tests/apitest/current.xml
+++ b/car-ui-lib/tests/apitest/current.xml
@@ -1,23 +1,17 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- THIS FILE WAS AUTO GENERATED, DO NOT EDIT MANUALLY. -->
+<!--This file is AUTO GENERATED, DO NOT EDIT MANUALLY.-->
 <resources>
-  <public type="array" name="car_ui_ime_wide_screen_allowed_package_list"/>
   <public type="attr" name="CarUiToolbarStyle"/>
   <public type="attr" name="carUiPreferenceStyle"/>
   <public type="attr" name="carUiRecyclerViewStyle"/>
-  <public type="attr" name="preferenceStyle"/>
   <public type="attr" name="state_ux_restricted"/>
-  <public type="bool" name="car_ui_alert_dialog_force_dismiss_button"/>
-  <public type="bool" name="car_ui_escrow_check_components_automatically"/>
-  <public type="bool" name="car_ui_ime_wide_screen_aligned_left"/>
-  <public type="bool" name="car_ui_ime_wide_screen_allow_app_hide_content_area"/>
+  <public type="bool" name="car_ui_enable_focus_area_background_highlight"/>
+  <public type="bool" name="car_ui_enable_focus_area_foreground_highlight"/>
   <public type="bool" name="car_ui_list_item_single_line_title"/>
-  <public type="bool" name="car_ui_preference_list_instant_change_callback"/>
   <public type="bool" name="car_ui_preference_list_show_full_screen"/>
   <public type="bool" name="car_ui_preference_show_chevron"/>
   <public type="bool" name="car_ui_scrollbar_enable"/>
   <public type="bool" name="car_ui_toolbar_logo_fills_nav_icon_space"/>
-  <public type="bool" name="car_ui_toolbar_menuitem_individual_click_listeners"/>
   <public type="bool" name="car_ui_toolbar_nav_icon_reserve_space"/>
   <public type="bool" name="car_ui_toolbar_show_logo"/>
   <public type="bool" name="car_ui_toolbar_tab_flexible_layout"/>
@@ -25,18 +19,12 @@
   <public type="color" name="car_ui_activity_background_color"/>
   <public type="color" name="car_ui_color_accent"/>
   <public type="color" name="car_ui_dialog_icon_color"/>
-  <public type="color" name="car_ui_ime_wide_screen_description_color"/>
-  <public type="color" name="car_ui_ime_wide_screen_description_title_color"/>
-  <public type="color" name="car_ui_ime_wide_screen_divider_color"/>
-  <public type="color" name="car_ui_ime_wide_screen_error_text_color"/>
-  <public type="color" name="car_ui_ime_wide_screen_search_item_sub_title_color"/>
-  <public type="color" name="car_ui_ime_wide_screen_search_item_title_color"/>
   <public type="color" name="car_ui_list_item_divider"/>
   <public type="color" name="car_ui_preference_icon_color"/>
   <public type="color" name="car_ui_preference_two_action_divider_color"/>
   <public type="color" name="car_ui_recyclerview_divider_color"/>
   <public type="color" name="car_ui_ripple_color"/>
-  <public type="color" name="car_ui_scrollbar_arrow"/>
+  <public type="color" name="car_ui_rotary_focus_color"/>
   <public type="color" name="car_ui_scrollbar_thumb"/>
   <public type="color" name="car_ui_text_color_hint"/>
   <public type="color" name="car_ui_text_color_primary"/>
@@ -48,10 +36,6 @@
   <public type="color" name="car_ui_toolbar_tab_item_selector"/>
   <public type="color" name="car_ui_toolbar_tab_selected_color"/>
   <public type="color" name="car_ui_toolbar_tab_unselected_color"/>
-  <public type="dimen" name="car_ui_app_styled_dialog_height"/>
-  <public type="dimen" name="car_ui_app_styled_dialog_position_x"/>
-  <public type="dimen" name="car_ui_app_styled_dialog_position_y"/>
-  <public type="dimen" name="car_ui_app_styled_dialog_width"/>
   <public type="dimen" name="car_ui_body1_size"/>
   <public type="dimen" name="car_ui_body2_size"/>
   <public type="dimen" name="car_ui_body3_size"/>
@@ -65,42 +49,14 @@
   <public type="dimen" name="car_ui_dialog_title_margin"/>
   <public type="dimen" name="car_ui_divider_width"/>
   <public type="dimen" name="car_ui_header_list_item_text_start_margin"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_action_button_height"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_action_button_margin_bottom"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_action_button_margin_left"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_action_button_text_size"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_description_padding_top"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_description_text_size"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_description_title_margin_top"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_description_title_padding_left"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_description_title_text_size"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_divider_width"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_error_text_padding_start"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_error_text_size"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_input_area_height"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_input_area_padding_end"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_input_area_padding_top"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_input_edit_text_padding_left"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_input_edit_text_padding_right"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_input_edit_text_size"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_input_padding_start"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_keyboard_area_padding_bottom"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_keyboard_area_padding_end"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_keyboard_area_padding_start"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_keyboard_width"/>
-  <public type="dimen" name="car_ui_ime_wide_screen_recycler_view_padding_top"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_icon_size"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_secondary_image_padding_left"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_sub_title_padding_left"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_sub_title_padding_top"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_sub_title_text_size"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_title_padding_left"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_title_padding_top"/>
-  <public type="dimen" name="car_ui_ime_wide_search_item_title_text_size"/>
   <public type="dimen" name="car_ui_list_item_action_divider_height"/>
   <public type="dimen" name="car_ui_list_item_action_divider_width"/>
   <public type="dimen" name="car_ui_list_item_avatar_icon_height"/>
   <public type="dimen" name="car_ui_list_item_avatar_icon_width"/>
+  <public type="dimen" name="car_ui_list_item_check_box_end_inset"/>
+  <public type="dimen" name="car_ui_list_item_check_box_height"/>
+  <public type="dimen" name="car_ui_list_item_check_box_icon_container_width"/>
+  <public type="dimen" name="car_ui_list_item_check_box_start_inset"/>
   <public type="dimen" name="car_ui_list_item_content_icon_height"/>
   <public type="dimen" name="car_ui_list_item_content_icon_width"/>
   <public type="dimen" name="car_ui_list_item_end_inset"/>
@@ -109,6 +65,10 @@
   <public type="dimen" name="car_ui_list_item_height"/>
   <public type="dimen" name="car_ui_list_item_icon_container_width"/>
   <public type="dimen" name="car_ui_list_item_icon_size"/>
+  <public type="dimen" name="car_ui_list_item_radio_button_end_inset"/>
+  <public type="dimen" name="car_ui_list_item_radio_button_height"/>
+  <public type="dimen" name="car_ui_list_item_radio_button_icon_container_width"/>
+  <public type="dimen" name="car_ui_list_item_radio_button_start_inset"/>
   <public type="dimen" name="car_ui_list_item_start_inset"/>
   <public type="dimen" name="car_ui_list_item_supplemental_icon_size"/>
   <public type="dimen" name="car_ui_list_item_text_no_icon_start_margin"/>
@@ -121,8 +81,6 @@
   <public type="dimen" name="car_ui_padding_4"/>
   <public type="dimen" name="car_ui_padding_5"/>
   <public type="dimen" name="car_ui_padding_6"/>
-  <public type="dimen" name="car_ui_padding_7"/>
-  <public type="dimen" name="car_ui_padding_8"/>
   <public type="dimen" name="car_ui_preference_category_icon_margin_end"/>
   <public type="dimen" name="car_ui_preference_category_icon_size"/>
   <public type="dimen" name="car_ui_preference_category_min_height"/>
@@ -150,7 +108,6 @@
   <public type="dimen" name="car_ui_scrollbar_deceleration_times_divisor"/>
   <public type="dimen" name="car_ui_scrollbar_margin"/>
   <public type="dimen" name="car_ui_scrollbar_milliseconds_per_inch"/>
-  <public type="dimen" name="car_ui_scrollbar_min_thumb_height"/>
   <public type="dimen" name="car_ui_scrollbar_padding_bottom"/>
   <public type="dimen" name="car_ui_scrollbar_padding_top"/>
   <public type="dimen" name="car_ui_scrollbar_separator_margin"/>
@@ -193,31 +150,23 @@
   <public type="dimen" name="wrap_content"/>
   <public type="drawable" name="car_ui_activity_background"/>
   <public type="drawable" name="car_ui_divider"/>
+  <public type="drawable" name="car_ui_focus_area_background_highlight"/>
+  <public type="drawable" name="car_ui_focus_area_foreground_highlight"/>
   <public type="drawable" name="car_ui_icon_add"/>
   <public type="drawable" name="car_ui_icon_arrow_back"/>
-  <public type="drawable" name="car_ui_icon_chevron"/>
   <public type="drawable" name="car_ui_icon_close"/>
   <public type="drawable" name="car_ui_icon_delete"/>
   <public type="drawable" name="car_ui_icon_down"/>
   <public type="drawable" name="car_ui_icon_edit"/>
-  <public type="drawable" name="car_ui_icon_error"/>
-  <public type="drawable" name="car_ui_icon_lock"/>
   <public type="drawable" name="car_ui_icon_overflow_menu"/>
   <public type="drawable" name="car_ui_icon_save"/>
   <public type="drawable" name="car_ui_icon_search"/>
   <public type="drawable" name="car_ui_icon_search_nav_icon"/>
   <public type="drawable" name="car_ui_icon_settings"/>
-  <public type="drawable" name="car_ui_ime_wide_screen_background"/>
-  <public type="drawable" name="car_ui_ime_wide_screen_content_area_background"/>
-  <public type="drawable" name="car_ui_ime_wide_screen_input_area_background"/>
-  <public type="drawable" name="car_ui_ime_wide_screen_input_area_tint_color"/>
-  <public type="drawable" name="car_ui_ime_wide_screen_input_area_tint_error_color"/>
-  <public type="drawable" name="car_ui_ime_wide_screen_no_content_background"/>
   <public type="drawable" name="car_ui_list_header_background"/>
   <public type="drawable" name="car_ui_list_item_avatar_icon_outline"/>
   <public type="drawable" name="car_ui_list_item_background"/>
   <public type="drawable" name="car_ui_list_item_divider"/>
-  <public type="drawable" name="car_ui_list_limiting_message_background"/>
   <public type="drawable" name="car_ui_preference_icon_chevron"/>
   <public type="drawable" name="car_ui_preference_icon_chevron_disabled"/>
   <public type="drawable" name="car_ui_preference_icon_chevron_enabled"/>
@@ -232,51 +181,27 @@
   <public type="drawable" name="car_ui_toolbar_menu_item_icon_ripple"/>
   <public type="drawable" name="car_ui_toolbar_search_close_icon"/>
   <public type="drawable" name="car_ui_toolbar_search_search_icon"/>
+  <public type="id" name="action_container"/>
+  <public type="id" name="action_container_touch_interceptor"/>
+  <public type="id" name="action_divider"/>
   <public type="id" name="action_widget_container"/>
+  <public type="id" name="avatar_icon"/>
+  <public type="id" name="body"/>
   <public type="id" name="car_ui_alert_icon"/>
   <public type="id" name="car_ui_alert_subtitle"/>
   <public type="id" name="car_ui_alert_title"/>
-  <public type="id" name="car_ui_base_layout_content_container"/>
-  <public type="id" name="car_ui_closeKeyboard"/>
-  <public type="id" name="car_ui_component_reference"/>
-  <public type="id" name="car_ui_contentAreaAutomotive"/>
-  <public type="id" name="car_ui_divider"/>
-  <public type="id" name="car_ui_first_action_container"/>
-  <public type="id" name="car_ui_focus_area"/>
-  <public type="id" name="car_ui_fullscreenArea"/>
-  <public type="id" name="car_ui_imeWideScreenInputArea"/>
-  <public type="id" name="car_ui_ime_carboard_area"/>
-  <public type="id" name="car_ui_ime_surface"/>
-  <public type="id" name="car_ui_inputExtractActionAutomotive"/>
-  <public type="id" name="car_ui_inputExtractEditTextContainer"/>
-  <public type="id" name="car_ui_list_item_action_container"/>
-  <public type="id" name="car_ui_list_item_action_container_touch_interceptor"/>
-  <public type="id" name="car_ui_list_item_action_divider"/>
-  <public type="id" name="car_ui_list_item_avatar_icon"/>
-  <public type="id" name="car_ui_list_item_body"/>
-  <public type="id" name="car_ui_list_item_checkbox_widget"/>
-  <public type="id" name="car_ui_list_item_content_icon"/>
+  <public type="id" name="car_ui_check_box_end_guideline"/>
+  <public type="id" name="car_ui_check_box_start_guideline"/>
   <public type="id" name="car_ui_list_item_end_guideline"/>
-  <public type="id" name="car_ui_list_item_icon"/>
-  <public type="id" name="car_ui_list_item_icon_container"/>
-  <public type="id" name="car_ui_list_item_radio_button_widget"/>
-  <public type="id" name="car_ui_list_item_reduced_touch_interceptor"/>
   <public type="id" name="car_ui_list_item_start_guideline"/>
-  <public type="id" name="car_ui_list_item_supplemental_icon"/>
-  <public type="id" name="car_ui_list_item_switch_widget"/>
-  <public type="id" name="car_ui_list_item_title"/>
-  <public type="id" name="car_ui_list_item_touch_interceptor"/>
-  <public type="id" name="car_ui_list_limiting_message"/>
-  <public type="id" name="car_ui_preference_container_without_widget"/>
+  <public type="id" name="car_ui_preference_fragment_container"/>
   <public type="id" name="car_ui_recycler_view"/>
   <public type="id" name="car_ui_scroll_bar"/>
   <public type="id" name="car_ui_scrollbar_page_down"/>
   <public type="id" name="car_ui_scrollbar_page_up"/>
   <public type="id" name="car_ui_scrollbar_thumb"/>
   <public type="id" name="car_ui_scrollbar_track"/>
-  <public type="id" name="car_ui_second_action_container"/>
-  <public type="id" name="car_ui_secondary_action"/>
-  <public type="id" name="car_ui_secondary_action_concrete"/>
+  <public type="id" name="car_ui_toolbar"/>
   <public type="id" name="car_ui_toolbar_background"/>
   <public type="id" name="car_ui_toolbar_bottom_guideline"/>
   <public type="id" name="car_ui_toolbar_bottom_styleable"/>
@@ -307,19 +232,20 @@
   <public type="id" name="car_ui_toolbar_title_logo"/>
   <public type="id" name="car_ui_toolbar_title_logo_container"/>
   <public type="id" name="car_ui_toolbar_top_guideline"/>
-  <public type="id" name="car_ui_wideScreenClearData"/>
-  <public type="id" name="car_ui_wideScreenDescription"/>
-  <public type="id" name="car_ui_wideScreenDescriptionTitle"/>
-  <public type="id" name="car_ui_wideScreenError"/>
-  <public type="id" name="car_ui_wideScreenErrorMessage"/>
-  <public type="id" name="car_ui_wideScreenExtractedTextIcon"/>
-  <public type="id" name="car_ui_wideScreenInputArea"/>
-  <public type="id" name="car_ui_wideScreenSearchResultList"/>
+  <public type="id" name="check_box_container"/>
+  <public type="id" name="checkbox"/>
+  <public type="id" name="checkbox_widget"/>
   <public type="id" name="container"/>
+  <public type="id" name="content"/>
+  <public type="id" name="content_icon"/>
+  <public type="id" name="icon"/>
+  <public type="id" name="icon_container"/>
   <public type="id" name="list"/>
   <public type="id" name="nested_recycler_view_layout"/>
   <public type="id" name="radio_button"/>
+  <public type="id" name="radio_button_widget"/>
   <public type="id" name="recycler_view"/>
+  <public type="id" name="reduced_touch_interceptor"/>
   <public type="id" name="search"/>
   <public type="id" name="seek_bar"/>
   <public type="id" name="seek_bar_text_left"/>
@@ -328,8 +254,14 @@
   <public type="id" name="seekbar"/>
   <public type="id" name="seekbar_value"/>
   <public type="id" name="spinner"/>
+  <public type="id" name="supplemental_icon"/>
+  <public type="id" name="switch_widget"/>
+  <public type="id" name="text"/>
   <public type="id" name="textbox"/>
+  <public type="id" name="title"/>
   <public type="id" name="title_template"/>
+  <public type="id" name="toolbar"/>
+  <public type="id" name="touch_interceptor"/>
   <public type="integer" name="car_ui_default_max_string_length"/>
   <public type="integer" name="car_ui_scrollbar_longpress_initial_delay"/>
   <public type="integer" name="car_ui_scrollbar_longpress_repeat_interval"/>
@@ -338,22 +270,19 @@
   <public type="layout" name="car_ui_alert_dialog_title_with_subtitle"/>
   <public type="layout" name="car_ui_base_layout"/>
   <public type="layout" name="car_ui_base_layout_toolbar"/>
+  <public type="layout" name="car_ui_base_layout_toolbar_legacy"/>
+  <public type="layout" name="car_ui_check_box_list_item"/>
   <public type="layout" name="car_ui_header_list_item"/>
-  <public type="layout" name="car_ui_ims_wide_screen_input_view"/>
   <public type="layout" name="car_ui_list_item"/>
-  <public type="layout" name="car_ui_list_item_compact"/>
-  <public type="layout" name="car_ui_list_limiting_message"/>
   <public type="layout" name="car_ui_list_preference"/>
+  <public type="layout" name="car_ui_list_preference_with_toolbar"/>
   <public type="layout" name="car_ui_preference"/>
   <public type="layout" name="car_ui_preference_category"/>
   <public type="layout" name="car_ui_preference_chevron"/>
   <public type="layout" name="car_ui_preference_dialog_edittext"/>
   <public type="layout" name="car_ui_preference_dropdown"/>
   <public type="layout" name="car_ui_preference_fragment"/>
-  <public type="layout" name="car_ui_preference_two_action_icon"/>
-  <public type="layout" name="car_ui_preference_two_action_switch"/>
-  <public type="layout" name="car_ui_preference_two_action_text"/>
-  <public type="layout" name="car_ui_preference_two_action_text_borderless"/>
+  <public type="layout" name="car_ui_preference_fragment_with_toolbar"/>
   <public type="layout" name="car_ui_preference_widget_checkbox"/>
   <public type="layout" name="car_ui_preference_widget_seekbar"/>
   <public type="layout" name="car_ui_preference_widget_switch"/>
@@ -364,7 +293,6 @@
   <public type="layout" name="car_ui_seekbar_dialog"/>
   <public type="layout" name="car_ui_toolbar"/>
   <public type="layout" name="car_ui_toolbar_menu_item"/>
-  <public type="layout" name="car_ui_toolbar_menu_item_primary"/>
   <public type="layout" name="car_ui_toolbar_search_view"/>
   <public type="layout" name="car_ui_toolbar_tab_item"/>
   <public type="layout" name="car_ui_toolbar_tab_item_flexible"/>
@@ -372,12 +300,10 @@
   <public type="layout" name="car_ui_toolbar_tab_item_layout_flexible"/>
   <public type="layout" name="car_ui_toolbar_two_row"/>
   <public type="layout" name="car_ui_two_action_preference"/>
-  <public type="raw" name="car_ui_keep"/>
   <public type="string" name="car_ui_alert_dialog_default_button"/>
   <public type="string" name="car_ui_dialog_preference_negative"/>
   <public type="string" name="car_ui_dialog_preference_positive"/>
   <public type="string" name="car_ui_ellipsis"/>
-  <public type="string" name="car_ui_ime_wide_screen_system_property_name"/>
   <public type="string" name="car_ui_installer_process_name"/>
   <public type="string" name="car_ui_preference_switch_off"/>
   <public type="string" name="car_ui_preference_switch_on"/>
@@ -385,14 +311,13 @@
   <public type="string" name="car_ui_scrollbar_component"/>
   <public type="string" name="car_ui_scrollbar_page_down_button"/>
   <public type="string" name="car_ui_scrollbar_page_up_button"/>
-  <public type="string" name="car_ui_scrolling_limited_message"/>
-  <public type="string" name="car_ui_shared_library_package_system_property_name"/>
   <public type="string" name="car_ui_toolbar_default_search_hint"/>
   <public type="string" name="car_ui_toolbar_menu_item_overflow_title"/>
   <public type="string" name="car_ui_toolbar_menu_item_search_title"/>
   <public type="string" name="car_ui_toolbar_menu_item_settings_title"/>
   <public type="string" name="car_ui_toolbar_nav_icon_content_description"/>
   <public type="style" name="CarUiPreferenceTheme"/>
+  <public type="style" name="CarUiPreferenceTheme.WithToolbar"/>
   <public type="style" name="Preference.CarUi"/>
   <public type="style" name="Preference.CarUi.Category"/>
   <public type="style" name="Preference.CarUi.CheckBoxPreference"/>
@@ -412,6 +337,7 @@
   <public type="style" name="Preference.CarUi.SeekBarPreference"/>
   <public type="style" name="Preference.CarUi.SwitchPreference"/>
   <public type="style" name="PreferenceFragment.CarUi"/>
+  <public type="style" name="PreferenceFragment.CarUi.WithToolbar"/>
   <public type="style" name="PreferenceFragmentList.CarUi"/>
   <public type="style" name="TextAppearance.CarUi"/>
   <public type="style" name="TextAppearance.CarUi.AlertDialog.Subtitle"/>
diff --git a/car-ui-lib/tests/apitest/git_utils.py b/car-ui-lib/tests/apitest/git_utils.py
index 9d19432..d3b83a5 100755
--- a/car-ui-lib/tests/apitest/git_utils.py
+++ b/car-ui-lib/tests/apitest/git_utils.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # Copyright 2019, The Android Open Source Project
 #
diff --git a/car-ui-lib/tests/apitest/resource_name_allowed.xml b/car-ui-lib/tests/apitest/resource_name_allowed.xml
deleted file mode 100644
index 733ca28..0000000
--- a/car-ui-lib/tests/apitest/resource_name_allowed.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!--Copyright (C) 2020 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.-->
-
-<!--
-    car-ui-lib resource names should follow the patterns below:
-    attr: ^CarUi*
-    style: *CarUi*
-    others: ^car_ui_*
-
-    Adding resource names to the following list will bypass name validation check.
-    The intention is to make it easier to maintain keep.xml
--->
-<resources>
-    <item type="id" name="recycler_view"/>
-    <item type="attr" name="state_ux_restricted"/>
-    <item type="id" name="radio_button"/>
-    <item type="id" name="spinner"/>
-    <item type="id" name="list"/>
-    <item type="id" name="seek_bar_text_left"/>
-    <item type="id" name="seek_bar_text_right"/>
-    <item type="id" name="nested_recycler_view_layout"/>
-    <item type="id" name="seek_bar"/>
-    <item type="id" name="textbox"/>
-    <item type="id" name="action_widget_container"/>
-    <item type="id" name="title_template"/>
-    <item type="id" name="seekbar"/>
-    <item type="id" name="seekbar_value"/>
-    <item type="id" name="search"/>
-    <item type="id" name="toolbar"/>
-    <item type="id" name="container"/>
-    <item type="dimen" name="wrap_content"/>
-    <item type="id" name="seek_bar_text_top"/>
-    <item type="attr" name="preferenceStyle"/>
-</resources>
diff --git a/car-ui-lib/tests/apitest/resource_utils.py b/car-ui-lib/tests/apitest/resource_utils.py
index fa5556a..8429d33 100755
--- a/car-ui-lib/tests/apitest/resource_utils.py
+++ b/car-ui-lib/tests/apitest/resource_utils.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # Copyright 2019, The Android Open Source Project
 #
@@ -100,27 +100,18 @@
     # lxml installed
     import lxml.etree as etree
     doc = etree.parse(filename)
-    root = doc.getroot()
+    resourceTag = doc.getroot()
     result = set()
-    for resource in root:
+    for resource in resourceTag:
         if resource.tag == 'declare-styleable' or resource.tag is etree.Comment:
             continue
 
         resName = resource.get('name')
         resType = resource.tag
-        if resType == "string-array":
-            resType = "array"
         if resource.tag == 'item' or resource.tag == 'public':
             resType = resource.get('type')
 
-        if resType == 'overlayable':
-            for policy in resource:
-                for overlayable in policy:
-                    resName = overlayable.get('name')
-                    resType = overlayable.get('type')
-                    add_resource_to_set(result, Resource(resName, resType,
-                                                        ResourceLocation(filename, resource.sourceline)))
-        else:
+        if resType != 'overlayable':
             add_resource_to_set(result, Resource(resName, resType,
                                                  ResourceLocation(filename, resource.sourceline)))
 
diff --git a/car-ui-lib/tests/apitest/verify_rro.py b/car-ui-lib/tests/apitest/verify_rro.py
index 5975d54..a58210d 100755
--- a/car-ui-lib/tests/apitest/verify_rro.py
+++ b/car-ui-lib/tests/apitest/verify_rro.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # Copyright 2019, The Android Open Source Project
 #
@@ -16,13 +16,9 @@
 
 import argparse
 import sys
-from resource_utils import get_all_resources, merge_resources
+from resource_utils import get_all_resources, remove_layout_resources, merge_resources
 from git_utils import has_chassis_changes
 
-if sys.version_info[0] != 3:
-    print("Must use python 3")
-    sys.exit(1)
-
 def main():
     parser = argparse.ArgumentParser(description="Check that an rro does not attempt to overlay any resources that don't exist")
     parser.add_argument('--sha', help='Git hash of current changes. This script will not run if this is provided and there are no chassis changes.')
@@ -40,11 +36,11 @@
 
     rro_resources = set()
     for resDir in args.rro:
-        merge_resources(rro_resources, get_all_resources(resDir[0]))
+        merge_resources(rro_resources, remove_layout_resources(get_all_resources(resDir[0])))
 
     base_resources = set()
     for resDir in args.base:
-        merge_resources(base_resources, get_all_resources(resDir[0]))
+        merge_resources(base_resources, remove_layout_resources(get_all_resources(resDir[0])))
 
     extras = rro_resources.difference(base_resources)
     if len(extras) > 0:
diff --git a/car-ui-lib/tests/paintbooth/Android.bp b/car-ui-lib/tests/paintbooth/Android.bp
new file mode 100644
index 0000000..e303d83
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/Android.bp
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_app {
+    name: "PaintBooth",
+
+    srcs: [
+    	"src/**/*.java",
+    	"src/**/*.kt",
+    ],
+
+    required: ["privapp_whitelist_com.android.car.ui.paintbooth"],
+
+    resource_dirs: ["res", "res-public"],
+
+    platform_apis: true,
+
+    certificate: "platform",
+
+    privileged: true,
+
+    static_libs: [
+        "car-ui-lib",
+        "android.car.userlib",
+		"guava",
+		"gson-prebuilt-jar",
+    ],
+
+    optimize: {
+        enabled: false,
+    },
+
+    dex_preopt: {
+        enabled: false,
+    },
+
+    product_variables: {
+        pdk: {
+            enabled: false,
+        },
+    },
+    export_package_resources: true,
+}
diff --git a/car-ui-lib/tests/paintbooth/AndroidManifest-gradle.xml b/car-ui-lib/tests/paintbooth/AndroidManifest-gradle.xml
new file mode 100644
index 0000000..3184bd7
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/AndroidManifest-gradle.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.car.ui.paintbooth">
+
+  <application
+      android:supportsRtl="true"
+      android:icon="@drawable/ic_launcher"
+      android:label="@string/app_name"
+      android:theme="@style/Theme.CarUi.WithToolbar">
+    <activity
+        android:name=".MainActivity"
+        android:exported="true">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN"/>
+        <category android:name="android.intent.category.LAUNCHER"/>
+      </intent-filter>
+    </activity>
+
+    <activity
+        android:name=".dialogs.DialogsActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".caruirecyclerview.CarUiRecyclerViewActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".caruirecyclerview.GridCarUiRecyclerViewActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".preferences.PreferenceActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".toolbar.ToolbarActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity">
+      <meta-data android:name="distractionOptimized" android:value="true"/>
+    </activity>
+    <activity
+        android:name=".toolbar.OldToolbarActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"
+        android:theme="@style/Theme.CarUi">
+      <meta-data android:name="distractionOptimized" android:value="true"/>
+    </activity>
+    <activity
+        android:name=".overlays.OverlayActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity">
+      <meta-data android:name="distractionOptimized" android:value="true"/>
+    </activity>
+    <activity
+        android:name=".widgets.WidgetActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".caruirecyclerview.CarUiListItemActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+
+    <service
+        android:label="Current Activity Service"
+        android:exported="false"
+        android:name=".currentactivity.CurrentActivityService"/>
+    <service
+        android:label="Visible Bounds Simulator"
+        android:exported="false"
+        android:name=".VisibleBoundsSimulator"/>
+  </application>
+</manifest>
diff --git a/car-ui-lib/tests/paintbooth/AndroidManifest.xml b/car-ui-lib/tests/paintbooth/AndroidManifest.xml
new file mode 100644
index 0000000..c277ff5
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/AndroidManifest.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.car.ui.paintbooth">
+
+  <uses-sdk
+      android:minSdkVersion="28"
+      android:targetSdkVersion="28"/>
+
+  <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+  <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+  <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
+  <uses-permission android:name="android.permission.MANAGE_USERS"/>
+  <!-- Required to use the TYPE_DISPLAY_OVERLAY layout param for the current activity overlay -->
+  <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
+  <!-- Required for listening to android task stack changes -->
+  <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+  <uses-permission android:name="android.permission.REAL_GET_TASKS" />
+  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+  <!-- Required for using TYPE_APPLICATION_OVERLAY to display overlays -->
+  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+  <!-- Required to test permission dialogs -->
+  <uses-permission android:name="android.permission.CAMERA"/>
+  <uses-permission android:name="android.permission.READ_CONTACTS"/>
+  <uses-permission android:name="android.permission.SEND_SMS"/>
+  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
+
+  <application
+      android:supportsRtl="true"
+      android:icon="@drawable/ic_launcher"
+      android:label="@string/app_name"
+      android:theme="@style/Theme.CarUi.WithToolbar">
+    <activity
+        android:name=".MainActivity"
+        android:exported="true">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN"/>
+        <category android:name="android.intent.category.LAUNCHER"/>
+      </intent-filter>
+    </activity>
+
+    <activity
+        android:name=".dialogs.DialogsActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".caruirecyclerview.CarUiRecyclerViewActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".caruirecyclerview.GridCarUiRecyclerViewActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".preferences.PreferenceActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".toolbar.ToolbarActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity">
+      <meta-data android:name="distractionOptimized" android:value="true"/>
+    </activity>
+    <activity
+        android:name=".toolbar.NoCarUiToolbarActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"
+        android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
+    <activity
+        android:name=".toolbar.OldToolbarActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"
+        android:theme="@style/Theme.CarUi"/>
+    <activity
+        android:name=".overlays.OverlayActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity">
+      <meta-data android:name="distractionOptimized" android:value="true"/>
+    </activity>
+    <activity
+        android:name=".widgets.WidgetActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+    <activity
+        android:name=".caruirecyclerview.CarUiListItemActivity"
+        android:exported="false"
+        android:parentActivityName=".MainActivity"/>
+
+    <service
+        android:label="Current Activity Service"
+        android:exported="false"
+        android:name=".currentactivity.CurrentActivityService"/>
+    <service
+        android:label="Visible Bounds Simulator"
+        android:exported="false"
+        android:name=".VisibleBoundsSimulator"/>
+  </application>
+</manifest>
diff --git a/car-ui-lib/tests/paintbooth/build.gradle b/car-ui-lib/tests/paintbooth/build.gradle
new file mode 100644
index 0000000..e85a629
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/build.gradle
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 29
+    defaultConfig {
+        applicationId "com.android.car.ui.paintbooth"
+        minSdkVersion 28
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest-gradle.xml'
+            java {
+                srcDirs = ['src']
+                filter.excludes = [
+                        "com/android/car/ui/paintbooth/overlays/OverlayManagerImpl.java",
+                        "com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java",
+                ]
+            }
+            res.srcDirs = ['res', 'res-public']
+        }
+    }
+}
+
+dependencies {
+    implementation project(':')
+    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0'
+    api 'androidx.annotation:annotation:1.1.0'
+    api 'androidx.constraintlayout:constraintlayout:1.1.3'
+    api 'androidx.recyclerview:recyclerview:1.0.0'
+}
diff --git a/car-ui-lib/paintbooth/gradlew b/car-ui-lib/tests/paintbooth/gradlew
similarity index 100%
rename from car-ui-lib/paintbooth/gradlew
rename to car-ui-lib/tests/paintbooth/gradlew
diff --git a/car-ui-lib/paintbooth/gradlew.bat b/car-ui-lib/tests/paintbooth/gradlew.bat
similarity index 100%
rename from car-ui-lib/paintbooth/gradlew.bat
rename to car-ui-lib/tests/paintbooth/gradlew.bat
diff --git a/car-ui-lib/paintbooth/src/main/res-public/values/public.xml b/car-ui-lib/tests/paintbooth/res-public/values/public.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res-public/values/public.xml
rename to car-ui-lib/tests/paintbooth/res-public/values/public.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_cut.xml b/car-ui-lib/tests/paintbooth/res/drawable/ic_cut.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/drawable/ic_cut.xml
rename to car-ui-lib/tests/paintbooth/res/drawable/ic_cut.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_launcher.png b/car-ui-lib/tests/paintbooth/res/drawable/ic_launcher.png
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/drawable/ic_launcher.png
rename to car-ui-lib/tests/paintbooth/res/drawable/ic_launcher.png
Binary files differ
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_sample_logo.png b/car-ui-lib/tests/paintbooth/res/drawable/ic_sample_logo.png
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/drawable/ic_sample_logo.png
rename to car-ui-lib/tests/paintbooth/res/drawable/ic_sample_logo.png
Binary files differ
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_settings_gear.xml b/car-ui-lib/tests/paintbooth/res/drawable/ic_settings_gear.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/drawable/ic_settings_gear.xml
rename to car-ui-lib/tests/paintbooth/res/drawable/ic_settings_gear.xml
diff --git a/car-ui-lib/tests/paintbooth/res/drawable/ic_settings_wifi.xml b/car-ui-lib/tests/paintbooth/res/drawable/ic_settings_wifi.xml
new file mode 100644
index 0000000..9a09d70
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/res/drawable/ic_settings_wifi.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="64"
+    android:viewportHeight="64">
+  <path
+      android:pathData="M36.87,39.05a7,7 0,1 1,-9.901 9.9,7 7,0 0,1 9.901,-9.9zM14.243,26.323c9.763,-9.764 25.593,-9.764 35.355,0M53.84,22.08C41.735,9.972 22.106,9.972 10,22.08M18.486,30.565c7.42,-7.42 19.449,-7.42 26.869,0M22.728,34.808c5.077,-5.077 13.308,-5.077 18.385,0"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#FFF"/>
+</vector>
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_tracklist.xml b/car-ui-lib/tests/paintbooth/res/drawable/ic_tracklist.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/drawable/ic_tracklist.xml
rename to car-ui-lib/tests/paintbooth/res/drawable/ic_tracklist.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/simulated_screen_shape.xml b/car-ui-lib/tests/paintbooth/res/drawable/simulated_screen_shape.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/drawable/simulated_screen_shape.xml
rename to car-ui-lib/tests/paintbooth/res/drawable/simulated_screen_shape.xml
diff --git a/car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_activity.xml b/car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_activity.xml
new file mode 100644
index 0000000..5ae7e7f
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_activity.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<com.android.car.ui.recyclerview.CarUiRecyclerView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/list"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background"/>
diff --git a/car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_activity_with_old_toolbar.xml b/car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_activity_with_old_toolbar.xml
new file mode 100644
index 0000000..cce0cde
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_activity_with_old_toolbar.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background">
+
+    <com.android.car.ui.recyclerview.CarUiRecyclerView
+        android:id="@+id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clipToPadding="false"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"/>
+
+    <com.android.car.ui.toolbar.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/car_ui_recycler_view_list_item.xml b/car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_list_item.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/layout/car_ui_recycler_view_list_item.xml
rename to car-ui-lib/tests/paintbooth/res/layout/car_ui_recycler_view_list_item.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/details_preference_widget.xml b/car-ui-lib/tests/paintbooth/res/layout/details_preference_widget.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/layout/details_preference_widget.xml
rename to car-ui-lib/tests/paintbooth/res/layout/details_preference_widget.xml
diff --git a/car-ui-lib/tests/paintbooth/res/layout/grid_car_ui_recycler_view_activity.xml b/car-ui-lib/tests/paintbooth/res/layout/grid_car_ui_recycler_view_activity.xml
new file mode 100644
index 0000000..2b0d1a4
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/res/layout/grid_car_ui_recycler_view_activity.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<com.android.car.ui.recyclerview.CarUiRecyclerView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/list"
+    app:layoutStyle="grid"
+    app:numOfColumns="4"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/car_ui_activity_background" />
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/list_item.xml b/car-ui-lib/tests/paintbooth/res/layout/list_item.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/layout/list_item.xml
rename to car-ui-lib/tests/paintbooth/res/layout/list_item.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/list_item_switch.xml b/car-ui-lib/tests/paintbooth/res/layout/list_item_switch.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/layout/list_item_switch.xml
rename to car-ui-lib/tests/paintbooth/res/layout/list_item_switch.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/no_car_ui_toolbar_activity.xml b/car-ui-lib/tests/paintbooth/res/layout/no_car_ui_toolbar_activity.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/layout/no_car_ui_toolbar_activity.xml
rename to car-ui-lib/tests/paintbooth/res/layout/no_car_ui_toolbar_activity.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/layout/simulated_screen_shape_container.xml b/car-ui-lib/tests/paintbooth/res/layout/simulated_screen_shape_container.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/layout/simulated_screen_shape_container.xml
rename to car-ui-lib/tests/paintbooth/res/layout/simulated_screen_shape_container.xml
diff --git a/car-ui-lib/tests/paintbooth/res/layout/widgets_activity.xml b/car-ui-lib/tests/paintbooth/res/layout/widgets_activity.xml
new file mode 100644
index 0000000..dcadcea
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/res/layout/widgets_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+
+    <CheckBox
+        android:id="@+id/check"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/widget_checkbox_text"/>
+
+    <Switch
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/widget_switch_text"/>
+</LinearLayout>
diff --git a/car-ui-lib/paintbooth/src/main/res/values/arrays.xml b/car-ui-lib/tests/paintbooth/res/values/arrays.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/values/arrays.xml
rename to car-ui-lib/tests/paintbooth/res/values/arrays.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/values/colors.xml b/car-ui-lib/tests/paintbooth/res/values/colors.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/values/colors.xml
rename to car-ui-lib/tests/paintbooth/res/values/colors.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/values/dimens.xml b/car-ui-lib/tests/paintbooth/res/values/dimens.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/values/dimens.xml
rename to car-ui-lib/tests/paintbooth/res/values/dimens.xml
diff --git a/car-ui-lib/tests/paintbooth/res/values/strings.xml b/car-ui-lib/tests/paintbooth/res/values/strings.xml
new file mode 100644
index 0000000..f347784
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/res/values/strings.xml
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+  <!-- Application name [CHAR LIMIT=30] -->
+  <string name="app_name" translatable="false">Paint Booth (Gerrit)</string>
+
+  <!-- Description of the CurrentActivityService. [CHAR_LIMIT=200] -->
+  <string name="current_activity_service_description">Shows the current activity</string>
+
+  <!-- Strings for Preference Samples -->
+  <eat-comment/>
+
+  <!-- Preferences page title [CHAR_LIMIT=13] -->
+  <string name="preferences_screen_title">Settings</string>
+
+  <!--This section is for basic attributes -->
+  <eat-comment/>
+  <!-- Category title for basic preferences [CHAR_LIMIT=26]-->
+  <string name="basic_preferences">Basic attributes</string>
+  <!-- Title of a basic preference [CHAR_LIMIT=10]-->
+  <string name="title_basic_preference">Preference</string>
+  <!-- Summary of a basic preference [CHAR_LIMIT=71]-->
+  <string name="summary_basic_preference">Simple preference with no special attributes</string>
+
+  <!-- Title of a preference with stylized text [CHAR_LIMIT=71]-->
+  <string name="title_stylish_preference"><b>Very</b> <i>stylish</i> <u>preference</u></string>
+  <!-- Summary of a preference with stylized text [CHAR_LIMIT=150]-->
+  <string name="summary_stylish_preference">Define style tags such as &lt;b&gt; in a string resource to customize a preference\'s text</string>
+
+  <!-- Title of an icon preference [CHAR_LIMIT=25]-->
+  <string name="title_icon_preference">Icon preference</string>
+  <!-- Summary of an icon preference [CHAR_LIMIT=103]-->
+  <string name="summary_icon_preference">Define a drawable to display it at the start of the preference</string>
+
+  <!-- Title of a single line title preference [CHAR_LIMIT=165]-->
+  <string name="title_single_line_title_preference">Single line title preference - no matter how long the title is it will never wrap to multiple lines</string>
+  <!-- Summary of a single line title preference [CHAR_LIMIT=108]-->
+  <string name="summary_single_line_title_preference">This title will be ellipsized instead of wrapping to another line</string>
+
+  <!-- Title of a single line title preference without summary [CHAR_LIMIT=28]-->
+  <string name="title_single_line_no_summary">Single line preference - no summary</string>
+
+  <!--This section is for preferences that contain a widget in their layout -->
+  <eat-comment/>
+  <!-- Category title for preferences with widgets [CHAR_LIMIT=12]-->
+  <string name="widgets">Widgets</string>
+
+  <!-- Title of a two action preference [CHAR_LIMIT=31]-->
+  <string name="title_twoaction_preference">TwoAction preference</string>
+  <!-- Summary of a two action preference [CHAR_LIMIT=70]-->
+  <string name="summary_twoaction_preference">A widget should be visible on the right</string>
+
+  <!-- Title of a checkbox preference [CHAR_LIMIT=31]-->
+  <string name="title_checkbox_preference">Checkbox preference</string>
+  <!-- Summary of a checkbox preference [CHAR_LIMIT=78]-->
+  <string name="summary_checkbox_preference">Tap anywhere in this preference to toggle state</string>
+
+  <!-- Title of a switch preference [CHAR_LIMIT=28]-->
+  <string name="title_switch_preference">Switch preference</string>
+  <!-- Summary of a switch preference [CHAR_LIMIT=78]-->
+  <string name="summary_switch_preference">Tap anywhere in this preference to toggle state</string>
+
+  <!-- Title of a dropdown preference [CHAR_LIMIT=31]-->
+  <string name="title_dropdown_preference">Dropdown preference</string>
+
+  <!-- Title of a seekbar preference [CHAR_LIMIT=30]-->
+  <string name="title_seekbar_preference">Seekbar preference</string>
+  <!-- Summary of an seekbar preference [CHAR_LIMIT=32]-->
+  <string name="summary_seekbar_preference">Seekbar summary</string>
+
+  <!--This section is for preferences that launch a dialog to edit the preference -->
+  <eat-comment/>
+  <!-- Category title for preferences which launch dialogs [CHAR_LIMIT=12]-->
+  <string name="dialogs">Dialogs</string>
+
+  <!-- Title of an edittext preference [CHAR_LIMIT=32]-->
+  <string name="title_edittext_preference">EditText preference</string>
+  <!-- Title of the dialog for an edittext preference [CHAR_LIMIT=43]-->
+  <string name="dialog_title_edittext_preference">This title can be changed!</string>
+
+  <!-- Title of a list preference [CHAR_LIMIT=25]-->
+  <string name="title_list_preference">List preference</string>
+  <!-- Title of the dialog for a list preference [CHAR_LIMIT=30]-->
+  <string name="dialog_title_list_preference">Choose one option!</string>
+
+  <!-- Title of a multi-select list preference [CHAR_LIMIT=46]-->
+  <string name="title_multi_list_preference">Multi-select list preference</string>
+  <!-- Summary of a multi-select list preference [CHAR_LIMIT=71]-->
+  <string name="summary_multi_list_preference">Shows a dialog with multiple choice options</string>
+  <!-- Title of the dialog for a multi-select list preference [CHAR_LIMIT=33]-->
+  <string name="dialog_title_multi_list_preference">Choose some options!</string>
+
+  <!--This section is for advanced attributes-->
+  <eat-comment/>
+  <!-- Category title for preferences with advanced attributes [CHAR_LIMIT=32]-->
+  <string name="advanced_attributes">Advanced attributes</string>
+
+  <!-- Title of an expandable preference [CHAR_LIMIT=45]-->
+  <string name="title_expandable_preference">Expandable preference group</string>
+  <!-- Summary of an expandable preference [CHAR_LIMIT=131]-->
+  <string name="summary_expandable_preference">This group shows one item and collapses the rest into the advanced button below</string>
+
+  <!-- Title of a preference which launches an intent [CHAR_LIMIT=28]-->
+  <string name="title_intent_preference">Intent preference</string>
+  <!-- Summary of a preference which launches an intent [CHAR_LIMIT=51]-->
+  <string name="summary_intent_preference">Launches an intent when pressed</string>
+
+  <!-- Title of a parent preference [CHAR_LIMIT=28]-->
+  <string name="title_parent_preference">Parent preference</string>
+  <!-- Summary of a parent preference [CHAR_LIMIT=130]-->
+  <string name="summary_parent_preference">Toggling this preference will change the enabled state of the preference below</string>
+
+  <!-- Title of a child preference [CHAR_LIMIT=26]-->
+  <string name="title_child_preference">Child preference</string>
+  <!-- Summary of a child preference [CHAR_LIMIT=123]-->
+  <string name="summary_child_preference">The enabled state of this preference is controlled by the preference above</string>
+
+  <!-- Title of a switch preference with variable summaries [CHAR_LIMIT=45]-->
+  <string name="title_toggle_summary_preference">Variable summary preference</string>
+  <!-- Summary of a variable summary preference when the preference is on [CHAR_LIMIT=118]-->
+  <string name="summary_on_toggle_summary_preference">On! :) - the summary of this preference changes depending on its state</string>
+  <!-- Summary of a variable summary preference when the preference is off [CHAR_LIMIT=118]-->
+  <string name="summary_off_toggle_summary_preference">Off! :( - the summary of this preference changes depending on its state</string>
+
+  <!-- Title of a copyable preference [CHAR_LIMIT=31]-->
+  <string name="title_copyable_preference">Copyable preference</string>
+  <!-- Summary of a copyable preference [CHAR_LIMIT=81]-->
+  <string name="summary_copyable_preference">Long press on this preference to copy its summary</string>
+
+  <!-- Title of a Advanced preference [CHAR_LIMIT=13]-->
+  <string name="advanced_preference">Advanced</string>
+
+  <!-- Title of a Intent preference [CHAR_LIMIT=28]-->
+  <string name="intent_preference">Intent preference</string>
+
+  <!--This section is for toolbar attributes -->
+  <eat-comment/>
+
+  <!-- Text for change title button [CHAR_LIMIT=20]-->
+  <string name="toolbar_change_title">Change title</string>
+
+  <!-- Text for set xml button [CHAR_LIMIT=45]-->
+  <string name="toolbar_set_xml_resource">MenuItem: Set to XML source</string>
+
+  <!-- Text for add icon button [CHAR_LIMIT=30]-->
+  <string name="toolbar_add_icon">MenuItem: Add Icon</string>
+
+  <!-- Text for add untined icon button [CHAR_LIMIT=45]-->
+  <string name="toolbar_add_untined_icon">MenuItem: Add untinted icon</string>
+
+  <!-- Text for add overflow button [CHAR_LIMIT=36]-->
+  <string name="toolbar_add_overflow">Overflow MenuItem: Add Simple</string>
+
+  <!-- Text for add overflow button [CHAR_LIMIT=36]-->
+  <string name="toolbar_add_overflow_switch">Overflow MenuItem: Add switchable</string>
+
+  <!-- Text for add icon text overflow button [CHAR_LIMIT=45]-->
+  <string name="toolbar_add_icon_text_overflow">Overflow MenuItem: Add icon and text</string>
+
+  <!-- Text for add switch button [CHAR_LIMIT=33]-->
+  <string name="toolbar_add_switch">MenuItem: Add Switch</string>
+
+  <!-- Text for add text button [CHAR_LIMIT=30]-->
+  <string name="toolbar_add_text">MenuItem: Add text</string>
+
+  <!-- Text for add icon text button [CHAR_LIMIT=45]-->
+  <string name="toolbar_add_icon_text">MenuItem: Add icon and text</string>
+
+  <!-- Text for add untined icon and text button [CHAR_LIMIT=60]-->
+  <string name="toolbar_add_untinted_icon_and_text">MenuItem: Add untinted icon and text</string>
+
+  <!-- Text for add activatable button [CHAR_LIMIT=41]-->
+  <string name="toolbar_add_activatable">MenuItem: Add activatable</string>
+
+  <!-- Text for add activatable button [CHAR_LIMIT=36]-->
+  <string name="toolbar_add_morphing">MenuItem: Add morphing</string>
+
+  <!-- Text for toggle visibility button [CHAR_LIMIT=45]-->
+  <string name="toolbar_toggle_visibility">MenuItem: Toggle Visibility</string>
+
+  <!-- Text for toggle enable button [CHAR_LIMIT=40]-->
+  <string name="toolbar_toggle_enable">MenuItem: Toggle Enabled</string>
+
+  <!-- Text for toggle enable button [CHAR_LIMIT=49]-->
+  <string name="toolbar_toggle_perform_click">MenuItem: Call PerformClick()</string>
+
+  <!-- Text for toggle icon button [CHAR_LIMIT=35]-->
+  <string name="toolbar_toggle_icon">MenuItem: Toggle Icon</string>
+
+  <!-- Text for toggle show while search button [CHAR_LIMIT=61]-->
+  <string name="toolbar_toggle_show_while_search">MenuItem: Toggle show while searching</string>
+
+  <!-- Text for cycle nav button mode button [CHAR_LIMIT=35]-->
+  <string name="toolbar_cycle_nav_button">Cycle nav button mode</string>
+
+  <!-- Text for toggle logo button [CHAR_LIMIT=19]-->
+  <string name="toolbar_toggle_logo">Toggle logo</string>
+
+  <!-- Text for cycle state button [CHAR_LIMIT=20]-->
+  <string name="toolbar_cycle_state">Cycle state</string>
+
+  <!-- Text for toggle search hint button [CHAR_LIMIT=30]-->
+  <string name="toolbar_toggle_search_hint">Toggle search hint</string>
+
+  <!-- Text for toggle background button [CHAR_LIMIT=30]-->
+  <string name="toolbar_toggle_background">Toggle background</string>
+
+  <!-- Text for add tab button [CHAR_LIMIT=12]-->
+  <string name="toolbar_add_tab">Add tab</string>
+
+  <!-- Text for add tab with custom text button [CHAR_LIMIT=40]-->
+  <string name="toolbar_add_tab_with_custom_text">Add tab with custom text</string>
+
+  <!-- Text for showing tabs in subpages [CHAR_LIMIT=50]-->
+  <string name="toolbar_show_tabs_in_subpage">Toggle showing tabs in subpages</string>
+
+  <!-- Text for toggle search icon button [CHAR_LIMIT=30]-->
+  <string name="toolbar_toggle_search_icon">Toggle search icon</string>
+
+  <!--This section is for dialog attributes -->
+  <eat-comment/>
+
+  <!-- Text for show dialog button [CHAR_LIMIT=18]-->
+  <string name="dialog_show_dialog">Show Dialog</string>
+
+  <!-- Text for show dialog button [CHAR_LIMIT=30]-->
+  <string name="dialog_show_dialog_icon">Show Dialog with icon</string>
+
+  <!-- Text for Dialog with edit text box button [CHAR_LIMIT=50]-->
+  <string name="dialog_show_dialog_edit">Show Dialog with edit text box</string>
+
+  <!-- Text for show Dialog with only positive button button [CHAR_LIMIT=61]-->
+  <string name="dialog_show_dialog_only_positive">Show Dialog with only positive button</string>
+
+  <!-- Text for show Dialog With no button provided button [CHAR_LIMIT=60]-->
+  <string name="dialog_show_dialog_no_button">Show Dialog With no button provided</string>
+
+  <!-- Text for show Dialog With Checkbox button [CHAR_LIMIT=41]-->
+  <string name="dialog_show_dialog_checkbox">Show Dialog With Checkbox</string>
+
+  <!-- Text for show Dialog without title button [CHAR_LIMIT=41]-->
+  <string name="dialog_show_dialog_no_title">Show Dialog without title</string>
+
+  <!-- Text for show Toast button [CHAR_LIMIT=16]-->
+  <string name="dialog_show_toast">Show Toast</string>
+
+  <!-- Button that shows a dialog with a subtitle [CHAR_LIMIT=50]-->
+  <string name="dialog_show_subtitle">Show Dialog with title and subtitle</string>
+
+  <!-- Button that shows a dialog with a subtitle and icon [CHAR_LIMIT=50]-->
+  <string name="dialog_show_subtitle_and_icon">Show Dialog with title, subtitle, and icon</string>
+
+  <!-- Button that shows a dialog with a long title, subtitle and icon [CHAR_LIMIT=500]-->
+  <string name="dialog_show_long_subtitle_and_icon">Show Dialog with a long title, subtitle, and icon</string>
+
+  <!-- Text to show Dialog with single choice items-->
+  <string name="dialog_show_single_choice">Show with single choice items</string>
+
+  <!-- Text to show a permission Dialog [CHAR_LIMIT=50] -->
+  <string name="dialog_show_permission_dialog">Show permission dialog</string>
+
+  <!-- Text to show a permission Dialog for multiple permissions [CHAR_LIMIT=50] -->
+  <string name="dialog_show_multi_permission_dialog">Show multiple permissions dialog</string>
+
+  <!-- Text on button to show a permission dialog asking for the users location. [CHAR_LIMIT=100] -->
+  <string name="dialog_show_foreground_permission_dialog">Show foreground permission dialog</string>
+
+  <!-- Text on button to show a permission dialog asking for the users location in the background [CHAR_LIMIT=100] -->
+  <string name="dialog_show_background_permission_dialog">Show background permission dialog</string>
+
+  <!--This section is for widget attributes -->
+  <eat-comment/>
+  <!-- Text for checkbox [CHAR_LIMIT=16]-->
+  <string name="widget_checkbox_text">I\'m a check box</string>
+  <!-- Text for switch [CHAR_LIMIT=25]-->
+  <string name="widget_switch_text">I\'m a switch</string>
+
+</resources>
diff --git a/car-ui-lib/paintbooth/src/main/res/xml/current_activity_service.xml b/car-ui-lib/tests/paintbooth/res/xml/current_activity_service.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/xml/current_activity_service.xml
rename to car-ui-lib/tests/paintbooth/res/xml/current_activity_service.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/xml/menuitems.xml b/car-ui-lib/tests/paintbooth/res/xml/menuitems.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/xml/menuitems.xml
rename to car-ui-lib/tests/paintbooth/res/xml/menuitems.xml
diff --git a/car-ui-lib/paintbooth/src/main/res/xml/preference_overlays.xml b/car-ui-lib/tests/paintbooth/res/xml/preference_overlays.xml
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/res/xml/preference_overlays.xml
rename to car-ui-lib/tests/paintbooth/res/xml/preference_overlays.xml
diff --git a/car-ui-lib/tests/paintbooth/res/xml/preference_samples.xml b/car-ui-lib/tests/paintbooth/res/xml/preference_samples.xml
new file mode 100644
index 0000000..d9a891c
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/res/xml/preference_samples.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    app:title="@string/preferences_screen_title">
+
+    <PreferenceCategory
+        android:title="@string/basic_preferences">
+
+        <Preference
+            android:key="preference"
+            android:summary="@string/summary_basic_preference"
+            android:title="@string/title_basic_preference"/>
+
+        <Preference
+            android:key="preference_disabled_without_ripple"
+            android:summary="Without ripple"
+            android:title="@string/title_basic_preference"/>
+
+        <Preference
+            android:key="preference_disabled_with_ripple"
+            android:summary="With ripple"
+            android:title="@string/title_basic_preference"/>
+
+        <Preference
+            android:key="stylized"
+            android:dependency="preference"
+            android:summary="@string/summary_stylish_preference"
+            android:title="@string/title_stylish_preference"/>
+
+        <Preference
+            android:icon="@drawable/ic_settings_wifi"
+            android:key="icon"
+            android:summary="@string/summary_icon_preference"
+            android:title="@string/title_icon_preference"/>
+
+        <Preference
+            android:key="single_line_title"
+            android:summary="@string/summary_single_line_title_preference"
+            android:title="@string/title_single_line_title_preference"
+            app:singleLineTitle="true"/>
+
+        <Preference
+            android:key="single_line_no_summary"
+            android:title="@string/title_single_line_no_summary"
+            app:singleLineTitle="true"/>
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:title="@string/widgets">
+
+        <CheckBoxPreference
+            android:key="checkbox"
+            android:summary="@string/summary_checkbox_preference"
+            android:title="@string/title_checkbox_preference"/>
+
+        <DropDownPreference
+            android:entries="@array/entries"
+            android:entryValues="@array/entry_values"
+            android:key="dropdown"
+            android:title="@string/title_dropdown_preference"
+            app:useSimpleSummaryProvider="true"/>
+
+        <SeekBarPreference
+            android:defaultValue="5"
+            android:key="seekbar"
+            android:max="10"
+            android:title="@string/title_seekbar_preference"/>
+
+        <SwitchPreference
+            android:key="switch"
+            android:summary="@string/summary_switch_preference"
+            android:title="@string/title_switch_preference"/>
+
+        <com.android.car.ui.preference.CarUiTwoActionPreference
+            android:key="twoaction"
+            android:summary="@string/summary_twoaction_preference"
+            android:title="@string/title_twoaction_preference"
+            android:widgetLayout="@layout/details_preference_widget"/>
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:title="@string/dialogs">
+
+        <EditTextPreference
+            android:dialogTitle="@string/dialog_title_edittext_preference"
+            android:key="edittext"
+            android:title="@string/title_edittext_preference"
+            app:useSimpleSummaryProvider="true"/>
+
+        <ListPreference
+            android:dialogTitle="@string/dialog_title_list_preference"
+            android:entries="@array/entries"
+            android:entryValues="@array/entry_values"
+            android:key="list"
+            android:title="@string/title_list_preference"
+            app:useSimpleSummaryProvider="true"/>
+
+        <MultiSelectListPreference
+            android:dialogTitle="@string/dialog_title_multi_list_preference"
+            android:entries="@array/entries"
+            android:entryValues="@array/entry_values"
+            android:key="multi_select_list"
+            android:summary="@string/summary_multi_list_preference"
+            android:title="@string/title_multi_list_preference"/>
+
+        <com.android.car.ui.preference.CarUiSeekBarDialogPreference
+            android:dialogTitle="Seekbar Dialog"
+            android:key="seekbarDialog"
+            android:summary="@string/summary_seekbar_preference"
+            android:title="@string/title_seekbar_preference"/>
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="@string/advanced_preference"
+        android:title="@string/advanced_attributes"
+        app:initialExpandedChildrenCount="1">
+
+        <Preference
+            android:key="expandable"
+            android:summary="@string/summary_expandable_preference"
+            android:title="@string/title_expandable_preference"/>
+
+        <Preference
+            android:summary="@string/summary_intent_preference"
+            android:title="@string/title_intent_preference">
+
+            <intent android:action="android.intent.action.VIEW"
+                    android:data="http://www.android.com"/>
+
+        </Preference>
+
+        <Preference
+            android:key="copyable"
+            android:selectable="false"
+            android:summary="@string/summary_copyable_preference"
+            android:title="@string/title_copyable_preference"
+            app:enableCopying="true"/>
+
+        <SwitchPreference
+            android:dependency="parent"
+            android:key="child"
+            android:summary="@string/summary_child_preference"
+            android:title="@string/title_child_preference"/>
+
+        <SwitchPreference
+            android:key="toggle_summary"
+            android:summaryOff="@string/summary_off_toggle_summary_preference"
+            android:summaryOn="@string/summary_on_toggle_summary_preference"
+            android:title="@string/title_toggle_summary_preference"/>
+
+        <SwitchPreference
+            android:key="parent"
+            android:summary="@string/summary_parent_preference"
+            android:title="@string/title_parent_preference"/>
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/MainActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/MainActivity.java
new file mode 100644
index 0000000..02b8088
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/MainActivity.java
@@ -0,0 +1,332 @@
+/*
+ * 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.ui.paintbooth;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Switch;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.paintbooth.caruirecyclerview.CarUiListItemActivity;
+import com.android.car.ui.paintbooth.caruirecyclerview.CarUiRecyclerViewActivity;
+import com.android.car.ui.paintbooth.caruirecyclerview.GridCarUiRecyclerViewActivity;
+import com.android.car.ui.paintbooth.currentactivity.CurrentActivityService;
+import com.android.car.ui.paintbooth.dialogs.DialogsActivity;
+import com.android.car.ui.paintbooth.overlays.OverlayActivity;
+import com.android.car.ui.paintbooth.preferences.PreferenceActivity;
+import com.android.car.ui.paintbooth.toolbar.NoCarUiToolbarActivity;
+import com.android.car.ui.paintbooth.toolbar.OldToolbarActivity;
+import com.android.car.ui.paintbooth.toolbar.ToolbarActivity;
+import com.android.car.ui.paintbooth.widgets.WidgetActivity;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.ToolbarController;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Paint booth app
+ */
+public class MainActivity extends Activity implements InsetsChangedListener {
+
+    public static final String STOP_SERVICE = "com.android.car.ui.paintbooth.StopService";
+
+    /**
+     * List of all sample activities.
+     */
+    private final List<ListElement> mActivities = Arrays.asList(
+            new ServiceElement("Show foreground activities", CurrentActivityService.class),
+            new ServiceElement("Simulate Screen Bounds", VisibleBoundsSimulator.class),
+            new ActivityElement("Dialogs sample", DialogsActivity.class),
+            new ActivityElement("List sample", CarUiRecyclerViewActivity.class),
+            new ActivityElement("Grid sample", GridCarUiRecyclerViewActivity.class),
+            new ActivityElement("Preferences sample", PreferenceActivity.class),
+            new ActivityElement("Overlays", OverlayActivity.class),
+            new ActivityElement("Toolbar sample", ToolbarActivity.class),
+            new ActivityElement("Old toolbar sample", OldToolbarActivity.class),
+            new ActivityElement("No CarUiToolbar sample", NoCarUiToolbarActivity.class),
+            new ActivityElement("Widget sample", WidgetActivity.class),
+            new ActivityElement("ListItem sample", CarUiListItemActivity.class));
+
+    private abstract static class ViewHolder extends RecyclerView.ViewHolder {
+
+        ViewHolder(@NonNull View itemView) {
+            super(itemView);
+        }
+
+        public abstract void bind(ListElement element);
+    }
+
+    private class ActivityViewHolder extends ViewHolder {
+        private final Button mButton;
+
+        ActivityViewHolder(@NonNull View itemView) {
+            super(itemView);
+            mButton = itemView.requireViewById(R.id.button);
+        }
+
+        @Override
+        public void bind(ListElement e) {
+            if (!(e instanceof ActivityElement)) {
+                throw new IllegalArgumentException("Expected an ActivityElement");
+            }
+            ActivityElement element = (ActivityElement) e;
+            mButton.setText(element.getText());
+            mButton.setOnClickListener(v ->
+                    startActivity(new Intent(itemView.getContext(), element.getActivity())));
+        }
+    }
+
+    private class ServiceViewHolder extends ViewHolder {
+        private final Switch mSwitch;
+
+        ServiceViewHolder(@NonNull View itemView) {
+            super(itemView);
+            mSwitch = itemView.requireViewById(R.id.button);
+        }
+
+        @Override
+        public void bind(ListElement e) {
+            if (!(e instanceof ServiceElement)) {
+                throw new IllegalArgumentException("Expected an ActivityElement");
+            }
+            ServiceElement element = (ServiceElement) e;
+            mSwitch.setChecked(isServiceRunning(element.getService()));
+            mSwitch.setText(element.getText());
+            mSwitch.setOnClickListener(v -> {
+                Intent intent = new Intent(itemView.getContext(), element.getService());
+                if (isServiceRunning(element.getService())) {
+                    intent.setAction(STOP_SERVICE);
+                }
+                startForegroundService(intent);
+            });
+        }
+    }
+
+    private final RecyclerView.Adapter<ViewHolder> mAdapter =
+            new RecyclerView.Adapter<ViewHolder>() {
+                @NonNull
+                @Override
+                public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+                    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+                    if (viewType == ListElement.TYPE_ACTIVITY) {
+                        return new ActivityViewHolder(
+                                inflater.inflate(R.layout.list_item, parent, false));
+                    } else if (viewType == ListElement.TYPE_SERVICE) {
+                        return new ServiceViewHolder(
+                                inflater.inflate(R.layout.list_item_switch, parent, false));
+                    } else {
+                        throw new IllegalArgumentException("Unknown viewType: " + viewType);
+                    }
+                }
+
+                @Override
+                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+                    holder.bind(mActivities.get(position));
+                }
+
+                @Override
+                public int getItemCount() {
+                    return mActivities.size();
+                }
+
+                @Override
+                public int getItemViewType(int position) {
+                    return mActivities.get(position).getType();
+                }
+            };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.car_ui_recycler_view_activity);
+
+        ToolbarController toolbar = CarUi.requireToolbar(this);
+        toolbar.setLogo(R.drawable.ic_launcher);
+        toolbar.setTitle(getTitle());
+
+        CarUiRecyclerView prv = findViewById(R.id.list);
+        prv.setAdapter(mAdapter);
+
+        initLeakCanary();
+    }
+
+    private void initLeakCanary() {
+        // This sets LeakCanary to report errors after a single leak instead of 5, and to ask for
+        // permission to use storage, which it needs to work.
+        //
+        // Equivalent to this non-reflection code:
+        //
+        // Config config = LeakCanary.INSTANCE.getConfig();
+        // LeakCanary.INSTANCE.setConfig(config.copy(config.getDumpHeap(),
+        //     config.getDumpHeapWhenDebugging(),
+        //     1,
+        //     config.getReferenceMatchers(),
+        //     config.getObjectInspectors(),
+        //     config.getOnHeapAnalyzedListener(),
+        //     config.getMetatadaExtractor(),
+        //     config.getComputeRetainedHeapSize(),
+        //     config.getMaxStoredHeapDumps(),
+        //     true,
+        //     config.getUseExperimentalLeakFinders()));
+        try {
+            Class<?> canaryClass = Class.forName("leakcanary.LeakCanary");
+            try {
+                Class<?> onHeapAnalyzedListenerClass =
+                        Class.forName("leakcanary.OnHeapAnalyzedListener");
+                Class<?> metadataExtractorClass = Class.forName("shark.MetadataExtractor");
+                Method getConfig = canaryClass.getMethod("getConfig");
+                Class<?> configClass = getConfig.getReturnType();
+                Method setConfig = canaryClass.getMethod("setConfig", configClass);
+                Method copy = configClass.getMethod("copy", boolean.class, boolean.class,
+                        int.class, List.class, List.class, onHeapAnalyzedListenerClass,
+                        metadataExtractorClass, boolean.class, int.class, boolean.class,
+                        boolean.class);
+
+                Object canary = canaryClass.getField("INSTANCE").get(null);
+                Object currentConfig = getConfig.invoke(canary);
+
+                Boolean dumpHeap = (Boolean) configClass
+                        .getMethod("getDumpHeap").invoke(currentConfig);
+                Boolean dumpHeapWhenDebugging = (Boolean) configClass
+                        .getMethod("getDumpHeapWhenDebugging").invoke(currentConfig);
+                List<?> referenceMatchers = (List<?>) configClass
+                        .getMethod("getReferenceMatchers").invoke(currentConfig);
+                List<?> objectInspectors = (List<?>) configClass
+                        .getMethod("getObjectInspectors").invoke(currentConfig);
+                Object onHeapAnalyzedListener = configClass
+                        .getMethod("getOnHeapAnalyzedListener").invoke(currentConfig);
+                // Yes, LeakCanary misspelled metadata
+                Object metadataExtractor = configClass
+                        .getMethod("getMetatadaExtractor").invoke(currentConfig);
+                Boolean computeRetainedHeapSize = (Boolean) configClass
+                        .getMethod("getComputeRetainedHeapSize").invoke(currentConfig);
+                Integer maxStoredHeapDumps = (Integer) configClass
+                        .getMethod("getMaxStoredHeapDumps").invoke(currentConfig);
+                Boolean useExperimentalLeakFinders = (Boolean) configClass
+                        .getMethod("getUseExperimentalLeakFinders").invoke(currentConfig);
+
+                setConfig.invoke(canary, copy.invoke(currentConfig,
+                        dumpHeap,
+                        dumpHeapWhenDebugging,
+                        1,
+                        referenceMatchers,
+                        objectInspectors,
+                        onHeapAnalyzedListener,
+                        metadataExtractor,
+                        computeRetainedHeapSize,
+                        maxStoredHeapDumps,
+                        true,
+                        useExperimentalLeakFinders));
+
+            } catch (ReflectiveOperationException e) {
+                Log.e("paintbooth", "Error initializing LeakCanary", e);
+                Toast.makeText(this, "Error initializing LeakCanary", Toast.LENGTH_LONG).show();
+            }
+        } catch (ClassNotFoundException e) {
+            // LeakCanary is not used in this build, do nothing.
+        }
+    }
+
+    private boolean isServiceRunning(Class<? extends Service> serviceClazz) {
+        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
+                Integer.MAX_VALUE)) {
+            if (serviceClazz.getName().equals(service.service.getClassName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        requireViewById(R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        requireViewById(android.R.id.content)
+                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+
+    private abstract static class ListElement {
+        static final int TYPE_ACTIVITY = 0;
+        static final int TYPE_SERVICE = 1;
+
+        private final String mText;
+
+        ListElement(String text) {
+            mText = text;
+        }
+
+        String getText() {
+            return mText;
+        }
+
+        abstract int getType();
+    }
+
+    private static class ActivityElement extends ListElement {
+        private final Class<? extends Activity> mActivityClass;
+
+        ActivityElement(String text, Class<? extends Activity> activityClass) {
+            super(text);
+            mActivityClass = activityClass;
+        }
+
+        Class<? extends Activity> getActivity() {
+            return mActivityClass;
+        }
+
+        @Override
+        int getType() {
+            return TYPE_ACTIVITY;
+        }
+    }
+
+    private static class ServiceElement extends ListElement {
+        private final Class<? extends Service> mServiceClass;
+
+        ServiceElement(String text, Class<? extends Service> serviceClass) {
+            super(text);
+            mServiceClass = serviceClass;
+        }
+
+        Class<? extends Service> getService() {
+            return mServiceClass;
+        }
+
+        @Override
+        int getType() {
+            return TYPE_SERVICE;
+        }
+    }
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/VisibleBoundsSimulator.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/VisibleBoundsSimulator.java
new file mode 100644
index 0000000..63a2aed
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/VisibleBoundsSimulator.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.paintbooth;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.os.IBinder;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.core.app.NotificationCompat;
+
+/**
+ * To start the service:
+ * adb shell am start-foreground-service com.android.car.ui.paintbooth/.DisplayService
+ *
+ * To stop the service:
+ * adb shell am stopservice com.android.car.ui.paintbooth/.DisplayService
+ *
+ * When the service is started it will draw a overlay view on top of the screen displayed. This
+ * overlay comes from a SVG file that can be modified to take different shapes. This service will be
+ * used to display different screen styles from OEMs.
+ */
+public class VisibleBoundsSimulator extends Service {
+    private static final int FOREGROUND_SERVICE_ID = 222;
+    private View mContainer;
+
+    private WindowManager mWindowManager;
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (MainActivity.STOP_SERVICE.equals(intent.getAction())) {
+            stopSelf();
+        }
+
+        return START_STICKY;
+    }
+
+    @Override
+    public void onCreate() {
+
+        Intent notificationIntent = new Intent(this, VisibleBoundsSimulator.class);
+
+        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
+                notificationIntent, 0);
+
+        NotificationChannel channel = new NotificationChannel("DisplayService",
+                "Show overlay screen",
+                NotificationManager.IMPORTANCE_DEFAULT);
+        NotificationManager notificationManager =
+                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+        notificationManager.createNotificationChannel(channel);
+
+        Notification notification =
+                new NotificationCompat.Builder(this, "DisplayService")
+                        .setSmallIcon(R.drawable.ic_launcher)
+                        .setContentTitle("DisplayService")
+                        .setContentText("Show overlay screen")
+                        .setContentIntent(pendingIntent).build();
+
+        startForeground(FOREGROUND_SERVICE_ID, notification);
+        applyDisplayOverlay();
+    }
+
+    /**
+     * Creates a view overlay on top of a new window. The overlay gravity is set to left and
+     * bottom. If the width and height is not provided then the default is to take up the entire
+     * screen. Overlay will show bounds around the view and we can still click through the window.
+     */
+    private void applyDisplayOverlay() {
+        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
+
+        DisplayMetrics displayMetrics = new DisplayMetrics();
+
+        mWindowManager.getDefaultDisplay().getRealMetrics(displayMetrics);
+        int screenHeight = displayMetrics.heightPixels;
+        int screenWidth = displayMetrics.widthPixels;
+        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.WRAP_CONTENT,
+                // WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY is a hidden api, so
+                // use its value here so we can still compile on gradle / google3
+                WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW + 26,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
+                PixelFormat.TRANSLUCENT);
+
+        params.packageName = this.getPackageName();
+        params.gravity = Gravity.BOTTOM | Gravity.LEFT;
+
+        Display display = mWindowManager.getDefaultDisplay();
+        Point size = new Point();
+        display.getSize(size);
+        int height = size.y;
+
+        params.x = 0;
+        // If the sysUI is showing and nav bar is taking up some space at the bottom we want to
+        // offset the height of the navBar so that the overlay starts from the bottom left.
+        params.y = -(screenHeight - height);
+
+        float overlayWidth = getApplicationContext().getResources().getDimension(
+                R.dimen.screen_shape_container_width);
+        float overlayHeight = getApplicationContext().getResources().getDimension(
+                R.dimen.screen_shape_container_height);
+
+
+        params.width = (int) (overlayWidth == 0 ? screenWidth : overlayHeight);
+        params.height = (int) (overlayHeight == 0 ? screenHeight : overlayHeight);
+        params.setTitle("Simulated display bound");
+
+        mContainer = inflater.inflate(R.layout.simulated_screen_shape_container, null);
+        mContainer.setLayoutParams(params);
+
+        mWindowManager.addView(mContainer, params);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mWindowManager.removeView(mContainer);
+        stopSelf();
+    }
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java
new file mode 100644
index 0000000..f6db6d3
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.paintbooth.caruirecyclerview;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiHeaderListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+
+import java.util.ArrayList;
+
+/**
+ * Activity that shows {@link CarUiRecyclerView} with dummy {@link CarUiContentListItem} entries
+ */
+public class CarUiListItemActivity extends Activity implements InsetsChangedListener {
+
+    private final ArrayList<CarUiListItem> mData = new ArrayList<>();
+    private CarUiListItemAdapter mAdapter;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.car_ui_recycler_view_activity);
+
+        ToolbarController toolbar = CarUi.requireToolbar(this);
+        toolbar.setTitle(getTitle());
+        toolbar.setState(Toolbar.State.SUBPAGE);
+
+        CarUiRecyclerView recyclerView = findViewById(R.id.list);
+        mAdapter = new CarUiListItemAdapter(generateDummyData());
+        recyclerView.setAdapter(mAdapter);
+    }
+
+    private ArrayList<CarUiListItem> generateDummyData() {
+        Context context = this;
+
+        CarUiHeaderListItem header = new CarUiHeaderListItem("First header");
+        mData.add(header);
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test title");
+        item.setBody("Test body");
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test title with no body");
+        mData.add(item);
+
+        header = new CarUiHeaderListItem("Random header", "with header body");
+        mData.add(header);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setBody("Test body with no title");
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test Title");
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test Title");
+        item.setBody("Test body text");
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test Title -- with content icon");
+        item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT);
+        item.setIcon(getDrawable(R.drawable.ic_sample_logo));
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test Title");
+        item.setBody("With avatar icon.");
+        item.setIcon(getDrawable(R.drawable.ic_sample_logo));
+        item.setPrimaryIconType(CarUiContentListItem.IconType.AVATAR);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test Title");
+        item.setBody("Displays toast on click");
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setOnItemClickedListener(item1 -> {
+            Toast.makeText(context, "Item clicked", Toast.LENGTH_SHORT).show();
+        });
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setTitle("Title -- Item with checkbox");
+        item.setBody("Will present toast on change of selection state.");
+        item.setOnCheckedChangeListener(
+                (listItem, isChecked) -> Toast.makeText(context,
+                        "Item checked state is: " + isChecked, Toast.LENGTH_SHORT).show());
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setEnabled(false);
+        item.setTitle("Title -- Checkbox that is disabled");
+        item.setBody("Clicks should not have any affect");
+        item.setOnCheckedChangeListener(
+                (listItem, isChecked) -> Toast.makeText(context,
+                        "Item checked state is: " + isChecked, Toast.LENGTH_SHORT).show());
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setBody("Body -- Item with switch  -- with click listener");
+        item.setOnItemClickedListener(item1 -> {
+            Toast.makeText(context, "Click on item with switch", Toast.LENGTH_SHORT).show();
+        });
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setTitle("Title -- Item with checkbox");
+        item.setBody("Item is initially checked");
+        item.setChecked(true);
+        mData.add(item);
+
+        CarUiContentListItem radioItem1 = new CarUiContentListItem(
+                CarUiContentListItem.Action.RADIO_BUTTON);
+        CarUiContentListItem radioItem2 = new CarUiContentListItem(
+                CarUiContentListItem.Action.RADIO_BUTTON);
+
+        radioItem1.setTitle("Title -- Item with radio button");
+        radioItem1.setBody("Item is initially unchecked checked");
+        radioItem1.setChecked(false);
+        radioItem1.setOnCheckedChangeListener((listItem, isChecked) -> {
+            if (isChecked) {
+                radioItem2.setChecked(false);
+                mAdapter.notifyItemChanged(mData.indexOf(radioItem2));
+            }
+        });
+        mData.add(radioItem1);
+
+        radioItem2.setIcon(getDrawable(R.drawable.ic_launcher));
+        radioItem2.setTitle("Item is mutually exclusive with item above");
+        radioItem2.setChecked(true);
+        radioItem2.setOnCheckedChangeListener((listItem, isChecked) -> {
+            if (isChecked) {
+                radioItem1.setChecked(false);
+                mAdapter.notifyItemChanged(mData.indexOf(radioItem1));
+            }
+        });
+        mData.add(radioItem2);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setTitle("Title");
+        item.setBody("Random body text -- with action divider");
+        item.setActionDividerVisible(true);
+        item.setSupplementalIcon(getDrawable(R.drawable.ic_launcher));
+        item.setChecked(true);
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setTitle("Null supplemental icon");
+        item.setChecked(true);
+        mData.add(item);
+
+        item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
+        item.setTitle("Supplemental icon with listener");
+        item.setSupplementalIcon(getDrawable(R.drawable.ic_launcher),
+                v -> Toast.makeText(context, "Clicked supplemental icon",
+                        Toast.LENGTH_SHORT).show());
+        item.setChecked(true);
+        mData.add(item);
+
+        return mData;
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        requireViewById(R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        requireViewById(android.R.id.content)
+                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiRecyclerViewActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiRecyclerViewActivity.java
new file mode 100644
index 0000000..810b10c
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiRecyclerViewActivity.java
@@ -0,0 +1,73 @@
+/*
+ * 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.ui.paintbooth.caruirecyclerview;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+
+import java.util.ArrayList;
+
+/**
+ * Activity that shows CarUiRecyclerView example with dummy data.
+ */
+public class CarUiRecyclerViewActivity extends Activity implements InsetsChangedListener {
+    private final ArrayList<String> mData = new ArrayList<>();
+    private final int mDataToGenerate = 100;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.car_ui_recycler_view_activity);
+
+        ToolbarController toolbar = CarUi.requireToolbar(this);
+        toolbar.setTitle(getTitle());
+        toolbar.setState(Toolbar.State.SUBPAGE);
+
+        CarUiRecyclerView recyclerView = findViewById(R.id.list);
+        recyclerView.setLayoutManager(new LinearLayoutManager(this));
+
+        RecyclerViewAdapter adapter = new RecyclerViewAdapter(generateDummyData());
+        recyclerView.setAdapter(adapter);
+    }
+
+    private ArrayList<String> generateDummyData() {
+        for (int i = 0; i <= mDataToGenerate; i++) {
+            mData.add("data" + i);
+        }
+        return mData;
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        requireViewById(R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        requireViewById(android.R.id.content)
+                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+}
+
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/GridCarUiRecyclerViewActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/GridCarUiRecyclerViewActivity.java
new file mode 100644
index 0000000..7d98a1e
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/GridCarUiRecyclerViewActivity.java
@@ -0,0 +1,69 @@
+/*
+ * 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.ui.paintbooth.caruirecyclerview;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+
+import java.util.ArrayList;
+
+/** Activity that shows GridCarUiRecyclerView example with dummy data. */
+public class GridCarUiRecyclerViewActivity extends Activity implements
+        InsetsChangedListener {
+    private final ArrayList<String> mData = new ArrayList<>();
+    private final int mDataToGenerate = 200;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.grid_car_ui_recycler_view_activity);
+
+        ToolbarController toolbar = CarUi.requireToolbar(this);
+        toolbar.setTitle(getTitle());
+        toolbar.setState(Toolbar.State.SUBPAGE);
+
+        CarUiRecyclerView recyclerView = findViewById(R.id.list);
+
+        RecyclerViewAdapter adapter = new RecyclerViewAdapter(generateDummyData());
+        recyclerView.setAdapter(adapter);
+    }
+
+    private ArrayList<String> generateDummyData() {
+        for (int i = 1; i <= mDataToGenerate; i++) {
+            mData.add("data" + i);
+        }
+        return mData;
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        requireViewById(R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        requireViewById(android.R.id.content)
+                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/RecyclerViewAdapter.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/RecyclerViewAdapter.java
new file mode 100644
index 0000000..07dea21
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/RecyclerViewAdapter.java
@@ -0,0 +1,75 @@
+/*
+ * 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.ui.paintbooth.caruirecyclerview;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.paintbooth.R;
+
+import java.util.ArrayList;
+
+/**
+ * Implementation of {@link RecyclerViewAdapter} that can be used with RecyclerViews.
+ */
+public class RecyclerViewAdapter extends
+        RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
+
+    private ArrayList<String> mData;
+
+    public RecyclerViewAdapter(ArrayList<String> data) {
+        this.mData = data;
+    }
+
+    @NonNull
+    @Override
+    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        LayoutInflater inflator = LayoutInflater.from(parent.getContext());
+        View view = inflator.inflate(R.layout.car_ui_recycler_view_list_item, parent, false);
+        return new RecyclerViewHolder(view);
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
+        String title = mData.get(position);
+        holder.mTextTitle.setText(title);
+    }
+
+    @Override
+    public int getItemCount() {
+        return mData.size();
+    }
+
+
+    /**
+     * Holds views for each element in the list.
+     */
+    public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
+        TextView mTextTitle;
+
+        RecyclerViewHolder(@NonNull View itemView) {
+            super(itemView);
+            mTextTitle = itemView.findViewById(R.id.textTitle);
+        }
+    }
+}
+
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManager.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManager.java
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManager.java
rename to car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManager.java
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java
new file mode 100644
index 0000000..8adbdad
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/ActivityTaskManagerImpl.java
@@ -0,0 +1,77 @@
+/*
+ * 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.ui.paintbooth.currentactivity;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.IActivityTaskManager;
+import android.content.ComponentName;
+import android.os.RemoteException;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is a wrapper around {@link android.app.ActivityTaskManager} that is excluded from
+ * the gradle and google3 builds.
+ */
+class ActivityTaskManagerImpl implements ActivityTaskManager {
+
+    IActivityTaskManager mActivityTaskManager = android.app.ActivityTaskManager.getService();
+
+    Map<TaskStackListener, android.app.TaskStackListener> mListenerMapping = new HashMap<>();
+
+    @Override
+    public List<RunningTaskInfo> getTasks(int maxNum) throws RemoteException {
+        return mActivityTaskManager.getTasks(maxNum);
+    }
+
+    @Override
+    public void registerTaskStackListener(TaskStackListener listener) throws RemoteException {
+        mListenerMapping.put(listener, new android.app.TaskStackListener() {
+            @Override
+            public void onTaskCreated(int taskId, ComponentName componentName) {
+                listener.onTaskCreated(taskId, componentName);
+            }
+
+            @Override
+            public void onTaskRemoved(int taskId) {
+                listener.onTaskRemoved(taskId);
+            }
+
+            @Override
+            public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) {
+                listener.onTaskDescriptionChanged(taskInfo);
+            }
+
+            @Override
+            public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+                listener.onTaskMovedToFront(taskInfo);
+            }
+        });
+
+        mActivityTaskManager.registerTaskStackListener(mListenerMapping.get(listener));
+    }
+
+    @Override
+    public void unregisterTaskStackListener(TaskStackListener listener) throws RemoteException {
+        mActivityTaskManager.unregisterTaskStackListener(mListenerMapping.get(listener));
+        mListenerMapping.remove(listener);
+    }
+
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/CurrentActivityService.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/CurrentActivityService.java
new file mode 100644
index 0000000..3c87f62
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/currentactivity/CurrentActivityService.java
@@ -0,0 +1,230 @@
+/*
+ * 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.ui.paintbooth.currentactivity;
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.core.app.NotificationCompat;
+import androidx.core.content.ContextCompat;
+
+import com.android.car.ui.paintbooth.MainActivity;
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.paintbooth.currentactivity.ActivityTaskManager.TaskStackListener;
+
+import java.util.List;
+
+/**
+ * To start the service:
+ * adb shell am start-foreground-service -n com.android.car.ui.paintbooth/.CurrentActivityService
+ *
+ * To stop the service:
+ * adb shell am start-foreground-service -n com.android.car.ui.paintbooth/.CurrentActivityService -a
+ * com.android.car.ui.paintbooth.StopService
+ */
+public class CurrentActivityService extends Service {
+    private static final int FOREGROUND_SERVICE_ID = 111;
+
+    private WindowManager mWindowManager;
+    private TextView mTextView;
+    private Handler mHandler;
+
+    @Override
+    public void onCreate() {
+        mHandler = new Handler(Looper.getMainLooper());
+
+        if (ContextCompat.checkSelfPermission(this, "android.permission.REAL_GET_TASKS")
+                != PackageManager.PERMISSION_GRANTED) {
+            Toast.makeText(this, "android.permission.REAL_GET_TASKS is not granted!",
+                    Toast.LENGTH_LONG).show();
+        }
+
+        Intent notificationIntent = new Intent(this, CurrentActivityService.class);
+
+        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
+                notificationIntent, 0);
+
+        NotificationChannel channel = new NotificationChannel("CurrentActivityService",
+                "Show current activity",
+                NotificationManager.IMPORTANCE_DEFAULT);
+        NotificationManager notificationManager =
+                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+        notificationManager.createNotificationChannel(channel);
+
+        Notification notification =
+                new NotificationCompat.Builder(this, "CurrentActivityService")
+                        .setSmallIcon(R.drawable.ic_launcher)
+                        .setContentTitle("CurrentActivityService")
+                        .setContentText("Show current activity")
+                        .setContentIntent(pendingIntent).build();
+
+        startForeground(FOREGROUND_SERVICE_ID, notification);
+
+        try {
+            ActivityTaskManager.getService().registerTaskStackListener(mTaskStackListener);
+        } catch (RemoteException e) {
+            Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+        }
+
+        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
+                PixelFormat.TRANSLUCENT);
+
+        mTextView = new TextView(this);
+        layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
+        layoutParams.x = 0;
+        layoutParams.y = 100;
+        mTextView.setLayoutParams(layoutParams);
+        mTextView.setBackgroundColor(Color.argb(50, 0, 255, 0));
+
+        mTextView.setOnTouchListener(new View.OnTouchListener() {
+
+            private int mInitialX = 0;
+            private int mInitialY = 0;
+            private float mInitialTouchX;
+            private float mInitialTouchY;
+
+            @Override
+            public boolean onTouch(View view, MotionEvent event) {
+                switch (event.getAction() & MotionEvent.ACTION_MASK) {
+                    case MotionEvent.ACTION_DOWN:
+                        mInitialX = layoutParams.x;
+                        mInitialY = layoutParams.y;
+                        mInitialTouchX = event.getRawX();
+                        mInitialTouchY = event.getRawY();
+                        break;
+                    case MotionEvent.ACTION_MOVE:
+                        WindowManager.LayoutParams layoutParams =
+                                (WindowManager.LayoutParams) view.getLayoutParams();
+                        layoutParams.x = mInitialX + (int) (event.getRawX() - mInitialTouchX);
+                        layoutParams.y = mInitialY + (int) (event.getRawY() - mInitialTouchY);
+                        mWindowManager.updateViewLayout(view, layoutParams);
+                        return true;
+                    default:
+                        break;
+                }
+
+                return false;
+            }
+        });
+
+        try {
+            mWindowManager.addView(mTextView, layoutParams);
+        } catch (RuntimeException e) {
+            Toast.makeText(this, "Couldn't display overlay", Toast.LENGTH_SHORT)
+                .show();
+        }
+
+        showCurrentTask();
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (MainActivity.STOP_SERVICE.equals(intent.getAction())) {
+            stopSelf();
+        }
+
+        return START_STICKY;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public void onDestroy() {
+        mHandler.removeCallbacksAndMessages(null);
+        mWindowManager.removeView(mTextView);
+        try {
+            ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener);
+        } catch (RemoteException e) {
+            Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+        }
+    }
+
+    /**
+     * This requires system permissions or else it will only fetch the current app and the launcher
+     * app
+     */
+    private void showCurrentTask() {
+        try {
+            List<ActivityManager.RunningTaskInfo> tasks =
+                    ActivityTaskManager.getService().getTasks(1);
+            if (!tasks.isEmpty()) {
+                updateComponentName(tasks.get(0).topActivity);
+            }
+        } catch (RemoteException e) {
+            Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+        }
+    }
+
+    private void updateComponentName(ComponentName componentName) {
+        mHandler.post(() -> {
+            if (mTextView != null && componentName != null) {
+                mTextView.setText(componentName.flattenToShortString().replace('/', '\n'));
+            }
+        });
+    }
+
+    private final TaskStackListener mTaskStackListener = new TaskStackListener() {
+        @Override
+        public void onTaskCreated(int taskId, ComponentName componentName) {
+            updateComponentName(componentName);
+        }
+
+        @Override
+        public void onTaskRemoved(int taskId) {
+            showCurrentTask();
+        }
+
+        @Override
+        public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) {
+            updateComponentName(taskInfo.topActivity);
+        }
+
+        @Override
+        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+            updateComponentName(taskInfo.topActivity);
+        }
+    };
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/dialogs/DialogsActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/dialogs/DialogsActivity.java
new file mode 100644
index 0000000..7cf1cce
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/dialogs/DialogsActivity.java
@@ -0,0 +1,312 @@
+/*
+ * 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.ui.paintbooth.dialogs;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.AlertDialogBuilder;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.recyclerview.CarUiRadioButtonListItem;
+import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Activity that shows different dialogs from the device default theme.
+ */
+public class DialogsActivity extends Activity implements InsetsChangedListener {
+
+    private final List<Pair<Integer, View.OnClickListener>> mButtons = new ArrayList<>();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.car_ui_recycler_view_activity);
+        ToolbarController toolbar = CarUi.requireToolbar(this);
+        toolbar.setTitle(getTitle());
+        toolbar.setState(Toolbar.State.SUBPAGE);
+
+        mButtons.add(Pair.create(R.string.dialog_show_dialog,
+                v -> showDialog()));
+        mButtons.add(Pair.create(R.string.dialog_show_dialog_icon,
+                v -> showDialogWithIcon()));
+        mButtons.add(Pair.create(R.string.dialog_show_dialog_edit,
+                v -> showDialogWithTextBox()));
+        mButtons.add(Pair.create(R.string.dialog_show_dialog_only_positive,
+                v -> showDialogWithOnlyPositiveButton()));
+        mButtons.add(Pair.create(R.string.dialog_show_dialog_no_button,
+                v -> showDialogWithNoButtonProvided()));
+        mButtons.add(Pair.create(R.string.dialog_show_dialog_checkbox,
+                v -> showDialogWithCheckbox()));
+        mButtons.add(Pair.create(R.string.dialog_show_dialog_no_title,
+                v -> showDialogWithoutTitle()));
+        mButtons.add(Pair.create(R.string.dialog_show_toast,
+                v -> showToast()));
+        mButtons.add(Pair.create(R.string.dialog_show_subtitle,
+                v -> showDialogWithSubtitle()));
+        mButtons.add(Pair.create(R.string.dialog_show_subtitle_and_icon,
+                v -> showDialogWithSubtitleAndIcon()));
+        mButtons.add(Pair.create(R.string.dialog_show_long_subtitle_and_icon,
+                v -> showDialogWithLongSubtitleAndIcon()));
+        mButtons.add(Pair.create(R.string.dialog_show_single_choice,
+                v -> showDialogWithSingleChoiceItems()));
+        mButtons.add(Pair.create(R.string.dialog_show_permission_dialog,
+                v -> showPermissionDialog()));
+        mButtons.add(Pair.create(R.string.dialog_show_multi_permission_dialog,
+                v -> showMultiPermissionDialog()));
+        mButtons.add(Pair.create(R.string.dialog_show_foreground_permission_dialog,
+                v -> showForegroundPermissionDialog()));
+        mButtons.add(Pair.create(R.string.dialog_show_background_permission_dialog,
+                v -> showBackgroundPermissionDialog()));
+
+        CarUiRecyclerView recyclerView = requireViewById(R.id.list);
+        recyclerView.setAdapter(mAdapter);
+    }
+
+    private void showDialog() {
+        new AlertDialogBuilder(this)
+                .setTitle("Standard Alert Dialog")
+                .setMessage("With a message to show.")
+                .setNeutralButton("NEUTRAL", (dialogInterface, which) -> {
+                })
+                .setPositiveButton("OK", (dialogInterface, which) -> {
+                })
+                .setNegativeButton("CANCEL", (dialogInterface, which) -> {
+                })
+                .show();
+    }
+
+    private void showDialogWithIcon() {
+        new AlertDialogBuilder(this)
+                .setTitle("Alert dialog with icon")
+                .setMessage("The message body of the alert")
+                .setIcon(R.drawable.ic_tracklist)
+                .show();
+    }
+
+    private void showDialogWithNoButtonProvided() {
+        new AlertDialogBuilder(this)
+                .setTitle("Standard Alert Dialog")
+                .show();
+    }
+
+    private void showDialogWithCheckbox() {
+        new AlertDialogBuilder(this)
+                .setTitle("Custom Dialog Box")
+                .setMultiChoiceItems(
+                        new CharSequence[]{"I am a checkbox"},
+                        new boolean[]{false},
+                        (dialog, which, isChecked) -> {
+                        })
+                .setPositiveButton("OK", (dialogInterface, which) -> {
+                })
+                .setNegativeButton("CANCEL", (dialogInterface, which) -> {
+                })
+                .show();
+    }
+
+    private void showDialogWithTextBox() {
+        new AlertDialogBuilder(this)
+                .setTitle("Standard Alert Dialog")
+                .setEditBox("Edit me please", null, null)
+                .setPositiveButton("OK", (dialogInterface, i) -> {
+                })
+                .show();
+    }
+
+    private void showDialogWithOnlyPositiveButton() {
+        new AlertDialogBuilder(this)
+                .setTitle("Standard Alert Dialog").setMessage("With a message to show.")
+                .setPositiveButton("OK", (dialogInterface, i) -> {
+                })
+                .show();
+    }
+
+    private void showDialogWithoutTitle() {
+        new AlertDialogBuilder(this)
+                .setMessage("I dont have a title.")
+                .setPositiveButton("OK", (dialogInterface, i) -> {
+                })
+                .setNegativeButton("CANCEL", (dialogInterface, which) -> {
+                })
+                .show();
+    }
+
+    private void showToast() {
+        Toast.makeText(this, "Toast message looks like this", Toast.LENGTH_LONG).show();
+    }
+
+    private void showDialogWithSubtitle() {
+        new AlertDialogBuilder(this)
+                .setTitle("My Title!")
+                .setSubtitle("My Subtitle!")
+                .setMessage("My Message!")
+                .show();
+    }
+
+    private void showDialogWithSingleChoiceItems() {
+        ArrayList<CarUiRadioButtonListItem> data = new ArrayList<>();
+
+        CarUiRadioButtonListItem item = new CarUiRadioButtonListItem();
+        item.setTitle("First item");
+        data.add(item);
+
+        item = new CarUiRadioButtonListItem();
+        item.setTitle("Second item");
+        data.add(item);
+
+        item = new CarUiRadioButtonListItem();
+        item.setTitle("Third item");
+        data.add(item);
+
+        new AlertDialogBuilder(this)
+                .setTitle("Select one option.")
+                .setSubtitle("Ony one option may be selected at a time")
+                .setSingleChoiceItems(new CarUiRadioButtonListItemAdapter(data), null)
+                .show();
+    }
+
+    private void showDialogWithSubtitleAndIcon() {
+        new AlertDialogBuilder(this)
+                .setTitle("My Title!")
+                .setSubtitle("My Subtitle!")
+                .setMessage("My Message!")
+                .setIcon(R.drawable.ic_tracklist)
+                .show();
+    }
+
+    private void showDialogWithLongSubtitleAndIcon() {
+        new AlertDialogBuilder(this)
+                .setTitle("This is a very long title. It should likely span across "
+                            + "multiple lines or something. It shouldn't get cut off.")
+                .setSubtitle("This is a very long subtitle. It should likely span across "
+                        + "multiple lines or something. It shouldn't get cut off.")
+                .setMessage("My Message!")
+                .setIcon(R.drawable.ic_tracklist)
+                .show();
+    }
+
+    private void showPermissionDialog() {
+        if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
+            Toast.makeText(this, "Permission already granted. Remove CAMERA permission from "
+                    + "Settings > All apps > PaintBooth", Toast.LENGTH_SHORT).show();
+            return;
+        }
+        requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
+    }
+
+    private void showMultiPermissionDialog() {
+        if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
+                && checkSelfPermission(Manifest.permission.SEND_SMS)
+                    == PackageManager.PERMISSION_GRANTED
+                && checkSelfPermission(Manifest.permission.READ_CONTACTS)
+                    == PackageManager.PERMISSION_GRANTED) {
+            Toast.makeText(this, "Permissions are already granted. Remove CAMERA, SEND_SMS or "
+                    + "READ_CONTACTS permission from Settings > All apps > PaintBooth",
+                    Toast.LENGTH_SHORT).show();
+            return;
+        }
+        requestPermissions(new String[]{Manifest.permission.CAMERA,
+                Manifest.permission.READ_CONTACTS, Manifest.permission.SEND_SMS}, 1);
+    }
+
+    private void showForegroundPermissionDialog() {
+        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
+    }
+
+    private void showBackgroundPermissionDialog() {
+        requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1);
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            int[] grantResults) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Permission ");
+        for (int i = 0; i < permissions.length; i++) {
+            sb.append(permissions[i]);
+            sb.append("=");
+            sb.append(grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied");
+            sb.append("\n");
+        }
+        Toast.makeText(this, sb.toString(), Toast.LENGTH_SHORT).show();
+    }
+
+    private static class ViewHolder extends RecyclerView.ViewHolder {
+
+        private final Button mButton;
+
+        ViewHolder(View itemView) {
+            super(itemView);
+            mButton = itemView.requireViewById(R.id.button);
+        }
+
+        public void bind(Integer title, View.OnClickListener listener) {
+            mButton.setText(title);
+            mButton.setOnClickListener(listener);
+        }
+    }
+
+    private final RecyclerView.Adapter<ViewHolder> mAdapter =
+            new RecyclerView.Adapter<ViewHolder>() {
+                @Override
+                public int getItemCount() {
+                    return mButtons.size();
+                }
+
+                @Override
+                public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
+                    View item =
+                            LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,
+                                    parent, false);
+                    return new ViewHolder(item);
+                }
+
+                @Override
+                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+                    Pair<Integer, View.OnClickListener> pair = mButtons.get(position);
+                    holder.bind(pair.first, pair.second);
+                }
+            };
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        requireViewById(R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        requireViewById(android.R.id.content)
+                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/overlays/OverlayActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/overlays/OverlayActivity.java
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/overlays/OverlayActivity.java
rename to car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/overlays/OverlayActivity.java
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/overlays/OverlayManager.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/overlays/OverlayManager.java
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/overlays/OverlayManager.java
rename to car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/overlays/OverlayManager.java
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/overlays/OverlayManagerImpl.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/overlays/OverlayManagerImpl.java
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/overlays/OverlayManagerImpl.java
rename to car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/overlays/OverlayManagerImpl.java
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/PreferenceActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/preferences/PreferenceActivity.java
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/preferences/PreferenceActivity.java
rename to car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/preferences/PreferenceActivity.java
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/preferences/PreferenceDemoFragment.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/preferences/PreferenceDemoFragment.java
new file mode 100644
index 0000000..233c873
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/preferences/PreferenceDemoFragment.java
@@ -0,0 +1,54 @@
+/*
+ * 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.ui.paintbooth.preferences;
+
+import android.os.Bundle;
+
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.preference.CarUiPreference;
+import com.android.car.ui.preference.CarUiSwitchPreference;
+import com.android.car.ui.preference.PreferenceFragment;
+
+/**
+ * Fragment to load preferences
+ */
+public class PreferenceDemoFragment extends PreferenceFragment {
+
+    @Override
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        // Load the preferences from an XML resource
+        setPreferencesFromResource(R.xml.preference_samples, rootKey);
+        CarUiPreference preferenceDisabledWithoutRipple = findPreference(
+                "preference_disabled_without_ripple");
+        preferenceDisabledWithoutRipple.setEnabled(false);
+        preferenceDisabledWithoutRipple.setMessageToShowWhenDisabledPreferenceClicked(
+                "I am disabled because...");
+        preferenceDisabledWithoutRipple.setShouldShowRippleOnDisabledPreference(false);
+
+        CarUiPreference preferenceDisabledWithRipple = findPreference(
+                "preference_disabled_with_ripple");
+        preferenceDisabledWithRipple.setEnabled(false);
+        preferenceDisabledWithRipple.setMessageToShowWhenDisabledPreferenceClicked(
+                "I am disabled because...");
+        preferenceDisabledWithRipple.setShouldShowRippleOnDisabledPreference(true);
+
+        CarUiSwitchPreference carUiSwitchPreference = findPreference("switch");
+        carUiSwitchPreference.setEnabled(false);
+        carUiSwitchPreference.setMessageToShowWhenDisabledPreferenceClicked(
+                "I am disabled because...");
+    }
+}
diff --git a/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/toolbar/NoCarUiToolbarActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/NoCarUiToolbarActivity.java
similarity index 100%
rename from car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/toolbar/NoCarUiToolbarActivity.java
rename to car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/NoCarUiToolbarActivity.java
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/OldToolbarActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/OldToolbarActivity.java
new file mode 100644
index 0000000..f427990
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/OldToolbarActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.paintbooth.toolbar;
+
+import android.os.Bundle;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.toolbar.Toolbar;
+
+public class OldToolbarActivity extends ToolbarActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Toolbar toolbar = requireViewById(R.id.toolbar);
+        RecyclerView rv = requireViewById(R.id.list);
+        toolbar.registerToolbarHeightChangeListener(height -> {
+            rv.setPadding(0, height, 0, 0);
+        });
+    }
+
+    @Override
+    protected int getLayout() {
+        return R.layout.car_ui_recycler_view_activity_with_old_toolbar;
+    }
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java
new file mode 100644
index 0000000..938f448
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/toolbar/ToolbarActivity.java
@@ -0,0 +1,452 @@
+/*
+ * 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.ui.paintbooth.toolbar;
+
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.AlertDialogBuilder;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.MenuItem;
+import com.android.car.ui.toolbar.TabLayout;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ToolbarActivity extends AppCompatActivity implements InsetsChangedListener {
+
+    private List<MenuItem> mMenuItems = new ArrayList<>();
+    private List<Pair<CharSequence, View.OnClickListener>> mButtons = new ArrayList<>();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(getLayout());
+
+        ToolbarController toolbarNonFinal = CarUi.getToolbar(this);
+        if (toolbarNonFinal == null) {
+            toolbarNonFinal = requireViewById(R.id.toolbar);
+        }
+        ToolbarController toolbar = toolbarNonFinal;
+        toolbar.setTitle(getTitle());
+        toolbar.setState(Toolbar.State.SUBPAGE);
+        toolbar.setLogo(R.drawable.ic_launcher);
+        toolbar.registerOnBackListener(
+                () -> {
+                    if (toolbar.getState() == Toolbar.State.SEARCH
+                            || toolbar.getState() == Toolbar.State.EDIT) {
+                        toolbar.setState(Toolbar.State.SUBPAGE);
+                        return true;
+                    }
+                    return false;
+                });
+
+        mMenuItems.add(MenuItem.builder(this)
+                .setToSearch()
+                .setOnClickListener(i -> toolbar.setState(Toolbar.State.SEARCH))
+                .build());
+
+        toolbar.setMenuItems(mMenuItems);
+
+        mButtons.add(Pair.create("Toggle progress bar", v -> {
+            toolbar.getProgressBar().setVisible(!toolbar.getProgressBar().isVisible());
+        }));
+
+        mButtons.add(Pair.create("Change title", v ->
+                toolbar.setTitle(toolbar.getTitle() + " X")));
+
+        mButtons.add(Pair.create("Add/Change subtitle", v -> {
+            CharSequence subtitle = toolbar.getSubtitle();
+            if (TextUtils.isEmpty(subtitle)) {
+                toolbar.setSubtitle("Subtitle");
+            } else {
+                toolbar.setSubtitle(subtitle + " X");
+            }
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_set_xml_resource), v -> {
+            mMenuItems.clear();
+            toolbar.setMenuItems(R.xml.menuitems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setToSettings()
+                    .setOnClickListener(i -> Toast.makeText(this, "Clicked",
+                            Toast.LENGTH_SHORT).show())
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_untined_icon), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setIcon(R.drawable.ic_tracklist)
+                    .setTinted(false)
+                    .setOnClickListener(
+                            i -> Toast.makeText(this, "Clicked",
+                                    Toast.LENGTH_SHORT).show())
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_switch), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setCheckable()
+                    .setOnClickListener(
+                            i ->
+                                    Toast.makeText(this,
+                                            "Checked? " + i.isChecked(),
+                                            Toast.LENGTH_SHORT)
+                                            .show())
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_text), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setTitle("Baz")
+                    .setOnClickListener(
+                            i -> Toast.makeText(this, "Clicked",
+                                    Toast.LENGTH_SHORT).show())
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon_text), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setIcon(R.drawable.ic_tracklist)
+                    .setTitle("Bar")
+                    .setShowIconAndTitle(true)
+                    .setOnClickListener(
+                            i -> Toast.makeText(this, "Clicked",
+                                    Toast.LENGTH_SHORT).show())
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_untinted_icon_and_text), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setIcon(R.drawable.ic_tracklist)
+                    .setTitle("Bar")
+                    .setShowIconAndTitle(true)
+                    .setTinted(false)
+                    .setOnClickListener(
+                            i -> Toast.makeText(this, "Clicked",
+                                    Toast.LENGTH_SHORT).show())
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_activatable), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setIcon(R.drawable.ic_tracklist)
+                    .setActivatable()
+                    .setOnClickListener(
+                            i -> Toast.makeText(this, "Clicked",
+                                    Toast.LENGTH_SHORT).show())
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_morphing), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setTitle("Become icon")
+                    .setOnClickListener(i ->
+                            i.setIcon(i.getIcon() == null ? R.drawable.ic_tracklist : 0))
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        Mutable<Integer> overflowCounter = new Mutable<>(1);
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_overflow), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setTitle("Foo " + overflowCounter.value)
+                    .setOnClickListener(
+                            i -> Toast.makeText(this, "Clicked",
+                                    Toast.LENGTH_SHORT).show())
+                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+            overflowCounter.value++;
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_overflow_switch), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setTitle("Foo " + overflowCounter.value)
+                    .setOnClickListener(
+                            i -> Toast.makeText(this,
+                                    i.isChecked() ? "Checked" : "Unchecked",
+                                    Toast.LENGTH_SHORT)
+                                    .show())
+                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
+                    .setCheckable()
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+            overflowCounter.value++;
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_icon_text_overflow), v -> {
+            mMenuItems.add(MenuItem.builder(this)
+                    .setIcon(R.drawable.ic_tracklist)
+                    .setTitle("Bar")
+                    .setShowIconAndTitle(true)
+                    .setOnClickListener(
+                            i -> Toast.makeText(this, "Clicked",
+                                    Toast.LENGTH_SHORT).show())
+                    .setDisplayBehavior(MenuItem.DisplayBehavior.NEVER)
+                    .build());
+            toolbar.setMenuItems(mMenuItems);
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_visibility),
+                v -> getMenuItem(item -> item.setVisible(!item.isVisible()))));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_enable),
+                v -> getMenuItem(item -> item.setEnabled(!item.isEnabled()))));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_perform_click),
+                v -> getMenuItem(MenuItem::performClick)));
+
+        final Drawable altIcon = getDrawable(R.drawable.ic_cut);
+        Map<MenuItem, Drawable> iconBackups = new HashMap<>();
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_icon), v ->
+                getMenuItem(item -> {
+                    Drawable currentIcon = item.getIcon();
+                    Drawable newIcon = altIcon;
+                    if (iconBackups.containsKey(item)) {
+                        newIcon = iconBackups.get(item);
+                    }
+                    item.setIcon(newIcon);
+                    iconBackups.put(item, currentIcon);
+                })));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_show_while_search), v ->
+                toolbar.setShowMenuItemsWhileSearching(
+                        !toolbar.getShowMenuItemsWhileSearching())));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_cycle_nav_button), v -> {
+            Toolbar.NavButtonMode mode = toolbar.getNavButtonMode();
+            if (mode == Toolbar.NavButtonMode.BACK) {
+                toolbar.setNavButtonMode(Toolbar.NavButtonMode.CLOSE);
+            } else if (mode == Toolbar.NavButtonMode.CLOSE) {
+                toolbar.setNavButtonMode(Toolbar.NavButtonMode.DOWN);
+            } else {
+                toolbar.setNavButtonMode(Toolbar.NavButtonMode.BACK);
+            }
+        }));
+
+        Mutable<Boolean> hasLogo = new Mutable<>(true);
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_logo), v -> {
+            toolbar.setLogo(hasLogo.value ? 0 : R.drawable.ic_launcher);
+            hasLogo.value = !hasLogo.value;
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_cycle_state), v -> {
+            if (toolbar.getState() == Toolbar.State.SUBPAGE) {
+                toolbar.setState(Toolbar.State.HOME);
+            } else if (toolbar.getState() == Toolbar.State.HOME) {
+                toolbar.setState(Toolbar.State.EDIT);
+            } else {
+                toolbar.setState(Toolbar.State.SUBPAGE);
+            }
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_search_hint), v -> {
+            if (toolbar.getSearchHint().toString().contentEquals("Foo")) {
+                toolbar.setSearchHint("Bar");
+            } else {
+                toolbar.setSearchHint("Foo");
+            }
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_background),
+                v -> toolbar.setBackgroundShown(!toolbar.getBackgroundShown())));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_tab), v -> toolbar.addTab(
+                new TabLayout.Tab(getDrawable(R.drawable.ic_launcher), "Foo"))));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_add_tab_with_custom_text), v -> {
+            SimpleTextWatcher textWatcher = new SimpleTextWatcher();
+            new AlertDialogBuilder(this)
+                    .setEditBox(null, textWatcher, null)
+                    .setTitle("Enter the text for the title")
+                    .setPositiveButton("Ok", (dialog, which) ->
+                            toolbar.addTab(
+                                    new TabLayout.Tab(
+                                            getDrawable(
+                                                    R.drawable.ic_launcher),
+                                            textWatcher.getText())))
+                    .show();
+        }));
+
+        mButtons.add(Pair.create(getString(R.string.toolbar_show_tabs_in_subpage), v ->
+                toolbar.setShowTabsInSubpage(!toolbar.getShowTabsInSubpage())));
+
+        Mutable<Boolean> showingLauncherIcon = new Mutable<>(false);
+        mButtons.add(Pair.create(getString(R.string.toolbar_toggle_search_icon), v -> {
+            if (showingLauncherIcon.value) {
+                toolbar.setSearchIcon(0);
+            } else {
+                toolbar.setSearchIcon(R.drawable.ic_launcher);
+            }
+            showingLauncherIcon.value = !showingLauncherIcon.value;
+        }));
+
+        CarUiRecyclerView prv = requireViewById(R.id.list);
+        prv.setAdapter(mAdapter);
+    }
+
+    /** Override in subclasses to change the layout */
+    protected int getLayout() {
+        return R.layout.car_ui_recycler_view_activity;
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        requireViewById(R.id.list)
+                .setPadding(0, insets.getTop(), 0, insets.getBottom());
+        requireViewById(android.R.id.content)
+                .setPadding(insets.getLeft(), 0, insets.getRight(), 0);
+    }
+
+    public void xmlMenuItemClicked(MenuItem item) {
+        Toast.makeText(this, "Xml item clicked! " + item.getTitle() + ", id: " + item.getId(),
+                Toast.LENGTH_SHORT).show();
+    }
+
+    private void getMenuItem(MenuItem.OnClickListener listener) {
+        if (mMenuItems.size() == 1) {
+            listener.onClick(mMenuItems.get(0));
+            return;
+        }
+
+        SimpleTextWatcher textWatcher = new SimpleTextWatcher();
+        new AlertDialogBuilder(this)
+                .setEditBox("", textWatcher, null, InputType.TYPE_CLASS_NUMBER)
+                .setTitle("Enter the index of the MenuItem")
+                .setPositiveButton("Ok", (dialog, which) -> {
+                    try {
+                        MenuItem item = mMenuItems.get(
+                                Integer.parseInt(textWatcher.getText()));
+                        listener.onClick(item);
+                    } catch (NumberFormatException | IndexOutOfBoundsException e) {
+                        Toast.makeText(this, "Invalid index \"" + textWatcher.getText()
+                                        + "\", valid range is 0 to " + (mMenuItems.size() - 1),
+                                Toast.LENGTH_LONG).show();
+                    }
+                }).show();
+    }
+
+    private static class ViewHolder extends RecyclerView.ViewHolder {
+
+        private final Button mButton;
+
+        ViewHolder(View itemView) {
+            super(itemView);
+            mButton = itemView.requireViewById(R.id.button);
+        }
+
+        public void bind(CharSequence title, View.OnClickListener listener) {
+            mButton.setText(title);
+            mButton.setOnClickListener(listener);
+        }
+    }
+
+    private final RecyclerView.Adapter<ViewHolder> mAdapter =
+            new RecyclerView.Adapter<ViewHolder>() {
+                @Override
+                public int getItemCount() {
+                    return mButtons.size();
+                }
+
+                @Override
+                public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
+                    View item =
+                            LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,
+                                    parent, false);
+                    return new ViewHolder(item);
+                }
+
+                @Override
+                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+                    Pair<CharSequence, View.OnClickListener> pair = mButtons.get(position);
+                    holder.bind(pair.first, pair.second);
+                }
+            };
+
+    /**
+     * For changing values from lambdas
+     */
+    private static final class Mutable<E> {
+
+        public E value;
+
+        Mutable() {
+            value = null;
+        }
+
+        Mutable(E value) {
+            this.value = value;
+        }
+    }
+
+    /**
+     * Used for getting text from a dialog.
+     */
+    private static final class SimpleTextWatcher implements TextWatcher {
+
+        private String mValue;
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            mValue = s.toString();
+        }
+
+        public String getText() {
+            return mValue;
+        }
+    }
+}
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/widgets/WidgetActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/widgets/WidgetActivity.java
new file mode 100644
index 0000000..ab97ae3
--- /dev/null
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/widgets/WidgetActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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.ui.paintbooth.widgets;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.paintbooth.R;
+import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+
+/**
+ * Activity that shows different widgets from the device default theme.
+ */
+public class WidgetActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.widgets_activity);
+        ToolbarController toolbar = CarUi.requireToolbar(this);
+        toolbar.setTitle(getTitle());
+        toolbar.setState(Toolbar.State.SUBPAGE);
+    }
+}
diff --git a/car-ui-lib/tests/robotests/Android.bp b/car-ui-lib/tests/robotests/Android.bp
new file mode 100644
index 0000000..20e67ef
--- /dev/null
+++ b/car-ui-lib/tests/robotests/Android.bp
@@ -0,0 +1,53 @@
+//
+// 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.
+//
+
+//###########################################################
+// CarUi lib just for Robolectric test target.     #
+//###########################################################
+android_app {
+    name: "CarUi",
+
+    resource_dirs: [
+        "res",
+    ],
+
+    platform_apis: true,
+
+    privileged: true,
+
+    libs: ["android.car"],
+
+    static_libs: ["car-ui-lib"],
+
+}
+
+//###############################################
+// Car Ui Robolectric test target. #
+//###############################################
+android_robolectric_test {
+    name: "CarUiRoboTests",
+
+    srcs: ["src/**/*.java"],
+
+    java_resource_dirs: ["config"],
+
+    libs: [
+        "android.car",
+        "testng",
+    ],
+
+    instrumentation_for: "CarUi",
+}
diff --git a/car-ui-lib/tests/robotests/AndroidManifest.xml b/car-ui-lib/tests/robotests/AndroidManifest.xml
new file mode 100644
index 0000000..b62579f
--- /dev/null
+++ b/car-ui-lib/tests/robotests/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.car.ui">
+</manifest>
diff --git a/car-ui-lib/tests/robotests/build.gradle b/car-ui-lib/tests/robotests/build.gradle
new file mode 100644
index 0000000..88387b8
--- /dev/null
+++ b/car-ui-lib/tests/robotests/build.gradle
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.5.3'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+// Library-level build file
+
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 29
+
+    defaultConfig {
+        minSdkVersion 28
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest.xml'
+            res.srcDirs = ['res']
+        }
+
+        test {
+            java.srcDirs = ['src']
+        }
+    }
+
+    testOptions {
+        unitTests {
+            includeAndroidResources = true
+        }
+    }
+}
+
+dependencies {
+    implementation project(':')
+    testImplementation "androidx.test.ext:junit:1.1.1"
+    testImplementation 'org.robolectric:robolectric:4.2'
+    testImplementation "org.mockito:mockito-core:2.19.0"
+    testImplementation "com.google.truth:truth:0.29"
+    testImplementation "org.testng:testng:6.9.9"
+
+    // This is the gradle equivalent of linking to android.car in our Android.mk
+    implementation files('../../../../../../../out/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/classes.jar')
+}
diff --git a/car-ui-lib/tests/robotests/config/robolectric.properties b/car-ui-lib/tests/robotests/config/robolectric.properties
new file mode 100644
index 0000000..849e07f
--- /dev/null
+++ b/car-ui-lib/tests/robotests/config/robolectric.properties
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2019 Google Inc.
+#
+# 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.
+#
+sdk=NEWEST_SDK
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_launcher.png b/car-ui-lib/tests/robotests/res/drawable/test_ic_launcher.png
similarity index 100%
copy from car-ui-lib/paintbooth/src/main/res/drawable/ic_launcher.png
copy to car-ui-lib/tests/robotests/res/drawable/test_ic_launcher.png
Binary files differ
diff --git a/car-ui-lib/tests/robotests/res/layout/test_custom_view.xml b/car-ui-lib/tests/robotests/res/layout/test_custom_view.xml
new file mode 100644
index 0000000..7a52259
--- /dev/null
+++ b/car-ui-lib/tests/robotests/res/layout/test_custom_view.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/text_box_1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Text Box 1"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/text_box_2"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"/>
+
+    <TextView
+        android:id="@+id/text_box_2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Text Box 2"
+        app:layout_constraintStart_toEndOf="@id/text_box_1"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"/>
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/car-ui-lib/tests/robotests/res/layout/test_grid_car_ui_recycler_view.xml b/car-ui-lib/tests/robotests/res/layout/test_grid_car_ui_recycler_view.xml
new file mode 100644
index 0000000..e5bf7a3
--- /dev/null
+++ b/car-ui-lib/tests/robotests/res/layout/test_grid_car_ui_recycler_view.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <com.android.car.ui.recyclerview.CarUiRecyclerView
+        android:id="@+id/test_prv"
+        app:layoutStyle="grid"
+        app:numOfColumns="4"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</FrameLayout>
diff --git a/car-ui-lib/tests/robotests/res/layout/test_linear_car_ui_recycler_view.xml b/car-ui-lib/tests/robotests/res/layout/test_linear_car_ui_recycler_view.xml
new file mode 100644
index 0000000..8f7f2ad
--- /dev/null
+++ b/car-ui-lib/tests/robotests/res/layout/test_linear_car_ui_recycler_view.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <com.android.car.ui.recyclerview.CarUiRecyclerView
+        android:id="@+id/test_prv"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</FrameLayout>
diff --git a/car-ui-lib/tests/robotests/res/layout/test_toolbar.xml b/car-ui-lib/tests/robotests/res/layout/test_toolbar.xml
new file mode 100644
index 0000000..19a1111
--- /dev/null
+++ b/car-ui-lib/tests/robotests/res/layout/test_toolbar.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <com.android.car.ui.toolbar.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+</FrameLayout>
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiListItemTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiListItemTest.java
new file mode 100644
index 0000000..cf28632
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiListItemTest.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import com.android.car.ui.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class CarUiListItemTest {
+
+    private CarUiRecyclerView mListView;
+    private Context mContext;
+
+    @Mock
+    CarUiContentListItem.OnCheckedChangeListener mOnCheckedChangeListener;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mListView = new CarUiRecyclerView(mContext);
+    }
+
+    private CarUiListItemAdapter.ListItemViewHolder getListItemViewHolderAtPosition(int position) {
+        return (CarUiListItemAdapter.ListItemViewHolder) mListView.findViewHolderForAdapterPosition(
+                position);
+    }
+
+    private View getListItemTitleAtPosition(int position) {
+        return getListItemViewHolderAtPosition(position).itemView.findViewById(R.id.title);
+    }
+
+    private View getListItemBodyAtPosition(int position) {
+        return getListItemViewHolderAtPosition(position).itemView.findViewById(R.id.body);
+    }
+
+    private View getListItemIconContainerAtPosition(int position) {
+        return getListItemViewHolderAtPosition(position).itemView.findViewById(R.id.icon_container);
+    }
+
+    private View getListItemActionContainerAtPosition(int position) {
+        return getListItemViewHolderAtPosition(position)
+                .itemView.findViewById(R.id.action_container);
+    }
+
+    private Switch getListItemSwitchAtPosition(int position) {
+        return getListItemViewHolderAtPosition(position).itemView.findViewById(R.id.switch_widget);
+    }
+
+    private CheckBox getListItemCheckBoxAtPosition(int position) {
+        return getListItemViewHolderAtPosition(position)
+                .itemView.findViewById(R.id.checkbox_widget);
+    }
+
+    private View getListItemIconAtPosition(int position) {
+        return getListItemViewHolderAtPosition(position).itemView.findViewById(R.id.icon);
+    }
+
+    private CarUiListItemAdapter.HeaderViewHolder getHeaderViewHolderAtPosition(int position) {
+        return (CarUiListItemAdapter.HeaderViewHolder) mListView.findViewHolderForAdapterPosition(
+                position);
+    }
+
+    private TextView getHeaderViewHolderTitleAtPosition(int position) {
+        return getHeaderViewHolderAtPosition(position).itemView.findViewById(R.id.title);
+    }
+
+    private TextView getHeaderViewHolderBodyAtPosition(int position) {
+        return getHeaderViewHolderAtPosition(position).itemView.findViewById(R.id.body);
+    }
+
+    private void updateRecyclerViewAdapter(CarUiListItemAdapter adapter) {
+        mListView.setAdapter(adapter);
+
+        // Force CarUiRecyclerView and the nested RecyclerView to be laid out.
+        mListView.measure(0, 0);
+        mListView.layout(0, 0, 100, 10000);
+
+        if (mListView != null) {
+            mListView.measure(0, 0);
+            mListView.layout(0, 0, 100, 10000);
+        }
+
+        // Required to init nested RecyclerView
+        mListView.getViewTreeObserver().dispatchOnGlobalLayout();
+    }
+
+    @Test
+    public void testItemVisibility_withTitle() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test title");
+        items.add(item);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        assertThat(getListItemTitleAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemBodyAtPosition(0).getVisibility()).isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemIconContainerAtPosition(0).getVisibility())
+                .isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemActionContainerAtPosition(0).getVisibility())
+                .isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void testItemVisibility_withTitle_withBody() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test title");
+        item.setBody("Test body");
+        items.add(item);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        assertThat(getListItemTitleAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemBodyAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemIconContainerAtPosition(0).getVisibility())
+                .isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemActionContainerAtPosition(0).getVisibility())
+                .isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void testItemVisibility_withTitle_withIcon() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test title");
+        item.setIcon(mContext.getDrawable(R.drawable.car_ui_icon_close));
+        items.add(item);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        assertThat(getListItemTitleAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemBodyAtPosition(0).getVisibility()).isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemIconContainerAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemIconAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemActionContainerAtPosition(0).getVisibility())
+                .isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void testItemVisibility_withTitle_withCheckbox() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
+        item.setTitle("Test title");
+        items.add(item);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        assertThat(getListItemTitleAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemBodyAtPosition(0).getVisibility()).isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemIconContainerAtPosition(0).getVisibility())
+                .isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemActionContainerAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemSwitchAtPosition(0).getVisibility()).isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemCheckBoxAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemCheckBoxAtPosition(0).isChecked()).isEqualTo(false);
+    }
+
+    @Test
+    public void testItemVisibility_withTitle_withBody_withSwitch() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
+        item.setTitle("Test title");
+        item.setBody("Body text");
+        items.add(item);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        assertThat(getListItemTitleAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemBodyAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemIconContainerAtPosition(0).getVisibility())
+                .isNotEqualTo(View.VISIBLE);
+        assertThat(getListItemActionContainerAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemSwitchAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getListItemSwitchAtPosition(0).isChecked()).isEqualTo(false);
+        assertThat(getListItemCheckBoxAtPosition(0).getVisibility()).isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void testCheckedState_switch() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
+        item.setTitle("Test title");
+        item.setOnCheckedChangeListener(mOnCheckedChangeListener);
+        item.setChecked(true);
+        items.add(item);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        Switch switchWidget = getListItemSwitchAtPosition(0);
+
+        assertThat(switchWidget.isChecked()).isEqualTo(true);
+        switchWidget.performClick();
+        assertThat(switchWidget.isChecked()).isEqualTo(false);
+        verify(mOnCheckedChangeListener, times(1))
+                .onCheckedChanged(item, false);
+    }
+
+    @Test
+    public void testCheckedState_checkbox() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
+        item.setTitle("Test title");
+        item.setOnCheckedChangeListener(mOnCheckedChangeListener);
+        items.add(item);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        CheckBox checkBox = getListItemCheckBoxAtPosition(0);
+
+        assertThat(checkBox.isChecked()).isEqualTo(false);
+        checkBox.performClick();
+        assertThat(checkBox.isChecked()).isEqualTo(true);
+        verify(mOnCheckedChangeListener, times(1))
+                .onCheckedChanged(item, true);
+    }
+
+    @Test
+    public void testHeader_onlyTitle() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CharSequence title = "Test header";
+        CarUiHeaderListItem header = new CarUiHeaderListItem(title);
+        items.add(header);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        assertThat(getHeaderViewHolderTitleAtPosition(0).getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(getHeaderViewHolderTitleAtPosition(0).getText()).isEqualTo(title);
+        assertThat(getHeaderViewHolderBodyAtPosition(0).getVisibility()).isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void testHeader_titleAndBody() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CharSequence title = "Test header";
+        CharSequence body = "With body text";
+
+        CarUiHeaderListItem header = new CarUiHeaderListItem(title, body);
+        items.add(header);
+
+        updateRecyclerViewAdapter(new CarUiListItemAdapter(items));
+
+        TextView titleView = getHeaderViewHolderTitleAtPosition(0);
+        TextView bodyView = getHeaderViewHolderBodyAtPosition(0);
+
+        assertThat(titleView.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(titleView.getText()).isEqualTo(title);
+        assertThat(bodyView.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(bodyView.getText()).isEqualTo(body);
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiRecyclerViewAdapterTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiRecyclerViewAdapterTest.java
new file mode 100644
index 0000000..4d21851
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiRecyclerViewAdapterTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.ViewGroup;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class CarUiRecyclerViewAdapterTest {
+
+    private Context mContext;
+    private CarUiRecyclerViewAdapter mCarUiRecyclerViewAdapter;
+
+    @Mock
+    private ViewGroup mParent;
+    @Mock
+    private ViewGroup.LayoutParams mLayoutParams;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
+        mCarUiRecyclerViewAdapter = new CarUiRecyclerViewAdapter();
+    }
+
+    @Test
+    public void getItemCount_shouldAlwaysBeOne() {
+        assertThat(mCarUiRecyclerViewAdapter.getItemCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void onCreateViewHolder_frameLayoutNotNull() {
+
+        when(mParent.getContext()).thenReturn(mContext);
+        when(mParent.generateLayoutParams(any())).thenReturn(mLayoutParams);
+
+        CarUiRecyclerViewAdapter.NestedRowViewHolder nestedRowViewHolder =
+                mCarUiRecyclerViewAdapter.onCreateViewHolder(mParent, 0);
+
+        assertThat(nestedRowViewHolder.frameLayout).isNotNull();
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
new file mode 100644
index 0000000..c0b87de
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+import com.android.car.ui.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class CarUiRecyclerViewTest {
+
+    private Context mContext;
+    private View mView;
+    private CarUiRecyclerView mCarUiRecyclerView;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
+    }
+
+    @Test
+    public void onHeightChanged_shouldAddTheValueToInitialTopValue() {
+        mView = LayoutInflater.from(mContext)
+                .inflate(R.layout.test_linear_car_ui_recycler_view, null);
+
+        mCarUiRecyclerView = mView.findViewById(R.id.test_prv);
+
+        assertThat(mCarUiRecyclerView.getPaddingBottom()).isEqualTo(0);
+        assertThat(mCarUiRecyclerView.getPaddingTop()).isEqualTo(0);
+        assertThat(mCarUiRecyclerView.getPaddingStart()).isEqualTo(0);
+        assertThat(mCarUiRecyclerView.getPaddingEnd()).isEqualTo(0);
+
+        mCarUiRecyclerView.onHeightChanged(10);
+
+        assertThat(mCarUiRecyclerView.getPaddingTop()).isEqualTo(10);
+        assertThat(mCarUiRecyclerView.getPaddingBottom()).isEqualTo(0);
+        assertThat(mCarUiRecyclerView.getPaddingStart()).isEqualTo(0);
+        assertThat(mCarUiRecyclerView.getPaddingEnd()).isEqualTo(0);
+    }
+
+    @Test
+    public void setAdapter_shouldInitializeLinearLayoutManager() {
+        mView = LayoutInflater.from(mContext)
+                .inflate(R.layout.test_linear_car_ui_recycler_view, null);
+
+        mCarUiRecyclerView = mView.findViewById(R.id.test_prv);
+
+        assertThat(mCarUiRecyclerView.getLayoutManager()).isInstanceOf(
+                LinearLayoutManager.class);
+    }
+
+    @Test
+    public void setAdapter_shouldInitializeGridLayoutManager() {
+        mView = LayoutInflater.from(mContext)
+                .inflate(R.layout.test_grid_car_ui_recycler_view, null);
+
+        mCarUiRecyclerView = mView.findViewById(R.id.test_prv);
+
+        assertThat(mCarUiRecyclerView.getLayoutManager()).isInstanceOf(
+                GridLayoutManager.class);
+    }
+
+    @Test
+    public void init_shouldContainRecyclerView() {
+        mView = LayoutInflater.from(mContext)
+                .inflate(R.layout.test_grid_car_ui_recycler_view, null);
+
+        mCarUiRecyclerView = mView.findViewById(R.id.test_prv);
+
+        assertThat(mCarUiRecyclerView).isNotNull();
+    }
+
+    @Test
+    public void init_shouldHaveGridLayout() {
+        mCarUiRecyclerView = new CarUiRecyclerView(mContext,
+                Robolectric.buildAttributeSet().addAttribute(R.attr.layoutStyle, "grid").build());
+        assertThat(mCarUiRecyclerView.getLayoutManager()).isInstanceOf(
+                GridLayoutManager.class);
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiSmoothScrollerTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiSmoothScrollerTest.java
new file mode 100644
index 0000000..c5dc78b
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiSmoothScrollerTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static androidx.recyclerview.widget.LinearSmoothScroller.SNAP_TO_START;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class CarUiSmoothScrollerTest {
+
+    private Context mContext;
+    private CarUiSmoothScroller mCarUiSmoothScroller;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mCarUiSmoothScroller = new CarUiSmoothScroller(mContext);
+    }
+
+    @Test
+    public void calculateTimeForScrolling_shouldInitializeAllValues() {
+        assertThat(mCarUiSmoothScroller.mMillisecondsPerInch).isNotEqualTo(0);
+        assertThat(mCarUiSmoothScroller.mDecelerationTimeDivisor).isNotEqualTo(0);
+        assertThat(mCarUiSmoothScroller.mMillisecondsPerPixel).isNotEqualTo(0);
+        assertThat(mCarUiSmoothScroller.mInterpolator).isNotNull();
+        assertThat(mCarUiSmoothScroller.mDensityDpi).isNotEqualTo(0);
+    }
+
+    @Test
+    public void getVerticalSnapPreference_shouldReturnSnapToStart() {
+        assertThat(mCarUiSmoothScroller.getVerticalSnapPreference()).isEqualTo(SNAP_TO_START);
+    }
+
+    @Test
+    public void calculateTimeForScrolling_shouldReturnMultiplierOfMillisecondsPerPixel() {
+        assertThat(mCarUiSmoothScroller.calculateTimeForScrolling(20)).isEqualTo(
+                (int) Math.ceil(Math.abs(20) * mCarUiSmoothScroller.mMillisecondsPerPixel));
+    }
+
+    @Test
+    public void calculateTimeForDeceleration_shouldReturnNotBeZero() {
+        assertThat(mCarUiSmoothScroller.calculateTimeForDeceleration(20)).isNotEqualTo(0);
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiSnapHelperTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiSnapHelperTest.java
new file mode 100644
index 0000000..62edd3d
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiSnapHelperTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class CarUiSnapHelperTest {
+
+    private Context mContext;
+    private CarUiSnapHelper mCarUiSnapHelper;
+
+    @Mock
+    private RecyclerView mRecyclerView;
+    @Mock
+    private LinearLayoutManager mLayoutManager;
+    @Mock
+    private RecyclerView.Adapter mAdapter;
+    @Mock
+    private View mChild;
+    @Mock
+    private RecyclerView.LayoutParams mLayoutParams;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        mCarUiSnapHelper = new CarUiSnapHelper(mContext);
+
+        when(mRecyclerView.getContext()).thenReturn(mContext);
+        mCarUiSnapHelper.attachToRecyclerView(mRecyclerView);
+    }
+
+    @Test
+    public void calculateDistanceToFinalSnap_shouldReturnTopMarginDifference() {
+        when(mRecyclerView.getLayoutManager()).thenReturn(mLayoutManager);
+        when(mRecyclerView.isInTouchMode()).thenReturn(true);
+        when(mLayoutManager.getItemCount()).thenReturn(1);
+        when(mLayoutManager.canScrollVertically()).thenReturn(true);
+        when(mLayoutManager.getChildCount()).thenReturn(1);
+        // some delta
+        when(mLayoutManager.getDecoratedTop(any())).thenReturn(10);
+        when(mChild.getLayoutParams()).thenReturn(mLayoutParams);
+
+        int[] distance = mCarUiSnapHelper.calculateDistanceToFinalSnap(mLayoutManager, mChild);
+
+        assertThat(distance[1]).isEqualTo(10);
+    }
+
+    @Test
+    public void calculateScrollDistance_shouldScrollHeightOfView() {
+        when(mRecyclerView.getLayoutManager()).thenReturn(mLayoutManager);
+        when(mLayoutManager.getItemCount()).thenReturn(1);
+        when(mLayoutManager.canScrollVertically()).thenReturn(true);
+        when(mLayoutManager.getChildCount()).thenReturn(1);
+        // some delta
+        when(mLayoutManager.getDecoratedTop(any())).thenReturn(10);
+        when(mChild.getLayoutParams()).thenReturn(mLayoutParams);
+        when(mLayoutManager.getChildAt(0)).thenReturn(mChild);
+        when(mLayoutManager.getHeight()).thenReturn(-50);
+
+        int[] distance = mCarUiSnapHelper.calculateScrollDistance(0, 10);
+
+        assertThat(distance[1]).isEqualTo(50);
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/DefaultScrollBarTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/DefaultScrollBarTest.java
new file mode 100644
index 0000000..1cd59df
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/DefaultScrollBarTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class DefaultScrollBarTest {
+
+    private Context mContext;
+    private ScrollBar mScrollBar;
+
+    @Mock
+    private RecyclerView mRecyclerView;
+    @Mock
+    private FrameLayout mParent;
+    @Mock
+    private FrameLayout.LayoutParams mLayoutParams;
+    @Mock
+    private RecyclerView.RecycledViewPool mRecycledViewPool;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        mScrollBar = new DefaultScrollBar();
+    }
+
+    @Test
+    public void initialize_shouldInitializeScrollListener() {
+        when(mRecyclerView.getContext()).thenReturn(mContext);
+        when(mRecyclerView.getParent()).thenReturn(mParent);
+        when(mRecyclerView.getRecycledViewPool()).thenReturn(mRecycledViewPool);
+        when(mParent.generateLayoutParams(any())).thenReturn(mLayoutParams);
+
+        View scrollView = LayoutInflater.from(mContext).inflate(
+                R.layout.car_ui_recyclerview_scrollbar, null);
+        mScrollBar.initialize(mRecyclerView, scrollView);
+
+        // called once in DefaultScrollBar and once in SnapHelper while setting up the call backs
+        // when we use attachToRecyclerView(recyclerview)
+        verify(mRecyclerView, times(2)).addOnScrollListener(
+                any(RecyclerView.OnScrollListener.class));
+    }
+
+    @Test
+    public void initialize_shouldSetMaxRecyclerViews() {
+        when(mRecyclerView.getContext()).thenReturn(mContext);
+        when(mRecyclerView.getParent()).thenReturn(mParent);
+        when(mRecyclerView.getRecycledViewPool()).thenReturn(mRecycledViewPool);
+        when(mParent.generateLayoutParams(any())).thenReturn(mLayoutParams);
+
+        View scrollView = LayoutInflater.from(mContext).inflate(
+                R.layout.car_ui_recyclerview_scrollbar, null);
+        mScrollBar.initialize(mRecyclerView, scrollView);
+
+        verify(mRecycledViewPool).setMaxRecycledViews(0, 12);
+    }
+
+    @Test
+    public void initialize_shouldNotHaveFlingListener() {
+        when(mRecyclerView.getContext()).thenReturn(mContext);
+        when(mRecyclerView.getParent()).thenReturn(mParent);
+        when(mRecyclerView.getRecycledViewPool()).thenReturn(mRecycledViewPool);
+        when(mParent.generateLayoutParams(any())).thenReturn(mLayoutParams);
+
+        View scrollView = LayoutInflater.from(mContext).inflate(
+                R.layout.car_ui_recyclerview_scrollbar, null);
+        mScrollBar.initialize(mRecyclerView, scrollView);
+
+        verify(mRecyclerView).setOnFlingListener(null);
+    }
+
+    @Test
+    public void setPadding_shouldSetStartAndEndPadding() {
+        when(mRecyclerView.getContext()).thenReturn(mContext);
+        when(mRecyclerView.getParent()).thenReturn(mParent);
+        when(mRecyclerView.getRecycledViewPool()).thenReturn(mRecycledViewPool);
+        when(mParent.generateLayoutParams(any())).thenReturn(mLayoutParams);
+
+        View scrollView = LayoutInflater.from(mContext).inflate(
+                R.layout.car_ui_recyclerview_scrollbar, null);
+        mScrollBar.initialize(mRecyclerView, scrollView);
+        mScrollBar.setPadding(10, 20);
+
+        assertThat(scrollView.getPaddingTop()).isEqualTo(10);
+        assertThat(scrollView.getPaddingBottom()).isEqualTo(20);
+    }
+
+    @Test
+    public void setPadding_shouldThrowErrorWithoutInitialization() {
+        assertThrows(NullPointerException.class, () -> mScrollBar.setPadding(10, 20));
+    }
+
+    @Test
+    public void requestLayout_shouldThrowErrorWithoutInitialization() {
+        assertThrows(NullPointerException.class, () -> mScrollBar.requestLayout());
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ExtendedShadowTypeface.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ExtendedShadowTypeface.java
new file mode 100644
index 0000000..a5bc1b1
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ExtendedShadowTypeface.java
@@ -0,0 +1,34 @@
+/*
+ * 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.ui.toolbar;
+
+import android.graphics.Typeface;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowTypeface;
+
+@Implements(Typeface.class)
+public class ExtendedShadowTypeface extends ShadowTypeface {
+    @Implementation
+    protected static Typeface create(Typeface family, int weight, boolean italic) {
+        // Increment style by 10 to distinguish when a style has been italicized. This a workaround
+        // for ShadowTypeface not supporting italicization for Typeface.
+        int style = italic ? weight + 10 : weight;
+        return ShadowTypeface.create(family, style);
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ShadowAsyncLayoutInflater.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ShadowAsyncLayoutInflater.java
new file mode 100644
index 0000000..817ab97
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ShadowAsyncLayoutInflater.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.toolbar;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Shadow of {@link AsyncLayoutInflater} that inflates synchronously, so that tests
+ * don't have to have complicated code to wait for these inflations.
+ */
+@Implements(AsyncLayoutInflater.class)
+public class ShadowAsyncLayoutInflater {
+    @Implementation
+    public void inflate(@LayoutRes int resid, @Nullable ViewGroup parent,
+            @NonNull AsyncLayoutInflater.OnInflateFinishedListener callback) {
+        View result = LayoutInflater.from(parent.getContext())
+                .inflate(resid, parent, false);
+
+        callback.onInflateFinished(result, resid, parent);
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/TestActivity.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/TestActivity.java
new file mode 100644
index 0000000..dcbe1cd
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/TestActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.ui.toolbar;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.R;
+
+/** An activity to use in the Toolbar tests */
+public class TestActivity extends Activity {
+
+    private int mTimesBackPressed = 0;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.test_toolbar);
+    }
+
+    @Override
+    public void onBackPressed() {
+        mTimesBackPressed++;
+        super.onBackPressed();
+    }
+
+    public int getTimesBackPressed() {
+        return mTimesBackPressed;
+    }
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ToolbarTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ToolbarTest.java
new file mode 100644
index 0000000..6cd127b
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/toolbar/ToolbarTest.java
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.toolbar;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+
+import com.android.car.ui.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ExtendedShadowTypeface.class, ShadowAsyncLayoutInflater.class},
+        qualifiers = "land")
+public class ToolbarTest {
+
+    private Context mContext;
+    private Resources mResources;
+    private ActivityController<TestActivity> mActivityController;
+    private TestActivity mActivity;
+    private Toolbar mToolbar;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mResources = mContext.getResources();
+        mActivityController = Robolectric.buildActivity(TestActivity.class);
+        mActivityController.setup();
+        mActivity = mActivityController.get();
+        mToolbar = mActivity.findViewById(R.id.toolbar);
+    }
+
+    @Test
+    public void getters_nochanges_shouldReturnDefaults() {
+        assertThat(mToolbar.getBackgroundShown()).isEqualTo(true);
+        assertThat(mToolbar.getShowMenuItemsWhileSearching()).isEqualTo(false);
+        assertThat(mToolbar.getState()).isEquivalentAccordingToCompareTo(Toolbar.State.HOME);
+        assertThat(mToolbar.getNavButtonMode()).isEquivalentAccordingToCompareTo(
+                Toolbar.NavButtonMode.BACK);
+    }
+
+    @Test
+    public void setState_subpage_shouldCauseGetStateToReturnSubpage() {
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+
+        assertThat(mToolbar.getState()).isEquivalentAccordingToCompareTo(Toolbar.State.SUBPAGE);
+    }
+
+    @Test
+    public void setters_and_getters_test() {
+        mToolbar.setTitle("Foo");
+        mToolbar.setSearchHint("Foo2");
+        mToolbar.setBackgroundShown(false);
+        mToolbar.setShowMenuItemsWhileSearching(true);
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+        mToolbar.setNavButtonMode(Toolbar.NavButtonMode.CLOSE);
+
+        assertThat(mToolbar.getTitle().toString()).isEqualTo("Foo");
+        assertThat(mToolbar.getSearchHint().toString()).isEqualTo("Foo2");
+        assertThat(mToolbar.getBackgroundShown()).isEqualTo(false);
+        assertThat(mToolbar.getShowMenuItemsWhileSearching()).isEqualTo(true);
+        assertThat(mToolbar.getState()).isEquivalentAccordingToCompareTo(Toolbar.State.SUBPAGE);
+        assertThat(mToolbar.getNavButtonMode()).isEquivalentAccordingToCompareTo(
+                Toolbar.NavButtonMode.CLOSE);
+    }
+
+    @Test
+    public void showLogo_whenSet_andStateIsHome() {
+        mToolbar.setState(Toolbar.State.HOME);
+        mToolbar.setLogo(R.drawable.test_ic_launcher);
+
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_logo).isShown()).isTrue();
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_title_logo).isShown()).isFalse();
+    }
+
+    @Test
+    public void hideLogo_andTitleLogo_whenSet_andStateIsHome_andLogoIsDisabled() {
+        mockResources();
+        when(mResources.getBoolean(R.bool.car_ui_toolbar_show_logo)).thenReturn(false);
+
+        Toolbar toolbar = new Toolbar(mContext);
+        toolbar.setState(Toolbar.State.HOME);
+        toolbar.setLogo(R.drawable.test_ic_launcher);
+
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_logo)).isFalse();
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_title_logo)).isFalse();
+    }
+
+    @Test
+    public void showTitleLogo_whenSet_andStateIsNotHome() {
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+        mToolbar.setLogo(R.drawable.test_ic_launcher);
+
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_logo).isShown()).isFalse();
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_title_logo).isShown()).isTrue();
+    }
+
+    @Test
+    public void hideLogo_andTitleLogo_whenNotSet_andStateIsHome() {
+        mToolbar.setState(Toolbar.State.HOME);
+        mToolbar.setLogo(0);
+
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_logo).isShown()).isFalse();
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_title_logo).isShown()).isFalse();
+    }
+
+    @Test
+    public void hideLogo_andTitleLogo_whenNotSet_andStateIsNotHome() {
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+        mToolbar.setLogo(0);
+
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_logo).isShown()).isFalse();
+        assertThat(mToolbar.findViewById(R.id.car_ui_toolbar_title_logo).isShown()).isFalse();
+    }
+
+    @Test
+    public void registerOnBackListener_whenBackIsPressed_shouldCallListener() {
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+        Mutable<Integer> timesBackPressed = new Mutable<>(0);
+        Toolbar.OnBackListener listener = () -> {
+            timesBackPressed.value++;
+            return false;
+        };
+
+        mToolbar.registerOnBackListener(listener);
+        pressBack();
+
+        assertThat(timesBackPressed.value).isEqualTo(1);
+        assertThat(mActivity.getTimesBackPressed()).isEqualTo(1);
+    }
+
+    @Test
+    public void registerOnBackListener_whenAListenerReturnsTrue_shouldSuppressBack() {
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+
+        mToolbar.registerOnBackListener(() -> true);
+        pressBack();
+        mToolbar.registerOnBackListener(() -> false);
+        pressBack();
+
+        assertThat(mActivity.getTimesBackPressed()).isEqualTo(0);
+    }
+
+    @Test
+    public void testState_twoRow_withTitle_withTabs() {
+        mockResources();
+        when(mResources.getBoolean(R.bool.car_ui_toolbar_tabs_on_second_row)).thenReturn(true);
+
+        Toolbar toolbar = new Toolbar(mContext);
+        assertThat(toolbar.isTabsInSecondRow()).isTrue();
+
+        // Set title and tabs for toolbar.
+        toolbar.setTitle("Test title");
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+
+        // Toolbar should display two rows, showing both title and tabs.
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_tabs)).isTrue();
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_title)).isTrue();
+    }
+
+    @Test
+    public void testState_twoRow_withTitle()  {
+        mockResources();
+        when(mResources.getBoolean(R.bool.car_ui_toolbar_tabs_on_second_row)).thenReturn(true);
+
+        Toolbar toolbar = new Toolbar(mContext);
+        assertThat(toolbar.isTabsInSecondRow()).isTrue();
+
+        toolbar.setTitle("Test title");
+
+        // Toolbar should display two rows, but no tabs are set so they should not be visible.
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_title)).isTrue();
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_tabs)).isFalse();
+    }
+
+    @Test
+    public void testState_twoRow_withTabs() {
+        mockResources();
+        when(mResources.getBoolean(R.bool.car_ui_toolbar_tabs_on_second_row)).thenReturn(true);
+
+        Toolbar toolbar = new Toolbar(mContext);
+        assertThat(toolbar.isTabsInSecondRow()).isTrue();
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+
+        // Toolbar should display two rows with an empty title and tabs.
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_tabs)).isTrue();
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_title)).isTrue();
+    }
+
+    @Test
+    public void testState_oneRow_withTitle_withTabs() {
+        mockResources();
+        when(mResources.getBoolean(R.bool.car_ui_toolbar_tabs_on_second_row)).thenReturn(false);
+
+        Toolbar toolbar = new Toolbar(mContext);
+        assertThat(toolbar.isTabsInSecondRow()).isFalse();
+
+        // Set title and tabs for toolbar.
+        toolbar.setTitle("Test title");
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+
+        // With only one row available, toolbar will only show tabs and not the title.
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_tabs)).isTrue();
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_title)).isFalse();
+    }
+
+    @Test
+    public void testState_oneRow_withTitle() {
+        mockResources();
+        when(mResources.getBoolean(R.bool.car_ui_toolbar_tabs_on_second_row)).thenReturn(false);
+
+
+        Toolbar toolbar = new Toolbar(mContext);
+        assertThat(toolbar.isTabsInSecondRow()).isFalse();
+
+        toolbar.setTitle("Test title");
+
+        // Toolbar should display one row with the title and no tabs.
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_tabs)).isFalse();
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_title)).isTrue();
+    }
+
+    @Test
+    public void testState_oneRow_withTabs() {
+        mockResources();
+        when(mResources.getBoolean(R.bool.car_ui_toolbar_tabs_on_second_row)).thenReturn(false);
+
+
+        Toolbar toolbar = new Toolbar(mContext);
+        assertThat(toolbar.isTabsInSecondRow()).isFalse();
+
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+        toolbar.addTab(new TabLayout.Tab(mContext.getDrawable(R.drawable.test_ic_launcher), "Foo"));
+
+        // Toolbar should display one row with only tabs.
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_tabs)).isTrue();
+        assertThat(isViewInToolbarShown(toolbar, R.id.car_ui_toolbar_title)).isFalse();
+    }
+
+    @Test
+    public void registerOnBackListener_whenListenerRegisteredTwice_shouldntCallListenerTwice() {
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+        Mutable<Integer> timesBackPressed = new Mutable<>(0);
+        Toolbar.OnBackListener listener = () -> {
+            timesBackPressed.value++;
+            return false;
+        };
+
+        // Registering a second time shouldn't do anything
+        mToolbar.registerOnBackListener(listener);
+        mToolbar.registerOnBackListener(listener);
+        pressBack();
+
+        assertThat(timesBackPressed.value).isEqualTo(1);
+    }
+
+    @Test
+    public void unregisterOnBackListener_previouslyRegisteredListener_shouldUnregister() {
+        mToolbar.setState(Toolbar.State.SUBPAGE);
+        Mutable<Integer> timesBackPressed = new Mutable<>(0);
+        Toolbar.OnBackListener listener = () -> {
+            timesBackPressed.value++;
+            return false;
+        };
+
+        mToolbar.registerOnBackListener(listener);
+        mToolbar.unregisterOnBackListener(listener);
+        pressBack();
+
+        assertThat(timesBackPressed.value).isEqualTo(0);
+    }
+
+    @Test
+    public void menuItems_builder_id() {
+        MenuItem item = MenuItem.builder(mContext)
+                .setId(5)
+                .build();
+
+        assertThat(item.getId()).isEqualTo(5);
+    }
+
+    @Test
+    public void menuItems_setId_shouldWork() {
+        MenuItem item = MenuItem.builder(mContext).build();
+
+        assertThat(item.getId()).isEqualTo(View.NO_ID);
+
+        item.setId(7);
+
+        assertThat(item.getId()).isEqualTo(7);
+    }
+
+    @Test
+    public void menuItems_whenClicked_shouldCallListener() {
+        assertThat(getMenuItemCount()).isEqualTo(0);
+
+        Mutable<Boolean> button1Clicked = new Mutable<>(false);
+        Mutable<Boolean> button2Clicked = new Mutable<>(false);
+        mToolbar.setMenuItems(Arrays.asList(
+                createMenuItem(i -> button1Clicked.value = true),
+                createMenuItem(i -> button2Clicked.value = true)));
+
+        assertThat(getMenuItemCount()).isEqualTo(2);
+
+        getMenuItemView(0).performClick();
+
+        assertThat(button1Clicked.value).isTrue();
+
+        getMenuItemView(1).performClick();
+
+        assertThat(button2Clicked.value).isTrue();
+    }
+
+    @Test
+    public void menuItems_null_shouldRemoveExistingMenuItems() {
+        mToolbar.setMenuItems(Arrays.asList(
+                createMenuItem(i -> {
+                }),
+                createMenuItem(i -> {
+                })));
+
+        assertThat(getMenuItemCount()).isEqualTo(2);
+
+        mToolbar.setMenuItems(null);
+
+        assertThat(getMenuItemCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void menuItems_setVisibility_shouldDefaultToShown() {
+        MenuItem item = createMenuItem(i -> {
+        });
+        mToolbar.setMenuItems(Collections.singletonList(item));
+
+        assertThat(getMenuItemView(0).isShown()).isTrue();
+    }
+
+    @Test
+    public void menuItems_setVisibility_shouldHide() {
+        MenuItem item = createMenuItem(i -> {
+        });
+        mToolbar.setMenuItems(Collections.singletonList(item));
+
+        item.setVisible(false);
+        assertThat(getMenuItemView(0).isShown()).isFalse();
+    }
+
+    @Test
+    public void menuItems_setVisibility_shouldReshowAfterHiding() {
+        MenuItem item = createMenuItem(i -> {
+        });
+        mToolbar.setMenuItems(Collections.singletonList(item));
+
+        item.setVisible(false);
+        item.setVisible(true);
+        assertThat(getMenuItemView(0).isShown()).isTrue();
+    }
+
+    @Test
+    public void menuItems_equalItems_shouldntRecreateViews() {
+        List<MenuItem> menuItems = Arrays.asList(
+                createMenuItem(i -> {
+                }),
+                createMenuItem(i -> {
+                }));
+        mToolbar.setMenuItems(menuItems);
+
+        assertThat(getMenuItemCount()).isEqualTo(2);
+
+        View firstMenuItemView = getMenuItemView(0);
+
+        mToolbar.setMenuItems(menuItems);
+
+        assertThat(firstMenuItemView).isSameAs(getMenuItemView(0));
+    }
+
+    @Test
+    public void menuItems_searchScreen_shouldHideMenuItems() {
+        mToolbar.setMenuItems(Arrays.asList(
+                MenuItem.builder(mContext).setToSearch().build(),
+                createMenuItem(i -> {
+                })));
+
+        mToolbar.setShowMenuItemsWhileSearching(false);
+        mToolbar.setState(Toolbar.State.SEARCH);
+
+        assertThat(getMenuItemView(0).isShown()).isFalse();
+        assertThat(getMenuItemView(1).isShown()).isFalse();
+    }
+
+    @Test
+    public void menuItems_showMenuItemsWhileSearching() {
+        mToolbar.setMenuItems(Arrays.asList(
+                MenuItem.builder(mContext).setToSearch().build(),
+                createMenuItem(i -> {
+                })));
+
+        mToolbar.setShowMenuItemsWhileSearching(true);
+        mToolbar.setState(Toolbar.State.SEARCH);
+
+        assertThat(getMenuItemView(0).isShown()).isFalse();
+        assertThat(getMenuItemView(1).isShown()).isTrue();
+    }
+
+    private MenuItem createMenuItem(MenuItem.OnClickListener listener) {
+        return MenuItem.builder(mContext)
+                .setTitle("Button!")
+                .setOnClickListener(listener)
+                .build();
+    }
+
+    private void mockResources() {
+        mContext = spy(RuntimeEnvironment.application);
+        mResources = spy(mContext.getResources());
+        when(mContext.getResources()).thenReturn(mResources);
+    }
+
+    private int getMenuItemCount() {
+        return mToolbar.getMenuItems().size();
+    }
+
+    /**
+     * IsShown() will return false for views that are not attached to an activity.
+     * This altered version will return true for that case.
+     */
+    private boolean isViewInToolbarShown(Toolbar toolbar, int id) {
+        View current = toolbar.findViewById(id);
+        //noinspection ConstantConditions
+        do {
+            if (current.getVisibility() != View.VISIBLE) {
+                return false;
+            }
+            ViewParent parent = current.getParent();
+            if (parent == null) {
+                return false; // We are not attached to the view root
+            }
+            if (parent == toolbar || !(parent instanceof View)) {
+                // Return true if we hit the toolbar, or this parent isn't a view.
+                // The parent wouldn't be a view if it was a ViewRootImpl, the parent
+                // of a whole view hierarchy
+                return true;
+            }
+            current = (View) parent;
+        } while (current != null);
+        return false;
+    }
+
+    private View getMenuItemView(int index) {
+        return ((ViewGroup) mToolbar
+                .findViewById(R.id.car_ui_toolbar_menu_items_container))
+                .getChildAt(index);
+    }
+
+    private void pressBack() {
+        mToolbar.findViewById(R.id.car_ui_toolbar_nav_icon_container).performClick();
+    }
+
+    private static class Mutable<T> {
+        public T value;
+
+        Mutable(T value) {
+            this.value = value;
+        }
+    }
+
+}
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/utils/CarUxRestrictionsUtilTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/utils/CarUxRestrictionsUtilTest.java
new file mode 100644
index 0000000..ea62ee5
--- /dev/null
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/utils/CarUxRestrictionsUtilTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.car.drivingstate.CarUxRestrictions;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class CarUxRestrictionsUtilTest {
+    private int[] mRestrictionsArray;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mRestrictionsArray = new int[]{
+                CarUxRestrictions.UX_RESTRICTIONS_NO_DIALPAD,
+                CarUxRestrictions.UX_RESTRICTIONS_NO_KEYBOARD,
+                CarUxRestrictions.UX_RESTRICTIONS_NO_DIALPAD
+                        | CarUxRestrictions.UX_RESTRICTIONS_NO_KEYBOARD,
+                CarUxRestrictions.UX_RESTRICTIONS_FULLY_RESTRICTED
+        };
+    }
+
+    @Test
+    public void testNullActiveRestriction() {
+        CarUxRestrictions activeRestrictions = null;
+        boolean[] expectedResults = {true, true, true, true};
+        for (int i = 0; i < mRestrictionsArray.length; i++) {
+            boolean actualResult = CarUxRestrictionsUtil.isRestricted(mRestrictionsArray[i],
+                    activeRestrictions);
+            assertThat(actualResult == expectedResults[i]).isTrue();
+        }
+    }
+
+    @Test
+    public void testOneActiveRestriction() {
+        CarUxRestrictions activeRestrictions = new CarUxRestrictions.Builder(/* reqOpt= */true,
+                CarUxRestrictions.UX_RESTRICTIONS_NO_DIALPAD, /* timestamp= */0).build();
+        boolean[] expectedResults = {true, false, true, true};
+        for (int i = 0; i < mRestrictionsArray.length; i++) {
+            boolean actualResult = CarUxRestrictionsUtil.isRestricted(mRestrictionsArray[i],
+                    activeRestrictions);
+            assertThat(actualResult == expectedResults[i]).isTrue();
+        }
+    }
+
+    @Test
+    public void testMultipleActiveRestrictions() {
+        CarUxRestrictions activeRestrictions = new CarUxRestrictions.Builder(/* reqOpt= */true,
+                CarUxRestrictions.UX_RESTRICTIONS_NO_DIALPAD
+                        | CarUxRestrictions.UX_RESTRICTIONS_NO_TEXT_MESSAGE, /* timestamp= */
+                0).build();
+        boolean[] expectedResults = {true, false, true, true};
+        for (int i = 0; i < mRestrictionsArray.length; i++) {
+            boolean actualResult = CarUxRestrictionsUtil.isRestricted(mRestrictionsArray[i],
+                    activeRestrictions);
+            assertThat(actualResult == expectedResults[i]).isTrue();
+        }
+    }
+}
diff --git a/car-ui-lib/tests/tools/quick_rro.py b/car-ui-lib/tests/tools/quick_rro.py
index 2e008df..aaf186b 100755
--- a/car-ui-lib/tests/tools/quick_rro.py
+++ b/car-ui-lib/tests/tools/quick_rro.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # Copyright 2019, The Android Open Source Project
 #
@@ -22,10 +22,6 @@
 import time
 from hashlib import sha1
 
-if sys.version_info[0] != 3:
-    print("Must use python 3")
-    sys.exit(1)
-
 def hex_to_letters(hex):
     """Converts numbers in a hex string to letters.
 
@@ -44,21 +40,19 @@
     """Generates a package name for the quickrro.
 
     The name is quickrro.<hash>. The hash is based on
-    all of the inputs to the RRO. (package/targetName to overlay and resources)
+    all of the inputs to the RRO. (package to overlay and resources)
     The hash will be entirely lowercase/uppercase letters, since
     android package names can't have numbers."""
-    hash = sha1(args.package.encode('UTF-8'))
-    if args.target_name:
-        hash.update(args.target_name.encode('UTF-8'))
-
+    hash = None
     if args.resources is not None:
         args.resources.sort()
-        hash.update(''.join(args.resources).encode('UTF-8'))
+        hash = sha1(''.join(args.resources) + args.package)
     else:
+        hash = sha1(args.package)
         for root, dirs, files in os.walk(args.dir):
             for file in files:
                 path = os.path.join(root, file)
-                hash.update(path.encode('UTF-8'))
+                hash.update(path)
                 with open(path, 'rb') as f:
                     while True:
                         buf = f.read(4096)
@@ -200,10 +194,7 @@
         f.write('          package="' + package_name + '">\n')
         f.write('    <application android:hasCode="false"/>\n')
         f.write('    <overlay android:priority="99"\n')
-        f.write('             android:targetPackage="' + args.package + '"\n')
-        if args.target_name is not None:
-            f.write('             android:targetName="' + args.target_name + '"\n')
-        f.write('             />\n')
+        f.write('             android:targetPackage="' + args.package + '"/>\n')
         f.write('</manifest>\n')
 
     run_command(['aapt2', 'compile', '-o', os.path.join(root_folder, 'compiled.zip'),
@@ -254,8 +245,6 @@
                         help='res folder rro')
     parser.add_argument('-p', '--package', default='com.android.car.ui.paintbooth',
                         help='The package to override. Defaults to paintbooth.')
-    parser.add_argument('-t', '--target-name',
-                        help='The name of the overlayable entry to RRO, if any.')
     parser.add_argument('--uninstall-all', action='store_true',
                         help='Uninstall all RROs created by this script')
     parser.add_argument('-I',
diff --git a/car-ui-lib/tests/unit/Android.bp b/car-ui-lib/tests/unit/Android.bp
new file mode 100644
index 0000000..da5f41d
--- /dev/null
+++ b/car-ui-lib/tests/unit/Android.bp
@@ -0,0 +1,48 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+    name: "CarUILibUnitTests",
+    certificate: "platform",
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.car"
+    ],
+    resource_dirs: [
+        "res",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.espresso.core",
+	"androidx.test.espresso.contrib",
+        "car-ui-lib",
+        "platform-test-annotations",
+        "mockito-target-inline-minus-junit4",
+        "truth-prebuilt",
+    ],
+
+    jni_libs: [
+        // For mockito extended
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+
+    // Include all test java files.
+    srcs: ["src/**/*.java"],
+
+    platform_apis: true,
+    test_suites: ["device-tests"],
+}
diff --git a/car-ui-lib/tests/unit/AndroidManifest.xml b/car-ui-lib/tests/unit/AndroidManifest.xml
new file mode 100644
index 0000000..e499db5
--- /dev/null
+++ b/car-ui-lib/tests/unit/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2020 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.car.ui.tests.unit">
+    <application android:debuggable="true">
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="com.android.car.ui.TestActivity" />
+        <activity android:name="com.android.car.ui.recyclerview.CarUiRecyclerViewTestActivity" />
+        <activity android:name="com.android.car.ui.FocusAreaTestActivity" />
+        <activity android:name="com.android.car.ui.FocusParkingViewTestActivity" />
+        <activity
+            android:name="com.android.car.ui.toolbar.ToolbarTestActivity"
+            android:theme="@style/Theme.CarUi.WithToolbar"/>
+    </application>
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.car.ui.tests.unit"
+        android:label="Chassis Test Cases">
+    </instrumentation>
+</manifest>
diff --git a/car-ui-lib/tests/unit/build.gradle b/car-ui-lib/tests/unit/build.gradle
new file mode 100644
index 0000000..2a80132
--- /dev/null
+++ b/car-ui-lib/tests/unit/build.gradle
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.5.3'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+// Library-level build file
+
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 29
+
+    defaultConfig {
+        minSdkVersion 28
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest.xml'
+            res.srcDirs = ['res']
+        }
+
+        androidTest {
+            java.srcDirs = ['src']
+        }
+    }
+
+    testOptions {
+        unitTests {
+            includeAndroidResources = true
+        }
+    }
+}
+
+dependencies {
+    implementation project(':')
+
+    androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
+    androidTestImplementation "com.google.truth:truth:0.29"
+    androidTestImplementation "androidx.test.ext:junit:1.1.1"
+    androidTestImplementation "org.mockito:mockito-core:2.19.0"
+    androidTestImplementation 'androidx.test:runner:1.1.0'
+    androidTestImplementation 'androidx.test:rules:1.1.0'
+
+    // This is needed to be able to spy certain classes with Mockito
+    // It's major/minor version must match Mockito's.
+    androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.19.0'
+
+    // This is the gradle equivalent of linking to android.car in our Android.mk
+    implementation files('../../../../../../../out/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/classes.jar')
+}
diff --git a/car-ui-lib/paintbooth/src/main/res/drawable/ic_launcher.png b/car-ui-lib/tests/unit/res/drawable/ic_launcher.png
similarity index 100%
copy from car-ui-lib/paintbooth/src/main/res/drawable/ic_launcher.png
copy to car-ui-lib/tests/unit/res/drawable/ic_launcher.png
Binary files differ
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_gone_test_activity.xml b/car-ui-lib/tests/unit/res/layout/car_ui_recycler_view_gone_test_activity.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_gone_test_activity.xml
rename to car-ui-lib/tests/unit/res/layout/car_ui_recycler_view_gone_test_activity.xml
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_invisible_test_activity.xml b/car-ui-lib/tests/unit/res/layout/car_ui_recycler_view_invisible_test_activity.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_invisible_test_activity.xml
rename to car-ui-lib/tests/unit/res/layout/car_ui_recycler_view_invisible_test_activity.xml
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_test_activity.xml b/car-ui-lib/tests/unit/res/layout/car_ui_recycler_view_test_activity.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_recycler_view_test_activity.xml
rename to car-ui-lib/tests/unit/res/layout/car_ui_recycler_view_test_activity.xml
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/empty_test_activity.xml b/car-ui-lib/tests/unit/res/layout/empty_test_activity.xml
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/androidTest/res/layout/empty_test_activity.xml
rename to car-ui-lib/tests/unit/res/layout/empty_test_activity.xml
diff --git a/car-ui-lib/tests/unit/res/layout/focus_area_test_activity.xml b/car-ui-lib/tests/unit/res/layout/focus_area_test_activity.xml
new file mode 100644
index 0000000..405bbfe
--- /dev/null
+++ b/car-ui-lib/tests/unit/res/layout/focus_area_test_activity.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <com.android.car.ui.TestFocusArea
+        android:id="@+id/focus_area"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <View
+            android:id="@+id/child"
+            android:focusable="true"
+            android:layout_width="10dp"
+            android:layout_height="10dp"/>
+    </com.android.car.ui.TestFocusArea>
+    <View
+        android:id="@+id/non_child"
+        android:focusable="true"
+        android:layout_width="10dp"
+        android:layout_height="10dp"/>
+</LinearLayout>
diff --git a/car-ui-lib/tests/unit/res/layout/focus_parking_view_test_activity.xml b/car-ui-lib/tests/unit/res/layout/focus_parking_view_test_activity.xml
new file mode 100644
index 0000000..f3f623d
--- /dev/null
+++ b/car-ui-lib/tests/unit/res/layout/focus_parking_view_test_activity.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <!-- In some cases Android will focus the first focusable view automatically. To prevent the
+         FocusParkingView getting focused unintentionally, we put a focusable Button above the
+         FocusParkingView. -->
+    <Button
+        android:layout_width="100dp"
+        android:layout_height="40dp"/>
+    <com.android.car.ui.FocusParkingView
+        android:id="@+id/focus_parking"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+</FrameLayout>
diff --git a/car-ui-lib/tests/unit/res/layout/test_list_item.xml b/car-ui-lib/tests/unit/res/layout/test_list_item.xml
new file mode 100644
index 0000000..e789145
--- /dev/null
+++ b/car-ui-lib/tests/unit/res/layout/test_list_item.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="10dp"
+        android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body"
+        android:id="@+id/text" />
+
+</LinearLayout>
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/FocusAreaTest.java b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusAreaTest.java
new file mode 100644
index 0000000..8b2ddc1
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusAreaTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui;
+
+import static org.junit.Assert.assertTrue;
+
+import android.view.View;
+
+import androidx.test.rule.ActivityTestRule;
+
+import com.android.car.ui.tests.unit.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/** Unit tests for {@link FocusArea}. */
+public class FocusAreaTest {
+    private static final long WAIT_TIME_MS = 3000;
+
+    @Rule
+    public ActivityTestRule<FocusAreaTestActivity> mActivityRule =
+            new ActivityTestRule<>(FocusAreaTestActivity.class);
+
+    private FocusAreaTestActivity mActivity;
+    private TestFocusArea mFocusArea;
+    private View mChild;
+    private View mNonChild;
+
+    @Before
+    public void setUp() {
+        mActivity = mActivityRule.getActivity();
+        mFocusArea = mActivity.findViewById(R.id.focus_area);
+        mChild = mActivity.findViewById(R.id.child);
+        mNonChild = mActivity.findViewById(R.id.non_child);
+    }
+
+    @Test
+    public void testLoseFocus() throws Exception {
+        mChild.post(() -> {
+            mChild.requestFocus();
+        });
+        mFocusArea.setOnDrawCalled(false);
+        mFocusArea.setDrawCalled(false);
+
+        // FocusArea lost focus.
+        CountDownLatch latch = new CountDownLatch(1);
+        mNonChild.post(() -> {
+            mNonChild.requestFocus();
+            mNonChild.post(() -> {
+                latch.countDown();
+            });
+        });
+        assertDrawMethodsCalled(latch);
+    }
+
+    @Test
+    public void testGetFocus() throws Exception {
+        mNonChild.post(() -> {
+            mNonChild.requestFocus();
+        });
+        mFocusArea.setOnDrawCalled(false);
+        mFocusArea.setDrawCalled(false);
+
+        // FocusArea got focus.
+        CountDownLatch latch = new CountDownLatch(1);
+        mChild.post(() -> {
+            mChild.requestFocus();
+            mChild.post(() -> {
+                latch.countDown();
+            });
+        });
+        assertDrawMethodsCalled(latch);
+    }
+
+    private void assertDrawMethodsCalled(CountDownLatch latch) throws Exception {
+        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+        assertTrue(mFocusArea.onDrawCalled());
+        assertTrue(mFocusArea.drawCalled());
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/FocusAreaTestActivity.java b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusAreaTestActivity.java
new file mode 100644
index 0000000..f027db6
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusAreaTestActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.tests.unit.R;
+
+/** An activity used for testing {@link FocusArea}. */
+public class FocusAreaTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.focus_area_test_activity);
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/FocusParkingViewTest.java b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusParkingViewTest.java
new file mode 100644
index 0000000..52236bd
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusParkingViewTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.rule.ActivityTestRule;
+
+import com.android.car.ui.tests.unit.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/** Unit test for {@link FocusParkingView}. */
+public class FocusParkingViewTest {
+
+    private static final long WAIT_TIME_MS = 3000;
+
+    @Rule
+    public ActivityTestRule<FocusParkingViewTestActivity> mActivityRule =
+            new ActivityTestRule<>(FocusParkingViewTestActivity.class);
+
+    private FocusParkingViewTestActivity mActivity;
+
+    @Before
+    public void setUp() {
+        mActivity = mActivityRule.getActivity();
+    }
+
+    @Test
+    public void testFocusParkingViewCanTakeFocus() throws Exception {
+        FocusParkingView focusParkingView = mActivity.findViewById(R.id.focus_parking);
+
+        CountDownLatch latch = new CountDownLatch(1);
+        focusParkingView.post(() -> {
+            focusParkingView.requestFocus();
+            focusParkingView.post(() -> {
+                latch.countDown();
+            });
+        });
+        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+
+        assertThat(focusParkingView.isFocused()).isTrue();
+    }
+    @Test
+    public void testFocusParkingViewFocusedWhenWindowLostFocus() throws Exception {
+        FocusParkingView focusParkingView = mActivity.findViewById(R.id.focus_parking);
+        assertThat(focusParkingView.isFocused()).isFalse();
+
+        CountDownLatch latch = new CountDownLatch(1);
+        focusParkingView.post(() -> {
+            focusParkingView.onWindowFocusChanged(false);
+            focusParkingView.post(() -> {
+                latch.countDown();
+            });
+        });
+        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+
+        assertThat(focusParkingView.isFocused()).isTrue();
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/FocusParkingViewTestActivity.java b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusParkingViewTestActivity.java
new file mode 100644
index 0000000..9357ca6
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/FocusParkingViewTestActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.tests.unit.R;
+
+
+/** An Activity used for testing {@link FocusParkingView}. */
+public class FocusParkingViewTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.focus_parking_view_test_activity);
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/TestActivity.java b/car-ui-lib/tests/unit/src/com/android/car/ui/TestActivity.java
new file mode 100644
index 0000000..db8c560
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/TestActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.tests.unit.R;
+
+/**
+ * An empty activity to be used for testing.
+ */
+public class TestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.empty_test_activity);
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/TestFocusArea.java b/car-ui-lib/tests/unit/src/com/android/car/ui/TestFocusArea.java
new file mode 100644
index 0000000..092624f
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/TestFocusArea.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+
+import androidx.annotation.Nullable;
+
+/** A {@link FocusArea} used for testing. */
+public class TestFocusArea extends FocusArea {
+
+    /** Whether {@link #onDraw(Canvas)} was called. */
+    private boolean mOnDrawCalled;
+
+    /** Whether {@link #draw(Canvas)} was called. */
+    private boolean mDrawCalled;
+
+    public TestFocusArea(Context context) {
+        super(context);
+    }
+
+    public TestFocusArea(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public TestFocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public TestFocusArea(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        mOnDrawCalled = true;
+        super.onDraw(canvas);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        mDrawCalled = true;
+        super.draw(canvas);
+    }
+
+    public boolean onDrawCalled() {
+        return mOnDrawCalled;
+    }
+
+    public void setOnDrawCalled(boolean onDrawCalled) {
+        mOnDrawCalled = onDrawCalled;
+    }
+
+    public boolean drawCalled() {
+        return mDrawCalled;
+    }
+
+    public void setDrawCalled(boolean drawCalled) {
+        mDrawCalled = drawCalled;
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/LowLevelActions.java b/car-ui-lib/tests/unit/src/com/android/car/ui/actions/LowLevelActions.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/LowLevelActions.java
rename to car-ui-lib/tests/unit/src/com/android/car/ui/actions/LowLevelActions.java
diff --git a/car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/actions/ViewActions.java b/car-ui-lib/tests/unit/src/com/android/car/ui/actions/ViewActions.java
similarity index 100%
rename from car-ui-lib/car-rotary-lib/src/androidTest/java/com/android/car/ui/actions/ViewActions.java
rename to car-ui-lib/tests/unit/src/com/android/car/ui/actions/ViewActions.java
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/WaitForViewAction.java b/car-ui-lib/tests/unit/src/com/android/car/ui/actions/WaitForViewAction.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/actions/WaitForViewAction.java
rename to car-ui-lib/tests/unit/src/com/android/car/ui/actions/WaitForViewAction.java
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/matchers/DrawableMatcher.java b/car-ui-lib/tests/unit/src/com/android/car/ui/matchers/DrawableMatcher.java
new file mode 100644
index 0000000..4c0d9bb
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/matchers/DrawableMatcher.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.matchers;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.ImageView;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+
+/* package */ class DrawableMatcher extends TypeSafeMatcher<View> {
+
+    private final int mDrawableId;
+
+    DrawableMatcher(int drawableId) {
+        mDrawableId = drawableId;
+    }
+
+    @Override
+    protected boolean matchesSafely(View item) {
+        if (!(item instanceof ImageView) || !item.isShown()) {
+            return false;
+        }
+
+        ImageView imageView = (ImageView) item;
+
+        Bitmap bitmap = drawableToBitmap(imageView.getDrawable());
+        Bitmap otherBitmap = drawableToBitmap(imageView.getContext().getDrawable(mDrawableId));
+
+        if (bitmap == null && otherBitmap == null) {
+            return true;
+        } else if ((bitmap == null) != (otherBitmap == null)) {
+            return false;
+        }
+
+        return bitmap.sameAs(otherBitmap);
+    }
+
+    private Bitmap drawableToBitmap(Drawable drawable) {
+        if (drawable == null) {
+            return null;
+        }
+
+        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
+                drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+        drawable.draw(canvas);
+        return bitmap;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText("has drawable with id " + mDrawableId);
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/NthChildMatcher.java b/car-ui-lib/tests/unit/src/com/android/car/ui/matchers/NthChildMatcher.java
similarity index 100%
rename from car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/NthChildMatcher.java
rename to car-ui-lib/tests/unit/src/com/android/car/ui/matchers/NthChildMatcher.java
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/matchers/ViewMatchers.java b/car-ui-lib/tests/unit/src/com/android/car/ui/matchers/ViewMatchers.java
new file mode 100644
index 0000000..1bee2e0
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/matchers/ViewMatchers.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.matchers;
+
+import android.view.View;
+
+import org.hamcrest.Matcher;
+
+public class ViewMatchers {
+    public static Matcher<View> withDrawable(int drawableId) {
+        return new DrawableMatcher(drawableId);
+    }
+
+    public static Matcher<View> nthChildOfView(Matcher<View> parentMatcher, int n) {
+        return new NthChildMatcher(parentMatcher, n);
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiListItemTest.java b/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiListItemTest.java
new file mode 100644
index 0000000..d5f5d13
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiListItemTest.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isNotChecked;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.view.View;
+
+import androidx.test.rule.ActivityTestRule;
+
+import com.android.car.ui.tests.unit.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.ArgumentMatchers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Unit tests for {@link CarUiListItem}. */
+public class CarUiListItemTest {
+
+    private CarUiRecyclerView mCarUiRecyclerView;
+
+    @Rule
+    public ActivityTestRule<CarUiRecyclerViewTestActivity> mActivityRule =
+            new ActivityTestRule<>(CarUiRecyclerViewTestActivity.class);
+
+    @Before
+    public void setUp() {
+        mCarUiRecyclerView = mActivityRule.getActivity().requireViewById(R.id.list);
+    }
+
+    @Test
+    public void testItemVisibility_withTitle() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test title");
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.title)).check(matches(isDisplayed()));
+        onView(withId(R.id.body)).check(matches(not(isDisplayed())));
+        onView(withId(R.id.icon_container)).check(matches(not(isDisplayed())));
+        onView(withId(R.id.action_container)).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    public void testItemVisibility_withBody() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setBody("Test body");
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.body)).check(matches(isDisplayed()));
+        onView(withId(R.id.title)).check(matches(not(isDisplayed())));
+        onView(withId(R.id.icon_container)).check(matches(not(isDisplayed())));
+        onView(withId(R.id.action_container)).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    public void testItemVisibility_withTitle_withBodyAndIcon() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+        item.setTitle("Test title");
+        item.setBody("Test body");
+        item.setIcon(mActivityRule.getActivity().getDrawable(R.drawable.car_ui_icon_close));
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.title)).check(matches(isDisplayed()));
+        onView(withId(R.id.body)).check(matches(isDisplayed()));
+        onView(withId(R.id.icon_container)).check(matches(isDisplayed()));
+        onView(withId(R.id.action_container)).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    public void testItem_withCheckbox() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem.OnCheckedChangeListener mockOnCheckedChangeListener = mock(
+                CarUiContentListItem.OnCheckedChangeListener.class);
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
+        item.setTitle("Test item with checkbox");
+        item.setOnCheckedChangeListener(mockOnCheckedChangeListener);
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.title)).check(matches(isDisplayed()));
+        onView(withId(R.id.checkbox_widget)).check(matches(isDisplayed()));
+        onView(withId(R.id.action_divider)).check(matches(not(isDisplayed())));
+
+        // List item with checkbox should be initially unchecked.
+        onView(withId(R.id.checkbox_widget)).check(matches(isNotChecked()));
+        // Clicks anywhere on the item should toggle the checkbox
+        onView(withId(R.id.title)).perform(click());
+        onView(withId(R.id.checkbox_widget)).check(matches(isChecked()));
+        // Check that onCheckChangedListener was invoked.
+        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, true);
+
+        // Uncheck checkbox with click on the action container
+        onView(withId(R.id.action_container)).perform(click());
+        onView(withId(R.id.checkbox_widget)).check(matches(isNotChecked()));
+        // Check that onCheckChangedListener was invoked.
+        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, false);
+    }
+
+    @Test
+    public void testItem_withSwitch() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
+        item.setBody("Test item with switch");
+        item.setChecked(true);
+        item.setActionDividerVisible(true);
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.body)).check(matches(isDisplayed()));
+        onView(withId(R.id.switch_widget)).check(matches(isDisplayed()));
+        onView(withId(R.id.action_divider)).check(matches(isDisplayed()));
+
+        // List item with checkbox should be initially checked.
+        onView(withId(R.id.switch_widget)).check(matches(isChecked()));
+        // Clicks anywhere on the item should toggle the switch
+        onView(withId(R.id.switch_widget)).perform(click());
+        onView(withId(R.id.switch_widget)).check(matches(isNotChecked()));
+        // Uncheck checkbox with click on the action container
+        onView(withId(R.id.body)).perform(click());
+        onView(withId(R.id.switch_widget)).check(matches(isChecked()));
+    }
+
+    @Test
+    public void testItem_withRadioButton() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem item = new CarUiContentListItem(
+                CarUiContentListItem.Action.RADIO_BUTTON);
+        item.setTitle("Test item with radio button");
+        item.setChecked(false);
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.title)).check(matches(isDisplayed()));
+        onView(withId(R.id.radio_button_widget)).check(matches(isDisplayed()));
+
+        // List item with checkbox should be initially not checked.
+        onView(withId(R.id.radio_button_widget)).check(matches(isNotChecked()));
+        // Clicks anywhere on the item should toggle the radio button.
+        onView(withId(R.id.radio_button_widget)).perform(click());
+        onView(withId(R.id.radio_button_widget)).check(matches(isChecked()));
+
+        // Repeated clicks on a selected radio button should not toggle the element once checked.
+        onView(withId(R.id.title)).perform(click());
+        onView(withId(R.id.radio_button_widget)).check(matches(isChecked()));
+    }
+
+    @Test
+    public void testItem_withListener() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem.OnClickListener mockOnCheckedChangeListener = mock(
+                CarUiContentListItem.OnClickListener.class);
+
+        CarUiContentListItem item = new CarUiContentListItem(
+                CarUiContentListItem.Action.NONE);
+        item.setIcon(mActivityRule.getActivity().getDrawable(R.drawable.car_ui_icon_close));
+        item.setTitle("Test item with listener");
+        item.setBody("Body text");
+        item.setOnItemClickedListener(mockOnCheckedChangeListener);
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.title)).check(matches(isDisplayed()));
+
+        // Clicks anywhere on the item should toggle the listener
+        onView(withId(R.id.title)).perform(click());
+        verify(mockOnCheckedChangeListener, times(1)).onClick(item);
+
+        onView(withId(R.id.body)).perform(click());
+        verify(mockOnCheckedChangeListener, times(2)).onClick(item);
+
+        onView(withId(R.id.icon_container)).perform(click());
+        verify(mockOnCheckedChangeListener, times(3)).onClick(item);
+    }
+
+    @Test
+    public void testItem_withSupplementalIconAndIconOnClickListener() {
+        List<CarUiListItem> items = new ArrayList<>();
+
+        CarUiContentListItem.OnClickListener mockedItemOnClickListener = mock(
+                CarUiContentListItem.OnClickListener.class);
+        View.OnClickListener mockedIconListener = mock(View.OnClickListener.class);
+
+        CarUiContentListItem item = new CarUiContentListItem(
+                CarUiContentListItem.Action.ICON);
+        item.setSupplementalIcon(
+                mActivityRule.getActivity().getDrawable(R.drawable.car_ui_icon_close),
+                mockedIconListener);
+        item.setOnItemClickedListener(mockedItemOnClickListener);
+        item.setTitle("Test item with listeners");
+        items.add(item);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));
+
+        onView(withId(R.id.title)).check(matches(isDisplayed()));
+
+        // Clicks anywhere on the item (outside of the icon) should only invoke the item click
+        // listener.
+        onView(withId(R.id.title)).perform(click());
+        verify(mockedItemOnClickListener, times(1)).onClick(item);
+
+        // Clicks anywhere on the icon should invoke both listeners.
+        onView(withId(R.id.action_container)).perform(click());
+        verify(mockedItemOnClickListener, times(2)).onClick(item);
+        verify(mockedIconListener, times(1)).onClick(ArgumentMatchers.any(View.class));
+    }
+
+    @Test
+    public void testRadioButtonListItemAdapter() {
+        List<CarUiRadioButtonListItem> items = new ArrayList<>();
+
+        CarUiRadioButtonListItem itemOne = new CarUiRadioButtonListItem();
+        String itemOneTitle = "Item 1";
+        itemOne.setTitle(itemOneTitle);
+        items.add(itemOne);
+
+        CarUiRadioButtonListItem itemTwo = new CarUiRadioButtonListItem();
+        String itemTwoTitle = "Item 2";
+        itemTwo.setTitle(itemTwoTitle);
+        items.add(itemTwo);
+
+        CarUiRadioButtonListItem itemThree = new CarUiRadioButtonListItem();
+        String itemThreeTitle = "Item 3";
+        itemThree.setTitle(itemThreeTitle);
+        items.add(itemThree);
+
+        mCarUiRecyclerView.post(
+                () -> mCarUiRecyclerView.setAdapter(new CarUiRadioButtonListItemAdapter(items)));
+
+        onView(withText(itemOneTitle)).check(matches(isDisplayed()));
+        onView(withText(itemTwoTitle)).check(matches(isDisplayed()));
+        onView(withText(itemThreeTitle)).check(matches(isDisplayed()));
+
+        // All items are initially unchecked.
+        assertFalse(itemOne.isChecked());
+        assertFalse(itemTwo.isChecked());
+        assertFalse(itemThree.isChecked());
+
+        // Select first item.
+        onView(withText(itemOneTitle)).perform(click());
+        assertTrue(itemOne.isChecked());
+        assertFalse(itemTwo.isChecked());
+        assertFalse(itemThree.isChecked());
+
+        // Select second item.
+        onView(withText(itemTwoTitle)).perform(click());
+        assertFalse(itemOne.isChecked());
+        assertTrue(itemTwo.isChecked());
+        assertFalse(itemThree.isChecked());
+
+        // Select third item.
+        onView(withText(itemThreeTitle)).perform(click());
+        assertFalse(itemOne.isChecked());
+        assertFalse(itemTwo.isChecked());
+        assertTrue(itemThree.isChecked());
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java b/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
new file mode 100644
index 0000000..568395d
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
@@ -0,0 +1,864 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.PositionAssertions.isBottomAlignedWith;
+import static androidx.test.espresso.assertion.PositionAssertions.isCompletelyAbove;
+import static androidx.test.espresso.assertion.PositionAssertions.isLeftAlignedWith;
+import static androidx.test.espresso.assertion.PositionAssertions.isRightAlignedWith;
+import static androidx.test.espresso.assertion.PositionAssertions.isTopAlignedWith;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition;
+import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
+import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.android.car.ui.actions.LowLevelActions.performDrag;
+import static com.android.car.ui.actions.LowLevelActions.pressAndHold;
+import static com.android.car.ui.actions.LowLevelActions.release;
+import static com.android.car.ui.actions.LowLevelActions.touchDownAndUp;
+import static com.android.car.ui.actions.ViewActions.waitForView;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThan;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.espresso.IdlingRegistry;
+import androidx.test.espresso.IdlingResource;
+import androidx.test.rule.ActivityTestRule;
+
+import com.android.car.ui.TestActivity;
+import com.android.car.ui.tests.unit.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Unit tests for {@link CarUiRecyclerView}. */
+public class CarUiRecyclerViewTest {
+
+    @Rule
+    public ActivityTestRule<TestActivity> mActivityRule =
+            new ActivityTestRule<>(TestActivity.class);
+
+    private TestActivity mActivity;
+    private Context mTestableContext;
+    private Resources mTestableResources;
+
+    @Before
+    public void setUp() {
+        mActivity = mActivityRule.getActivity();
+        mTestableContext = spy(mActivity);
+        mTestableResources = spy(mActivity.getResources());
+        when(mTestableContext.getResources()).thenReturn(mTestableResources);
+    }
+
+    @After
+    public void tearDown() {
+        for (IdlingResource idlingResource : IdlingRegistry.getInstance().getResources()) {
+            IdlingRegistry.getInstance().unregister(idlingResource);
+        }
+    }
+
+    @Test
+    public void testIsScrollbarPresent_scrollbarEnabled() {
+        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
+        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+        ViewGroup container = mActivity.findViewById(R.id.test_container);
+        container.post(() -> {
+            container.addView(carUiRecyclerView);
+            carUiRecyclerView.setAdapter(new TestAdapter(100));
+        });
+
+        onView(withId(R.id.car_ui_scroll_bar)).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testIsScrollbarPresent_scrollbarDisabled() {
+        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
+        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+        ViewGroup container = mActivity.findViewById(R.id.test_container);
+        container.post(() -> {
+            container.addView(carUiRecyclerView);
+            carUiRecyclerView.setAdapter(new TestAdapter(100));
+        });
+
+        onView(withId(R.id.car_ui_scroll_bar)).check(doesNotExist());
+    }
+
+    @Test
+    public void testGridLayout() {
+        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
+                null, R.styleable.CarUiRecyclerView));
+
+        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
+                any(),
+                eq(R.styleable.CarUiRecyclerView),
+                anyInt(),
+                anyInt());
+        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_layoutStyle), anyInt()))
+                .thenReturn(CarUiRecyclerView.CarUiRecyclerViewLayout.GRID);
+        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_numOfColumns), anyInt()))
+                .thenReturn(3);
+
+        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+        ViewGroup container = mActivity.findViewById(R.id.test_container);
+        TestAdapter adapter = new TestAdapter(4);
+        container.post(() -> {
+            container.addView(carUiRecyclerView);
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        assertTrue(carUiRecyclerView.getLayoutManager() instanceof GridLayoutManager);
+
+        // Check that all items in the first row are top-aligned.
+        onView(withText(adapter.getItemText(0))).check(
+                isTopAlignedWith(withText(adapter.getItemText(1))));
+        onView(withText(adapter.getItemText(1))).check(
+                isTopAlignedWith(withText(adapter.getItemText(2))));
+
+        // Check that all items in the first row are bottom-aligned.
+        onView(withText(adapter.getItemText(0))).check(
+                isBottomAlignedWith(withText(adapter.getItemText(1))));
+        onView(withText(adapter.getItemText(1))).check(
+                isBottomAlignedWith(withText(adapter.getItemText(2))));
+
+        // Check that items in second row are rendered correctly below the first row.
+        onView(withText(adapter.getItemText(0))).check(
+                isCompletelyAbove(withText(adapter.getItemText(3))));
+        onView(withText(adapter.getItemText(0))).check(
+                isLeftAlignedWith(withText(adapter.getItemText(3))));
+        onView(withText(adapter.getItemText(0))).check(
+                isRightAlignedWith(withText(adapter.getItemText(3))));
+    }
+
+    @Test
+    public void testLinearLayout() {
+        TypedArray typedArray = spy(mActivity.getBaseContext().obtainStyledAttributes(
+                null, R.styleable.CarUiRecyclerView));
+
+        doReturn(typedArray).when(mTestableContext).obtainStyledAttributes(
+                any(),
+                eq(R.styleable.CarUiRecyclerView),
+                anyInt(),
+                anyInt());
+        when(typedArray.getInt(eq(R.styleable.CarUiRecyclerView_layoutStyle), anyInt()))
+                .thenReturn(CarUiRecyclerView.CarUiRecyclerViewLayout.LINEAR);
+
+        CarUiRecyclerView carUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+        ViewGroup container = mActivity.findViewById(R.id.test_container);
+        TestAdapter adapter = new TestAdapter(4);
+        container.post(() -> {
+            container.addView(carUiRecyclerView);
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        assertTrue(carUiRecyclerView.getLayoutManager() instanceof LinearLayoutManager);
+
+        // Check that item views are laid out linearly.
+        onView(withText(adapter.getItemText(0))).check(
+                isCompletelyAbove(withText(adapter.getItemText(1))));
+        onView(withText(adapter.getItemText(1))).check(
+                isCompletelyAbove(withText(adapter.getItemText(2))));
+        onView(withText(adapter.getItemText(2))).check(
+                isCompletelyAbove(withText(adapter.getItemText(3))));
+    }
+
+    @Test
+    public void testOnHeightChanged_shouldAddTheValueToInitialTopValue() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.findViewById(R.id.list);
+
+        assertEquals(carUiRecyclerView.getPaddingBottom(), 0);
+        assertEquals(carUiRecyclerView.getPaddingTop(), 0);
+        assertEquals(carUiRecyclerView.getPaddingStart(), 0);
+        assertEquals(carUiRecyclerView.getPaddingEnd(), 0);
+
+        mActivity.runOnUiThread(() -> carUiRecyclerView.onHeightChanged(10));
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        assertEquals(carUiRecyclerView.getPaddingTop(), 10);
+        assertEquals(carUiRecyclerView.getPaddingBottom(), 0);
+        assertEquals(carUiRecyclerView.getPaddingStart(), 0);
+        assertEquals(carUiRecyclerView.getPaddingEnd(), 0);
+    }
+
+    @Test
+    public void testVisibility_goneAtInflationWithChangeToVisible() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(
+                        R.layout.car_ui_recycler_view_gone_test_activity));
+
+        onView(withId(R.id.list)).check(matches(not(isDisplayed())));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(3);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+            carUiRecyclerView.setVisibility(View.VISIBLE);
+        });
+
+        // Check that items in are displayed.
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+        onView(withText(adapter.getItemText(1))).check(matches(isDisplayed()));
+        onView(withText(adapter.getItemText(2))).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testVisibility_invisibleAtInflationWithChangeToVisible() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(
+                        R.layout.car_ui_recycler_view_invisible_test_activity));
+
+        onView(withId(R.id.list)).check(matches(not(isDisplayed())));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(3);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+            carUiRecyclerView.setVisibility(View.VISIBLE);
+        });
+
+        // Check that items in are displayed.
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+        onView(withText(adapter.getItemText(1))).check(matches(isDisplayed()));
+        onView(withText(adapter.getItemText(2))).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testFirstItemAtTop_onInitialLoad() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(25);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+
+        LinearLayoutManager layoutManager =
+                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
+        assertEquals(layoutManager.findFirstVisibleItemPosition(), 0);
+    }
+
+    @Test
+    public void testPageUpAndDownMoveSameDistance() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(50);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+
+        LinearLayoutManager layoutManager =
+                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
+
+        // Move down one page so there will be sufficient pages for up and downs.
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+
+        int topPosition = layoutManager.findFirstVisibleItemPosition();
+
+        for (int i = 0; i < 3; i++) {
+            onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+            onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
+        }
+
+        assertEquals(layoutManager.findFirstVisibleItemPosition(), topPosition);
+    }
+
+    @Test
+    public void testContinuousScroll() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(50);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+
+        LinearLayoutManager layoutManager =
+                (LinearLayoutManager) carUiRecyclerView.getLayoutManager();
+
+        // Press and hold the down button for 2 seconds to scroll the list to bottom.
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(pressAndHold());
+        onView(isRoot()).perform(waitForView(withText("Sample item #49"), 3000));
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(release());
+
+        assertEquals(layoutManager.findLastCompletelyVisibleItemPosition(), 49);
+    }
+
+    @Test
+    public void testAlphaJumpToMiddleForThumbWhenTrackClicked() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(50);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+
+        View trackView = mActivity.requireViewById(R.id.car_ui_scrollbar_track);
+        // scroll to the middle
+        onView(withId(R.id.car_ui_scrollbar_track)).perform(
+                touchDownAndUp(0f, (trackView.getHeight() / 2f)));
+        onView(withText(adapter.getItemText(25))).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testAlphaJumpToEndAndStartForThumbWhenTrackClicked() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(50);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+
+        View trackView = mActivity.requireViewById(R.id.car_ui_scrollbar_track);
+        View thumbView = mActivity.requireViewById(R.id.car_ui_scrollbar_thumb);
+        // scroll to the end
+        onView(withId(R.id.car_ui_scrollbar_track)).perform(
+                touchDownAndUp(0f, trackView.getHeight() - 1));
+        onView(withText(adapter.getItemText(49))).check(matches(isDisplayed()));
+
+        // scroll to the start
+        onView(withId(R.id.car_ui_scrollbar_track)).perform(
+                touchDownAndUp(0f, (thumbView.getHeight() / 2f) + 1));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testThumbDragToCenter() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(50);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
+
+        View trackView = mActivity.requireViewById(R.id.car_ui_scrollbar_track);
+        View thumbView = mActivity.requireViewById(R.id.car_ui_scrollbar_thumb);
+        // drag and scroll to the middle
+        onView(withId(R.id.car_ui_scrollbar_track)).perform(
+                performDrag(0f, (thumbView.getHeight() / 2f), 0,
+                        (thumbView.getHeight() / 2f) - 1, 10, Float.MAX_VALUE,
+                        trackView.getHeight() / 2f));
+        onView(withText(adapter.getItemText(25))).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testPageUpButtonDisabledAtTop() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        TestAdapter adapter = new TestAdapter(15);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+
+        // Initially page_up button is disabled.
+        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(not(isEnabled())));
+
+        // Moving down, should enable the up bottom.
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+        onView(withId(R.id.car_ui_scrollbar_page_up)).check(matches(isEnabled()));
+
+        // Move back up; this should disable the up button again.
+        onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click()).check(
+                matches(not(isEnabled())));
+    }
+
+    @Test
+    public void testPageDownScrollsOverLongItem() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        int itemCount = 100;
+        // Position the long item in the middle.
+        int longItemPosition = itemCount / 2;
+
+        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
+        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.TALL);
+        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+
+        OrientationHelper orientationHelper =
+                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
+
+        int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+        // Scroll to a position where long item is partially visible.
+        // Scrolling from top, scrollToPosition() aligns the pos-1 item to bottom.
+        onView(withId(R.id.list)).perform(scrollToPosition(longItemPosition - 1));
+        // Scroll by half the height of the screen so the long item is partially visible.
+        mActivity.runOnUiThread(() -> carUiRecyclerView.scrollBy(0, screenHeight / 2));
+
+        onView(withText(adapter.getItemText(longItemPosition))).check(matches(isDisplayed()));
+
+        // Verify long item is partially shown.
+        View longItem = getLongItem(carUiRecyclerView);
+        assertThat(
+                orientationHelper.getDecoratedStart(longItem),
+                is(greaterThan(carUiRecyclerView.getTop())));
+
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+
+        // Verify long item is snapped to top.
+        assertThat(orientationHelper.getDecoratedStart(longItem), is(equalTo(0)));
+        assertThat(orientationHelper.getDecoratedEnd(longItem),
+                is(greaterThan(carUiRecyclerView.getBottom())));
+
+        // Set a limit to avoid test stuck in non-moving state.
+        while (orientationHelper.getDecoratedEnd(longItem) > carUiRecyclerView.getBottom()) {
+            onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+        }
+
+        // Verify long item end is aligned to bottom.
+        assertThat(orientationHelper.getDecoratedEnd(longItem),
+                is(equalTo(carUiRecyclerView.getHeight())));
+
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+        // Verify that the long item is no longer visible; Should be on the next child
+        assertThat(
+                orientationHelper.getDecoratedStart(longItem),
+                is(lessThan(carUiRecyclerView.getTop())));
+    }
+
+    @Test
+    public void testPageUpScrollsOverLongItem() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        int itemCount = 100;
+        // Position the long item in the middle.
+        int longItemPosition = itemCount / 2;
+
+        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
+        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.TALL);
+        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+
+        OrientationHelper orientationHelper =
+                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
+
+        // Scroll to a position just below the long item.
+        onView(withId(R.id.list)).perform(scrollToPosition(longItemPosition + 1));
+
+        // Verify long item is off-screen.
+        View longItem = getLongItem(carUiRecyclerView);
+        assertThat(
+                orientationHelper.getDecoratedEnd(longItem),
+                is(greaterThan(carUiRecyclerView.getTop())));
+
+        onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
+
+        // Verify long item is snapped to bottom.
+        assertThat(orientationHelper.getDecoratedEnd(longItem),
+                is(equalTo(carUiRecyclerView.getHeight())));
+        assertThat(orientationHelper.getDecoratedStart(longItem), is(lessThan(0)));
+
+
+        int decoratedStart = orientationHelper.getDecoratedStart(longItem);
+
+        while (decoratedStart < 0) {
+            onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
+            decoratedStart = orientationHelper.getDecoratedStart(longItem);
+        }
+
+        // Verify long item top is aligned to top.
+        assertThat(orientationHelper.getDecoratedStart(longItem), is(equalTo(0)));
+    }
+
+    @Test
+    public void testPageDownScrollsOverVeryLongItem() {
+        mActivity.runOnUiThread(
+                () -> mActivity.setContentView(R.layout.car_ui_recycler_view_test_activity));
+
+        onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+        int itemCount = 100;
+        // Position the long item in the middle.
+        int longItemPosition = itemCount / 2;
+
+        Map<Integer, TestAdapter.ItemHeight> heightOverrides = new HashMap<>();
+        heightOverrides.put(longItemPosition, TestAdapter.ItemHeight.EXTRA_TALL);
+        TestAdapter adapter = new TestAdapter(itemCount, heightOverrides);
+
+        CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+        mActivity.runOnUiThread(() -> {
+            carUiRecyclerView.setAdapter(adapter);
+        });
+
+        IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+
+        OrientationHelper orientationHelper =
+                OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
+
+        int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+        // Scroll to a position where long item is partially visible.
+        // Scrolling from top, scrollToPosition() aligns the pos-1 item to bottom.
+        onView(withId(R.id.list)).perform(scrollToPosition(longItemPosition - 1));
+        // Scroll by half the height of the screen so the long item is partially visible.
+        mActivity.runOnUiThread(() -> carUiRecyclerView.scrollBy(0, screenHeight / 2));
+
+        onView(withText(adapter.getItemText(longItemPosition))).check(matches(isDisplayed()));
+
+        // Verify long item is partially shown.
+        View longItem = getLongItem(carUiRecyclerView);
+        assertThat(
+                orientationHelper.getDecoratedStart(longItem),
+                is(greaterThan(carUiRecyclerView.getTop())));
+
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+
+        // Verify long item is snapped to top.
+        assertThat(orientationHelper.getDecoratedStart(longItem), is(equalTo(0)));
+        assertThat(orientationHelper.getDecoratedEnd(longItem),
+                is(greaterThan(carUiRecyclerView.getBottom())));
+
+        onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
+
+        // Verify long item does not snap to bottom.
+        assertThat(orientationHelper.getDecoratedEnd(longItem),
+                not(equalTo(carUiRecyclerView.getHeight())));
+    }
+
+
+    @Test
+    public void testSetPaddingToRecyclerViewContainerWithScrollbar() {
+        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
+
+        CarUiRecyclerView mCarUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
+
+        mCarUiRecyclerView.setPadding(10, 10, 10, 10);
+
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
+    }
+
+    @Test
+    public void testSetPaddingToRecyclerViewContainerWithoutScrollbar() {
+        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
+
+        CarUiRecyclerView mCarUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
+
+        mCarUiRecyclerView.setPadding(10, 10, 10, 10);
+
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(10)));
+    }
+
+    @Test
+    public void testSetPaddingRelativeToRecyclerViewContainerWithScrollbar() {
+        doReturn(true).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
+
+        CarUiRecyclerView mCarUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
+
+        mCarUiRecyclerView.setPaddingRelative(10, 10, 10, 10);
+
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
+    }
+
+    @Test
+    public void testSetPaddingRelativeToRecyclerViewContainerWithoutScrollbar() {
+        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
+
+        CarUiRecyclerView mCarUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(0)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(0)));
+
+        mCarUiRecyclerView.setPaddingRelative(10, 10, 10, 10);
+
+        assertThat(mCarUiRecyclerView.getPaddingTop(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingBottom(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingStart(), is(equalTo(10)));
+        assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(10)));
+    }
+
+    /**
+     * Returns an item in the current list view whose height is taller than that of
+     * the CarUiRecyclerView. If that item exists, then it is returned; otherwise an {@link
+     * IllegalStateException} is thrown.
+     *
+     * @return An item that is taller than the CarUiRecyclerView.
+     */
+    private View getLongItem(CarUiRecyclerView recyclerView) {
+        for (int i = 0; i < recyclerView.getChildCount(); i++) {
+            View item = recyclerView.getChildAt(i);
+
+            if (item.getHeight() > recyclerView.getHeight()) {
+                return item;
+            }
+        }
+
+        throw new IllegalStateException(
+                "No item found that is longer than the height of the CarUiRecyclerView.");
+    }
+
+    /** A test adapter that handles inflating test views and binding data to it. */
+    private static class TestAdapter extends RecyclerView.Adapter<TestViewHolder> {
+
+        public enum ItemHeight {
+            STANDARD,
+            TALL,
+            EXTRA_TALL
+        }
+
+        private final List<String> mData;
+        private final Map<Integer, ItemHeight> mHeightOverrides;
+
+        TestAdapter(int itemCount, Map<Integer, ItemHeight> overrides) {
+            mHeightOverrides = overrides;
+            mData = new ArrayList<>(itemCount);
+
+            for (int i = 0; i < itemCount; i++) {
+                mData.add(getItemText(i));
+            }
+        }
+
+        TestAdapter(int itemCount) {
+            this(itemCount, new HashMap<>());
+        }
+
+        String getItemText(int position) {
+            if (position > mData.size()) {
+                return null;
+            }
+
+            return String.format("Sample item #%d", position);
+        }
+
+        @NonNull
+        @Override
+        public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+            return new TestViewHolder(inflater, parent);
+        }
+
+        @Override
+        public void onBindViewHolder(@NonNull TestViewHolder holder, int position) {
+            ItemHeight height = ItemHeight.STANDARD;
+
+            if (mHeightOverrides.containsKey(position)) {
+                height = mHeightOverrides.get(position);
+            }
+
+            int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+
+            switch (height) {
+                case STANDARD:
+                    break;
+                case TALL:
+                    holder.itemView.setMinimumHeight(screenHeight);
+                    break;
+                case EXTRA_TALL:
+                    holder.itemView.setMinimumHeight(screenHeight * 2);
+                    break;
+                default:
+                    throw new IllegalStateException("Unexpected value: " + height);
+            }
+
+            holder.bind(mData.get(position));
+        }
+
+        @Override
+        public int getItemCount() {
+            return mData.size();
+        }
+    }
+
+    private static class TestViewHolder extends RecyclerView.ViewHolder {
+        private TextView mTextView;
+
+        TestViewHolder(LayoutInflater inflater, ViewGroup parent) {
+            super(inflater.inflate(R.layout.test_list_item, parent, false));
+            mTextView = itemView.findViewById(R.id.text);
+        }
+
+        void bind(String text) {
+            mTextView.setText(text);
+        }
+    }
+
+    /**
+     * An {@link IdlingResource} that will prevent assertions from running while the {@link
+     * CarUiRecyclerView} is scrolling.
+     */
+    private static class ScrollIdlingResource implements IdlingResource {
+        private boolean mIdle = true;
+        private ResourceCallback mResourceCallback;
+
+        ScrollIdlingResource(CarUiRecyclerView carUiRecyclerView) {
+            carUiRecyclerView
+                    .addOnScrollListener(
+                            new RecyclerView.OnScrollListener() {
+                                @Override
+                                public void onScrollStateChanged(@NonNull RecyclerView recyclerView,
+                                        int newState) {
+                                    super.onScrollStateChanged(recyclerView, newState);
+                                    mIdle = (newState == RecyclerView.SCROLL_STATE_IDLE
+                                            // Treat dragging as idle, or Espresso will
+                                            // block itself when swiping.
+                                            || newState == RecyclerView.SCROLL_STATE_DRAGGING);
+                                    if (mIdle && mResourceCallback != null) {
+                                        mResourceCallback.onTransitionToIdle();
+                                    }
+                                }
+
+                                @Override
+                                public void onScrolled(@NonNull RecyclerView recyclerView, int dx,
+                                        int dy) {
+                                }
+                            });
+        }
+
+        @Override
+        public String getName() {
+            return ScrollIdlingResource.class.getName();
+        }
+
+        @Override
+        public boolean isIdleNow() {
+            return mIdle;
+        }
+
+        @Override
+        public void registerIdleTransitionCallback(ResourceCallback callback) {
+            mResourceCallback = callback;
+        }
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTestActivity.java b/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTestActivity.java
new file mode 100644
index 0000000..6fb5746
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/recyclerview/CarUiRecyclerViewTestActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.recyclerview;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.tests.unit.R;
+
+/**
+ * An {@link Activity} that contains only an empty {@link CarUiRecyclerView}.
+ */
+public class CarUiRecyclerViewTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.car_ui_recycler_view_test_activity);
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/toolbar/ToolbarTest.java b/car-ui-lib/tests/unit/src/com/android/car/ui/toolbar/ToolbarTest.java
new file mode 100644
index 0000000..9d5af2c
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/toolbar/ToolbarTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.toolbar;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.hasChildCount;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
+import static androidx.test.espresso.matcher.ViewMatchers.withHint;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.android.car.ui.actions.ViewActions.waitForView;
+import static com.android.car.ui.matchers.ViewMatchers.nthChildOfView;
+import static com.android.car.ui.matchers.ViewMatchers.withDrawable;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+
+import static org.hamcrest.core.IsNot.not;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.view.View;
+
+import androidx.test.rule.ActivityTestRule;
+
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.tests.unit.R;
+
+import org.hamcrest.Matcher;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.function.Consumer;
+
+/** Unit test for {@link ToolbarController}. */
+public class ToolbarTest {
+
+    @Rule
+    public ActivityTestRule<ToolbarTestActivity> mActivityRule =
+            new ActivityTestRule<>(ToolbarTestActivity.class);
+
+    @Test
+    public void test_setTitle_displaysTitle() throws Throwable {
+        runWithToolbar((toolbar) -> toolbar.setTitle("Test title"));
+
+        onView(withText("Test title")).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void test_setSubtitle_displaysSubtitle() throws Throwable {
+        runWithToolbar((toolbar) -> toolbar.setSubtitle("Test subtitle"));
+
+        onView(withText("Test subtitle")).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void test_setSearchHint_isDisplayed() throws Throwable {
+        runWithToolbar((toolbar) -> {
+            toolbar.setSearchHint("Test search hint");
+            toolbar.setState(Toolbar.State.SEARCH);
+        });
+
+        onView(withHint("Test search hint")).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void setters_and_getters_test() throws Throwable {
+        runWithToolbar((toolbar) -> {
+            toolbar.setTitle("Foo");
+            toolbar.setSearchHint("Foo2");
+            toolbar.setShowMenuItemsWhileSearching(true);
+            toolbar.setState(Toolbar.State.SUBPAGE);
+            toolbar.setNavButtonMode(Toolbar.NavButtonMode.CLOSE);
+
+            assertThat(toolbar.getTitle().toString()).isEqualTo("Foo");
+            assertThat(toolbar.getSearchHint().toString()).isEqualTo("Foo2");
+            assertThat(toolbar.getShowMenuItemsWhileSearching()).isEqualTo(true);
+            assertThat(toolbar.getState()).isEquivalentAccordingToCompareTo(Toolbar.State.SUBPAGE);
+            assertThat(toolbar.getNavButtonMode()).isEquivalentAccordingToCompareTo(
+                    Toolbar.NavButtonMode.CLOSE);
+        });
+    }
+
+    @Test
+    public void test_setLogo_displaysLogo() throws Throwable {
+        runWithToolbar((toolbar) -> toolbar.setLogo(R.drawable.ic_launcher));
+
+        onView(withDrawable(R.drawable.ic_launcher)).check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void pressBack_withoutListener_callsActivityOnBack() throws Throwable {
+        runWithToolbar((toolbar) -> toolbar.setState(Toolbar.State.SUBPAGE));
+
+        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());
+
+        assertTrue(mActivityRule.getActivity().isFinishing());
+        assertEquals(mActivityRule.getActivityResult().getResultCode(), Activity.RESULT_CANCELED);
+    }
+
+    @Test
+    public void pressBack_withListenerThatReturnsFalse_callsActivityOnBack() throws Throwable {
+        runWithToolbar((toolbar) -> {
+            toolbar.setState(Toolbar.State.SUBPAGE);
+            toolbar.registerOnBackListener(() -> false);
+        });
+
+        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());
+
+        assertTrue(mActivityRule.getActivity().isFinishing());
+        assertEquals(mActivityRule.getActivityResult().getResultCode(), Activity.RESULT_CANCELED);
+    }
+
+    @Test
+    public void pressBack_withListenerThatReturnsTrue_doesntCallActivityOnBack() throws Throwable {
+        runWithToolbar((toolbar) -> {
+            toolbar.setState(Toolbar.State.SUBPAGE);
+            toolbar.registerOnBackListener(() -> true);
+        });
+
+        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());
+
+        assertFalse(mActivityRule.getActivity().isFinishing());
+    }
+
+    @Test
+    public void pressBack_withUnregisteredListener_doesntCallActivityOnBack() throws Throwable {
+        runWithToolbar((toolbar) -> {
+            toolbar.setState(Toolbar.State.SUBPAGE);
+            Toolbar.OnBackListener listener = () -> true;
+            toolbar.registerOnBackListener(listener);
+            toolbar.registerOnBackListener(listener);
+            toolbar.unregisterOnBackListener(listener);
+        });
+
+        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());
+
+        assertTrue(mActivityRule.getActivity().isFinishing());
+    }
+
+    @Test
+    public void menuItems_setId_shouldWork() {
+        MenuItem item = MenuItem.builder(mActivityRule.getActivity()).build();
+
+        assertThat(item.getId()).isEqualTo(View.NO_ID);
+
+        item.setId(7);
+
+        assertThat(item.getId()).isEqualTo(7);
+    }
+
+    @Test
+    public void menuItems_whenClicked_shouldCallListener() throws Throwable {
+        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
+        MenuItem menuItem = MenuItem.builder(mActivityRule.getActivity())
+                .setTitle("Button!")
+                .setOnClickListener(callback)
+                .build();
+        runWithToolbar((toolbar) -> toolbar.setMenuItems(Collections.singletonList(menuItem)));
+
+        waitForMenuItems();
+
+        onView(firstMenuItem()).perform(click());
+
+        verify(callback).onClick(menuItem);
+    }
+
+    @Test
+    public void menuItems_null_shouldRemoveExistingMenuItems() throws Throwable {
+        runWithToolbar((toolbar) ->
+                toolbar.setMenuItems(Arrays.asList(
+                        MenuItem.builder(mActivityRule.getActivity())
+                                .setTitle("Button!")
+                                .build(),
+                        MenuItem.builder(mActivityRule.getActivity())
+                                .setTitle("Button2!")
+                                .build()
+                )));
+        waitForMenuItems();
+
+        onView(withId(R.id.car_ui_toolbar_menu_items_container)).check(matches(hasChildCount(2)));
+
+        runWithToolbar((toolbar) -> toolbar.setMenuItems(null));
+
+        onView(withId(R.id.car_ui_toolbar_menu_items_container)).check(matches(hasChildCount(0)));
+    }
+
+    @Test
+    public void menuItems_setVisibility_shouldHide() throws Throwable {
+        MenuItem menuItem = MenuItem.builder(mActivityRule.getActivity())
+                .setTitle("Button!")
+                .build();
+        runWithToolbar((toolbar) -> toolbar.setMenuItems(Collections.singletonList(menuItem)));
+        waitForMenuItems();
+
+        onView(withText("Button!")).check(matches(isDisplayed()));
+
+        runWithToolbar((toolbar) -> menuItem.setVisible(false));
+
+        onView(withText("Button!")).check(matches(not(isDisplayed())));
+    }
+
+    @Test
+    public void menuItems_searchScreen_shouldHideMenuItems() throws Throwable {
+        runWithToolbar((toolbar) -> {
+            toolbar.setMenuItems(Arrays.asList(
+                    MenuItem.builder(mActivityRule.getActivity())
+                            .setToSearch()
+                            .build(),
+                    MenuItem.builder(mActivityRule.getActivity())
+                            .setTitle("Button!")
+                            .build()));
+            toolbar.setShowMenuItemsWhileSearching(false);
+            toolbar.setState(Toolbar.State.SEARCH);
+        });
+        waitForMenuItems();
+
+        // All menuitems should be hidden if we're hiding menuitems while searching
+        onView(withText("Button!")).check(matches(not(isDisplayed())));
+        onView(firstMenuItem()).check(matches(not(isDisplayed())));
+
+        runWithToolbar((toolbar) -> toolbar.setShowMenuItemsWhileSearching(true));
+
+        // Even if not hiding MenuItems while searching, the search MenuItem should still be hidden
+        onView(withText("Button!")).check(matches(isDisplayed()));
+        onView(firstMenuItem()).check(matches(not(isDisplayed())));
+    }
+
+    private void runWithToolbar(Consumer<ToolbarController> toRun) throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            ToolbarController toolbar = CarUi.requireToolbar(mActivityRule.getActivity());
+            toRun.accept(toolbar);
+        });
+    }
+
+    private Matcher<View> firstMenuItem() {
+        return nthChildOfView(withId(R.id.car_ui_toolbar_menu_items_container), 0);
+    }
+
+    private void waitForMenuItems() {
+        onView(isRoot()).perform(waitForView(firstMenuItem(), 500));
+    }
+}
diff --git a/car-ui-lib/tests/unit/src/com/android/car/ui/toolbar/ToolbarTestActivity.java b/car-ui-lib/tests/unit/src/com/android/car/ui/toolbar/ToolbarTestActivity.java
new file mode 100644
index 0000000..e54ac83
--- /dev/null
+++ b/car-ui-lib/tests/unit/src/com/android/car/ui/toolbar/ToolbarTestActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.ui.toolbar;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.tests.unit.R;
+
+/** An Activity used for testing {@link ToolbarController}. */
+public class ToolbarTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.empty_test_activity);
+    }
+}
diff --git a/car-ui-lib/trailing-blank-line-hook.sh b/car-ui-lib/trailing-blank-line-hook.sh
index a850d8e..d69489d 100755
--- a/car-ui-lib/trailing-blank-line-hook.sh
+++ b/car-ui-lib/trailing-blank-line-hook.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-result=$(find car-ui-lib/ -type f \( -iname \*.java -o -iname \*.xml \) -a \( ! -wholename \*/.idea/\* \) \( ! -wholename \*/build/\* \) -print0 | xargs -0 -L1 bash -c 'test "$(tail -c 1 "$0")" && echo "No new line at end of $0"')
+result=$(find car-ui-lib/ -type f \( -iname \*.java -o -iname \*.xml \) -a \( ! -wholename \*/.idea/\* \) -print0 | xargs -0 -L1 bash -c 'test "$(tail -c 1 "$0")" && echo "No new line at end of $0"')
 if [ \( ! -z "$result" \)  -o \( $(echo "$result" | wc -l) -gt 1 \) ]
 then
     echo "$result" && false;
diff --git a/car-uxr-client-lib/Android.bp b/car-uxr-client-lib/Android.bp
deleted file mode 100644
index ca4fb09..0000000
--- a/car-uxr-client-lib/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_library {
-
-    name: "car-uxr-client-lib",
-
-    srcs: ["src/**/*.java"],
-
-    optimize: {
-        enabled: false,
-    },
-
-    libs: [
-        "android.car-system-stubs",
-    ],
-    sdk_version: "system_current",
-
-    static_libs: [
-        "androidx.recyclerview_recyclerview",
-        "androidx.lifecycle_lifecycle-common-java8",
-        "car-ui-lib",
-    ],
-}
diff --git a/car-uxr-client-lib/AndroidManifest.xml b/car-uxr-client-lib/AndroidManifest.xml
deleted file mode 100644
index 9550419..0000000
--- a/car-uxr-client-lib/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2020 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.car.uxr">
-</manifest>
diff --git a/car-uxr-client-lib/OWNERS b/car-uxr-client-lib/OWNERS
deleted file mode 100644
index 55f7d43..0000000
--- a/car-uxr-client-lib/OWNERS
+++ /dev/null
@@ -1,9 +0,0 @@
-# People who can approve changes for submission.
-johnchoi@google.com
-stenning@google.com
-igorr@google.com
-
-# Engs
-pardis@google.com
-jjoz@google.com
-
diff --git a/car-uxr-client-lib/README.md b/car-uxr-client-lib/README.md
deleted file mode 100644
index 7f57376..0000000
--- a/car-uxr-client-lib/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Android Automotive App-side User Experience Restriction (UXR) library
-Components and resources designed to reduce the amount of work needed by
-Automotive app developers to add User Experience Restriction Engine
-support to their apps.
-
-Source: /packages/apps/Car/libs/car-uxr-client-lib
-
diff --git a/car-uxr-client-lib/res/values/attrs.xml b/car-uxr-client-lib/res/values/attrs.xml
deleted file mode 100644
index 084e30d..0000000
--- a/car-uxr-client-lib/res/values/attrs.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<!--
-  ~ An example uxr_config.xml file would look like:
-  ~ <Mapping xmlns:app="http://schemas.android.com/apk/res-auto">
-  ~     <ListConfig
-  ~         app:id="@+id/call_log_list_uxr_config"
-  ~         app:maxLength="10"
-  ~         app:message="@string/call_log_scrolling_limited_message"
-  ~     />
-  ~ </Mapping>
-  -->
-<resources>
-    <!-- Global container of uxr related app configs -->
-    <declare-styleable name="CarUxRestrictionsAppConfig"/>
-    <!-- The mapping of lists to their uxr related override values. -->
-    <declare-styleable name="CarUxRestrictionsAppConfig_Mapping"/>
-
-    <!-- Uxr related overrides for a specific list -->
-    <declare-styleable name="CarUxRestrictionsAppConfig_ListConfig">
-        <!-- Id of ListConfig, used to differentiate them -->
-        <attr name="id" format="reference"/>
-        <!-- Used to limit the length of a list. -->
-        <attr name="maxLength" format="integer"/>
-        <!-- Used to educate users why their scrolling experience is limited. -->
-        <attr name="message" format="string"/>
-    </declare-styleable>
-</resources>
\ No newline at end of file
diff --git a/car-uxr-client-lib/src/com/android/car/uxr/CarUxRestrictionsAppConfig.java b/car-uxr-client-lib/src/com/android/car/uxr/CarUxRestrictionsAppConfig.java
deleted file mode 100644
index 49634ca..0000000
--- a/car-uxr-client-lib/src/com/android/car/uxr/CarUxRestrictionsAppConfig.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.uxr;
-
-import android.content.Context;
-
-import androidx.annotation.IdRes;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.annotation.XmlRes;
-
-import java.util.Map;
-
-/**
- * A container class for app specific Car User Experience Restriction override configurations.
- *
- * <p>{@link #getInstance(Context, int)} will returned a lazily populated cached reference to the
- * configurations object that is read using
- * {@link CarUxRestrictionsAppConfigParser#parseConfig(Context, int)}.
- *
- * <p>{@link #getMapping()} can be used to access the mapping of component IDs to configurations
- * specific to that component.
- */
-public class CarUxRestrictionsAppConfig {
-
-    private final Map<Integer, ListConfig> mMapping;
-    private static CarUxRestrictionsAppConfig sInstance;
-
-    CarUxRestrictionsAppConfig(Map<Integer, ListConfig> mapping) {
-        mMapping = mapping;
-    }
-
-    /**
-     * Returns a cached reference to the {@link CarUxRestrictionsAppConfig} object
-     * resulting from parsing the contents of {@code xmlRes} xml resource.
-     *
-     * @param context - the app context
-     * @param xmlRes  - the xml resource that contains the UXR override configs.
-     */
-    public static CarUxRestrictionsAppConfig getInstance(Context context, @XmlRes int xmlRes) {
-        if (sInstance == null) {
-            sInstance = CarUxRestrictionsAppConfigParser.parseConfig(context, xmlRes);
-        }
-
-        return sInstance;
-    }
-
-    /**
-     * Returns a {@link Map} of Resource Ids as ints to {@link ListConfig} objects.
-     */
-    public Map<Integer, ListConfig> getMapping() {
-        return mMapping;
-    }
-
-    /**
-     * A class representing Car User Experience Restriction override configurations for a list UI
-     * component.
-     */
-    public static class ListConfig {
-        @IdRes
-        private final int mId;
-        private final Integer mContentLimit;
-        @StringRes
-        private final Integer mScrollingLimitedMessageResId;
-
-        private ListConfig(@IdRes int id, @Nullable Integer contentLimit,
-                @StringRes Integer scrollingLimitedMessageResId) {
-            mId = id;
-            mContentLimit = contentLimit;
-            mScrollingLimitedMessageResId = scrollingLimitedMessageResId;
-        }
-
-        /**
-         * Returns a {@code Builder} that can be used to build a {@link ListConfig} object for a
-         * component identified with the provided {@code id}.
-         *
-         * @param id - an identifier for the component whose behavior needs to be overridden with
-         *           the configurations specified in the resulting {@link ListConfig} object.
-         */
-        public static Builder builder(@IdRes int id) {
-            return new Builder(id);
-        }
-
-        /**
-         * Returns the identifier for the component whose behavior needs to be overridden by this
-         * config object.
-         */
-        @IdRes
-        public int getId() {
-            return mId;
-        }
-
-        /**
-         * Returns the item limit to impose on the contents of the corresponding list component.
-         */
-        @Nullable
-        public Integer getContentLimit() {
-            return mContentLimit;
-        }
-
-        /**
-         * Returns the string resource ID to use when educating users about why the content in the
-         * list they're browsing has been limited.
-         */
-        @Nullable
-        @StringRes
-        public Integer getScrollingLimitedMessageResId() {
-            return mScrollingLimitedMessageResId;
-        }
-
-        /**
-         * A Builder for {@link ListConfig}.
-         */
-        public static class Builder {
-            @IdRes
-            private final int mId;
-            private Integer mContentLimit;
-            @StringRes
-            private Integer mScrollingLimitedMessageResId;
-
-
-            /**
-             * Constructs a {@code Builder} that can be used to build a {@link ListConfig} object
-             * for a component identified with the provided {@code id}.
-             *
-             * @param id - an identifier for the component whose behavior needs to be overridden
-             *           with the configurations specified in the resulting {@link ListConfig}
-             *           object.
-             */
-            private Builder(@IdRes int id) {
-                mId = id;
-            }
-
-            /**
-             * Sets the item limit to impose on the contents of the corresponding list component.
-             *
-             * @param contentLimit - the item limit
-             * @return this {@code Builder} object to facilitate chaining.
-             */
-            public Builder setContentLimit(int contentLimit) {
-                mContentLimit = contentLimit;
-                return this;
-            }
-
-            /**
-             * Sets the string resource ID to use when educating users about why the content in the
-             * * list they're browsing has been limited.
-             *
-             * @param scrollingLimitedMessageResId - an educational message string resource ID
-             * @return this {@code Builder} object to facilitate chaining.
-             */
-            public Builder setScrollingLimitedMessageResId(
-                    @StringRes int scrollingLimitedMessageResId) {
-                mScrollingLimitedMessageResId = scrollingLimitedMessageResId;
-                return this;
-            }
-
-            /**
-             * Build and return a {@link ListConfig} object with the values provided to this
-             * {@code Builder} object.
-             */
-            public ListConfig build() {
-                return new ListConfig(mId, mContentLimit, mScrollingLimitedMessageResId);
-            }
-        }
-    }
-}
diff --git a/car-uxr-client-lib/src/com/android/car/uxr/CarUxRestrictionsAppConfigParser.java b/car-uxr-client-lib/src/com/android/car/uxr/CarUxRestrictionsAppConfigParser.java
deleted file mode 100644
index 341e426..0000000
--- a/car-uxr-client-lib/src/com/android/car/uxr/CarUxRestrictionsAppConfigParser.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.car.uxr;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Xml;
-import android.view.View;
-
-import androidx.annotation.XmlRes;
-
-import com.android.car.uxr.CarUxRestrictionsAppConfig.ListConfig;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A parser that can read an XML resource file and construct the corresponding
- * {@link CarUxRestrictionsAppConfig} object.
- *
- * See car-uxr-client-lib/res/values/attrs.xml for the definition of the relevant XML tags.
- */
-public class CarUxRestrictionsAppConfigParser {
-    private static final String TAG = "UxrAppConfigParser";
-
-    static CarUxRestrictionsAppConfig parseConfig(Context context, @XmlRes int xmlRes) {
-        try (XmlResourceParser parser = context.getResources().getXml(xmlRes)) {
-            AttributeSet attrs = Xml.asAttributeSet(parser);
-            Map<Integer, ListConfig> mapping = new HashMap<>();
-
-            // Skip over the xml version tag
-            parser.next();
-            // Skip over the copyright comment block
-            parser.next();
-            parser.require(XmlPullParser.START_TAG, null, "Mapping");
-            while (parser.next() != XmlPullParser.END_TAG) {
-                ListConfig listConfig = parseListConfigItem(context, parser, attrs);
-                mapping.put(listConfig.getId(), listConfig);
-            }
-
-            return new CarUxRestrictionsAppConfig(mapping);
-        } catch (XmlPullParserException | IOException e) {
-            throw new RuntimeException("Unable to parse CarUxRestrictionsAppConfig", e);
-        }
-    }
-
-    private static ListConfig parseListConfigItem(
-            Context context, XmlResourceParser parser, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
-
-        parser.require(XmlPullParser.START_TAG, null, "ListConfig");
-
-        TypedArray a = context.obtainStyledAttributes(
-                attrs, R.styleable.CarUxRestrictionsAppConfig_ListConfig);
-
-        try {
-            int id = a.getResourceId(R.styleable.CarUxRestrictionsAppConfig_ListConfig_id,
-                    View.NO_ID);
-            if (id == View.NO_ID) {
-                throw new IllegalStateException("Id field is required");
-            }
-
-            boolean messageExists = a.hasValue(
-                    R.styleable.CarUxRestrictionsAppConfig_ListConfig_message);
-            int messageResId = a.getResourceId(
-                    R.styleable.CarUxRestrictionsAppConfig_ListConfig_message, View.NO_ID);
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, messageExists
-                        ? "message field is set to " + messageResId
-                        : "message field not specified");
-            }
-
-            boolean maxLengthExists = a.hasValue(
-                    R.styleable.CarUxRestrictionsAppConfig_ListConfig_maxLength);
-            int maxLengthInt = a.getInt(
-                    R.styleable.CarUxRestrictionsAppConfig_ListConfig_maxLength, 0);
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, maxLengthExists
-                        ? "maxLength field is set to " + maxLengthInt
-                        : "maxLength field not specified");
-            }
-
-            parser.next();
-            parser.require(XmlPullParser.END_TAG, null, "ListConfig");
-
-            ListConfig.Builder builder = ListConfig.builder(id);
-            if (maxLengthExists) {
-                builder.setContentLimit(maxLengthInt);
-            }
-            if (messageExists) {
-                builder.setScrollingLimitedMessageResId(messageResId);
-            }
-            return builder.build();
-        } finally {
-            a.recycle();
-        }
-    }
-}
diff --git a/car-uxr-client-lib/src/com/android/car/uxr/LifeCycleObserverUxrContentLimiter.java b/car-uxr-client-lib/src/com/android/car/uxr/LifeCycleObserverUxrContentLimiter.java
deleted file mode 100644
index 3c8905e..0000000
--- a/car-uxr-client-lib/src/com/android/car/uxr/LifeCycleObserverUxrContentLimiter.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.uxr;
-
-import androidx.annotation.NonNull;
-import androidx.lifecycle.DefaultLifecycleObserver;
-import androidx.lifecycle.LifecycleOwner;
-
-import com.android.car.ui.recyclerview.ContentLimiting;
-
-/**
- * An implementation of {@link UxrContentLimiter} interface that also provides the functionality
- * necessary for a {@link DefaultLifecycleObserver}.
- *
- * <p>Relies heavily on the {@link UxrContentLimiterImpl} implementation of the
- * {@link UxrContentLimiter} interface.
- *
- * <p>For example, you could do the following to get yourself a lifecycle aware {@link
- * UxrContentLimiter}:
- * <pre>{@code
- * new LifeCycleObserverUxrContentLimiter(new UxrContentLimiterImpl(context,xmlRes));
- * }</pre>
- */
-public class LifeCycleObserverUxrContentLimiter
-        implements UxrContentLimiter, DefaultLifecycleObserver {
-
-    private final UxrContentLimiterImpl mDelegate;
-
-    public LifeCycleObserverUxrContentLimiter(UxrContentLimiterImpl delegate) {
-        mDelegate = delegate;
-    }
-
-    @Override
-    public void onStart(@NonNull LifecycleOwner owner) {
-        mDelegate.start();
-    }
-
-    @Override
-    public void onStop(@NonNull LifecycleOwner owner) {
-        mDelegate.stop();
-    }
-
-    @Override
-    public void setAdapter(ContentLimiting adapter) {
-        mDelegate.setAdapter(adapter);
-    }
-}
diff --git a/car-uxr-client-lib/src/com/android/car/uxr/UxrContentLimiter.java b/car-uxr-client-lib/src/com/android/car/uxr/UxrContentLimiter.java
deleted file mode 100644
index 9fd877e..0000000
--- a/car-uxr-client-lib/src/com/android/car/uxr/UxrContentLimiter.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.uxr;
-
-import com.android.car.ui.recyclerview.ContentLimiting;
-
-/**
- * An interface to facilitate the content limiting ability of {@link ContentLimiting}
- * {@link androidx.recyclerview.widget.RecyclerView.Adapter} objects based on changes to the state
- * of the car.
- */
-public interface UxrContentLimiter {
-
-    /**
-     * Registers the given {@link ContentLimiting} with this {@code UxrContentLimiter}.
-     *
-     * <p>That means that when the car state changes, if necessary, this
-     * {@code UxrContentLimiter} will limit the content in the given adapter.
-     *
-     * @param adapter - the adapter to associate with this content limiter.
-     */
-    void setAdapter(ContentLimiting adapter);
-}
diff --git a/car-uxr-client-lib/src/com/android/car/uxr/UxrContentLimiterImpl.java b/car-uxr-client-lib/src/com/android/car/uxr/UxrContentLimiterImpl.java
deleted file mode 100644
index ce22cca..0000000
--- a/car-uxr-client-lib/src/com/android/car/uxr/UxrContentLimiterImpl.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.uxr;
-
-import android.car.drivingstate.CarUxRestrictions;
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.IdRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.XmlRes;
-
-import com.android.car.ui.recyclerview.ContentLimiting;
-import com.android.car.ui.utils.CarUxRestrictionsUtil;
-import com.android.car.uxr.CarUxRestrictionsAppConfig.ListConfig;
-
-/**
- * A class that can work together with a {@link ContentLimiting} {@link
- * androidx.recyclerview.widget.RecyclerView.Adapter} object to provide content limiting ability
- * based on changes to the state of the car, by listening for the latest {@link CarUxRestrictions}.
- *
- * <p>This class manages 3 things:
- * <ul>
- *     <li> Communications with the User Experience Restriction Engine
- *     <li> Looking up app-side overrides for customizing the content-limiting behavior of a given
- *     list of items in a particular screen
- *     <li> Relaying the relevant parts of that information to the registered
- *     adapter at the right time
- * </ul>
- *
- * <p>The app-side overrides are accessed via the {@link CarUxRestrictionsAppConfig} object.
- *
- * <p>Because all but one of the dependencies for this class can be instantiated as soon as a
- * {@link Context} is available, we provide a separate {@link #setAdapter(ContentLimiting)}
- * API for linking the targeted adapter. That way the registration can happen in a different part of
- * code, and potentially in a different lifecycle method to provide maximum flexibility.
- */
-public class UxrContentLimiterImpl implements UxrContentLimiter {
-
-    private ContentLimiting mAdapter;
-    private ListConfig mListConfig;
-
-    private final CarUxRestrictionsUtil mCarUxRestrictionsUtil;
-    private final CarUxRestrictionsAppConfig mCarUxRestrictionsAppConfig;
-    private final CarUxRestrictionsUtil.OnUxRestrictionsChangedListener mListener =
-            new Listener();
-
-    private class Listener implements CarUxRestrictionsUtil.OnUxRestrictionsChangedListener {
-        private static final String TAG = "ContentLimitListener";
-
-        @Override
-        public void onRestrictionsChanged(@NonNull CarUxRestrictions carUxRestrictions) {
-            if (mAdapter == null) {
-                Log.w(TAG, "No adapter registered.");
-                return;
-            }
-
-            int maxItems = getMaxItemsToUse(carUxRestrictions, mAdapter.getConfigurationId());
-            logD("New limit " + maxItems);
-            mAdapter.setMaxItems(maxItems);
-        }
-
-        private int getMaxItemsToUse(CarUxRestrictions carUxRestrictions, @IdRes int id) {
-            // Unrelated restrictions are active. Quit early.
-            if ((carUxRestrictions.getActiveRestrictions()
-                    & CarUxRestrictions.UX_RESTRICTIONS_LIMIT_CONTENT)
-                    == 0) {
-                logD("Lists are unrestricted.");
-                return ContentLimiting.UNLIMITED;
-            }
-
-            if (mListConfig == null || mListConfig.getContentLimit() == null) {
-                logD("No configs found for adapter with the ID: " + id
-                        + " Using the default limit");
-                return carUxRestrictions.getMaxCumulativeContentItems();
-            }
-
-            logD("Using the provided override.");
-            return mListConfig.getContentLimit();
-        }
-
-        private void logD(String s) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, s);
-            }
-        }
-    }
-
-    /**
-     * Constructs a {@link UxrContentLimiterImpl} object given the app context and the XML resource
-     * file to parse the User Experience Restriction override configs from.
-     *
-     * @param context - the app context
-     * @param xmlRes  - the UXR override config XML resource
-     */
-    public UxrContentLimiterImpl(Context context, @XmlRes int xmlRes) {
-        mCarUxRestrictionsUtil = CarUxRestrictionsUtil.getInstance(context);
-        mCarUxRestrictionsAppConfig = CarUxRestrictionsAppConfig.getInstance(context, xmlRes);
-    }
-
-    @Override
-    public void setAdapter(ContentLimiting adapter) {
-        mAdapter = adapter;
-        int key = mAdapter.getConfigurationId();
-        if (mCarUxRestrictionsAppConfig.getMapping().containsKey(key)) {
-            mListConfig = mCarUxRestrictionsAppConfig.getMapping().get(key);
-            Integer overriddenMessageResId = mListConfig.getScrollingLimitedMessageResId();
-            if (overriddenMessageResId != null) {
-                mAdapter.setScrollingLimitedMessageResId(overriddenMessageResId);
-            }
-        }
-    }
-
-    /**
-     * Start listening for changes to {@link CarUxRestrictions}.
-     */
-    public void start() {
-        mCarUxRestrictionsUtil.register(mListener);
-    }
-
-    /**
-     * Stop listening for changes to {@link CarUxRestrictions}.
-     */
-    public void stop() {
-        mCarUxRestrictionsUtil.unregister(mListener);
-    }
-}
diff --git a/connected-device-lib/Android.bp b/connected-device-lib/Android.bp
new file mode 100644
index 0000000..55ee640
--- /dev/null
+++ b/connected-device-lib/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_library {
+    name: "connected-device-lib",
+
+    srcs: ["src/**/*.java"],
+
+    manifest: "AndroidManifest.xml",
+
+    resource_dirs: ["res"],
+
+    optimize: {
+        enabled: false,
+    },
+
+    libs: ["android.car"],
+
+    static_libs: [
+        "androidx.room_room-runtime",
+        "connected-device-protos",
+        "encryption-runner",
+        "guava",
+    ],
+
+    plugins: [
+        "androidx.room_room-compiler-plugin",
+    ],
+
+    platform_apis: true,
+}
diff --git a/connected-device-lib/AndroidManifest.xml b/connected-device-lib/AndroidManifest.xml
new file mode 100644
index 0000000..d02ffce
--- /dev/null
+++ b/connected-device-lib/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.car.connecteddevice">
+
+  <!--  Needed for BLE scanning/advertising -->
+  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+  <uses-permission android:name="android.permission.BLUETOOTH"/>
+  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+
+  <!--  Needed for detecting foreground user -->
+  <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+  <uses-permission android:name="android.permission.MANAGE_USERS" />
+</manifest>
diff --git a/connected-device-lib/OWNERS b/connected-device-lib/OWNERS
new file mode 100644
index 0000000..108da4e
--- /dev/null
+++ b/connected-device-lib/OWNERS
@@ -0,0 +1,5 @@
+# People who can approve changes for submission.
+nicksauer@google.com
+ramperry@google.com
+ajchen@google.com
+danharms@google.com
diff --git a/connected-device-lib/proto/Android.bp b/connected-device-lib/proto/Android.bp
new file mode 100644
index 0000000..c9dcb73
--- /dev/null
+++ b/connected-device-lib/proto/Android.bp
@@ -0,0 +1,26 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_library_static {
+    name: "connected-device-protos",
+    host_supported: true,
+    proto: {
+        type: "lite",
+    },
+    srcs: ["*.proto"],
+    jarjar_rules: "jarjar-rules.txt",
+    sdk_version: "28",
+}
diff --git a/connected-device-lib/proto/ble_device_message.proto b/connected-device-lib/proto/ble_device_message.proto
new file mode 100644
index 0000000..581d6a0
--- /dev/null
+++ b/connected-device-lib/proto/ble_device_message.proto
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package com.android.car.connecteddevice.proto;
+
+import "packages/apps/Car/libs/connected-device-lib/proto/operation_type.proto";
+
+option java_package = "com.android.car.connecteddevice.BleStreamProtos";
+option java_outer_classname = "BleDeviceMessageProto";
+
+// A message between devices.
+message BleDeviceMessage {
+  // The operation that this message represents.
+  OperationType operation = 1;
+
+  // Whether the payload field is encrypted.
+  bool is_payload_encrypted = 2;
+
+  // Identifier of the intended recipient.
+  bytes recipient = 3;
+
+  // The bytes that represent the content for this message.
+  bytes payload = 4;
+}
\ No newline at end of file
diff --git a/connected-device-lib/proto/ble_packet.proto b/connected-device-lib/proto/ble_packet.proto
new file mode 100644
index 0000000..c2ce262
--- /dev/null
+++ b/connected-device-lib/proto/ble_packet.proto
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package com.android.car.connecteddevice.proto;
+
+option java_package = "com.android.car.connecteddevice.BleStreamProtos";
+option java_outer_classname = "BlePacketProto";
+
+// A packet across a BLE channel.
+message BlePacket {
+  // A 1-based packet number. The first message will have a value of "1" rather
+  // than "0".
+  fixed32 packet_number = 1;
+
+  // The total number of packets in the message stream.
+  int32 total_packets = 2;
+
+  // Id of message for reassembly on other side
+  int32 message_id = 3;
+
+  // The bytes that represent the message content for this packet.
+  bytes payload = 4;
+}
diff --git a/connected-device-lib/proto/ble_version_exchange.proto b/connected-device-lib/proto/ble_version_exchange.proto
new file mode 100644
index 0000000..a7e8021
--- /dev/null
+++ b/connected-device-lib/proto/ble_version_exchange.proto
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package com.android.car.connecteddevice.proto;
+
+option java_package = "com.android.car.connecteddevice.BleStreamProtos";
+option java_outer_classname = "VersionExchangeProto";
+
+message BleVersionExchange {
+  // Minimum supported protobuf version.
+  int32 minSupportedMessagingVersion = 1;
+
+  // Maximum supported protobuf version.
+  int32 maxSupportedMessagingVersion = 2;
+
+  // Minimum supported version of the encryption engine.
+  int32 minSupportedSecurityVersion = 3;
+
+  // Maximum supported version of the encryption engine.
+  int32 maxSupportedSecurityVersion = 4;
+}
diff --git a/connected-device-lib/proto/jarjar-rules.txt b/connected-device-lib/proto/jarjar-rules.txt
new file mode 100644
index 0000000..d27aecb
--- /dev/null
+++ b/connected-device-lib/proto/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.** com.android.car.protobuf.@1
diff --git a/connected-device-lib/proto/operation_type.proto b/connected-device-lib/proto/operation_type.proto
new file mode 100644
index 0000000..d447ccc
--- /dev/null
+++ b/connected-device-lib/proto/operation_type.proto
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package com.android.car.connecteddevice.proto;
+
+option java_package = "com.android.car.connecteddevice.BleStreamProtos";
+option java_outer_classname = "BleOperationProto";
+
+// The different message types that indicate the content of the payload.
+//
+// Ensure that these values are positive to reduce incurring too many bytes
+// to encode.
+enum OperationType {
+  // The contents of the payload are unknown.
+  //
+  // Note, this enum name is prefixed. See
+  // go/proto-best-practices-checkers#enum-default-value-name-conflict
+  OPERATION_TYPE_UNKNOWN = 0;
+
+  // The payload contains handshake messages needed to set up encryption.
+  ENCRYPTION_HANDSHAKE = 2;
+
+  // The message is an acknowledgment of a previously received message. The
+  // payload for this type should be empty.
+  ACK = 3;
+
+  // The payload contains a client-specific message.
+  CLIENT_MESSAGE = 4;
+}
diff --git a/connected-device-lib/res/values/config.xml b/connected-device-lib/res/values/config.xml
new file mode 100644
index 0000000..b090b92
--- /dev/null
+++ b/connected-device-lib/res/values/config.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- These values must be modified for the connected device lib to function properly.-->
+    <string name="car_service_uuid" translatable="false">00000000-0000-0000-0000-000000000000</string>
+    <string name="car_association_service_uuid" translatable="false">00000000-0000-0000-0000-000000000000</string>
+    <string name="car_reconnect_service_uuid" translatable="false">00000000-0000-0000-0000-000000000000</string>
+    <string name="car_reconnect_data_uuid" translatable="false">00000000-0000-0000-0000-000000000000</string>
+    <string name="car_bg_mask" translatable="false">00000000000000000000000000000000</string>
+
+    <string name="car_secure_read_uuid" translatable="false">5e2a68a6-27be-43f9-8d1e-4546976fabd7</string>
+    <string name="car_secure_write_uuid" translatable="false">5e2a68a5-27be-43f9-8d1e-4546976fabd7</string>
+
+    <string name="connected_device_shared_preferences" translatable="false">com.android.car.connecteddevice</string>
+
+    <!--
+    This value must be between 23 and 185. 23 is the default MTU size for Android, and 185 is
+    the max MTU size supported for iOS. Verify your device and target companion devices support a
+    larger MTU prior to modifying.
+    -->
+    <integer name="car_default_mtu_size">23</integer>
+</resources>
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/AssociationCallback.java b/connected-device-lib/src/com/android/car/connecteddevice/AssociationCallback.java
new file mode 100644
index 0000000..fb7000b
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/AssociationCallback.java
@@ -0,0 +1,56 @@
+/*
+ * 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.connecteddevice;
+
+import android.annotation.NonNull;
+
+/** Callbacks that will be invoked during associating a new client. */
+public interface AssociationCallback {
+
+    /**
+     * Invoked when IHU starts advertising with its device name for association successfully.
+     *
+     * @param deviceName The device name to identify the car.
+     */
+    void onAssociationStartSuccess(@NonNull String deviceName);
+
+    /** Invoked when IHU failed to start advertising for association. */
+    void onAssociationStartFailure();
+
+    /**
+     * Invoked when a {@link ConnectedDeviceManager.DeviceError} has been encountered in attempting
+     * to associate a new device.
+     *
+     * @param error The failure indication.
+     */
+    void onAssociationError(@ConnectedDeviceManager.DeviceError int error);
+
+    /**
+     * Invoked when a verification code needs to be displayed. The user needs to confirm, and
+     * then call {@link ConnectedDeviceManager#notifyOutOfBandAccepted()}.
+     *
+     * @param code The verification code.
+     */
+    void onVerificationCodeAvailable(@NonNull String code);
+
+    /**
+     * Invoked when the association has completed.
+     *
+     * @param deviceId The id of the newly associated device.
+     */
+    void onAssociationCompleted(@NonNull String deviceId);
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ConnectedDeviceManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ConnectedDeviceManager.java
new file mode 100644
index 0000000..4add85e
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ConnectedDeviceManager.java
@@ -0,0 +1,941 @@
+/*
+ * 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.connecteddevice;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import com.android.car.connecteddevice.ble.BleCentralManager;
+import com.android.car.connecteddevice.ble.BlePeripheralManager;
+import com.android.car.connecteddevice.ble.CarBleCentralManager;
+import com.android.car.connecteddevice.ble.CarBleManager;
+import com.android.car.connecteddevice.ble.CarBlePeripheralManager;
+import com.android.car.connecteddevice.ble.DeviceMessage;
+import com.android.car.connecteddevice.model.AssociatedDevice;
+import com.android.car.connecteddevice.model.ConnectedDevice;
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage.AssociatedDeviceCallback;
+import com.android.car.connecteddevice.util.ByteUtils;
+import com.android.car.connecteddevice.util.EventLog;
+import com.android.car.connecteddevice.util.ThreadSafeCallbacks;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+
+/** Manager of devices connected to the car. */
+public class ConnectedDeviceManager {
+
+    private static final String TAG = "ConnectedDeviceManager";
+
+    // Device name length is limited by available bytes in BLE advertisement data packet.
+    //
+    // BLE advertisement limits data packet length to 31
+    // Currently we send:
+    // - 18 bytes for 16 chars UUID: 16 bytes + 2 bytes for header;
+    // - 3 bytes for advertisement being connectable;
+    // which leaves 10 bytes.
+    // Subtracting 2 bytes used by header, we have 8 bytes for device name.
+    private static final int DEVICE_NAME_LENGTH_LIMIT = 8;
+
+    // The mac address randomly rotates every 7-15 minutes. To be safe, we will rotate our
+    // reconnect advertisement every 6 minutes to avoid crossing a rotation.
+    private static final Duration MAX_ADVERTISEMENT_DURATION = Duration.ofMinutes(6);
+
+    private final ConnectedDeviceStorage mStorage;
+
+    private final CarBleCentralManager mCentralManager;
+
+    private final CarBlePeripheralManager mPeripheralManager;
+
+    private final ThreadSafeCallbacks<DeviceAssociationCallback> mDeviceAssociationCallbacks =
+            new ThreadSafeCallbacks<>();
+
+    private final ThreadSafeCallbacks<ConnectionCallback> mActiveUserConnectionCallbacks =
+            new ThreadSafeCallbacks<>();
+
+    private final ThreadSafeCallbacks<ConnectionCallback> mAllUserConnectionCallbacks =
+            new ThreadSafeCallbacks<>();
+
+    // deviceId -> (recipientId -> callbacks)
+    private final Map<String, Map<UUID, ThreadSafeCallbacks<DeviceCallback>>> mDeviceCallbacks =
+            new ConcurrentHashMap<>();
+
+    // deviceId -> device
+    private final Map<String, InternalConnectedDevice> mConnectedDevices =
+            new ConcurrentHashMap<>();
+
+    // recipientId -> (deviceId -> message bytes)
+    private final Map<UUID, Map<String, List<byte[]>>> mRecipientMissedMessages =
+            new ConcurrentHashMap<>();
+
+    // Recipient ids that received multiple callback registrations indicate that the recipient id
+    // has been compromised. Another party now has access the messages intended for that recipient.
+    // As a safeguard, that recipient id will be added to this list and blocked from further
+    // callback notifications.
+    private final Set<UUID> mBlacklistedRecipients = new CopyOnWriteArraySet<>();
+
+    private final AtomicBoolean mIsConnectingToUserDevice = new AtomicBoolean(false);
+
+    private final AtomicBoolean mHasStarted = new AtomicBoolean(false);
+
+    private String mNameForAssociation;
+
+    private AssociationCallback mAssociationCallback;
+
+    private MessageDeliveryDelegate mMessageDeliveryDelegate;
+
+    @Retention(SOURCE)
+    @IntDef(prefix = { "DEVICE_ERROR_" },
+            value = {
+                    DEVICE_ERROR_INVALID_HANDSHAKE,
+                    DEVICE_ERROR_INVALID_MSG,
+                    DEVICE_ERROR_INVALID_DEVICE_ID,
+                    DEVICE_ERROR_INVALID_VERIFICATION,
+                    DEVICE_ERROR_INVALID_CHANNEL_STATE,
+                    DEVICE_ERROR_INVALID_ENCRYPTION_KEY,
+                    DEVICE_ERROR_STORAGE_FAILURE,
+                    DEVICE_ERROR_INVALID_SECURITY_KEY,
+                    DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED,
+                    DEVICE_ERROR_UNEXPECTED_DISCONNECTION
+            }
+    )
+    public @interface DeviceError {}
+    public static final int DEVICE_ERROR_INVALID_HANDSHAKE = 0;
+    public static final int DEVICE_ERROR_INVALID_MSG = 1;
+    public static final int DEVICE_ERROR_INVALID_DEVICE_ID = 2;
+    public static final int DEVICE_ERROR_INVALID_VERIFICATION = 3;
+    public static final int DEVICE_ERROR_INVALID_CHANNEL_STATE = 4;
+    public static final int DEVICE_ERROR_INVALID_ENCRYPTION_KEY = 5;
+    public static final int DEVICE_ERROR_STORAGE_FAILURE = 6;
+    public static final int DEVICE_ERROR_INVALID_SECURITY_KEY = 7;
+    public static final int DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED = 8;
+    public static final int DEVICE_ERROR_UNEXPECTED_DISCONNECTION = 9;
+
+    public ConnectedDeviceManager(@NonNull Context context) {
+        this(context, new ConnectedDeviceStorage(context), new BleCentralManager(context),
+                new BlePeripheralManager(context),
+                UUID.fromString(context.getString(R.string.car_service_uuid)),
+                UUID.fromString(context.getString(R.string.car_association_service_uuid)),
+                UUID.fromString(context.getString(R.string.car_reconnect_service_uuid)),
+                UUID.fromString(context.getString(R.string.car_reconnect_data_uuid)),
+                context.getString(R.string.car_bg_mask),
+                UUID.fromString(context.getString(R.string.car_secure_write_uuid)),
+                UUID.fromString(context.getString(R.string.car_secure_read_uuid)),
+                context.getResources().getInteger(R.integer.car_default_mtu_size));
+    }
+
+    private ConnectedDeviceManager(
+            @NonNull Context context,
+            @NonNull ConnectedDeviceStorage storage,
+            @NonNull BleCentralManager bleCentralManager,
+            @NonNull BlePeripheralManager blePeripheralManager,
+            @NonNull UUID serviceUuid,
+            @NonNull UUID associationServiceUuid,
+            @NonNull UUID reconnectServiceUuid,
+            @NonNull UUID reconnectDataUuid,
+            @NonNull String bgMask,
+            @NonNull UUID writeCharacteristicUuid,
+            @NonNull UUID readCharacteristicUuid,
+            int defaultMtuSize) {
+        this(storage,
+                new CarBleCentralManager(context, bleCentralManager, storage, serviceUuid, bgMask,
+                        writeCharacteristicUuid, readCharacteristicUuid),
+                new CarBlePeripheralManager(blePeripheralManager, storage, associationServiceUuid,
+                        reconnectServiceUuid, reconnectDataUuid, writeCharacteristicUuid,
+                        readCharacteristicUuid, MAX_ADVERTISEMENT_DURATION, defaultMtuSize));
+    }
+
+    @VisibleForTesting
+    ConnectedDeviceManager(
+            @NonNull ConnectedDeviceStorage storage,
+            @NonNull CarBleCentralManager centralManager,
+            @NonNull CarBlePeripheralManager peripheralManager) {
+        Executor callbackExecutor = Executors.newSingleThreadExecutor();
+        mStorage = storage;
+        mCentralManager = centralManager;
+        mPeripheralManager = peripheralManager;
+        mCentralManager.registerCallback(generateCarBleCallback(centralManager), callbackExecutor);
+        mPeripheralManager.registerCallback(generateCarBleCallback(peripheralManager),
+                callbackExecutor);
+        mStorage.setAssociatedDeviceCallback(mAssociatedDeviceCallback);
+    }
+
+    /**
+     * Start internal processes and begin discovering devices. Must be called before any
+     * connections can be made using {@link #connectToActiveUserDevice()}.
+     */
+    public void start() {
+        if (mHasStarted.getAndSet(true)) {
+            reset();
+        } else {
+            logd(TAG, "Starting ConnectedDeviceManager.");
+            EventLog.onConnectedDeviceManagerStarted();
+        }
+        // TODO (b/141312136) Start central manager
+        mPeripheralManager.start();
+        connectToActiveUserDevice();
+    }
+
+    /** Reset internal processes and disconnect any active connections. */
+    public void reset() {
+        logd(TAG, "Resetting ConnectedDeviceManager.");
+        for (InternalConnectedDevice device : mConnectedDevices.values()) {
+            removeConnectedDevice(device.mConnectedDevice.getDeviceId(), device.mCarBleManager);
+        }
+        mPeripheralManager.stop();
+        // TODO (b/141312136) Stop central manager
+        mIsConnectingToUserDevice.set(false);
+    }
+
+    /** Returns {@link List<ConnectedDevice>} of devices currently connected. */
+    @NonNull
+    public List<ConnectedDevice> getActiveUserConnectedDevices() {
+        List<ConnectedDevice> activeUserConnectedDevices = new ArrayList<>();
+        for (InternalConnectedDevice device : mConnectedDevices.values()) {
+            if (device.mConnectedDevice.isAssociatedWithActiveUser()) {
+                activeUserConnectedDevices.add(device.mConnectedDevice);
+            }
+        }
+        logd(TAG, "Returned " + activeUserConnectedDevices.size() + " active user devices.");
+        return activeUserConnectedDevices;
+    }
+
+    /**
+     * Register a callback for triggered associated device related events.
+     *
+     * @param callback {@link DeviceAssociationCallback} to register.
+     * @param executor {@link Executor} to execute triggers on.
+     */
+    public void registerDeviceAssociationCallback(@NonNull DeviceAssociationCallback callback,
+            @NonNull @CallbackExecutor Executor executor) {
+        mDeviceAssociationCallbacks.add(callback, executor);
+    }
+
+    /**
+     * Unregister a device association callback.
+     *
+     * @param callback {@link DeviceAssociationCallback} to unregister.
+     */
+    public void unregisterDeviceAssociationCallback(@NonNull DeviceAssociationCallback callback) {
+        mDeviceAssociationCallbacks.remove(callback);
+    }
+
+    /**
+     * Register a callback for manager triggered connection events for only the currently active
+     * user's devices.
+     *
+     * @param callback {@link ConnectionCallback} to register.
+     * @param executor {@link Executor} to execute triggers on.
+     */
+    public void registerActiveUserConnectionCallback(@NonNull ConnectionCallback callback,
+            @NonNull @CallbackExecutor Executor executor) {
+        mActiveUserConnectionCallbacks.add(callback, executor);
+    }
+
+    /**
+     * Unregister a connection callback from manager.
+     *
+     * @param callback {@link ConnectionCallback} to unregister.
+     */
+    public void unregisterConnectionCallback(ConnectionCallback callback) {
+        mActiveUserConnectionCallbacks.remove(callback);
+        mAllUserConnectionCallbacks.remove(callback);
+    }
+
+    /** Connect to a device for the active user if available. */
+    @VisibleForTesting
+    void connectToActiveUserDevice() {
+        Executors.defaultThreadFactory().newThread(() -> {
+            logd(TAG, "Received request to connect to active user's device.");
+            connectToActiveUserDeviceInternal();
+        }).start();
+    }
+
+    private void connectToActiveUserDeviceInternal() {
+        try {
+            if (mIsConnectingToUserDevice.get()) {
+                logd(TAG, "A request has already been made to connect to this user's device. "
+                        + "Ignoring redundant request.");
+                return;
+            }
+            List<AssociatedDevice> userDevices = mStorage.getActiveUserAssociatedDevices();
+            if (userDevices.isEmpty()) {
+                logw(TAG, "No devices associated with active user. Ignoring.");
+                return;
+            }
+
+            // Only currently support one device per user for fast association, so take the
+            // first one.
+            AssociatedDevice userDevice = userDevices.get(0);
+            if (!userDevice.isConnectionEnabled()) {
+                logd(TAG, "Connection is disabled on device " + userDevice + ".");
+                return;
+            }
+            if (mConnectedDevices.containsKey(userDevice.getDeviceId())) {
+                logd(TAG, "Device has already been connected. No need to attempt connection "
+                        + "again.");
+                return;
+            }
+            EventLog.onStartDeviceSearchStarted();
+            mIsConnectingToUserDevice.set(true);
+            mPeripheralManager.connectToDevice(UUID.fromString(userDevice.getDeviceId()));
+        } catch (Exception e) {
+            loge(TAG, "Exception while attempting connection with active user's device.", e);
+        }
+    }
+
+    /**
+     * Start the association with a new device.
+     *
+     * @param callback Callback for association events.
+     */
+    public void startAssociation(@NonNull AssociationCallback callback) {
+        mAssociationCallback = callback;
+        Executors.defaultThreadFactory().newThread(() -> {
+            logd(TAG, "Received request to start association.");
+            mPeripheralManager.startAssociation(getNameForAssociation(),
+                    mInternalAssociationCallback);
+        }).start();
+    }
+
+    /** Stop the association with any device. */
+    public void stopAssociation(@NonNull AssociationCallback callback) {
+        if (mAssociationCallback != callback) {
+            logd(TAG, "Stop association called with unrecognized callback. Ignoring.");
+            return;
+        }
+        mAssociationCallback = null;
+        mPeripheralManager.stopAssociation(mInternalAssociationCallback);
+    }
+
+    /**
+     * Get a list of associated devices for the given user.
+     *
+     * @return Associated device list.
+     */
+    @NonNull
+    public List<AssociatedDevice> getActiveUserAssociatedDevices() {
+        return mStorage.getActiveUserAssociatedDevices();
+    }
+
+    /** Notify that the user has accepted a pairing code or any out-of-band confirmation. */
+    public void notifyOutOfBandAccepted() {
+        mPeripheralManager.notifyOutOfBandAccepted();
+    }
+
+    /**
+     * Remove the associated device with the given device identifier for the current user.
+     *
+     * @param deviceId Device identifier.
+     */
+    public void removeActiveUserAssociatedDevice(@NonNull String deviceId) {
+        mStorage.removeAssociatedDeviceForActiveUser(deviceId);
+        disconnectDevice(deviceId);
+    }
+
+    /**
+     * Enable connection on an associated device.
+     *
+     * @param deviceId Device identifier.
+     */
+    public void enableAssociatedDeviceConnection(@NonNull String deviceId) {
+        logd(TAG, "enableAssociatedDeviceConnection() called on " + deviceId);
+        mStorage.updateAssociatedDeviceConnectionEnabled(deviceId,
+                /* isConnectionEnabled= */ true);
+        connectToActiveUserDevice();
+    }
+
+    /**
+     * Disable connection on an associated device.
+     *
+     * @param deviceId Device identifier.
+     */
+    public void disableAssociatedDeviceConnection(@NonNull String deviceId) {
+        logd(TAG, "disableAssociatedDeviceConnection() called on " + deviceId);
+        mStorage.updateAssociatedDeviceConnectionEnabled(deviceId,
+                /* isConnectionEnabled= */ false);
+        disconnectDevice(deviceId);
+    }
+
+    private void disconnectDevice(String deviceId) {
+        InternalConnectedDevice device = mConnectedDevices.get(deviceId);
+        if (device != null) {
+            device.mCarBleManager.disconnectDevice(deviceId);
+            removeConnectedDevice(deviceId, device.mCarBleManager);
+        }
+    }
+
+    /**
+     * Register a callback for a specific device and recipient.
+     *
+     * @param device {@link ConnectedDevice} to register triggers on.
+     * @param recipientId {@link UUID} to register as recipient of.
+     * @param callback {@link DeviceCallback} to register.
+     * @param executor {@link Executor} on which to execute callback.
+     */
+    public void registerDeviceCallback(@NonNull ConnectedDevice device, @NonNull UUID recipientId,
+            @NonNull DeviceCallback callback, @NonNull @CallbackExecutor Executor executor) {
+        if (isRecipientBlacklisted(recipientId)) {
+            notifyOfBlacklisting(device, recipientId, callback, executor);
+            return;
+        }
+        logd(TAG, "New callback registered on device " + device.getDeviceId() + " for recipient "
+                + recipientId);
+        String deviceId = device.getDeviceId();
+        Map<UUID, ThreadSafeCallbacks<DeviceCallback>> recipientCallbacks =
+                mDeviceCallbacks.computeIfAbsent(deviceId, key -> new HashMap<>());
+
+        // Device already has a callback registered with this recipient UUID. For the
+        // protection of the user, this UUID is now blacklisted from future subscriptions
+        // and the original subscription is notified and removed.
+        if (recipientCallbacks.containsKey(recipientId)) {
+            blacklistRecipient(deviceId, recipientId);
+            notifyOfBlacklisting(device, recipientId, callback, executor);
+            return;
+        }
+
+        ThreadSafeCallbacks<DeviceCallback> newCallbacks = new ThreadSafeCallbacks<>();
+        newCallbacks.add(callback, executor);
+        recipientCallbacks.put(recipientId, newCallbacks);
+
+        List<byte[]> messages = popMissedMessages(recipientId, device.getDeviceId());
+        if (messages != null) {
+            for (byte[] message : messages) {
+                newCallbacks.invoke(deviceCallback ->
+                        deviceCallback.onMessageReceived(device, message));
+            }
+        }
+    }
+
+    /**
+     * Set the delegate for message delivery operations.
+     *
+     * @param delegate The {@link MessageDeliveryDelegate} to set. {@code null} to unset.
+     */
+    public void setMessageDeliveryDelegate(@Nullable MessageDeliveryDelegate delegate) {
+        mMessageDeliveryDelegate = delegate;
+    }
+
+    private void notifyOfBlacklisting(@NonNull ConnectedDevice device, @NonNull UUID recipientId,
+            @NonNull DeviceCallback callback, @NonNull Executor executor) {
+        loge(TAG, "Multiple callbacks registered for recipient " + recipientId + "! Your "
+                + "recipient id is no longer secure and has been blocked from future use.");
+        executor.execute(() ->
+                callback.onDeviceError(device, DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED));
+    }
+
+    private void saveMissedMessage(@NonNull String deviceId, @NonNull UUID recipientId,
+            @NonNull byte[] message) {
+        // Store last message in case recipient registers callbacks in the future.
+        logd(TAG, "No recipient registered for device " + deviceId + " and recipient "
+                + recipientId + " combination. Saving message.");
+        mRecipientMissedMessages.computeIfAbsent(recipientId, __ -> new HashMap<>())
+                .computeIfAbsent(deviceId, __ -> new ArrayList<>()).add(message);
+    }
+
+    /**
+     * Remove the last message sent for this device prior to a {@link DeviceCallback} being
+     * registered.
+     *
+     * @param recipientId Recipient's id
+     * @param deviceId Device id
+     * @return The missed {@code byte[]} messages, or {@code null} if no messages were
+     *         missed.
+     */
+    @Nullable
+    private List<byte[]> popMissedMessages(@NonNull UUID recipientId, @NonNull String deviceId) {
+        Map<String, List<byte[]>> missedMessages = mRecipientMissedMessages.get(recipientId);
+        if (missedMessages == null) {
+            return null;
+        }
+
+        return missedMessages.remove(deviceId);
+    }
+
+    /**
+     * Unregister callback from device events.
+     *
+     * @param device {@link ConnectedDevice} callback was registered on.
+     * @param recipientId {@link UUID} callback was registered under.
+     * @param callback {@link DeviceCallback} to unregister.
+     */
+    public void unregisterDeviceCallback(@NonNull ConnectedDevice device,
+            @NonNull UUID recipientId, @NonNull DeviceCallback callback) {
+        logd(TAG, "Device callback unregistered on device " + device.getDeviceId() + " for "
+                + "recipient " + recipientId + ".");
+
+        Map<UUID, ThreadSafeCallbacks<DeviceCallback>> recipientCallbacks =
+                mDeviceCallbacks.get(device.getDeviceId());
+        if (recipientCallbacks == null) {
+            return;
+        }
+        ThreadSafeCallbacks<DeviceCallback> callbacks = recipientCallbacks.get(recipientId);
+        if (callbacks == null) {
+            return;
+        }
+
+        callbacks.remove(callback);
+        if (callbacks.size() == 0) {
+            recipientCallbacks.remove(recipientId);
+        }
+    }
+
+    /**
+     * Securely send message to a device.
+     *
+     * @param device {@link ConnectedDevice} to send the message to.
+     * @param recipientId Recipient {@link UUID}.
+     * @param message Message to send.
+     * @throws IllegalStateException Secure channel has not been established.
+     */
+    public void sendMessageSecurely(@NonNull ConnectedDevice device, @NonNull UUID recipientId,
+            @NonNull byte[] message) throws IllegalStateException {
+        sendMessage(device, recipientId, message, /* isEncrypted= */ true);
+    }
+
+    /**
+     * Send an unencrypted message to a device.
+     *
+     * @param device {@link ConnectedDevice} to send the message to.
+     * @param recipientId Recipient {@link UUID}.
+     * @param message Message to send.
+     */
+    public void sendMessageUnsecurely(@NonNull ConnectedDevice device, @NonNull UUID recipientId,
+            @NonNull byte[] message) {
+        sendMessage(device, recipientId, message, /* isEncrypted= */ false);
+    }
+
+    private void sendMessage(@NonNull ConnectedDevice device, @NonNull UUID recipientId,
+            @NonNull byte[] message, boolean isEncrypted) throws IllegalStateException {
+        String deviceId = device.getDeviceId();
+        logd(TAG, "Sending new message to device " + deviceId + " for " + recipientId
+                + " containing " + message.length + ". Message will be sent securely: "
+                + isEncrypted + ".");
+
+        InternalConnectedDevice connectedDevice = mConnectedDevices.get(deviceId);
+        if (connectedDevice == null) {
+            loge(TAG, "Attempted to send message to unknown device " + deviceId + ". Ignoring.");
+            return;
+        }
+
+        if (isEncrypted && !connectedDevice.mConnectedDevice.hasSecureChannel()) {
+            throw new IllegalStateException("Cannot send a message securely to device that has not "
+                    + "established a secure channel.");
+        }
+
+        connectedDevice.mCarBleManager.sendMessage(deviceId,
+                new DeviceMessage(recipientId, isEncrypted, message));
+    }
+
+    private boolean isRecipientBlacklisted(UUID recipientId) {
+        return mBlacklistedRecipients.contains(recipientId);
+    }
+
+    private void blacklistRecipient(@NonNull String deviceId, @NonNull UUID recipientId) {
+        Map<UUID, ThreadSafeCallbacks<DeviceCallback>> recipientCallbacks =
+                mDeviceCallbacks.get(deviceId);
+        if (recipientCallbacks == null) {
+            // Should never happen, but null-safety check.
+            return;
+        }
+
+        ThreadSafeCallbacks<DeviceCallback> existingCallback = recipientCallbacks.get(recipientId);
+        if (existingCallback == null) {
+            // Should never happen, but null-safety check.
+            return;
+        }
+
+        InternalConnectedDevice connectedDevice = mConnectedDevices.get(deviceId);
+        if (connectedDevice != null) {
+            recipientCallbacks.get(recipientId).invoke(
+                    callback ->
+                            callback.onDeviceError(connectedDevice.mConnectedDevice,
+                                    DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED)
+            );
+        }
+
+        recipientCallbacks.remove(recipientId);
+        mBlacklistedRecipients.add(recipientId);
+    }
+
+    @VisibleForTesting
+    void addConnectedDevice(@NonNull String deviceId, @NonNull CarBleManager bleManager) {
+        if (mConnectedDevices.containsKey(deviceId)) {
+            // Device already connected. No-op until secure channel established.
+            return;
+        }
+        logd(TAG, "New device with id " + deviceId + " connected.");
+        ConnectedDevice connectedDevice = new ConnectedDevice(
+                deviceId,
+                /* deviceName= */ null,
+                mStorage.getActiveUserAssociatedDeviceIds().contains(deviceId),
+                /* hasSecureChannel= */ false
+        );
+
+        mConnectedDevices.put(deviceId, new InternalConnectedDevice(connectedDevice, bleManager));
+        invokeConnectionCallbacks(connectedDevice.isAssociatedWithActiveUser(),
+                callback -> callback.onDeviceConnected(connectedDevice));
+    }
+
+    @VisibleForTesting
+    void removeConnectedDevice(@NonNull String deviceId, @NonNull CarBleManager bleManager) {
+        logd(TAG, "Device " + deviceId + " disconnected from manager " + bleManager);
+        InternalConnectedDevice connectedDevice = getConnectedDeviceForManager(deviceId,
+                bleManager);
+
+        // If disconnect happened on peripheral, open for future requests to connect.
+        if (bleManager == mPeripheralManager) {
+            mIsConnectingToUserDevice.set(false);
+        }
+
+        if (connectedDevice == null) {
+            return;
+        }
+
+        mConnectedDevices.remove(deviceId);
+        boolean isAssociated = connectedDevice.mConnectedDevice.isAssociatedWithActiveUser();
+        invokeConnectionCallbacks(isAssociated,
+                callback -> callback.onDeviceDisconnected(connectedDevice.mConnectedDevice));
+
+        if (isAssociated || mConnectedDevices.isEmpty()) {
+            // Try to regain connection to active user's device.
+            connectToActiveUserDevice();
+        }
+    }
+
+    @VisibleForTesting
+    void onSecureChannelEstablished(@NonNull String deviceId,
+            @NonNull CarBleManager bleManager) {
+        if (mConnectedDevices.get(deviceId) == null) {
+            loge(TAG, "Secure channel established on unknown device " + deviceId + ".");
+            return;
+        }
+        ConnectedDevice connectedDevice = mConnectedDevices.get(deviceId).mConnectedDevice;
+        ConnectedDevice updatedConnectedDevice = new ConnectedDevice(connectedDevice.getDeviceId(),
+                connectedDevice.getDeviceName(), connectedDevice.isAssociatedWithActiveUser(),
+                /* hasSecureChannel= */ true);
+
+        boolean notifyCallbacks = getConnectedDeviceForManager(deviceId, bleManager) != null;
+
+        // TODO (b/143088482) Implement interrupt
+        // Ignore if central already holds the active device connection and interrupt the
+        // connection.
+
+        mConnectedDevices.put(deviceId,
+                new InternalConnectedDevice(updatedConnectedDevice, bleManager));
+        logd(TAG, "Secure channel established to " + deviceId + " . Notifying callbacks: "
+                + notifyCallbacks + ".");
+        if (notifyCallbacks) {
+            notifyAllDeviceCallbacks(deviceId,
+                    callback -> callback.onSecureChannelEstablished(updatedConnectedDevice));
+        }
+    }
+
+    @VisibleForTesting
+    void onMessageReceived(@NonNull String deviceId, @NonNull DeviceMessage message) {
+        logd(TAG, "New message received from device " + deviceId + " intended for "
+                + message.getRecipient() + " containing " + message.getMessage().length
+                + " bytes.");
+
+        InternalConnectedDevice connectedDevice = mConnectedDevices.get(deviceId);
+        if (connectedDevice == null) {
+            logw(TAG, "Received message from unknown device " + deviceId + "or to unknown "
+                    + "recipient " + message.getRecipient() + ".");
+            return;
+        }
+
+        if (mMessageDeliveryDelegate != null
+                && !mMessageDeliveryDelegate.shouldDeliverMessageForDevice(
+                        connectedDevice.mConnectedDevice)) {
+            logw(TAG, "The message delegate has rejected this message. It will not be "
+                    + "delivered to the intended recipient.");
+            return;
+        }
+
+        UUID recipientId = message.getRecipient();
+        Map<UUID, ThreadSafeCallbacks<DeviceCallback>> deviceCallbacks =
+                mDeviceCallbacks.get(deviceId);
+        if (deviceCallbacks == null) {
+            saveMissedMessage(deviceId, recipientId, message.getMessage());
+            return;
+        }
+        ThreadSafeCallbacks<DeviceCallback> recipientCallbacks =
+                deviceCallbacks.get(recipientId);
+        if (recipientCallbacks == null) {
+            saveMissedMessage(deviceId, recipientId, message.getMessage());
+            return;
+        }
+
+        recipientCallbacks.invoke(
+                callback -> callback.onMessageReceived(connectedDevice.mConnectedDevice,
+                        message.getMessage()));
+    }
+
+    @VisibleForTesting
+    void deviceErrorOccurred(@NonNull String deviceId) {
+        InternalConnectedDevice connectedDevice = mConnectedDevices.get(deviceId);
+        if (connectedDevice == null) {
+            logw(TAG, "Failed to establish secure channel on unknown device " + deviceId + ".");
+            return;
+        }
+
+        notifyAllDeviceCallbacks(deviceId,
+                callback -> callback.onDeviceError(connectedDevice.mConnectedDevice,
+                        DEVICE_ERROR_INVALID_SECURITY_KEY));
+    }
+
+    @VisibleForTesting
+    void onAssociationCompleted(@NonNull String deviceId) {
+        InternalConnectedDevice connectedDevice =
+                getConnectedDeviceForManager(deviceId, mPeripheralManager);
+        if (connectedDevice == null) {
+            return;
+        }
+
+        // The previous device is now obsolete and should be replaced with a new one properly
+        // reflecting the state of belonging to the active user and notify features.
+        if (connectedDevice.mConnectedDevice.isAssociatedWithActiveUser()) {
+            // Device was already marked as belonging to active user. No need to reissue callbacks.
+            return;
+        }
+        removeConnectedDevice(deviceId, mPeripheralManager);
+        addConnectedDevice(deviceId, mPeripheralManager);
+    }
+
+    @NonNull
+    private List<String> getActiveUserDeviceIds() {
+        return mStorage.getActiveUserAssociatedDeviceIds();
+    }
+
+    @Nullable
+    private InternalConnectedDevice getConnectedDeviceForManager(@NonNull String deviceId,
+            @NonNull CarBleManager bleManager) {
+        InternalConnectedDevice connectedDevice = mConnectedDevices.get(deviceId);
+        if (connectedDevice != null && connectedDevice.mCarBleManager == bleManager) {
+            return connectedDevice;
+        }
+
+        return null;
+    }
+
+    private void invokeConnectionCallbacks(boolean belongsToActiveUser,
+            @NonNull Consumer<ConnectionCallback> notification) {
+        logd(TAG, "Notifying connection callbacks for device belonging to active user "
+                + belongsToActiveUser + ".");
+        if (belongsToActiveUser) {
+            mActiveUserConnectionCallbacks.invoke(notification);
+        }
+        mAllUserConnectionCallbacks.invoke(notification);
+    }
+
+    private void notifyAllDeviceCallbacks(@NonNull String deviceId,
+            @NonNull Consumer<DeviceCallback> notification) {
+        logd(TAG, "Notifying all device callbacks for device " + deviceId + ".");
+        Map<UUID, ThreadSafeCallbacks<DeviceCallback>> deviceCallbacks =
+                mDeviceCallbacks.get(deviceId);
+        if (deviceCallbacks == null) {
+            return;
+        }
+
+        for (ThreadSafeCallbacks<DeviceCallback> callbacks : deviceCallbacks.values()) {
+            callbacks.invoke(notification);
+        }
+    }
+
+    /**
+     * Returns the name that should be used for the device during enrollment of a trusted device.
+     *
+     * <p>The returned name will be a combination of a prefix sysprop and randomized digits.
+     */
+    @NonNull
+    private String getNameForAssociation() {
+        if (mNameForAssociation == null) {
+            mNameForAssociation = ByteUtils.generateRandomNumberString(DEVICE_NAME_LENGTH_LIMIT);
+        }
+        return mNameForAssociation;
+    }
+
+    @NonNull
+    private CarBleManager.Callback generateCarBleCallback(@NonNull CarBleManager carBleManager) {
+        return new CarBleManager.Callback() {
+            @Override
+            public void onDeviceConnected(String deviceId) {
+                EventLog.onDeviceIdReceived();
+                addConnectedDevice(deviceId, carBleManager);
+            }
+
+            @Override
+            public void onDeviceDisconnected(String deviceId) {
+                removeConnectedDevice(deviceId, carBleManager);
+            }
+
+            @Override
+            public void onSecureChannelEstablished(String deviceId) {
+                EventLog.onSecureChannelEstablished();
+                ConnectedDeviceManager.this.onSecureChannelEstablished(deviceId, carBleManager);
+            }
+
+            @Override
+            public void onMessageReceived(String deviceId, DeviceMessage message) {
+                ConnectedDeviceManager.this.onMessageReceived(deviceId, message);
+            }
+
+            @Override
+            public void onSecureChannelError(String deviceId) {
+                deviceErrorOccurred(deviceId);
+            }
+        };
+    }
+
+    private final AssociationCallback mInternalAssociationCallback = new AssociationCallback() {
+        @Override
+        public void onAssociationStartSuccess(String deviceName) {
+            if (mAssociationCallback != null) {
+                mAssociationCallback.onAssociationStartSuccess(deviceName);
+            }
+        }
+
+        @Override
+        public void onAssociationStartFailure() {
+            if (mAssociationCallback != null) {
+                mAssociationCallback.onAssociationStartFailure();
+            }
+        }
+
+        @Override
+        public void onAssociationError(int error) {
+            if (mAssociationCallback != null) {
+                mAssociationCallback.onAssociationError(error);
+            }
+        }
+
+        @Override
+        public void onVerificationCodeAvailable(String code) {
+            if (mAssociationCallback != null) {
+                mAssociationCallback.onVerificationCodeAvailable(code);
+            }
+        }
+
+        @Override
+        public void onAssociationCompleted(String deviceId) {
+            if (mAssociationCallback != null) {
+                mAssociationCallback.onAssociationCompleted(deviceId);
+            }
+            ConnectedDeviceManager.this.onAssociationCompleted(deviceId);
+        }
+    };
+
+    private final AssociatedDeviceCallback mAssociatedDeviceCallback =
+            new AssociatedDeviceCallback() {
+        @Override
+        public void onAssociatedDeviceAdded(
+                AssociatedDevice device) {
+            mDeviceAssociationCallbacks.invoke(callback ->
+                    callback.onAssociatedDeviceAdded(device));
+        }
+
+        @Override
+        public void onAssociatedDeviceRemoved(AssociatedDevice device) {
+            mDeviceAssociationCallbacks.invoke(callback ->
+                    callback.onAssociatedDeviceRemoved(device));
+            logd(TAG, "Successfully removed associated device " + device + ".");
+        }
+
+        @Override
+        public void onAssociatedDeviceUpdated(AssociatedDevice device) {
+            mDeviceAssociationCallbacks.invoke(callback ->
+                    callback.onAssociatedDeviceUpdated(device));
+        }
+    };
+
+    /** Callback for triggered connection events from {@link ConnectedDeviceManager}. */
+    public interface ConnectionCallback {
+        /** Triggered when a new device has connected. */
+        void onDeviceConnected(@NonNull ConnectedDevice device);
+
+        /** Triggered when a device has disconnected. */
+        void onDeviceDisconnected(@NonNull ConnectedDevice device);
+    }
+
+    /** Triggered device events for a connected device from {@link ConnectedDeviceManager}. */
+    public interface DeviceCallback {
+        /**
+         * Triggered when secure channel has been established on a device. Encrypted messaging now
+         * available.
+         */
+        void onSecureChannelEstablished(@NonNull ConnectedDevice device);
+
+        /** Triggered when a new message is received from a device. */
+        void onMessageReceived(@NonNull ConnectedDevice device, @NonNull byte[] message);
+
+        /** Triggered when an error has occurred for a device. */
+        void onDeviceError(@NonNull ConnectedDevice device, @DeviceError int error);
+    }
+
+    /** Callback for association device related events. */
+    public interface DeviceAssociationCallback {
+
+        /** Triggered when an associated device has been added. */
+        void onAssociatedDeviceAdded(@NonNull AssociatedDevice device);
+
+        /** Triggered when an associated device has been removed. */
+        void onAssociatedDeviceRemoved(@NonNull AssociatedDevice device);
+
+        /** Triggered when the name of an associated device has been updated. */
+        void onAssociatedDeviceUpdated(@NonNull AssociatedDevice device);
+    }
+
+    /** Delegate for message delivery operations. */
+    public interface MessageDeliveryDelegate {
+
+        /** Indicate whether a message should be delivered for the specified device. */
+        boolean shouldDeliverMessageForDevice(@NonNull ConnectedDevice device);
+    }
+
+    private static class InternalConnectedDevice {
+        private final ConnectedDevice mConnectedDevice;
+        private final CarBleManager mCarBleManager;
+
+        InternalConnectedDevice(@NonNull ConnectedDevice connectedDevice,
+                @NonNull CarBleManager carBleManager) {
+            mConnectedDevice = connectedDevice;
+            mCarBleManager = carBleManager;
+        }
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/AssociationSecureChannel.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/AssociationSecureChannel.java
new file mode 100644
index 0000000..349af9e
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/AssociationSecureChannel.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.ble;
+
+import static android.car.encryptionrunner.EncryptionRunnerFactory.EncryptionRunnerType;
+import static android.car.encryptionrunner.EncryptionRunnerFactory.newRunner;
+import static android.car.encryptionrunner.HandshakeMessage.HandshakeState;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.car.encryptionrunner.EncryptionRunner;
+import android.car.encryptionrunner.HandshakeException;
+import android.car.encryptionrunner.HandshakeMessage;
+import android.car.encryptionrunner.Key;
+
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.util.ByteUtils;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.UUID;
+
+/**
+ * A secure channel established with the association flow.
+ */
+class AssociationSecureChannel extends SecureBleChannel {
+
+    private static final String TAG = "AssociationSecureChannel";
+
+    private static final int DEVICE_ID_BYTES = 16;
+
+    private final ConnectedDeviceStorage mStorage;
+
+    private ShowVerificationCodeListener mShowVerificationCodeListener;
+
+    @HandshakeState
+    private int mState = HandshakeState.UNKNOWN;
+
+    private Key mPendingKey;
+
+    private String mDeviceId;
+
+    AssociationSecureChannel(BleDeviceMessageStream stream, ConnectedDeviceStorage storage) {
+        this(stream, storage, newRunner(EncryptionRunnerType.UKEY2));
+    }
+
+    AssociationSecureChannel(BleDeviceMessageStream stream, ConnectedDeviceStorage storage,
+            EncryptionRunner encryptionRunner) {
+        super(stream, encryptionRunner);
+        encryptionRunner.setIsReconnect(false);
+        mStorage = storage;
+    }
+
+    @Override
+    void processHandshake(@NonNull byte[] message) throws HandshakeException {
+        switch (mState) {
+            case HandshakeState.UNKNOWN:
+                processHandshakeUnknown(message);
+                break;
+            case HandshakeState.IN_PROGRESS:
+                processHandshakeInProgress(message);
+                break;
+            case HandshakeState.FINISHED:
+                processHandshakeDeviceIdAndSecret(message);
+                break;
+            default:
+                loge(TAG, "Encountered unexpected handshake state: " + mState + ".");
+                notifySecureChannelFailure(CHANNEL_ERROR_INVALID_STATE);
+        }
+    }
+
+    private void processHandshakeUnknown(@NonNull byte[] message) throws HandshakeException {
+        logd(TAG, "Responding to handshake init request.");
+        HandshakeMessage handshakeMessage = getEncryptionRunner().respondToInitRequest(message);
+        mState = handshakeMessage.getHandshakeState();
+        sendHandshakeMessage(handshakeMessage.getNextMessage(), /* isEncrypted= */ false);
+    }
+
+    private void processHandshakeInProgress(@NonNull byte[] message) throws HandshakeException {
+        logd(TAG, "Continuing handshake.");
+        HandshakeMessage handshakeMessage = getEncryptionRunner().continueHandshake(message);
+        mState = handshakeMessage.getHandshakeState();
+
+        if (mState != HandshakeState.VERIFICATION_NEEDED) {
+            loge(TAG, "processHandshakeInProgress: Encountered unexpected handshake state: "
+                    + mState + ".");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_STATE);
+            return;
+        }
+
+        String code = handshakeMessage.getVerificationCode();
+        if (code == null) {
+            loge(TAG, "Unable to get verification code.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_VERIFICATION);
+            return;
+        }
+
+        if (mShowVerificationCodeListener == null) {
+            loge(TAG, "No verification code listener has been set. Unable to display verification "
+                    + "code to user.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_STATE);
+            return;
+        }
+
+        logd(TAG, "Showing pairing code: " + code);
+        mShowVerificationCodeListener.showVerificationCode(code);
+    }
+
+    private void processHandshakeDeviceIdAndSecret(@NonNull byte[] message) {
+        UUID deviceId = ByteUtils.bytesToUUID(Arrays.copyOf(message, DEVICE_ID_BYTES));
+        if (deviceId == null) {
+            loge(TAG, "Received invalid device id. Aborting.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_DEVICE_ID);
+            return;
+        }
+        mDeviceId = deviceId.toString();
+        notifyCallback(callback -> callback.onDeviceIdReceived(mDeviceId));
+
+        mStorage.saveEncryptionKey(mDeviceId, mPendingKey.asBytes());
+        mPendingKey = null;
+        try {
+            mStorage.saveChallengeSecret(mDeviceId,
+                    Arrays.copyOfRange(message, DEVICE_ID_BYTES, message.length));
+        } catch (InvalidParameterException e) {
+            loge(TAG, "Error saving challenge secret.", e);
+            notifySecureChannelFailure(CHANNEL_ERROR_STORAGE_ERROR);
+            return;
+        }
+
+        notifyCallback(Callback::onSecureChannelEstablished);
+    }
+
+    /** Set the listener that notifies to show verification code. {@code null} to clear. */
+    void setShowVerificationCodeListener(@Nullable ShowVerificationCodeListener listener) {
+        mShowVerificationCodeListener = listener;
+    }
+
+    @VisibleForTesting
+    @Nullable
+    ShowVerificationCodeListener getShowVerificationCodeListener() {
+        return mShowVerificationCodeListener;
+    }
+
+    /**
+     * Called by the client to notify that the user has accepted a pairing code or any out-of-band
+     * confirmation, and send confirmation signals to remote bluetooth device.
+     */
+    void notifyOutOfBandAccepted() {
+        HandshakeMessage message;
+        try {
+            message = getEncryptionRunner().verifyPin();
+        } catch (HandshakeException e) {
+            loge(TAG, "Error during PIN verification", e);
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_VERIFICATION);
+            return;
+        }
+        if (message.getHandshakeState() != HandshakeState.FINISHED) {
+            loge(TAG, "Handshake not finished after calling verify PIN. Instead got "
+                    + "state: " + message.getHandshakeState() + ".");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_STATE);
+            return;
+        }
+
+        Key localKey = message.getKey();
+        if (localKey == null) {
+            loge(TAG, "Unable to finish association, generated key is null.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_ENCRYPTION_KEY);
+            return;
+        }
+        mState = message.getHandshakeState();
+        setEncryptionKey(localKey);
+        mPendingKey = localKey;
+        logd(TAG, "Pairing code successfully verified.");
+        sendUniqueIdToClient();
+    }
+
+    private void sendUniqueIdToClient() {
+        UUID uniqueId = mStorage.getUniqueId();
+        DeviceMessage deviceMessage = new DeviceMessage(/* recipient= */ null,
+                /* isMessageEncrypted= */ true, ByteUtils.uuidToBytes(uniqueId));
+        logd(TAG, "Sending car's device id of " + uniqueId + " to device.");
+        sendHandshakeMessage(ByteUtils.uuidToBytes(uniqueId), /* isEncrypted= */ true);
+    }
+
+    /** Listener that will be invoked to display verification code. */
+    interface ShowVerificationCodeListener {
+        /**
+         * Invoke when a verification need to be displayed during device association.
+         *
+         * @param code The verification code to show.
+         */
+        void showVerificationCode(@NonNull String code);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/BleCentralManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/BleCentralManager.java
new file mode 100644
index 0000000..ca83a05
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/BleCentralManager.java
@@ -0,0 +1,194 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Class that manages BLE scanning operations.
+ */
+public class BleCentralManager {
+
+    private static final String TAG = "BleCentralManager";
+
+    private static final int RETRY_LIMIT = 5;
+
+    private static final int RETRY_INTERVAL_MS = 1000;
+
+    private final Context mContext;
+
+    private final Handler mHandler;
+
+    private List<ScanFilter> mScanFilters;
+
+    private ScanSettings mScanSettings;
+
+    private ScanCallback mScanCallback;
+
+    private BluetoothLeScanner mScanner;
+
+    private int mScannerStartCount = 0;
+
+    private AtomicInteger mScannerState = new AtomicInteger(STOPPED);
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            STOPPED,
+            STARTED,
+            SCANNING
+    })
+    private @interface ScannerState {}
+    private static final int STOPPED = 0;
+    private static final int STARTED = 1;
+    private static final int SCANNING = 2;
+
+    public BleCentralManager(@NonNull Context context) {
+        mContext = context;
+        mHandler = new Handler(context.getMainLooper());
+    }
+
+    /**
+     * Start the BLE scanning process.
+     *
+     * @param filters Optional list of {@link ScanFilter}s to apply to scan results.
+     * @param settings {@link ScanSettings} to apply to scanner.
+     * @param callback {@link ScanCallback} for scan events.
+     */
+    public void startScanning(@Nullable List<ScanFilter> filters, @NonNull ScanSettings settings,
+            @NonNull ScanCallback callback) {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
+            loge(TAG, "Attempted start scanning, but system does not support BLE. Ignoring");
+            return;
+        }
+        logd(TAG, "Request received to start scanning.");
+        mScannerStartCount = 0;
+        mScanFilters = filters;
+        mScanSettings = settings;
+        mScanCallback = callback;
+        updateScannerState(STARTED);
+        startScanningInternally();
+    }
+
+    /** Stop the scanner */
+    public void stopScanning() {
+        logd(TAG, "Attempting to stop scanning");
+        if (mScanner != null) {
+            mScanner.stopScan(mInternalScanCallback);
+        }
+        mScanCallback = null;
+        updateScannerState(STOPPED);
+    }
+
+    /** Returns {@code true} if currently scanning, {@code false} otherwise. */
+    public boolean isScanning() {
+        return mScannerState.get() == SCANNING;
+    }
+
+    /** Clean up the scanning process. */
+    public void cleanup() {
+        if (isScanning()) {
+            stopScanning();
+        }
+    }
+
+    private void startScanningInternally() {
+        logd(TAG, "Attempting to start scanning");
+        if (mScanner == null && BluetoothAdapter.getDefaultAdapter() != null) {
+            mScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
+        }
+        if (mScanner != null) {
+            mScanner.startScan(mScanFilters, mScanSettings, mInternalScanCallback);
+            updateScannerState(SCANNING);
+        } else {
+            mHandler.postDelayed(() -> {
+                // Keep trying
+                logd(TAG, "Scanner unavailable. Trying again.");
+                startScanningInternally();
+            }, RETRY_INTERVAL_MS);
+        }
+    }
+
+    private void updateScannerState(@ScannerState int newState) {
+        mScannerState.set(newState);
+    }
+
+    private final ScanCallback mInternalScanCallback = new ScanCallback() {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            if (mScanCallback != null) {
+                mScanCallback.onScanResult(callbackType, result);
+            }
+        }
+
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            logd(TAG, "Batch scan found " + results.size() + " results.");
+            if (mScanCallback != null) {
+                mScanCallback.onBatchScanResults(results);
+            }
+        }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            if (mScannerStartCount >= RETRY_LIMIT) {
+                loge(TAG, "Cannot start BLE Scanner. Scanning Retry count: "
+                        + mScannerStartCount);
+                if (mScanCallback != null) {
+                    mScanCallback.onScanFailed(errorCode);
+                }
+                return;
+            }
+
+            mScannerStartCount++;
+            logw(TAG, "BLE Scanner failed to start. Error: "
+                    + errorCode
+                    + " Retry: "
+                    + mScannerStartCount);
+            switch(errorCode) {
+                case SCAN_FAILED_ALREADY_STARTED:
+                    // Scanner already started. Do nothing.
+                    break;
+                case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
+                case SCAN_FAILED_INTERNAL_ERROR:
+                    mHandler.postDelayed(BleCentralManager.this::startScanningInternally,
+                            RETRY_INTERVAL_MS);
+                    break;
+                default:
+                    // Ignore other codes.
+            }
+        }
+    };
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/BleDeviceMessageStream.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/BleDeviceMessageStream.java
new file mode 100644
index 0000000..7ff3959
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/BleDeviceMessageStream.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.BleStreamProtos.BleOperationProto.OperationType;
+import static com.android.car.connecteddevice.BleStreamProtos.BlePacketProto.BlePacket;
+import static com.android.car.connecteddevice.BleStreamProtos.VersionExchangeProto.BleVersionExchange;
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.os.Handler;
+import android.os.Looper;
+
+import com.android.car.connecteddevice.BleStreamProtos.BleDeviceMessageProto.BleDeviceMessage;
+import com.android.car.connecteddevice.util.ByteUtils;
+import com.android.car.protobuf.ByteString;
+import com.android.car.protobuf.InvalidProtocolBufferException;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/** BLE message stream to a device. */
+class BleDeviceMessageStream {
+
+    private static final String TAG = "BleDeviceMessageStream";
+
+    // Only version 2 of the messaging and version 2 of the security supported.
+    private static final int MESSAGING_VERSION = 2;
+    private static final int SECURITY_VERSION = 2;
+
+    /*
+     * During bandwidth testing, it was discovered that allowing the stream to send as fast as it
+     * can blocked outgoing notifications from being received by the connected device. Adding a
+     * throttle to the outgoing messages alleviated this block and allowed both sides to
+     * send/receive in parallel successfully.
+     */
+    private static final long THROTTLE_DEFAULT_MS = 10L;
+    private static final long THROTTLE_WAIT_MS = 75L;
+
+    private final ArrayDeque<BlePacket> mPacketQueue = new ArrayDeque<>();
+
+    private final Map<Integer, ByteArrayOutputStream> mPendingData = new HashMap<>();
+
+    // messageId -> nextExpectedPacketNumber
+    private final Map<Integer, Integer> mPendingPacketNumber = new HashMap<>();
+
+    private final MessageIdGenerator mMessageIdGenerator = new MessageIdGenerator();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    private final AtomicBoolean mIsVersionExchanged = new AtomicBoolean(false);
+
+    private final AtomicBoolean mIsSendingInProgress = new AtomicBoolean(false);
+
+    private final AtomicLong mThrottleDelay = new AtomicLong(THROTTLE_DEFAULT_MS);
+
+    private final BlePeripheralManager mBlePeripheralManager;
+
+    private final BluetoothDevice mDevice;
+
+    private final BluetoothGattCharacteristic mWriteCharacteristic;
+
+    private final BluetoothGattCharacteristic mReadCharacteristic;
+
+    private MessageReceivedListener mMessageReceivedListener;
+
+    private MessageReceivedErrorListener mMessageReceivedErrorListener;
+
+    private int mMaxWriteSize;
+
+    BleDeviceMessageStream(@NonNull BlePeripheralManager blePeripheralManager,
+            @NonNull BluetoothDevice device,
+            @NonNull BluetoothGattCharacteristic writeCharacteristic,
+            @NonNull BluetoothGattCharacteristic readCharacteristic,
+            int defaultMaxWriteSize) {
+        mBlePeripheralManager = blePeripheralManager;
+        mDevice = device;
+        mWriteCharacteristic = writeCharacteristic;
+        mReadCharacteristic = readCharacteristic;
+        mBlePeripheralManager.addOnCharacteristicWriteListener(this::onCharacteristicWrite);
+        mBlePeripheralManager.addOnCharacteristicReadListener(this::onCharacteristicRead);
+        mMaxWriteSize = defaultMaxWriteSize;
+    }
+
+    /**
+     * Writes the given message to the write characteristic of this stream with operation type
+     * {@code CLIENT_MESSAGE}.
+     *
+     * This method will handle the chunking of messages based on the max write size.
+     *
+     * @param deviceMessage The data object contains recipient, isPayloadEncrypted and message.
+     */
+    void writeMessage(@NonNull DeviceMessage deviceMessage) {
+        writeMessage(deviceMessage, OperationType.CLIENT_MESSAGE);
+    }
+
+    /**
+     * Writes the given message to the write characteristic of this stream.
+     *
+     * This method will handle the chunking of messages based on the max write size. If it is
+     * a handshake message, the message recipient should be {@code null} and it cannot be
+     * encrypted.
+     *
+     * @param deviceMessage The data object contains recipient, isPayloadEncrypted and message.
+     * @param operationType The {@link OperationType} of this message.
+     */
+    void writeMessage(@NonNull DeviceMessage deviceMessage, OperationType operationType) {
+        logd(TAG, "Writing message with " + deviceMessage.getMessage().length + " bytes to device: "
+                + mDevice.getAddress() + ".");
+        BleDeviceMessage.Builder builder = BleDeviceMessage.newBuilder()
+                .setOperation(operationType)
+                .setIsPayloadEncrypted(deviceMessage.isMessageEncrypted())
+                .setPayload(ByteString.copyFrom(deviceMessage.getMessage()));
+
+        UUID recipient = deviceMessage.getRecipient();
+        if (recipient != null) {
+            builder.setRecipient(ByteString.copyFrom(ByteUtils.uuidToBytes(recipient)));
+        }
+
+        BleDeviceMessage bleDeviceMessage = builder.build();
+        byte[] rawBytes = bleDeviceMessage.toByteArray();
+        List<BlePacket> blePackets;
+        try {
+            blePackets = BlePacketFactory.makeBlePackets(rawBytes, mMessageIdGenerator.next(),
+                    mMaxWriteSize);
+        } catch (BlePacketFactoryException e) {
+            loge(TAG, "Error while creating message packets.", e);
+            return;
+        }
+        mPacketQueue.addAll(blePackets);
+        writeNextMessageInQueue();
+    }
+
+    private void writeNextMessageInQueue() {
+        mHandler.postDelayed(() -> {
+            if (mPacketQueue.isEmpty()) {
+                logd(TAG, "No more packets to send.");
+                return;
+            }
+            if (mIsSendingInProgress.get()) {
+                logd(TAG, "Unable to send packet at this time.");
+                return;
+            }
+
+            mIsSendingInProgress.set(true);
+            BlePacket packet = mPacketQueue.remove();
+            logd(TAG, "Writing packet " + packet.getPacketNumber() + " of "
+                    + packet.getTotalPackets() + " for " + packet.getMessageId() + ".");
+            mWriteCharacteristic.setValue(packet.toByteArray());
+            mBlePeripheralManager.notifyCharacteristicChanged(mDevice, mWriteCharacteristic,
+                    /* confirm= */ false);
+        }, mThrottleDelay.get());
+    }
+
+    private void onCharacteristicRead(@NonNull BluetoothDevice device) {
+        if (!mDevice.equals(device)) {
+            logw(TAG, "Received a read notification from a device (" + device.getAddress()
+                    + ") that is not the expected device (" + mDevice.getAddress() + ") registered "
+                    + "to this stream. Ignoring.");
+            return;
+        }
+
+        logd(TAG, "Releasing lock on characteristic.");
+        mIsSendingInProgress.set(false);
+        writeNextMessageInQueue();
+    }
+
+    private void onCharacteristicWrite(@NonNull BluetoothDevice device,
+            @NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value) {
+        logd(TAG, "Received a message from a device (" + device.getAddress() + ").");
+        if (!mDevice.equals(device)) {
+            logw(TAG, "Received a message from a device (" + device.getAddress() + ") that is not "
+                    + "the expected device (" + mDevice.getAddress() + ") registered to this "
+                    + "stream. Ignoring.");
+            return;
+        }
+
+        if (!characteristic.getUuid().equals(mReadCharacteristic.getUuid())) {
+            logw(TAG, "Received a write to a characteristic (" + characteristic.getUuid() + ") that"
+                    + " is not the expected UUID (" + mReadCharacteristic.getUuid() + "). "
+                    + "Ignoring.");
+            return;
+        }
+
+        if (!mIsVersionExchanged.get()) {
+            processVersionExchange(device, value);
+            return;
+        }
+
+        BlePacket packet;
+        try {
+            packet = BlePacket.parseFrom(value);
+        } catch (InvalidProtocolBufferException e) {
+            loge(TAG, "Can not parse Ble packet from client.", e);
+            if (mMessageReceivedErrorListener != null) {
+                mMessageReceivedErrorListener.onMessageReceivedError(e);
+            }
+            return;
+        }
+        processPacket(packet);
+    }
+
+    private void processVersionExchange(@NonNull BluetoothDevice device, @NonNull byte[] value) {
+        BleVersionExchange versionExchange;
+        try {
+            versionExchange = BleVersionExchange.parseFrom(value);
+        } catch (InvalidProtocolBufferException e) {
+            loge(TAG, "Could not parse version exchange message", e);
+            if (mMessageReceivedErrorListener != null) {
+                mMessageReceivedErrorListener.onMessageReceivedError(e);
+            }
+            return;
+        }
+        int minMessagingVersion = versionExchange.getMinSupportedMessagingVersion();
+        int maxMessagingVersion = versionExchange.getMaxSupportedMessagingVersion();
+        int minSecurityVersion = versionExchange.getMinSupportedSecurityVersion();
+        int maxSecurityVersion = versionExchange.getMaxSupportedSecurityVersion();
+        if (minMessagingVersion > MESSAGING_VERSION || maxMessagingVersion < MESSAGING_VERSION
+                || minSecurityVersion > SECURITY_VERSION || maxSecurityVersion < SECURITY_VERSION) {
+            loge(TAG, "Unsupported message version for min " + minMessagingVersion + " and max "
+                    + maxMessagingVersion + " or security version for " + minSecurityVersion
+                    + " and max " + maxSecurityVersion + ".");
+            if (mMessageReceivedErrorListener != null) {
+                mMessageReceivedErrorListener.onMessageReceivedError(
+                        new IllegalStateException("Unsupported version."));
+            }
+            return;
+        }
+
+        BleVersionExchange headunitVersion = BleVersionExchange.newBuilder()
+                .setMinSupportedMessagingVersion(MESSAGING_VERSION)
+                .setMaxSupportedMessagingVersion(MESSAGING_VERSION)
+                .setMinSupportedSecurityVersion(SECURITY_VERSION)
+                .setMaxSupportedSecurityVersion(SECURITY_VERSION)
+                .build();
+        mWriteCharacteristic.setValue(headunitVersion.toByteArray());
+        mBlePeripheralManager.notifyCharacteristicChanged(device, mWriteCharacteristic,
+                /* confirm= */ false);
+        mIsVersionExchanged.set(true);
+        logd(TAG, "Sent supported version to the phone.");
+    }
+
+    @VisibleForTesting
+    void processPacket(@NonNull BlePacket packet) {
+        // Messages are coming in. Need to throttle outgoing messages to allow outgoing
+        // notifications to make it to the device.
+        mThrottleDelay.set(THROTTLE_WAIT_MS);
+
+        int messageId = packet.getMessageId();
+        int packetNumber = packet.getPacketNumber();
+        int expectedPacket = mPendingPacketNumber.getOrDefault(messageId, 1);
+        if (packetNumber == expectedPacket - 1) {
+            logw(TAG, "Received duplicate packet " + packet.getPacketNumber() + " for message "
+                    + messageId + ". Ignoring.");
+            return;
+        }
+        if (packetNumber != expectedPacket) {
+            loge(TAG, "Received unexpected packet " + packetNumber + " for message "
+                    + messageId + ".");
+            if (mMessageReceivedErrorListener != null) {
+                mMessageReceivedErrorListener.onMessageReceivedError(
+                        new IllegalStateException("Packet received out of order."));
+            }
+            return;
+        }
+        mPendingPacketNumber.put(messageId, packetNumber + 1);
+
+        ByteArrayOutputStream currentPayloadStream =
+                mPendingData.getOrDefault(messageId, new ByteArrayOutputStream());
+        mPendingData.putIfAbsent(messageId, currentPayloadStream);
+
+        byte[] payload = packet.getPayload().toByteArray();
+        try {
+            currentPayloadStream.write(payload);
+        } catch (IOException e) {
+            loge(TAG, "Error writing packet to stream.", e);
+            if (mMessageReceivedErrorListener != null) {
+                mMessageReceivedErrorListener.onMessageReceivedError(e);
+            }
+            return;
+        }
+        logd(TAG, "Parsed packet " + packet.getPacketNumber() + " of "
+                + packet.getTotalPackets() + " for message " + messageId + ". Writing "
+                + payload.length + ".");
+
+        if (packet.getPacketNumber() != packet.getTotalPackets()) {
+            return;
+        }
+
+        byte[] messageBytes = currentPayloadStream.toByteArray();
+        mPendingData.remove(messageId);
+
+        // All message packets received. Resetting throttle back to default until next message
+        // started.
+        mThrottleDelay.set(THROTTLE_DEFAULT_MS);
+
+        logd(TAG, "Received complete device message " + messageId + " of " + messageBytes.length
+                + " bytes.");
+        BleDeviceMessage message;
+        try {
+            message = BleDeviceMessage.parseFrom(messageBytes);
+        } catch (InvalidProtocolBufferException e) {
+            loge(TAG, "Cannot parse device message from client.", e);
+            if (mMessageReceivedErrorListener != null) {
+                mMessageReceivedErrorListener.onMessageReceivedError(e);
+            }
+            return;
+        }
+
+        DeviceMessage deviceMessage = new DeviceMessage(
+                ByteUtils.bytesToUUID(message.getRecipient().toByteArray()),
+                message.getIsPayloadEncrypted(), message.getPayload().toByteArray());
+        if (mMessageReceivedListener != null) {
+            mMessageReceivedListener.onMessageReceived(deviceMessage, message.getOperation());
+        }
+    }
+
+    /** The maximum amount of bytes that can be written over BLE. */
+    void setMaxWriteSize(int maxWriteSize) {
+        if (maxWriteSize <= 0) {
+            return;
+        }
+        mMaxWriteSize = maxWriteSize;
+    }
+
+    /**
+     * Set the given listener to be notified when a new message was received from the
+     * client. If listener is {@code null}, clear.
+     */
+    void setMessageReceivedListener(@Nullable MessageReceivedListener listener) {
+        mMessageReceivedListener = listener;
+    }
+
+    /**
+     * Set the given listener to be notified when there was an error during receiving
+     * message from the client. If listener is {@code null}, clear.
+     */
+    void setMessageReceivedErrorListener(
+            @Nullable MessageReceivedErrorListener listener) {
+        mMessageReceivedErrorListener = listener;
+    }
+
+    /**
+     * Listener to be invoked when a complete message is received from the client.
+     */
+    interface MessageReceivedListener {
+
+        /**
+         * Called when a complete message is received from the client.
+         *
+         * @param deviceMessage The message received from the client.
+         * @param operationType The {@link OperationType} of the received message.
+         */
+        void onMessageReceived(@NonNull DeviceMessage deviceMessage, OperationType operationType);
+    }
+
+    /**
+     * Listener to be invoked when there was an error during receiving message from the client.
+     */
+    interface MessageReceivedErrorListener {
+        /**
+         * Called when there was an error during receiving message from the client.
+         *
+         * @param exception The error.
+         */
+        void onMessageReceivedError(@NonNull Exception exception);
+    }
+
+    /** A generator of unique IDs for messages. */
+    private static class MessageIdGenerator {
+        private final AtomicInteger mMessageId = new AtomicInteger(0);
+
+        int next() {
+            int current = mMessageId.getAndIncrement();
+            mMessageId.compareAndSet(Integer.MAX_VALUE, 0);
+            return current;
+        }
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePacketFactory.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePacketFactory.java
new file mode 100644
index 0000000..a0d0bb1
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePacketFactory.java
@@ -0,0 +1,155 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+
+import com.android.car.connecteddevice.BleStreamProtos.BlePacketProto.BlePacket;
+import com.android.car.protobuf.ByteString;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Factory for creating {@link BlePacket} protos.
+ */
+class BlePacketFactory {
+    private static final String TAG = "BlePacketFactory";
+
+    /**
+     * The size in bytes of a {@code fixed32} field in the proto.
+     */
+    private static final int FIXED_32_SIZE = 4;
+
+    /**
+     * The bytes needed to encode the field number in the proto.
+     *
+     * <p>Since the {@link BlePacket} only has 4 fields, it will only take 1 additional byte to
+     * encode.
+     */
+    private static final int FIELD_NUMBER_ENCODING_SIZE = 1;
+
+    /**
+     * The size in bytes of field {@code packet_number}. The proto field is a {@code fixed32}.
+     */
+    private static final int PACKET_NUMBER_ENCODING_SIZE =
+            FIXED_32_SIZE + FIELD_NUMBER_ENCODING_SIZE;
+
+    /**
+     * Split given data if necessary to fit within the given {@code maxSize}.
+     *
+     * @param payload The payload to potentially split across multiple {@link BlePacket}s.
+     * @param messageId The unique id for identifying message.
+     * @param maxSize The maximum size of each chunk.
+     * @return A list of {@link BlePacket}s.
+     * @throws BlePacketFactoryException if an error occurred during the splitting of data.
+     */
+    static List<BlePacket> makeBlePackets(byte[] payload, int messageId, int maxSize)
+            throws BlePacketFactoryException {
+        List<BlePacket> blePackets = new ArrayList<>();
+        int payloadSize = payload.length;
+        int totalPackets = getTotalPacketNumber(messageId, payloadSize, maxSize);
+        int maxPayloadSize = maxSize
+                - getPacketHeaderSize(totalPackets, messageId, Math.min(payloadSize, maxSize));
+
+        int start = 0;
+        int end = Math.min(payloadSize, maxPayloadSize);
+        for (int packetNum = 1; packetNum <= totalPackets; packetNum++) {
+            blePackets.add(BlePacket.newBuilder()
+                    .setPacketNumber(packetNum)
+                    .setTotalPackets(totalPackets)
+                    .setMessageId(messageId)
+                    .setPayload(ByteString.copyFrom(Arrays.copyOfRange(payload, start, end)))
+                    .build());
+            start = end;
+            end = Math.min(start + maxPayloadSize, payloadSize);
+        }
+        return blePackets;
+    }
+
+    /**
+     * Compute the header size for the {@link BlePacket} proto in bytes. This method assumes that
+     * the proto contains a payload.
+     */
+    @VisibleForTesting
+    static int getPacketHeaderSize(int totalPackets, int messageId, int payloadSize) {
+        return FIXED_32_SIZE + FIELD_NUMBER_ENCODING_SIZE
+                + getEncodedSize(totalPackets) + FIELD_NUMBER_ENCODING_SIZE
+                + getEncodedSize(messageId) + FIELD_NUMBER_ENCODING_SIZE
+                + getEncodedSize(payloadSize) + FIELD_NUMBER_ENCODING_SIZE;
+    }
+
+    /**
+     * Compute the total packets required to encode a payload of the given size.
+     */
+    @VisibleForTesting
+    static int getTotalPacketNumber(int messageId, int payloadSize, int maxSize)
+            throws BlePacketFactoryException {
+        int headerSizeWithoutTotalPackets = FIXED_32_SIZE + FIELD_NUMBER_ENCODING_SIZE
+                + getEncodedSize(messageId) + FIELD_NUMBER_ENCODING_SIZE
+                + getEncodedSize(Math.min(payloadSize, maxSize)) + FIELD_NUMBER_ENCODING_SIZE;
+
+        for (int value = 1; value <= PACKET_NUMBER_ENCODING_SIZE; value++) {
+            int packetHeaderSize = headerSizeWithoutTotalPackets + value
+                    + FIELD_NUMBER_ENCODING_SIZE;
+            int maxPayloadSize = maxSize - packetHeaderSize;
+            if (maxPayloadSize < 0) {
+                throw new BlePacketFactoryException("Packet header size too large.");
+            }
+            int totalPackets = (int) Math.ceil(payloadSize / (double) maxPayloadSize);
+            if (getEncodedSize(totalPackets) == value) {
+                return totalPackets;
+            }
+        }
+
+        loge(TAG, "Cannot get valid total packet number for message: messageId: "
+                + messageId + ", payloadSize: " + payloadSize + ", maxSize: " + maxSize);
+        throw new BlePacketFactoryException("No valid total packet number.");
+    }
+
+    /**
+     * This method implements Protocol Buffers encoding algorithm.
+     *
+     * <p>Computes the number of bytes that would be needed to store a 32-bit variant.
+     *
+     * @param value the data that need to be encoded
+     * @return the size of the encoded data
+     * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding#varints">
+     *     Protocol Buffers Encoding</a>
+     */
+    private static int getEncodedSize(int value) {
+        if (value < 0) {
+            return 10;
+        }
+        if ((value & (~0 << 7)) == 0) {
+            return 1;
+        }
+        if ((value & (~0 << 14)) == 0) {
+            return 2;
+        }
+        if ((value & (~0 << 21)) == 0) {
+            return 3;
+        }
+        if ((value & (~0 << 28)) == 0) {
+            return 4;
+        }
+        return 5;
+    }
+
+    private BlePacketFactory() {}
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePacketFactoryException.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePacketFactoryException.java
new file mode 100644
index 0000000..690ce28
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePacketFactoryException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.car.connecteddevice.ble;
+
+/**
+ * Exception for signaling {@link BlePacketFactory} errors.
+ */
+class BlePacketFactoryException extends Exception {
+    BlePacketFactoryException(String message) {
+        super(message);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePeripheralManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePeripheralManager.java
new file mode 100644
index 0000000..51da3d7
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/BlePeripheralManager.java
@@ -0,0 +1,527 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattServer;
+import android.bluetooth.BluetoothGattServerCallback;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.BluetoothLeAdvertiser;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+
+import com.android.car.connecteddevice.util.ByteUtils;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * A generic class that manages BLE peripheral operations like start/stop advertising, notifying
+ * connects/disconnects and reading/writing values to GATT characteristics.
+ */
+// TODO(b/123248433) This could move to a separate comms library.
+public class BlePeripheralManager {
+    private static final String TAG = "BlePeripheralManager";
+
+    private static final int BLE_RETRY_LIMIT = 5;
+    private static final int BLE_RETRY_INTERVAL_MS = 1000;
+
+    private static final int GATT_SERVER_RETRY_LIMIT = 20;
+    private static final int GATT_SERVER_RETRY_DELAY_MS = 200;
+
+    // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth
+    // .service.generic_access.xml
+    private static final UUID GENERIC_ACCESS_PROFILE_UUID =
+            UUID.fromString("00001800-0000-1000-8000-00805f9b34fb");
+    // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth
+    // .characteristic.gap.device_name.xml
+    private static final UUID DEVICE_NAME_UUID =
+            UUID.fromString("00002a00-0000-1000-8000-00805f9b34fb");
+
+    private final Handler mHandler;
+
+    private final Context mContext;
+    private final Set<Callback> mCallbacks = new CopyOnWriteArraySet<>();
+    private final Set<OnCharacteristicWriteListener> mWriteListeners = new HashSet<>();
+    private final Set<OnCharacteristicReadListener> mReadListeners = new HashSet<>();
+    private final AtomicReference<BluetoothGattServer> mGattServer = new AtomicReference<>();
+    private final AtomicReference<BluetoothGatt> mBluetoothGatt = new AtomicReference<>();
+
+    private int mMtuSize = 20;
+
+    private BluetoothManager mBluetoothManager;
+    private BluetoothLeAdvertiser mAdvertiser;
+    private int mAdvertiserStartCount;
+    private int mGattServerRetryStartCount;
+    private BluetoothGattService mBluetoothGattService;
+    private AdvertiseCallback mAdvertiseCallback;
+    private AdvertiseData mAdvertiseData;
+
+    public BlePeripheralManager(Context context) {
+        mContext = context;
+        mHandler = new Handler(mContext.getMainLooper());
+    }
+
+    /**
+     * Registers the given callback to be notified of various events within the {@link
+     * BlePeripheralManager}.
+     *
+     * @param callback The callback to be notified.
+     */
+    void registerCallback(@NonNull Callback callback) {
+        mCallbacks.add(callback);
+    }
+
+    /**
+     * Unregisters a previously registered callback.
+     *
+     * @param callback The callback to unregister.
+     */
+    void unregisterCallback(@NonNull Callback callback) {
+        mCallbacks.remove(callback);
+    }
+
+    /**
+     * Adds a listener to be notified of a write to characteristics.
+     *
+     * @param listener The listener to invoke.
+     */
+    void addOnCharacteristicWriteListener(@NonNull OnCharacteristicWriteListener listener) {
+        mWriteListeners.add(listener);
+    }
+
+    /**
+     * Removes the given listener from being notified of characteristic writes.
+     *
+     * @param listener The listener to remove.
+     */
+    void removeOnCharacteristicWriteListener(@NonNull OnCharacteristicWriteListener listener) {
+        mWriteListeners.remove(listener);
+    }
+
+    /**
+     * Adds a listener to be notified of reads to characteristics.
+     *
+     * @param listener The listener to invoke.
+     */
+    void addOnCharacteristicReadListener(@NonNull OnCharacteristicReadListener listener) {
+        mReadListeners.add(listener);
+    }
+
+    /**
+     * Removes the given listener from being notified of characteristic reads.
+     *
+     * @param listener The listener to remove.
+     */
+    void removeOnCharacteristicReadistener(@NonNull OnCharacteristicReadListener listener) {
+        mReadListeners.remove(listener);
+    }
+
+    /**
+     * Returns the current MTU size.
+     *
+     * @return The size of the MTU in bytes.
+     */
+    int getMtuSize() {
+        return mMtuSize;
+    }
+
+    /**
+     * Starts the GATT server with the given {@link BluetoothGattService} and begins advertising.
+     *
+     * <p>It is possible that BLE service is still in TURNING_ON state when this method is invoked.
+     * Therefore, several retries will be made to ensure advertising is started.
+     *
+     * @param service           {@link BluetoothGattService} that will be discovered by clients
+     * @param data              {@link AdvertiseData} data to advertise
+     * @param advertiseCallback {@link AdvertiseCallback} callback for advertiser
+     */
+    void startAdvertising(
+            BluetoothGattService service, AdvertiseData data, AdvertiseCallback advertiseCallback) {
+        logd(TAG, "startAdvertising: " + service.getUuid());
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
+            loge(TAG, "Attempted start advertising, but system does not support BLE. Ignoring.");
+            return;
+        }
+        // Clears previous session before starting advertising.
+        cleanup();
+        mBluetoothGattService = service;
+        mAdvertiseCallback = advertiseCallback;
+        mAdvertiseData = data;
+        mGattServerRetryStartCount = 0;
+        mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
+        mGattServer.set(mBluetoothManager.openGattServer(mContext, mGattServerCallback));
+        openGattServer();
+    }
+
+    /**
+     * Stops the GATT server from advertising.
+     *
+     * @param advertiseCallback The callback that is associated with the advertisement.
+     */
+    void stopAdvertising(AdvertiseCallback advertiseCallback) {
+        if (mAdvertiser != null) {
+            logd(TAG, "Stop advertising.");
+            mAdvertiser.stopAdvertising(advertiseCallback);
+        }
+    }
+
+    /**
+     * Notifies the characteristic change via {@link BluetoothGattServer}
+     */
+    void notifyCharacteristicChanged(
+            @NonNull BluetoothDevice device,
+            @NonNull BluetoothGattCharacteristic characteristic,
+            boolean confirm) {
+        BluetoothGattServer gattServer = mGattServer.get();
+        if (gattServer == null) {
+            return;
+        }
+
+        if (!gattServer.notifyCharacteristicChanged(device, characteristic, confirm)) {
+            loge(TAG, "notifyCharacteristicChanged failed");
+        }
+    }
+
+    /**
+     * Connect the Gatt server of the remote device to retrieve device name.
+     */
+    final void retrieveDeviceName(BluetoothDevice device) {
+        mBluetoothGatt.compareAndSet(null, device.connectGatt(mContext, false, mGattCallback));
+    }
+
+    /**
+     * Cleans up the BLE GATT server state.
+     */
+    void cleanup() {
+        // Stops the advertiser, scanner and GATT server. This needs to be done to avoid leaks.
+        if (mAdvertiser != null) {
+            mAdvertiser.stopAdvertising(mAdvertiseCallback);
+        }
+        // Clears all registered listeners. IHU only supports single connection in peripheral role.
+        mReadListeners.clear();
+        mWriteListeners.clear();
+        mAdvertiser = null;
+
+        BluetoothGattServer gattServer = mGattServer.getAndSet(null);
+        if (gattServer == null) {
+            return;
+        }
+
+        logd(TAG, "Stopping gatt server.");
+        BluetoothGatt bluetoothGatt = mBluetoothGatt.getAndSet(null);
+        if (bluetoothGatt != null) {
+            gattServer.cancelConnection(bluetoothGatt.getDevice());
+            logd(TAG, "Disconnecting gatt.");
+            bluetoothGatt.disconnect();
+            bluetoothGatt.close();
+        }
+        gattServer.clearServices();
+        gattServer.close();
+    }
+
+    private void openGattServer() {
+        // Only open one Gatt server.
+        BluetoothGattServer gattServer = mGattServer.get();
+        if (gattServer != null) {
+            logd(TAG, "Gatt Server created, retry count: " + mGattServerRetryStartCount);
+            gattServer.clearServices();
+            gattServer.addService(mBluetoothGattService);
+            AdvertiseSettings settings =
+                    new AdvertiseSettings.Builder()
+                            .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
+                            .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
+                            .setConnectable(true)
+                            .build();
+            mAdvertiserStartCount = 0;
+            startAdvertisingInternally(settings, mAdvertiseData, mAdvertiseCallback);
+            mGattServerRetryStartCount = 0;
+        } else if (mGattServerRetryStartCount < GATT_SERVER_RETRY_LIMIT) {
+            mGattServer.set(mBluetoothManager.openGattServer(mContext, mGattServerCallback));
+            mGattServerRetryStartCount++;
+            mHandler.postDelayed(() -> openGattServer(), GATT_SERVER_RETRY_DELAY_MS);
+        } else {
+            loge(TAG, "Gatt server not created - exceeded retry limit.");
+        }
+    }
+
+    private void startAdvertisingInternally(
+            AdvertiseSettings settings, AdvertiseData data, AdvertiseCallback advertiseCallback) {
+        if (BluetoothAdapter.getDefaultAdapter() != null) {
+            mAdvertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
+        }
+
+        if (mAdvertiser != null) {
+            logd(TAG, "Advertiser created, retry count: " + mAdvertiserStartCount);
+            mAdvertiser.startAdvertising(settings, data, advertiseCallback);
+            mAdvertiserStartCount = 0;
+        } else if (mAdvertiserStartCount < BLE_RETRY_LIMIT) {
+            mHandler.postDelayed(
+                    () -> startAdvertisingInternally(settings, data, advertiseCallback),
+                    BLE_RETRY_INTERVAL_MS);
+            mAdvertiserStartCount += 1;
+        } else {
+            loge(TAG, "Cannot start BLE Advertisement. Advertise Retry count: "
+                            + mAdvertiserStartCount);
+        }
+    }
+
+    private final BluetoothGattServerCallback mGattServerCallback =
+            new BluetoothGattServerCallback() {
+                @Override
+                public void onConnectionStateChange(BluetoothDevice device, int status,
+                                                    int newState) {
+                    logd(TAG, "BLE Connection State Change: " + newState);
+                    switch (newState) {
+                        case BluetoothProfile.STATE_CONNECTED:
+                            BluetoothGattServer gattServer = mGattServer.get();
+                            if (gattServer == null) {
+                                return;
+                            }
+                            gattServer.connect(device, /* autoConnect= */ false);
+                            for (Callback callback : mCallbacks) {
+                                callback.onRemoteDeviceConnected(device);
+                            }
+                            break;
+                        case BluetoothProfile.STATE_DISCONNECTED:
+                            for (Callback callback : mCallbacks) {
+                                callback.onRemoteDeviceDisconnected(device);
+                            }
+                            break;
+                        default:
+                            logw(TAG, "Connection state not connecting or disconnecting; ignoring: "
+                                    + newState);
+                    }
+                }
+
+                @Override
+                public void onServiceAdded(int status, BluetoothGattService service) {
+                    logd(TAG, "Service added status: " + status + " uuid: " + service.getUuid());
+                }
+
+                @Override
+                public void onCharacteristicWriteRequest(
+                        BluetoothDevice device,
+                        int requestId,
+                        BluetoothGattCharacteristic characteristic,
+                        boolean preparedWrite,
+                        boolean responseNeeded,
+                        int offset,
+                        byte[] value) {
+                    BluetoothGattServer gattServer = mGattServer.get();
+                    if (gattServer == null) {
+                        return;
+                    }
+                    gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                            value);
+                    for (OnCharacteristicWriteListener listener : mWriteListeners) {
+                        listener.onCharacteristicWrite(device, characteristic, value);
+                    }
+                }
+
+                @Override
+                public void onDescriptorWriteRequest(
+                        BluetoothDevice device,
+                        int requestId,
+                        BluetoothGattDescriptor descriptor,
+                        boolean preparedWrite,
+                        boolean responseNeeded,
+                        int offset,
+                        byte[] value) {
+                    logd(TAG, "Write request for descriptor: "
+                            + descriptor.getUuid()
+                            + "; value: "
+                            + ByteUtils.byteArrayToHexString(value));
+                    BluetoothGattServer gattServer = mGattServer.get();
+                    if (gattServer == null) {
+                        return;
+                    }
+                    gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                            value);
+                }
+
+                @Override
+                public void onMtuChanged(BluetoothDevice device, int mtu) {
+                    logd(TAG, "onMtuChanged: " + mtu + " for device " + device.getAddress());
+
+                    mMtuSize = mtu;
+
+                    for (Callback callback : mCallbacks) {
+                        callback.onMtuSizeChanged(mtu);
+                    }
+                }
+
+                @Override
+                public void onNotificationSent(BluetoothDevice device, int status) {
+                    super.onNotificationSent(device, status);
+                    if (status == BluetoothGatt.GATT_SUCCESS) {
+                        logd(TAG, "Notification sent successfully. Device: " + device.getAddress()
+                                + ", Status: " + status + ". Notifying all listeners.");
+                        for (OnCharacteristicReadListener listener : mReadListeners) {
+                            listener.onCharacteristicRead(device);
+                        }
+                    } else {
+                        loge(TAG, "Notification failed. Device: " + device + ", Status: "
+                                + status);
+                    }
+                }
+            };
+
+    private final BluetoothGattCallback mGattCallback =
+            new BluetoothGattCallback() {
+                @Override
+                public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+                    logd(TAG, "Gatt Connection State Change: " + newState);
+                    switch (newState) {
+                        case BluetoothProfile.STATE_CONNECTED:
+                            logd(TAG, "Gatt connected");
+                            BluetoothGatt bluetoothGatt = mBluetoothGatt.get();
+                            if (bluetoothGatt == null) {
+                                break;
+                            }
+                            bluetoothGatt.discoverServices();
+                            break;
+                        case BluetoothProfile.STATE_DISCONNECTED:
+                            logd(TAG, "Gatt Disconnected");
+                            break;
+                        default:
+                            logd(TAG, "Connection state not connecting or disconnecting; ignoring: "
+                                    + newState);
+                    }
+                }
+
+                @Override
+                public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+                    logd(TAG, "Gatt Services Discovered");
+                    BluetoothGatt bluetoothGatt = mBluetoothGatt.get();
+                    if (bluetoothGatt == null) {
+                        return;
+                    }
+                    BluetoothGattService gapService = bluetoothGatt.getService(
+                            GENERIC_ACCESS_PROFILE_UUID);
+                    if (gapService == null) {
+                        loge(TAG, "Generic Access Service is null.");
+                        return;
+                    }
+                    BluetoothGattCharacteristic deviceNameCharacteristic =
+                            gapService.getCharacteristic(DEVICE_NAME_UUID);
+                    if (deviceNameCharacteristic == null) {
+                        loge(TAG, "Device Name Characteristic is null.");
+                        return;
+                    }
+                    bluetoothGatt.readCharacteristic(deviceNameCharacteristic);
+                }
+
+                @Override
+                public void onCharacteristicRead(
+                        BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
+                        int status) {
+                    if (status == BluetoothGatt.GATT_SUCCESS) {
+                        String deviceName = characteristic.getStringValue(0);
+                        logd(TAG, "BLE Device Name: " + deviceName);
+
+                        for (Callback callback : mCallbacks) {
+                            callback.onDeviceNameRetrieved(deviceName);
+                        }
+                    } else {
+                        loge(TAG, "Reading GAP Failed: " + status);
+                    }
+                }
+            };
+
+    /**
+     * Interface to be notified of various events within the {@link BlePeripheralManager}.
+     */
+    interface Callback {
+        /**
+         * Triggered when the name of the remote device is retrieved.
+         *
+         * @param deviceName Name of the remote device.
+         */
+        void onDeviceNameRetrieved(@Nullable String deviceName);
+
+        /**
+         * Triggered if a remote client has requested to change the MTU for a given connection.
+         *
+         * @param size The new MTU size.
+         */
+        void onMtuSizeChanged(int size);
+
+        /**
+         * Triggered when a device (GATT client) connected.
+         *
+         * @param device Remote device that connected on BLE.
+         */
+        void onRemoteDeviceConnected(@NonNull BluetoothDevice device);
+
+        /**
+         * Triggered when a device (GATT client) disconnected.
+         *
+         * @param device Remote device that disconnected on BLE.
+         */
+        void onRemoteDeviceDisconnected(@NonNull BluetoothDevice device);
+    }
+
+    /**
+     * An interface for classes that wish to be notified of writes to a characteristic.
+     */
+    interface OnCharacteristicWriteListener {
+        /**
+         * Triggered when this BlePeripheralManager receives a write request from a remote device.
+         *
+         * @param device         The bluetooth device that holds the characteristic.
+         * @param characteristic The characteristic that was written to.
+         * @param value          The value that was written.
+         */
+        void onCharacteristicWrite(
+                @NonNull BluetoothDevice device,
+                @NonNull BluetoothGattCharacteristic characteristic,
+                @NonNull byte[] value);
+    }
+
+    /**
+     * An interface for classes that wish to be notified of reads on a characteristic.
+     */
+    interface OnCharacteristicReadListener {
+        /**
+         * Triggered when this BlePeripheralManager receives a read request from a remote device.
+         *
+         * @param device The bluetooth device that holds the characteristic.
+         */
+        void onCharacteristicRead(@NonNull BluetoothDevice device);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleCentralManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleCentralManager.java
new file mode 100644
index 0000000..b95458d
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleCentralManager.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+import static com.android.car.connecteddevice.util.ScanDataAnalyzer.containsUuidsInOverflow;
+
+import android.annotation.NonNull;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.os.ParcelUuid;
+
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * Communication manager for a car that maintains continuous connections with all devices in the car
+ * for the duration of a drive.
+ */
+public class CarBleCentralManager extends CarBleManager {
+
+    private static final String TAG = "CarBleCentralManager";
+
+    // system/bt/internal_include/bt_target.h#GATT_MAX_PHY_CHANNEL
+    private static final int MAX_CONNECTIONS = 7;
+
+    private static final UUID CHARACTERISTIC_CONFIG =
+            UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
+
+    private static final int STATUS_FORCED_DISCONNECT = -1;
+
+    private final ScanSettings mScanSettings = new ScanSettings.Builder()
+            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
+            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+            .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
+            .build();
+
+    private final CopyOnWriteArraySet<BleDevice> mIgnoredDevices = new CopyOnWriteArraySet<>();
+
+    private final Context mContext;
+
+    private final BleCentralManager mBleCentralManager;
+
+    private final UUID mServiceUuid;
+
+    private final UUID mWriteCharacteristicUuid;
+
+    private final UUID mReadCharacteristicUuid;
+
+    private final BigInteger mParsedBgServiceBitMask;
+
+    /**
+     * Create a new manager.
+     *
+     * @param context The caller's [Context].
+     * @param bleCentralManager [BleCentralManager] for establishing connections.
+     * @param connectedDeviceStorage Shared [ConnectedDeviceStorage] for companion features.
+     * @param serviceUuid [UUID] of peripheral's service.
+     * @param bgServiceMask iOS overflow bit mask for service UUID.
+     * @param writeCharacteristicUuid [UUID] of characteristic the car will write to.
+     * @param readCharacteristicUuid [UUID] of characteristic the device will write to.
+     */
+    public CarBleCentralManager(
+            @NonNull Context context,
+            @NonNull BleCentralManager bleCentralManager,
+            @NonNull ConnectedDeviceStorage connectedDeviceStorage,
+            @NonNull UUID serviceUuid,
+            @NonNull String bgServiceMask,
+            @NonNull UUID writeCharacteristicUuid,
+            @NonNull UUID readCharacteristicUuid) {
+        super(connectedDeviceStorage);
+        mContext = context;
+        mBleCentralManager = bleCentralManager;
+        mServiceUuid = serviceUuid;
+        mWriteCharacteristicUuid = writeCharacteristicUuid;
+        mReadCharacteristicUuid = readCharacteristicUuid;
+        mParsedBgServiceBitMask = new BigInteger(bgServiceMask, 16);
+    }
+
+    @Override
+    public void start() {
+        super.start();
+        mBleCentralManager.startScanning(/* filters= */ null, mScanSettings, mScanCallback);
+    }
+
+    @Override
+    public void stop() {
+        super.stop();
+        mBleCentralManager.stopScanning();
+    }
+
+    @Override
+    public void disconnectDevice(String deviceId) {
+        logd(TAG, "Request to disconnect from device " + deviceId + ".");
+        BleDevice device = getConnectedDevice(deviceId);
+        if (device == null) {
+            return;
+        }
+
+        deviceDisconnected(device, STATUS_FORCED_DISCONNECT);
+    }
+
+    private void ignoreDevice(@NonNull BleDevice device) {
+        mIgnoredDevices.add(device);
+    }
+
+    private boolean isDeviceIgnored(@NonNull BluetoothDevice device) {
+        for (BleDevice bleDevice : mIgnoredDevices) {
+            if (device.equals(bleDevice.mDevice)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean shouldAttemptConnection(@NonNull ScanResult result) {
+        // Ignore any results that are not connectable.
+        if (!result.isConnectable()) {
+            return false;
+        }
+
+        // Do not attempt to connect if we have already hit our max. This should rarely happen
+        // and is protecting against a race condition of scanning stopped and new results coming in.
+        if (getConnectedDevicesCount() >= MAX_CONNECTIONS) {
+            return false;
+        }
+
+        BluetoothDevice device = result.getDevice();
+
+        // Do not connect if device has already been ignored.
+        if (isDeviceIgnored(device)) {
+            return false;
+        }
+
+        // Check if already attempting to connect to this device.
+        if (getConnectedDevice(device) != null) {
+            return false;
+        }
+
+
+        // Ignore any device without a scan record.
+        ScanRecord scanRecord = result.getScanRecord();
+        if (scanRecord == null) {
+            return false;
+        }
+
+        // Connect to any device that is advertising our service UUID.
+        List<ParcelUuid> serviceUuids = scanRecord.getServiceUuids();
+        if (serviceUuids != null) {
+            for (ParcelUuid serviceUuid : serviceUuids) {
+                if (serviceUuid.getUuid().equals(mServiceUuid)) {
+                    return true;
+                }
+            }
+        }
+        if (containsUuidsInOverflow(scanRecord.getBytes(), mParsedBgServiceBitMask)) {
+            return true;
+        }
+
+        // Can safely ignore devices advertising unrecognized service uuids.
+        if (serviceUuids != null && !serviceUuids.isEmpty()) {
+            return false;
+        }
+
+        // TODO(b/139066293): Current implementation quickly exhausts connections resulting in
+        // greatly reduced performance for connecting to devices we know we want to connect to.
+        // Return true once fixed.
+        return false;
+    }
+
+    private void startDeviceConnection(@NonNull BluetoothDevice device) {
+        BluetoothGatt gatt = device.connectGatt(mContext, /* autoConnect= */ false,
+                mConnectionCallback, BluetoothDevice.TRANSPORT_LE);
+        if (gatt == null) {
+            return;
+        }
+
+        BleDevice bleDevice = new BleDevice(device, gatt);
+        bleDevice.mState = BleDeviceState.CONNECTING;
+        addConnectedDevice(bleDevice);
+
+        // Stop scanning if we have reached the maximum number of connections.
+        if (getConnectedDevicesCount() >= MAX_CONNECTIONS) {
+            mBleCentralManager.stopScanning();
+        }
+    }
+
+    private void deviceConnected(@NonNull BleDevice device) {
+        if (device.mGatt == null) {
+            loge(TAG, "Device connected with null gatt. Disconnecting.");
+            deviceDisconnected(device, BluetoothProfile.STATE_DISCONNECTED);
+            return;
+        }
+        device.mState = BleDeviceState.PENDING_VERIFICATION;
+        device.mGatt.discoverServices();
+        logd(TAG, "New device connected: " + device.mGatt.getDevice().getAddress()
+                + ". Active connections: " + getConnectedDevicesCount() + ".");
+    }
+
+    private void deviceDisconnected(@NonNull BleDevice device, int status) {
+        removeConnectedDevice(device);
+        if (device.mGatt != null) {
+            device.mGatt.close();
+        }
+        if (device.mDeviceId != null) {
+            mCallbacks.invoke(callback -> callback.onDeviceDisconnected(device.mDeviceId));
+        }
+        logd(TAG, "Device with id " + device.mDeviceId + " disconnected with state " + status
+                + ". Remaining active connections: " + getConnectedDevicesCount() + ".");
+    }
+
+    private final ScanCallback mScanCallback = new ScanCallback() {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            super.onScanResult(callbackType, result);
+            if (shouldAttemptConnection(result)) {
+                startDeviceConnection(result.getDevice());
+            }
+        }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            super.onScanFailed(errorCode);
+            loge(TAG, "BLE scanning failed with error code: " + errorCode);
+        }
+    };
+
+    private final BluetoothGattCallback mConnectionCallback = new BluetoothGattCallback() {
+        @Override
+        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+            super.onConnectionStateChange(gatt, status, newState);
+            if (gatt == null) {
+                logw(TAG, "Null gatt passed to onConnectionStateChange. Ignoring.");
+                return;
+            }
+
+            BleDevice connectedDevice = getConnectedDevice(gatt);
+            if (connectedDevice == null) {
+                return;
+            }
+
+            switch (newState) {
+                case BluetoothProfile.STATE_CONNECTED:
+                    deviceConnected(connectedDevice);
+                    break;
+                case BluetoothProfile.STATE_DISCONNECTED:
+                    deviceDisconnected(connectedDevice, status);
+                    break;
+                default:
+                    logd(TAG, "Connection state changed. New state: " + newState + " status: "
+                            + status);
+            }
+        }
+
+        @Override
+        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+            super.onServicesDiscovered(gatt, status);
+            if (gatt == null) {
+                logw(TAG, "Null gatt passed to onServicesDiscovered. Ignoring.");
+                return;
+            }
+
+            BleDevice connectedDevice = getConnectedDevice(gatt);
+            if (connectedDevice == null) {
+                return;
+            }
+            BluetoothGattService service = gatt.getService(mServiceUuid);
+            if (service == null) {
+                ignoreDevice(connectedDevice);
+                gatt.disconnect();
+                return;
+            }
+
+            connectedDevice.mState = BleDeviceState.CONNECTED;
+            BluetoothGattCharacteristic writeCharacteristic =
+                    service.getCharacteristic(mWriteCharacteristicUuid);
+            BluetoothGattCharacteristic readCharacteristic =
+                    service.getCharacteristic(mReadCharacteristicUuid);
+            if (writeCharacteristic == null || readCharacteristic == null) {
+                logw(TAG, "Unable to find expected characteristics on peripheral.");
+                gatt.disconnect();
+                return;
+            }
+
+            // Turn on notifications for read characteristic.
+            BluetoothGattDescriptor descriptor =
+                    readCharacteristic.getDescriptor(CHARACTERISTIC_CONFIG);
+            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
+            if (!gatt.writeDescriptor(descriptor)) {
+                loge(TAG, "Write descriptor to read characteristic failed.");
+                gatt.disconnect();
+                return;
+            }
+
+            if (!gatt.setCharacteristicNotification(readCharacteristic, /* enable= */ true)) {
+                loge(TAG, "Set notifications to read characteristic failed.");
+                gatt.disconnect();
+                return;
+            }
+
+            logd(TAG, "Service and characteristics successfully discovered.");
+        }
+
+        @Override
+        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            super.onDescriptorWrite(gatt, descriptor, status);
+            if (gatt == null) {
+                logw(TAG, "Null gatt passed to onDescriptorWrite. Ignoring.");
+                return;
+            }
+            // TODO(b/141312136): Create SecureBleChannel and assign to connectedDevice.
+        }
+    };
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.java
new file mode 100644
index 0000000..2c32beb
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBleManager.java
@@ -0,0 +1,247 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.util.ThreadSafeCallbacks;
+
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executor;
+
+/**
+ * Generic BLE manager for a car that keeps track of connected devices and their associated
+ * callbacks.
+ */
+public abstract class CarBleManager {
+
+    private static final String TAG = "CarBleManager";
+
+    final ConnectedDeviceStorage mStorage;
+
+    final CopyOnWriteArraySet<BleDevice> mConnectedDevices = new CopyOnWriteArraySet<>();
+
+    final ThreadSafeCallbacks<Callback> mCallbacks = new ThreadSafeCallbacks<>();
+
+    protected CarBleManager(@NonNull ConnectedDeviceStorage connectedDeviceStorage) {
+        mStorage = connectedDeviceStorage;
+    }
+
+    /**
+     * Initialize and start the manager.
+     */
+    public void start() {
+    }
+
+    /**
+     * Stop the manager and clean up.
+     */
+    public void stop() {
+        for (BleDevice device : mConnectedDevices) {
+            if (device.mGatt != null) {
+                device.mGatt.close();
+            }
+        }
+        mConnectedDevices.clear();
+    }
+
+    /**
+     * Register a {@link Callback} to be notified on the {@link Executor}.
+     */
+    public void registerCallback(@NonNull Callback callback, @NonNull Executor executor) {
+        mCallbacks.add(callback, executor);
+    }
+
+    /**
+     * Unregister a callback.
+     *
+     * @param callback The {@link Callback} to unregister.
+     */
+    public void unregisterCallback(@NonNull Callback callback) {
+        mCallbacks.remove(callback);
+    }
+
+    /**
+     * Send a message to a connected device.
+     *
+     * @param deviceId Id of connected device.
+     * @param message  {@link DeviceMessage} to send.
+     */
+    public void sendMessage(@NonNull String deviceId, @NonNull DeviceMessage message) {
+        BleDevice device = getConnectedDevice(deviceId);
+        if (device == null) {
+            logw(TAG, "Attempted to send message to unknown device $deviceId. Ignored.");
+            return;
+        }
+
+        sendMessage(device, message);
+    }
+
+    /**
+     * Send a message to a connected device.
+     *
+     * @param device  The connected {@link BleDevice}.
+     * @param message {@link DeviceMessage} to send.
+     */
+    public void sendMessage(@NonNull BleDevice device, @NonNull DeviceMessage message) {
+        String deviceId = device.mDeviceId;
+        if (deviceId == null) {
+            deviceId = "Unidentified device";
+        }
+
+        logd(TAG, "Writing " + message.getMessage().length + " bytes to " + deviceId + ".");
+        device.mSecureChannel.sendClientMessage(message);
+    }
+
+    /**
+     * Get the {@link BleDevice} with matching {@link BluetoothGatt} if available. Returns
+     * {@code null} if no matches are found.
+     */
+    @Nullable
+    BleDevice getConnectedDevice(@NonNull BluetoothGatt gatt) {
+        for (BleDevice device : mConnectedDevices) {
+            if (device.mGatt == gatt) {
+                return device;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the {@link BleDevice} with matching {@link BluetoothDevice} if available. Returns
+     * {@code null} if no matches are found.
+     */
+    @Nullable
+    BleDevice getConnectedDevice(@NonNull BluetoothDevice device) {
+        for (BleDevice connectedDevice : mConnectedDevices) {
+            if (device.equals(connectedDevice.mDevice)) {
+                return connectedDevice;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the {@link BleDevice} with matching device id if available. Returns {@code null} if
+     * no matches are found.
+     */
+    @Nullable
+    BleDevice getConnectedDevice(@NonNull String deviceId) {
+        for (BleDevice device : mConnectedDevices) {
+            if (deviceId.equals(device.mDeviceId)) {
+                return device;
+            }
+        }
+
+        return null;
+    }
+
+    /** Add the {@link BleDevice} that has connected. */
+    void addConnectedDevice(@NonNull BleDevice device) {
+        mConnectedDevices.add(device);
+    }
+
+    /** Return the number of devices currently connected. */
+    int getConnectedDevicesCount() {
+        return mConnectedDevices.size();
+    }
+
+    /** Remove [@link BleDevice} that has been disconnected. */
+    void removeConnectedDevice(@NonNull BleDevice device) {
+        mConnectedDevices.remove(device);
+    }
+
+    /** Disconnect the provided device from this manager. */
+    public abstract void disconnectDevice(@NonNull String deviceId);
+
+    /** State for a connected device. */
+    enum BleDeviceState {
+        CONNECTING,
+        PENDING_VERIFICATION,
+        CONNECTED,
+        UNKNOWN
+    }
+
+    /**
+     * Container class to hold information about a connected device.
+     */
+    static class BleDevice {
+
+        BluetoothDevice mDevice;
+        BluetoothGatt mGatt;
+        BleDeviceState mState;
+        String mDeviceId;
+        SecureBleChannel mSecureChannel;
+
+        BleDevice(@NonNull BluetoothDevice device, @Nullable BluetoothGatt gatt) {
+            mDevice = device;
+            mGatt = gatt;
+            mState = BleDeviceState.UNKNOWN;
+        }
+    }
+
+    /**
+     * Callback for triggered events from {@link CarBleManager}.
+     */
+    public interface Callback {
+        /**
+         * Triggered when device is connected and device id retrieved. Device is now ready to
+         * receive messages.
+         *
+         * @param deviceId Id of device that has connected.
+         */
+        void onDeviceConnected(@NonNull String deviceId);
+
+        /**
+         * Triggered when device is disconnected.
+         *
+         * @param deviceId Id of device that has disconnected.
+         */
+        void onDeviceDisconnected(@NonNull String deviceId);
+
+        /**
+         * Triggered when device has established encryption for secure communication.
+         *
+         * @param deviceId Id of device that has established encryption.
+         */
+        void onSecureChannelEstablished(@NonNull String deviceId);
+
+        /**
+         * Triggered when a new message is received.
+         *
+         * @param deviceId Id of the device that sent the message.
+         * @param message  {@link DeviceMessage} received.
+         */
+        void onMessageReceived(@NonNull String deviceId, @NonNull DeviceMessage message);
+
+        /**
+         * Triggered when an error when establishing the secure channel.
+         *
+         * @param deviceId Id of the device that experienced the error.
+         */
+        void onSecureChannelError(@NonNull String deviceId);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBlePeripheralManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBlePeripheralManager.java
new file mode 100644
index 0000000..3fe8e3b
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBlePeripheralManager.java
@@ -0,0 +1,670 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.ConnectedDeviceManager.DEVICE_ERROR_INVALID_HANDSHAKE;
+import static com.android.car.connecteddevice.ConnectedDeviceManager.DEVICE_ERROR_UNEXPECTED_DISCONNECTION;
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelUuid;
+
+import com.android.car.connecteddevice.AssociationCallback;
+import com.android.car.connecteddevice.model.AssociatedDevice;
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.util.ByteUtils;
+import com.android.car.connecteddevice.util.EventLog;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Communication manager that allows for targeted connections to a specific device in the car.
+ */
+public class CarBlePeripheralManager extends CarBleManager {
+
+    private static final String TAG = "CarBlePeripheralManager";
+
+    // Attribute protocol bytes attached to message. Available write size is MTU size minus att
+    // bytes.
+    private static final int ATT_PROTOCOL_BYTES = 3;
+
+    // Arbitrary delay time for a retry of association advertising if bluetooth adapter name change
+    // fails.
+    private static final long ASSOCIATE_ADVERTISING_DELAY_MS = 10L;
+
+    private static final UUID CLIENT_CHARACTERISTIC_CONFIG =
+            UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
+
+    private static final int SALT_BYTES = 8;
+
+    private static final int TOTAL_AD_DATA_BYTES = 16;
+
+    private static final int TRUNCATED_BYTES = 3;
+
+    private final BluetoothGattDescriptor mDescriptor =
+            new BluetoothGattDescriptor(CLIENT_CHARACTERISTIC_CONFIG,
+                    BluetoothGattDescriptor.PERMISSION_READ
+                            | BluetoothGattDescriptor.PERMISSION_WRITE);
+
+    private final ScheduledExecutorService mScheduler =
+            Executors.newSingleThreadScheduledExecutor();
+
+    private final BlePeripheralManager mBlePeripheralManager;
+
+    private final UUID mAssociationServiceUuid;
+
+    private final UUID mReconnectServiceUuid;
+
+    private final UUID mReconnectDataUuid;
+
+    private final BluetoothGattCharacteristic mWriteCharacteristic;
+
+    private final BluetoothGattCharacteristic mReadCharacteristic;
+
+    private final Handler mTimeoutHandler;
+
+    private final Duration mMaxReconnectAdvertisementDuration;
+
+    private final int mDefaultMtuSize;
+
+    private String mOriginalBluetoothName;
+
+    private String mClientDeviceName;
+
+    private String mClientDeviceAddress;
+
+    private String mReconnectDeviceId;
+
+    private byte[] mReconnectChallenge;
+
+    private AssociationCallback mAssociationCallback;
+
+    private AdvertiseCallback mAdvertiseCallback;
+
+    /**
+     * Initialize a new instance of manager.
+     *
+     * @param blePeripheralManager    {@link BlePeripheralManager} for establishing connection.
+     * @param connectedDeviceStorage  Shared {@link ConnectedDeviceStorage} for companion features.
+     * @param associationServiceUuid  {@link UUID} of association service.
+     * @param reconnectServiceUuid    {@link UUID} of reconnect service.
+     * @param reconnectDataUuid       {@link UUID} key of reconnect advertisement data.
+     * @param writeCharacteristicUuid {@link UUID} of characteristic the car will write to.
+     * @param readCharacteristicUuid  {@link UUID} of characteristic the device will write to.
+     * @param maxReconnectAdvertisementDuration Maximum duration to advertise for reconnect before
+     *                                          restarting.
+     * @param defaultMtuSize          Default MTU size for new channels.
+     */
+    public CarBlePeripheralManager(@NonNull BlePeripheralManager blePeripheralManager,
+            @NonNull ConnectedDeviceStorage connectedDeviceStorage,
+            @NonNull UUID associationServiceUuid,
+            @NonNull UUID reconnectServiceUuid,
+            @NonNull UUID reconnectDataUuid,
+            @NonNull UUID writeCharacteristicUuid,
+            @NonNull UUID readCharacteristicUuid,
+            @NonNull Duration maxReconnectAdvertisementDuration,
+            int defaultMtuSize) {
+        super(connectedDeviceStorage);
+        mBlePeripheralManager = blePeripheralManager;
+        mAssociationServiceUuid = associationServiceUuid;
+        mReconnectServiceUuid = reconnectServiceUuid;
+        mReconnectDataUuid = reconnectDataUuid;
+        mDescriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
+        mWriteCharacteristic = new BluetoothGattCharacteristic(writeCharacteristicUuid,
+                BluetoothGattCharacteristic.PROPERTY_NOTIFY,
+                BluetoothGattCharacteristic.PROPERTY_READ);
+        mReadCharacteristic = new BluetoothGattCharacteristic(readCharacteristicUuid,
+                BluetoothGattCharacteristic.PROPERTY_WRITE
+                        | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
+                BluetoothGattCharacteristic.PERMISSION_WRITE);
+        mReadCharacteristic.addDescriptor(mDescriptor);
+        mTimeoutHandler = new Handler(Looper.getMainLooper());
+        mMaxReconnectAdvertisementDuration = maxReconnectAdvertisementDuration;
+        mDefaultMtuSize = defaultMtuSize;
+    }
+
+    @Override
+    public void start() {
+        super.start();
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter == null) {
+            return;
+        }
+        String originalBluetoothName = mStorage.getStoredBluetoothName();
+        if (originalBluetoothName == null) {
+            return;
+        }
+        if (originalBluetoothName.equals(adapter.getName())) {
+            mStorage.removeStoredBluetoothName();
+            return;
+        }
+
+        logw(TAG, "Discovered mismatch in bluetooth adapter name. Resetting back to "
+                + originalBluetoothName + ".");
+        adapter.setName(originalBluetoothName);
+        mScheduler.schedule(
+                () -> verifyBluetoothNameRestored(originalBluetoothName),
+                ASSOCIATE_ADVERTISING_DELAY_MS, TimeUnit.MILLISECONDS);
+    }
+
+    @Override
+    public void stop() {
+        super.stop();
+        reset();
+    }
+
+    @Override
+    public void disconnectDevice(@NonNull String deviceId) {
+        BleDevice connectedDevice = getConnectedDevice();
+        if (connectedDevice == null || !deviceId.equals(connectedDevice.mDeviceId)) {
+            return;
+        }
+        reset();
+    }
+
+    private void reset() {
+        resetBluetoothAdapterName();
+        mClientDeviceAddress = null;
+        mClientDeviceName = null;
+        mAssociationCallback = null;
+        mBlePeripheralManager.cleanup();
+        mConnectedDevices.clear();
+        mReconnectDeviceId = null;
+        mReconnectChallenge = null;
+    }
+
+    /** Attempt to connect to device with provided id. */
+    public void connectToDevice(@NonNull UUID deviceId) {
+        for (BleDevice device : mConnectedDevices) {
+            if (UUID.fromString(device.mDeviceId).equals(deviceId)) {
+                logd(TAG, "Already connected to device " + deviceId + ".");
+                // Already connected to this device. Ignore requests to connect again.
+                return;
+            }
+        }
+
+        // Clear any previous session before starting a new one.
+        reset();
+        mReconnectDeviceId = deviceId.toString();
+        mAdvertiseCallback = new AdvertiseCallback() {
+            @Override
+            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+                super.onStartSuccess(settingsInEffect);
+                mTimeoutHandler.postDelayed(mTimeoutRunnable,
+                        mMaxReconnectAdvertisementDuration.toMillis());
+                logd(TAG, "Successfully started advertising for device " + deviceId + ".");
+            }
+        };
+        mBlePeripheralManager.unregisterCallback(mAssociationPeripheralCallback);
+        mBlePeripheralManager.registerCallback(mReconnectPeripheralCallback);
+        mTimeoutHandler.removeCallbacks(mTimeoutRunnable);
+        byte[] advertiseData = createReconnectData(mReconnectDeviceId);
+        if (advertiseData == null) {
+            loge(TAG, "Unable to create advertisement data. Aborting reconnect.");
+            return;
+        }
+        startAdvertising(mReconnectServiceUuid, mAdvertiseCallback, /* includeDeviceName= */ false,
+                advertiseData, mReconnectDataUuid);
+    }
+
+    /**
+     * Create data for reconnection advertisement.
+     *
+     * <p></p><p>Process:</p>
+     * <ol>
+     * <li>Generate random {@value SALT_BYTES} byte salt and zero-pad to
+     * {@value TOTAL_AD_DATA_BYTES} bytes.
+     * <li>Hash with stored challenge secret and truncate to {@value TRUNCATED_BYTES} bytes.
+     * <li>Concatenate hashed {@value TRUNCATED_BYTES} bytes with salt and return.
+     * </ol>
+     */
+    @Nullable
+    private byte[] createReconnectData(String deviceId) {
+        byte[] salt = ByteUtils.randomBytes(SALT_BYTES);
+        byte[] zeroPadded = ByteUtils.concatByteArrays(salt,
+                new byte[TOTAL_AD_DATA_BYTES - SALT_BYTES]);
+        mReconnectChallenge = mStorage.hashWithChallengeSecret(deviceId, zeroPadded);
+        if (mReconnectChallenge == null) {
+            return null;
+        }
+        return ByteUtils.concatByteArrays(Arrays.copyOf(mReconnectChallenge, TRUNCATED_BYTES),
+                salt);
+
+    }
+
+    @Nullable
+    private BleDevice getConnectedDevice() {
+        if (mConnectedDevices.isEmpty()) {
+            return null;
+        }
+        return mConnectedDevices.iterator().next();
+    }
+
+    /** Start the association with a new device */
+    public void startAssociation(@NonNull String nameForAssociation,
+            @NonNull AssociationCallback callback) {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter == null) {
+            loge(TAG, "Bluetooth is unavailable on this device. Unable to start associating.");
+            return;
+        }
+
+        reset();
+        mAssociationCallback = callback;
+        if (mOriginalBluetoothName == null) {
+            mOriginalBluetoothName = adapter.getName();
+            mStorage.storeBluetoothName(mOriginalBluetoothName);
+        }
+        adapter.setName(nameForAssociation);
+        logd(TAG, "Changing bluetooth adapter name from " + mOriginalBluetoothName + " to "
+                + nameForAssociation + ".");
+        mBlePeripheralManager.unregisterCallback(mReconnectPeripheralCallback);
+        mBlePeripheralManager.registerCallback(mAssociationPeripheralCallback);
+        mAdvertiseCallback = new AdvertiseCallback() {
+            @Override
+            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+                super.onStartSuccess(settingsInEffect);
+                callback.onAssociationStartSuccess(nameForAssociation);
+                logd(TAG, "Successfully started advertising for association.");
+            }
+
+            @Override
+            public void onStartFailure(int errorCode) {
+                super.onStartFailure(errorCode);
+                callback.onAssociationStartFailure();
+                logd(TAG, "Failed to start advertising for association. Error code: " + errorCode);
+            }
+        };
+        attemptAssociationAdvertising(nameForAssociation, callback);
+    }
+
+    /** Stop the association with any device. */
+    public void stopAssociation(@NonNull AssociationCallback callback) {
+        if (!isAssociating() || callback != mAssociationCallback) {
+            return;
+        }
+        reset();
+    }
+
+    private void attemptAssociationAdvertising(@NonNull String adapterName,
+            @NonNull AssociationCallback callback) {
+        if (mOriginalBluetoothName != null
+                && adapterName.equals(BluetoothAdapter.getDefaultAdapter().getName())) {
+            startAdvertising(mAssociationServiceUuid, mAdvertiseCallback,
+                    /* includeDeviceName= */ true, /* serviceData= */ null,
+                    /* serviceDataUuid= */ null);
+            return;
+        }
+
+        ScheduledFuture future = mScheduler.schedule(
+                () -> attemptAssociationAdvertising(adapterName, callback),
+                ASSOCIATE_ADVERTISING_DELAY_MS, TimeUnit.MILLISECONDS);
+        if (future.isCancelled()) {
+            // Association failed to start.
+            callback.onAssociationStartFailure();
+            return;
+        }
+        logd(TAG, "Adapter name change has not taken affect prior to advertising attempt. Trying "
+                + "again in " + ASSOCIATE_ADVERTISING_DELAY_MS + "  milliseconds.");
+    }
+
+    private void startAdvertising(@NonNull UUID serviceUuid, @NonNull AdvertiseCallback callback,
+            boolean includeDeviceName, @Nullable byte[] serviceData,
+            @Nullable UUID serviceDataUuid) {
+        BluetoothGattService gattService = new BluetoothGattService(serviceUuid,
+                BluetoothGattService.SERVICE_TYPE_PRIMARY);
+        gattService.addCharacteristic(mWriteCharacteristic);
+        gattService.addCharacteristic(mReadCharacteristic);
+
+        AdvertiseData.Builder builder = new AdvertiseData.Builder()
+                .setIncludeDeviceName(includeDeviceName);
+        ParcelUuid uuid = new ParcelUuid(serviceUuid);
+        builder.addServiceUuid(uuid);
+        if (serviceData != null) {
+            ParcelUuid dataUuid = uuid;
+            if (serviceDataUuid != null) {
+                dataUuid = new ParcelUuid(serviceDataUuid);
+            }
+            builder.addServiceData(dataUuid, serviceData);
+        }
+
+        mBlePeripheralManager.startAdvertising(gattService, builder.build(), callback);
+    }
+
+    /** Notify that the user has accepted a pairing code or other out-of-band confirmation. */
+    public void notifyOutOfBandAccepted() {
+        if (getConnectedDevice() == null) {
+            disconnectWithError("Null connected device found when out-of-band confirmation "
+                    + "received.");
+            return;
+        }
+
+        AssociationSecureChannel secureChannel =
+                (AssociationSecureChannel) getConnectedDevice().mSecureChannel;
+        if (secureChannel == null) {
+            disconnectWithError("Null SecureBleChannel found for the current connected device "
+                    + "when out-of-band confirmation received.");
+            return;
+        }
+
+        secureChannel.notifyOutOfBandAccepted();
+    }
+
+    @VisibleForTesting
+    @Nullable
+    SecureBleChannel getConnectedDeviceChannel() {
+        BleDevice connectedDevice = getConnectedDevice();
+        if (connectedDevice == null) {
+            return null;
+        }
+
+        return connectedDevice.mSecureChannel;
+    }
+
+    private void setDeviceId(@NonNull String deviceId) {
+        logd(TAG, "Setting device id: " + deviceId);
+        BleDevice connectedDevice = getConnectedDevice();
+        if (connectedDevice == null) {
+            disconnectWithError("Null connected device found when device id received.");
+            return;
+        }
+
+        connectedDevice.mDeviceId = deviceId;
+        mCallbacks.invoke(callback -> callback.onDeviceConnected(deviceId));
+    }
+
+    private void disconnectWithError(@NonNull String errorMessage) {
+        loge(TAG, errorMessage);
+        if (isAssociating()) {
+            mAssociationCallback.onAssociationError(DEVICE_ERROR_INVALID_HANDSHAKE);
+        }
+        reset();
+    }
+
+    private void resetBluetoothAdapterName() {
+        if (mOriginalBluetoothName == null) {
+            return;
+        }
+        logd(TAG, "Changing bluetooth adapter name back to " + mOriginalBluetoothName + ".");
+        BluetoothAdapter.getDefaultAdapter().setName(mOriginalBluetoothName);
+        mOriginalBluetoothName = null;
+    }
+
+    private void verifyBluetoothNameRestored(@NonNull String expectedName) {
+        String currentName = BluetoothAdapter.getDefaultAdapter().getName();
+        if (expectedName.equals(currentName)) {
+            logd(TAG, "Bluetooth adapter name restoration completed successfully. Removing stored "
+                    + "adapter name.");
+            mStorage.removeStoredBluetoothName();
+            return;
+        }
+        logd(TAG, "Bluetooth adapter name restoration has not taken affect yet. Checking again in "
+                + ASSOCIATE_ADVERTISING_DELAY_MS + " milliseconds.");
+        mScheduler.schedule(
+                () -> verifyBluetoothNameRestored(expectedName),
+                ASSOCIATE_ADVERTISING_DELAY_MS, TimeUnit.MILLISECONDS);
+    }
+
+    private void addConnectedDevice(BluetoothDevice device, boolean isReconnect) {
+        EventLog.onDeviceConnected();
+        mBlePeripheralManager.stopAdvertising(mAdvertiseCallback);
+        mTimeoutHandler.removeCallbacks(mTimeoutRunnable);
+        mClientDeviceAddress = device.getAddress();
+        mClientDeviceName = device.getName();
+        if (mClientDeviceName == null) {
+            logd(TAG, "Device connected, but name is null; issuing request to retrieve device "
+                    + "name.");
+            mBlePeripheralManager.retrieveDeviceName(device);
+        }
+
+        BleDeviceMessageStream secureStream = new BleDeviceMessageStream(mBlePeripheralManager,
+                device, mWriteCharacteristic, mReadCharacteristic,
+                mDefaultMtuSize - ATT_PROTOCOL_BYTES);
+        secureStream.setMessageReceivedErrorListener(
+                exception -> {
+                    disconnectWithError("Error occurred in stream: " + exception.getMessage());
+                });
+        SecureBleChannel secureChannel;
+        if (isReconnect) {
+            secureChannel = new ReconnectSecureChannel(secureStream, mStorage, mReconnectDeviceId,
+                    mReconnectChallenge);
+        } else {
+            secureChannel = new AssociationSecureChannel(secureStream, mStorage);
+        }
+        secureChannel.registerCallback(mSecureChannelCallback);
+        BleDevice bleDevice = new BleDevice(device, /* gatt= */ null);
+        bleDevice.mSecureChannel = secureChannel;
+        addConnectedDevice(bleDevice);
+        if (isReconnect) {
+            setDeviceId(mReconnectDeviceId);
+            mReconnectDeviceId = null;
+            mReconnectChallenge = null;
+        }
+    }
+
+    private void setMtuSize(int mtuSize) {
+        BleDevice connectedDevice = getConnectedDevice();
+        if (connectedDevice != null
+                && connectedDevice.mSecureChannel != null
+                && connectedDevice.mSecureChannel.getStream() != null) {
+            connectedDevice.mSecureChannel.getStream()
+                    .setMaxWriteSize(mtuSize - ATT_PROTOCOL_BYTES);
+        }
+    }
+
+    private boolean isAssociating() {
+        return mAssociationCallback != null;
+    }
+
+    private final BlePeripheralManager.Callback mReconnectPeripheralCallback =
+            new BlePeripheralManager.Callback() {
+
+                @Override
+                public void onDeviceNameRetrieved(String deviceName) {
+                    // Ignored.
+                }
+
+                @Override
+                public void onMtuSizeChanged(int size) {
+                    setMtuSize(size);
+                }
+
+                @Override
+                public void onRemoteDeviceConnected(BluetoothDevice device) {
+                    addConnectedDevice(device, /* isReconnect= */ true);
+                }
+
+                @Override
+                public void onRemoteDeviceDisconnected(BluetoothDevice device) {
+                    String deviceId = mReconnectDeviceId;
+                    BleDevice connectedDevice = getConnectedDevice(device);
+                    // Reset before invoking callbacks to avoid a race condition with reconnect
+                    // logic.
+                    reset();
+                    if (connectedDevice != null) {
+                        deviceId = connectedDevice.mDeviceId;
+                    }
+                    final String finalDeviceId = deviceId;
+                    if (finalDeviceId != null) {
+                        logd(TAG, "Connected device " + finalDeviceId + " disconnected.");
+                        mCallbacks.invoke(callback -> callback.onDeviceDisconnected(finalDeviceId));
+                    }
+                }
+            };
+
+    private final BlePeripheralManager.Callback mAssociationPeripheralCallback =
+            new BlePeripheralManager.Callback() {
+                @Override
+                public void onDeviceNameRetrieved(String deviceName) {
+                    if (deviceName == null) {
+                        return;
+                    }
+                    mClientDeviceName = deviceName;
+                    BleDevice connectedDevice = getConnectedDevice();
+                    if (connectedDevice == null || connectedDevice.mDeviceId == null) {
+                        return;
+                    }
+                    mStorage.updateAssociatedDeviceName(connectedDevice.mDeviceId, deviceName);
+                }
+
+                @Override
+                public void onMtuSizeChanged(int size) {
+                    setMtuSize(size);
+                }
+
+                @Override
+                public void onRemoteDeviceConnected(BluetoothDevice device) {
+                    resetBluetoothAdapterName();
+                    addConnectedDevice(device, /* isReconnect= */ false);
+                    BleDevice connectedDevice = getConnectedDevice();
+                    if (connectedDevice == null || connectedDevice.mSecureChannel == null) {
+                        return;
+                    }
+                    ((AssociationSecureChannel) connectedDevice.mSecureChannel)
+                            .setShowVerificationCodeListener(
+                                    code -> {
+                                        if (!isAssociating()) {
+                                            loge(TAG, "No valid callback for association.");
+                                            return;
+                                        }
+                                        mAssociationCallback.onVerificationCodeAvailable(code);
+                                    });
+                }
+
+                @Override
+                public void onRemoteDeviceDisconnected(BluetoothDevice device) {
+                    BleDevice connectedDevice = getConnectedDevice(device);
+                    if (isAssociating()) {
+                        mAssociationCallback.onAssociationError(
+                                DEVICE_ERROR_UNEXPECTED_DISCONNECTION);
+                    }
+                    // Reset before invoking callbacks to avoid a race condition with reconnect
+                    // logic.
+                    reset();
+                    if (connectedDevice != null && connectedDevice.mDeviceId != null) {
+                        mCallbacks.invoke(callback -> callback.onDeviceDisconnected(
+                                connectedDevice.mDeviceId));
+                    }
+                }
+            };
+
+    private final SecureBleChannel.Callback mSecureChannelCallback =
+            new SecureBleChannel.Callback() {
+                @Override
+                public void onSecureChannelEstablished() {
+                    BleDevice connectedDevice = getConnectedDevice();
+                    if (connectedDevice == null || connectedDevice.mDeviceId == null) {
+                        disconnectWithError("Null device id found when secure channel "
+                                + "established.");
+                        return;
+                    }
+                    String deviceId = connectedDevice.mDeviceId;
+                    if (mClientDeviceAddress == null) {
+                        disconnectWithError("Null device address found when secure channel "
+                                + "established.");
+                        return;
+                    }
+                    if (isAssociating()) {
+                        logd(TAG, "Secure channel established for un-associated device. Saving "
+                                + "association of that device for current user.");
+                        mStorage.addAssociatedDeviceForActiveUser(
+                                new AssociatedDevice(deviceId, mClientDeviceAddress,
+                                        mClientDeviceName, /* isConnectionEnabled= */ true));
+                        if (mAssociationCallback != null) {
+                            mAssociationCallback.onAssociationCompleted(deviceId);
+                            mAssociationCallback = null;
+                        }
+                    }
+                    mCallbacks.invoke(callback -> callback.onSecureChannelEstablished(deviceId));
+                }
+
+                @Override
+                public void onEstablishSecureChannelFailure(int error) {
+                    BleDevice connectedDevice = getConnectedDevice();
+                    if (connectedDevice == null || connectedDevice.mDeviceId == null) {
+                        disconnectWithError("Null device id found when secure channel failed to "
+                                + "establish.");
+                        return;
+                    }
+                    String deviceId = connectedDevice.mDeviceId;
+                    mCallbacks.invoke(callback -> callback.onSecureChannelError(deviceId));
+
+                    if (isAssociating()) {
+                        mAssociationCallback.onAssociationError(error);
+                    }
+
+                    disconnectWithError("Error while establishing secure connection.");
+                }
+
+                @Override
+                public void onMessageReceived(DeviceMessage deviceMessage) {
+                    BleDevice connectedDevice = getConnectedDevice();
+                    if (connectedDevice == null || connectedDevice.mDeviceId == null) {
+                        disconnectWithError("Null device id found when message received.");
+                        return;
+                    }
+
+                    logd(TAG, "Received new message from " + connectedDevice.mDeviceId
+                            + " with " + deviceMessage.getMessage().length + " bytes in its "
+                            + "payload. Notifying " + mCallbacks.size() + " callbacks.");
+                    mCallbacks.invoke(
+                            callback -> callback.onMessageReceived(connectedDevice.mDeviceId,
+                                    deviceMessage));
+                }
+
+                @Override
+                public void onMessageReceivedError(Exception exception) {
+                    // TODO(b/143879960) Extend the message error from here to continue up the
+                    // chain.
+                    disconnectWithError("Error while receiving message.");
+                }
+
+                @Override
+                public void onDeviceIdReceived(String deviceId) {
+                    setDeviceId(deviceId);
+                }
+            };
+
+    private final Runnable mTimeoutRunnable = new Runnable() {
+        @Override
+        public void run() {
+            logd(TAG, "Timeout period expired without a connection. Restarting advertisement.");
+            mBlePeripheralManager.stopAdvertising(mAdvertiseCallback);
+            connectToDevice(UUID.fromString(mReconnectDeviceId));
+        }
+    };
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/DeviceMessage.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/DeviceMessage.java
new file mode 100644
index 0000000..9d3ac48
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/DeviceMessage.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.BleStreamProtos.BleDeviceMessageProto.BleDeviceMessage;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.UUID;
+
+/** Holds the needed data from a {@link BleDeviceMessage}. */
+public class DeviceMessage {
+
+    private static final String TAG = "DeviceMessage";
+
+    private final UUID mRecipient;
+
+    private final boolean mIsMessageEncrypted;
+
+    private byte[] mMessage;
+
+    public DeviceMessage(@Nullable UUID recipient, boolean isMessageEncrypted,
+            @NonNull byte[] message) {
+        mRecipient = recipient;
+        mIsMessageEncrypted = isMessageEncrypted;
+        mMessage = message;
+    }
+
+    /** Returns the recipient for this message. {@code null} if no recipient set. */
+    @Nullable
+    public UUID getRecipient() {
+        return mRecipient;
+    }
+
+    /** Returns whether this message is encrypted. */
+    public boolean isMessageEncrypted() {
+        return mIsMessageEncrypted;
+    }
+
+    /** Returns the message payload. */
+    @Nullable
+    public byte[] getMessage() {
+        return mMessage;
+    }
+
+    /** Set the message payload. */
+    public void setMessage(@NonNull byte[] message) {
+        mMessage = message;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof DeviceMessage)) {
+            return false;
+        }
+        DeviceMessage deviceMessage = (DeviceMessage) obj;
+        return Objects.equals(mRecipient, deviceMessage.mRecipient)
+                && mIsMessageEncrypted == deviceMessage.mIsMessageEncrypted
+                && Arrays.equals(mMessage, deviceMessage.mMessage);
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * Objects.hash(mRecipient, mIsMessageEncrypted)
+                + Arrays.hashCode(mMessage);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/ReconnectSecureChannel.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/ReconnectSecureChannel.java
new file mode 100644
index 0000000..56eff5c
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/ReconnectSecureChannel.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.car.encryptionrunner.EncryptionRunner;
+import android.car.encryptionrunner.EncryptionRunnerFactory;
+import android.car.encryptionrunner.HandshakeException;
+import android.car.encryptionrunner.HandshakeMessage;
+import android.car.encryptionrunner.HandshakeMessage.HandshakeState;
+import android.car.encryptionrunner.Key;
+
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.util.ByteUtils;
+
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A secure channel established with the reconnection flow.
+ */
+class ReconnectSecureChannel extends SecureBleChannel {
+
+    private static final String TAG = "ReconnectSecureChannel";
+
+    private final ConnectedDeviceStorage mStorage;
+
+    private final String mDeviceId;
+
+    private final byte[] mExpectedChallengeResponse;
+
+    @HandshakeState
+    private int mState = HandshakeState.UNKNOWN;
+
+    private AtomicBoolean mHasVerifiedDevice = new AtomicBoolean(false);
+
+    /**
+     * Create a new secure reconnection channel.
+     *
+     * @param stream The {@link BleDeviceMessageStream} for communication with the device.
+     * @param storage {@link ConnectedDeviceStorage} for secure storage.
+     * @param deviceId Id of the device being reconnected.
+     * @param expectedChallengeResponse Expected response to challenge issued in reconnect.
+     */
+    ReconnectSecureChannel(@NonNull BleDeviceMessageStream stream,
+            @NonNull ConnectedDeviceStorage storage, @NonNull String deviceId,
+            @NonNull byte[] expectedChallengeResponse) {
+        super(stream, newReconnectRunner());
+        mStorage = storage;
+        mDeviceId = deviceId;
+        mExpectedChallengeResponse = expectedChallengeResponse;
+    }
+
+    private static EncryptionRunner newReconnectRunner() {
+        EncryptionRunner encryptionRunner = EncryptionRunnerFactory.newRunner();
+        encryptionRunner.setIsReconnect(true);
+        return encryptionRunner;
+    }
+
+    @Override
+    void processHandshake(byte[] message) throws HandshakeException {
+        switch (mState) {
+            case HandshakeState.UNKNOWN:
+                if (!mHasVerifiedDevice.get()) {
+                    processHandshakeDeviceVerification(message);
+                } else {
+                    processHandshakeInitialization(message);
+                }
+                break;
+            case HandshakeState.IN_PROGRESS:
+                processHandshakeInProgress(message);
+                break;
+            case HandshakeState.RESUMING_SESSION:
+                processHandshakeResumingSession(message);
+                break;
+            default:
+                loge(TAG, "Encountered unexpected handshake state: " + mState + ".");
+                notifySecureChannelFailure(CHANNEL_ERROR_INVALID_STATE);
+        }
+    }
+
+    private void processHandshakeDeviceVerification(byte[] message) {
+        byte[] challengeResponse = Arrays.copyOf(message,
+                mExpectedChallengeResponse.length);
+        byte[] deviceChallenge = Arrays.copyOfRange(message,
+                mExpectedChallengeResponse.length, message.length);
+        if (!Arrays.equals(mExpectedChallengeResponse, challengeResponse)) {
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_ENCRYPTION_KEY);
+            return;
+        }
+        logd(TAG, "Responding to challenge " + ByteUtils.byteArrayToHexString(deviceChallenge)
+                + ".");
+        byte[] deviceChallengeResponse = mStorage.hashWithChallengeSecret(mDeviceId,
+                deviceChallenge);
+        if (deviceChallengeResponse == null) {
+            notifySecureChannelFailure(CHANNEL_ERROR_STORAGE_ERROR);
+        }
+        sendHandshakeMessage(deviceChallengeResponse, /* isEncrypted= */ false);
+        mHasVerifiedDevice.set(true);
+    }
+
+    private void processHandshakeInitialization(byte[] message) throws HandshakeException {
+        logd(TAG, "Responding to handshake init request.");
+        HandshakeMessage handshakeMessage = getEncryptionRunner().respondToInitRequest(message);
+        mState = handshakeMessage.getHandshakeState();
+        sendHandshakeMessage(handshakeMessage.getNextMessage(), /* isEncrypted= */ false);
+    }
+
+    private void processHandshakeInProgress(@NonNull byte[] message) throws HandshakeException {
+        logd(TAG, "Continuing handshake.");
+        HandshakeMessage handshakeMessage = getEncryptionRunner().continueHandshake(message);
+        mState = handshakeMessage.getHandshakeState();
+    }
+
+    private void processHandshakeResumingSession(@NonNull byte[] message)
+            throws HandshakeException {
+        logd(TAG, "Start reconnection authentication.");
+
+        byte[] previousKey = mStorage.getEncryptionKey(mDeviceId);
+        if (previousKey == null) {
+            loge(TAG, "Unable to resume session, previous key is null.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_ENCRYPTION_KEY);
+            return;
+        }
+
+        HandshakeMessage handshakeMessage = getEncryptionRunner().authenticateReconnection(message,
+                previousKey);
+        mState = handshakeMessage.getHandshakeState();
+        if (mState != HandshakeState.FINISHED) {
+            loge(TAG, "Unable to resume session, unexpected next handshake state: " + mState + ".");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_STATE);
+            return;
+        }
+
+        Key newKey = handshakeMessage.getKey();
+        if (newKey == null) {
+            loge(TAG, "Unable to resume session, new key is null.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_ENCRYPTION_KEY);
+            return;
+        }
+
+        logd(TAG, "Saved new key for reconnection.");
+        mStorage.saveEncryptionKey(mDeviceId, newKey.asBytes());
+        setEncryptionKey(newKey);
+        sendServerAuthToClient(handshakeMessage.getNextMessage());
+        notifyCallback(Callback::onSecureChannelEstablished);
+    }
+
+    private void sendServerAuthToClient(@Nullable byte[] message) {
+        if (message == null) {
+            loge(TAG, "Unable to send server authentication message to client, message is null.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_MSG);
+            return;
+        }
+
+        sendHandshakeMessage(message, /* isEncrypted= */ false);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/SecureBleChannel.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/SecureBleChannel.java
new file mode 100644
index 0000000..858d7c8
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/SecureBleChannel.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.car.encryptionrunner.EncryptionRunner;
+import android.car.encryptionrunner.HandshakeException;
+import android.car.encryptionrunner.Key;
+
+import com.android.car.connecteddevice.BleStreamProtos.BleOperationProto.OperationType;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.security.SignatureException;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+
+/**
+ * Establishes a secure channel with {@link EncryptionRunner} over {@link BleDeviceMessageStream} as
+ * server side, sends and receives messages securely after the secure channel has been established.
+ */
+abstract class SecureBleChannel {
+
+    private static final String TAG = "SecureBleChannel";
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "CHANNEL_ERROR" },
+            value = {
+                    CHANNEL_ERROR_INVALID_HANDSHAKE,
+                    CHANNEL_ERROR_INVALID_MSG,
+                    CHANNEL_ERROR_INVALID_DEVICE_ID,
+                    CHANNEL_ERROR_INVALID_VERIFICATION,
+                    CHANNEL_ERROR_INVALID_STATE,
+                    CHANNEL_ERROR_INVALID_ENCRYPTION_KEY,
+                    CHANNEL_ERROR_STORAGE_ERROR
+            }
+    )
+    @interface ChannelError { }
+
+    /** Indicates an error during a Handshake of EncryptionRunner. */
+    static final int CHANNEL_ERROR_INVALID_HANDSHAKE = 0;
+    /** Received an invalid handshake message or has an invalid handshake message to send. */
+    static final int CHANNEL_ERROR_INVALID_MSG = 1;
+    /** Unable to retrieve a valid id. */
+    static final int CHANNEL_ERROR_INVALID_DEVICE_ID = 2;
+    /** Unable to get verification code or there's a error during pin verification. */
+    static final int CHANNEL_ERROR_INVALID_VERIFICATION = 3;
+    /** Encountered an unexpected handshake state. */
+    static final int CHANNEL_ERROR_INVALID_STATE = 4;
+    /** Failed to get a valid previous/new encryption key. */
+    static final int CHANNEL_ERROR_INVALID_ENCRYPTION_KEY = 5;
+    /** Failed to save or retrieve security keys. */
+    static final int CHANNEL_ERROR_STORAGE_ERROR = 6;
+
+
+    private final BleDeviceMessageStream mStream;
+
+    private final EncryptionRunner mEncryptionRunner;
+
+    private final AtomicReference<Key> mEncryptionKey = new AtomicReference<>();
+
+    private Callback mCallback;
+
+    SecureBleChannel(@NonNull BleDeviceMessageStream stream,
+            @NonNull EncryptionRunner encryptionRunner) {
+        mStream = stream;
+        mEncryptionRunner = encryptionRunner;
+        mStream.setMessageReceivedListener(this::onMessageReceived);
+    }
+
+    /** Logic for processing a handshake message from device. */
+    abstract void processHandshake(byte[] message) throws HandshakeException;
+
+    void sendHandshakeMessage(@Nullable byte[] message, boolean isEncrypted) {
+        if (message == null) {
+            loge(TAG, "Unable to send next handshake message, message is null.");
+            notifySecureChannelFailure(CHANNEL_ERROR_INVALID_MSG);
+            return;
+        }
+
+        logd(TAG, "Sending handshake message.");
+        DeviceMessage deviceMessage = new DeviceMessage(/* recipient= */ null,
+                isEncrypted, message);
+        if (deviceMessage.isMessageEncrypted()) {
+            encryptMessage(deviceMessage);
+        }
+        mStream.writeMessage(deviceMessage, OperationType.ENCRYPTION_HANDSHAKE);
+    }
+
+    /** Set the encryption key that secures this channel. */
+    void setEncryptionKey(@Nullable Key encryptionKey) {
+        mEncryptionKey.set(encryptionKey);
+    }
+
+    /**
+     * Send a client message.
+     * <p>Note: This should be called with an encrypted message only after the secure channel has
+     * been established.</p>
+     *
+     * @param deviceMessage The {@link DeviceMessage} to send.
+     */
+    void sendClientMessage(@NonNull DeviceMessage deviceMessage)
+            throws IllegalStateException {
+        if (deviceMessage.isMessageEncrypted()) {
+            encryptMessage(deviceMessage);
+        }
+        mStream.writeMessage(deviceMessage, OperationType.CLIENT_MESSAGE);
+    }
+
+    private void encryptMessage(@NonNull DeviceMessage deviceMessage) {
+        Key key = mEncryptionKey.get();
+        if (key == null) {
+            throw new IllegalStateException("Secure channel has not been established.");
+        }
+
+        byte[] encryptedMessage = key.encryptData(deviceMessage.getMessage());
+        deviceMessage.setMessage(encryptedMessage);
+    }
+
+    /** Get the BLE stream backing this channel. */
+    @NonNull
+    BleDeviceMessageStream getStream() {
+        return mStream;
+    }
+
+    /** Register a callback that notifies secure channel events. */
+    void registerCallback(Callback callback) {
+        mCallback = callback;
+    }
+
+    /** Unregister a callback. */
+    void unregisterCallback(Callback callback) {
+        if (callback == mCallback) {
+            mCallback = null;
+        }
+    }
+
+    @VisibleForTesting
+    @Nullable
+    Callback getCallback() {
+        return mCallback;
+    }
+
+    void notifyCallback(@NonNull Consumer<Callback> notification) {
+        if (mCallback != null) {
+            notification.accept(mCallback);
+        }
+    }
+
+    /** Notify callbacks that an error has occurred. */
+    void notifySecureChannelFailure(@ChannelError int error) {
+        loge(TAG, "Secure channel error: " + error);
+        notifyCallback(callback -> callback.onEstablishSecureChannelFailure(error));
+    }
+
+    /** Return the {@link EncryptionRunner} for this channel. */
+    @NonNull
+    EncryptionRunner getEncryptionRunner() {
+        return mEncryptionRunner;
+    }
+
+    /**
+     * Process the inner message and replace with decrypted value if necessary. If an error occurs
+     * the inner message will be replaced with {@code null} and call
+     * {@link Callback#onMessageReceivedError(Exception)} on the registered callback.
+     *
+     * @param deviceMessage The message to process.
+     * @return {@code true} if message was successfully processed. {@code false} if an error
+     * occurred.
+     */
+    @VisibleForTesting
+    boolean processMessage(@NonNull DeviceMessage deviceMessage) {
+        if (!deviceMessage.isMessageEncrypted()) {
+            logd(TAG, "Message was not decrypted. No further action necessary.");
+            return true;
+        }
+        Key key = mEncryptionKey.get();
+        if (key == null) {
+            loge(TAG, "Received encrypted message before secure channel has "
+                    + "been established.");
+            notifyCallback(callback -> callback.onMessageReceivedError(null));
+            deviceMessage.setMessage(null);
+            return false;
+        }
+        try {
+            byte[] decryptedMessage = key.decryptData(deviceMessage.getMessage());
+            deviceMessage.setMessage(decryptedMessage);
+            logd(TAG, "Decrypted secure message.");
+            return true;
+        } catch (SignatureException e) {
+            loge(TAG, "Could not decrypt client credentials.", e);
+            notifyCallback(callback -> callback.onMessageReceivedError(e));
+            deviceMessage.setMessage(null);
+
+            return false;
+        }
+    }
+
+    @VisibleForTesting
+    void onMessageReceived(@NonNull DeviceMessage deviceMessage, OperationType operationType) {
+        boolean success = processMessage(deviceMessage);
+        switch(operationType) {
+            case ENCRYPTION_HANDSHAKE:
+                if (!success) {
+                    notifyCallback(callback -> callback.onEstablishSecureChannelFailure(
+                            CHANNEL_ERROR_INVALID_HANDSHAKE));
+                    break;
+                }
+                logd(TAG, "Received handshake message.");
+                try {
+                    processHandshake(deviceMessage.getMessage());
+                } catch (HandshakeException e) {
+                    loge(TAG, "Handshake failed.", e);
+                    notifyCallback(callback -> callback.onEstablishSecureChannelFailure(
+                            CHANNEL_ERROR_INVALID_HANDSHAKE));
+                }
+                break;
+            case CLIENT_MESSAGE:
+                if (!success || deviceMessage.getMessage() == null) {
+                    break;
+                }
+                logd(TAG, "Received client message.");
+                notifyCallback(
+                        callback -> callback.onMessageReceived(deviceMessage));
+                break;
+            default:
+                loge(TAG, "Received unexpected operation type: " + operationType + ".");
+        }
+    }
+
+    /**
+     * Callbacks that will be invoked during establishing secure channel, sending and receiving
+     * messages securely.
+     */
+    interface Callback {
+        /**
+         * Invoked when secure channel has been established successfully.
+         */
+        default void onSecureChannelEstablished() { }
+
+        /**
+         * Invoked when a {@link ChannelError} has been encountered in attempting to establish
+         * a secure channel.
+         *
+         * @param error The failure indication.
+         */
+        default void onEstablishSecureChannelFailure(@SecureBleChannel.ChannelError int error) { }
+
+        /**
+         * Invoked when a complete message is received securely from the client and decrypted.
+         *
+         * @param deviceMessage The {@link DeviceMessage} with decrypted message.
+         */
+        default void onMessageReceived(@NonNull DeviceMessage deviceMessage) { }
+
+        /**
+         * Invoked when there was an error during a processing or decrypting of a client message.
+         *
+         * @param exception The error.
+         */
+        default void onMessageReceivedError(@Nullable Exception exception) { }
+
+        /**
+         * Invoked when the device id was received from the client.
+         *
+         * @param deviceId The unique device id of client.
+         */
+        default void onDeviceIdReceived(@NonNull String deviceId) { }
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/model/AssociatedDevice.java b/connected-device-lib/src/com/android/car/connecteddevice/model/AssociatedDevice.java
new file mode 100644
index 0000000..88fce6c
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/model/AssociatedDevice.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.model;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * Contains basic info of an associated device.
+ */
+public class AssociatedDevice {
+
+    private final String mDeviceId;
+
+    private final String mDeviceAddress;
+
+    private final String mDeviceName;
+
+    private final boolean mIsConnectionEnabled;
+
+
+    /**
+     * Create a new AssociatedDevice.
+     *
+     * @param deviceId Id of the associated device.
+     * @param deviceAddress Address of the associated device.
+     * @param deviceName Name of the associated device. {@code null} if not known.
+     * @param isConnectionEnabled If connection is enabled for this device.
+     */
+    public AssociatedDevice(@NonNull String deviceId, @NonNull String deviceAddress,
+            @Nullable String deviceName, boolean isConnectionEnabled) {
+        mDeviceId = deviceId;
+        mDeviceAddress = deviceAddress;
+        mDeviceName = deviceName;
+        mIsConnectionEnabled = isConnectionEnabled;
+    }
+
+    /** Returns the id for this device. */
+    @NonNull
+    public String getDeviceId() {
+        return mDeviceId;
+    }
+
+    /** Returns the address for this device. */
+    @NonNull
+    public String getDeviceAddress() {
+        return mDeviceAddress;
+    }
+
+    /** Returns the name for this device or {@code null} if not known. */
+    @Nullable
+    public String getDeviceName() {
+        return mDeviceName;
+    }
+
+    /** Return if connection is enabled for this device. */
+    public boolean isConnectionEnabled() {
+        return mIsConnectionEnabled;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof AssociatedDevice)) {
+            return false;
+        }
+        AssociatedDevice associatedDevice = (AssociatedDevice) obj;
+        return Objects.equals(mDeviceId, associatedDevice.mDeviceId)
+                && Objects.equals(mDeviceAddress, associatedDevice.mDeviceAddress)
+                && Objects.equals(mDeviceName, associatedDevice.mDeviceName)
+                && mIsConnectionEnabled == associatedDevice.mIsConnectionEnabled;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mDeviceId, mDeviceAddress, mDeviceName, mIsConnectionEnabled);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/model/ConnectedDevice.java b/connected-device-lib/src/com/android/car/connecteddevice/model/ConnectedDevice.java
new file mode 100644
index 0000000..d65f97d
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/model/ConnectedDevice.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.model;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * View model representing a connected device.
+ */
+public class ConnectedDevice {
+
+    private final String mDeviceId;
+
+    private final String mDeviceName;
+
+    private final boolean mBelongsToActiveUser;
+
+    private final boolean mHasSecureChannel;
+
+    /**
+     * Create a new connected device.
+     *
+     * @param deviceId Id of the connected device.
+     * @param deviceName Name of the connected device. {@code null} if not known.
+     * @param belongsToActiveUser User associated with this device is currently in the foreground.
+     * @param hasSecureChannel {@code true} if a secure channel is available for this device.
+     */
+    public ConnectedDevice(@NonNull String deviceId, @Nullable String deviceName,
+            boolean belongsToActiveUser, boolean hasSecureChannel) {
+        mDeviceId = deviceId;
+        mDeviceName = deviceName;
+        mBelongsToActiveUser = belongsToActiveUser;
+        mHasSecureChannel = hasSecureChannel;
+    }
+
+    /** Returns the id for this device. */
+    @NonNull
+    public String getDeviceId() {
+        return mDeviceId;
+    }
+
+    /** Returns the name for this device or {@code null} if not known. */
+    @Nullable
+    public String getDeviceName() {
+        return mDeviceName;
+    }
+
+    /**
+     * Returns {@code true} if this device is associated with the user currently in the foreground.
+     */
+    public boolean isAssociatedWithActiveUser() {
+        return mBelongsToActiveUser;
+    }
+
+    /** Returns {@code true} if this device has a secure channel available. */
+    public boolean hasSecureChannel() {
+        return mHasSecureChannel;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof ConnectedDevice)) {
+            return false;
+        }
+        ConnectedDevice connectedDevice = (ConnectedDevice) obj;
+        return Objects.equals(mDeviceId, connectedDevice.mDeviceId)
+                && Objects.equals(mDeviceName, connectedDevice.mDeviceName)
+                && mBelongsToActiveUser == connectedDevice.mBelongsToActiveUser
+                && mHasSecureChannel == connectedDevice.mHasSecureChannel;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mDeviceId, mDeviceName, mBelongsToActiveUser, mHasSecureChannel);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceChallengeSecretEntity.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceChallengeSecretEntity.java
new file mode 100644
index 0000000..ab802e6
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceChallengeSecretEntity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.storage;
+
+import androidx.annotation.NonNull;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+/**
+ * Table entity representing an challenge key for an associated device reconnection advertisement.
+ */
+@Entity(tableName = "associated_devices_challenge_secrets")
+public class AssociatedDeviceChallengeSecretEntity {
+
+    /** Id of the device. */
+    @PrimaryKey
+    @NonNull
+    public String id;
+
+    /** Encrypted challenge key. */
+    @NonNull
+    public String encryptedChallengeSecret;
+
+    public AssociatedDeviceChallengeSecretEntity(String id, String encryptedChallengeSecret) {
+        this.id = id;
+        this.encryptedChallengeSecret = encryptedChallengeSecret;
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceDao.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceDao.java
new file mode 100644
index 0000000..2a1e023
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceDao.java
@@ -0,0 +1,83 @@
+/*
+ * 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.connecteddevice.storage;
+
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
+
+import java.util.List;
+
+/**
+ * Queries for associated device table.
+ */
+@Dao
+public interface AssociatedDeviceDao {
+
+    /** Get an associated device based on device id. */
+    @Query("SELECT * FROM associated_devices WHERE id LIKE :deviceId LIMIT 1")
+    AssociatedDeviceEntity getAssociatedDevice(String deviceId);
+
+    /** Get all {@link AssociatedDeviceEntity}s associated with a user. */
+    @Query("SELECT * FROM associated_devices WHERE userId LIKE :userId")
+    List<AssociatedDeviceEntity> getAssociatedDevicesForUser(int userId);
+
+    /**
+     * Add a {@link AssociatedDeviceEntity}. Replace if a device already exists with the same
+     * device id.
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    void addOrReplaceAssociatedDevice(AssociatedDeviceEntity associatedDevice);
+
+    /** Remove a {@link AssociatedDeviceEntity}. */
+    @Delete
+    void removeAssociatedDevice(AssociatedDeviceEntity connectedDevice);
+
+    /** Get the key associated with a device id. */
+    @Query("SELECT * FROM associated_device_keys WHERE id LIKE :deviceId LIMIT 1")
+    AssociatedDeviceKeyEntity getAssociatedDeviceKey(String deviceId);
+
+    /**
+     * Add a {@link AssociatedDeviceKeyEntity}. Replace if a device key already exists with the
+     * same device id.
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    void addOrReplaceAssociatedDeviceKey(AssociatedDeviceKeyEntity keyEntity);
+
+    /** Remove a {@link AssociatedDeviceKeyEntity}. */
+    @Delete
+    void removeAssociatedDeviceKey(AssociatedDeviceKeyEntity keyEntity);
+
+    /** Get the challenge secret associated with a device id. */
+    @Query("SELECT * FROM associated_devices_challenge_secrets WHERE id LIKE :deviceId LIMIT 1")
+    AssociatedDeviceChallengeSecretEntity getAssociatedDeviceChallengeSecret(String deviceId);
+
+    /**
+     * Add a {@link AssociatedDeviceChallengeSecretEntity}. Replace if a secret already exists with
+     * the same device id.
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    void addOrReplaceAssociatedDeviceChallengeSecret(
+            AssociatedDeviceChallengeSecretEntity challengeSecretEntity);
+
+    /** Remove a {@link AssociatedDeviceChallengeSecretEntity}. */
+    @Delete
+    void removeAssociatedDeviceChallengeSecret(
+            AssociatedDeviceChallengeSecretEntity challengeSecretEntity);
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceEntity.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceEntity.java
new file mode 100644
index 0000000..1c5182c
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceEntity.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.storage;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+import com.android.car.connecteddevice.model.AssociatedDevice;
+
+/** Table entity representing an associated device. */
+@Entity(tableName = "associated_devices")
+public class AssociatedDeviceEntity {
+
+    /** Id of the device. */
+    @PrimaryKey
+    @NonNull
+    public String id;
+
+    /** Id of user associated with this device. */
+    public int userId;
+
+    /** Bluetooth address of the device. */
+    @Nullable
+    public String address;
+
+    /** Bluetooth device name. */
+    @Nullable
+    public String name;
+
+    /** {@code true} if the connection is enabled for this device.*/
+    public boolean isConnectionEnabled;
+
+    public AssociatedDeviceEntity() { }
+
+    public AssociatedDeviceEntity(int userId, AssociatedDevice associatedDevice,
+            boolean isConnectionEnabled) {
+        this.userId = userId;
+        id = associatedDevice.getDeviceId();
+        address = associatedDevice.getDeviceAddress();
+        name = associatedDevice.getDeviceName();
+        this.isConnectionEnabled = isConnectionEnabled;
+    }
+
+    /** Return a new {@link AssociatedDevice} of this entity. */
+    public AssociatedDevice toAssociatedDevice() {
+        return new AssociatedDevice(id, address, name, isConnectionEnabled);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceKeyEntity.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceKeyEntity.java
new file mode 100644
index 0000000..6cd791f
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceKeyEntity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.storage;
+
+import androidx.annotation.NonNull;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+/** Table entity representing a key for an associated device. */
+@Entity(tableName = "associated_device_keys")
+public class AssociatedDeviceKeyEntity {
+
+    /** Id of the device. */
+    @PrimaryKey
+    @NonNull
+    public String id;
+
+    @NonNull
+    public String encryptedKey;
+
+    public AssociatedDeviceKeyEntity() { }
+
+    public AssociatedDeviceKeyEntity(String deviceId, String encryptedKey) {
+        id = deviceId;
+        this.encryptedKey = encryptedKey;
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceDatabase.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceDatabase.java
new file mode 100644
index 0000000..98a7b0a
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceDatabase.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.storage;
+
+import androidx.room.Database;
+import androidx.room.RoomDatabase;
+
+/** Database for connected devices. */
+@Database(entities = { AssociatedDeviceEntity.class, AssociatedDeviceKeyEntity.class,
+        AssociatedDeviceChallengeSecretEntity.class },
+        version = 2,
+        exportSchema = false)
+public abstract class ConnectedDeviceDatabase extends RoomDatabase {
+
+    /** Return the DAO for the associated device table. */
+    public abstract AssociatedDeviceDao associatedDeviceDao();
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorage.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorage.java
new file mode 100644
index 0000000..19d894e
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorage.java
@@ -0,0 +1,564 @@
+/*
+ * 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.connecteddevice.storage;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+import static com.android.car.connecteddevice.util.SafeLog.loge;
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import android.util.Base64;
+
+import androidx.room.Room;
+
+import com.android.car.connecteddevice.R;
+import com.android.car.connecteddevice.model.AssociatedDevice;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/** Storage for connected devices in a car. */
+public class ConnectedDeviceStorage {
+    private static final String TAG = "CompanionStorage";
+
+    private static final String UNIQUE_ID_KEY = "CTABM_unique_id";
+    private static final String BT_NAME_KEY = "CTABM_bt_name";
+    private static final String KEY_ALIAS = "Ukey2Key";
+    private static final String CIPHER_TRANSFORMATION = "AES/GCM/NoPadding";
+    private static final String KEYSTORE_PROVIDER = "AndroidKeyStore";
+    private static final String DATABASE_NAME = "connected-device-database";
+    private static final String IV_SPEC_SEPARATOR = ";";
+
+    private static final String CHALLENGE_HASHING_ALGORITHM = "HmacSHA256";
+    // This delimiter separates deviceId and deviceInfo, so it has to differ from the
+    // TrustedDeviceInfo delimiter. Once new API can be added, deviceId will be added to
+    // TrustedDeviceInfo and this delimiter will be removed.
+
+    // The length of the authentication tag for a cipher in GCM mode. The GCM specification states
+    // that this length can only have the values {128, 120, 112, 104, 96}. Using the highest
+    // possible value.
+    private static final int GCM_AUTHENTICATION_TAG_LENGTH = 128;
+
+    @VisibleForTesting
+    static final int CHALLENGE_SECRET_BYTES = 32;
+
+    private final Context mContext;
+
+    private SharedPreferences mSharedPreferences;
+
+    private UUID mUniqueId;
+
+    private AssociatedDeviceDao mAssociatedDeviceDatabase;
+
+    private AssociatedDeviceCallback mAssociatedDeviceCallback;
+
+    public ConnectedDeviceStorage(@NonNull Context context) {
+        mContext = context;
+        mAssociatedDeviceDatabase = Room.databaseBuilder(context, ConnectedDeviceDatabase.class,
+                DATABASE_NAME)
+                .fallbackToDestructiveMigration()
+                .build()
+                .associatedDeviceDao();
+    }
+
+    /**
+     * Set a callback for associated device updates.
+     *
+     * @param callback {@link AssociatedDeviceCallback} to set.
+     */
+    public void setAssociatedDeviceCallback(
+            @NonNull AssociatedDeviceCallback callback) {
+        mAssociatedDeviceCallback = callback;
+    }
+
+    /** Clear the callback for association device callback updates. */
+    public void clearAssociationDeviceCallback() {
+        mAssociatedDeviceCallback = null;
+    }
+
+    /**
+     * Get communication encryption key for the given device.
+     *
+     * @param deviceId id of trusted device
+     * @return encryption key, null if device id is not recognized
+     */
+    @Nullable
+    public byte[] getEncryptionKey(@NonNull String deviceId) {
+        AssociatedDeviceKeyEntity entity =
+                mAssociatedDeviceDatabase.getAssociatedDeviceKey(deviceId);
+        if (entity == null) {
+            logd(TAG, "Encryption key not found!");
+            return null;
+        }
+        String[] values = entity.encryptedKey.split(IV_SPEC_SEPARATOR, -1);
+
+        if (values.length != 2) {
+            logd(TAG, "Stored encryption key had the wrong length.");
+            return null;
+        }
+
+        byte[] encryptedKey = Base64.decode(values[0], Base64.DEFAULT);
+        byte[] ivSpec = Base64.decode(values[1], Base64.DEFAULT);
+        return decryptWithKeyStore(KEY_ALIAS, encryptedKey, ivSpec);
+    }
+
+    /**
+     * Save encryption key for the given device.
+     *
+     * @param deviceId id of the device
+     * @param encryptionKey encryption key
+     */
+    public void saveEncryptionKey(@NonNull String deviceId, @NonNull byte[] encryptionKey) {
+        String encryptedKey = encryptWithKeyStore(KEY_ALIAS, encryptionKey);
+        AssociatedDeviceKeyEntity entity = new AssociatedDeviceKeyEntity(deviceId, encryptedKey);
+        mAssociatedDeviceDatabase.addOrReplaceAssociatedDeviceKey(entity);
+        logd(TAG, "Successfully wrote encryption key.");
+    }
+
+    /**
+     * Save challenge secret for the given device.
+     *
+     * @param deviceId id of the device
+     * @param secret   Secret associated with this device. Note: must be
+     *                 {@value CHALLENGE_SECRET_BYTES} bytes in length or an
+     *                 {@link InvalidParameterException} will be thrown.
+     */
+    public void saveChallengeSecret(@NonNull String deviceId, @NonNull byte[] secret) {
+        if (secret.length != CHALLENGE_SECRET_BYTES) {
+            throw new InvalidParameterException("Secrets must be " + CHALLENGE_SECRET_BYTES
+                    + " bytes in length.");
+        }
+
+        String encryptedKey = encryptWithKeyStore(KEY_ALIAS, secret);
+        AssociatedDeviceChallengeSecretEntity entity = new AssociatedDeviceChallengeSecretEntity(
+                deviceId, encryptedKey);
+        mAssociatedDeviceDatabase.addOrReplaceAssociatedDeviceChallengeSecret(entity);
+        logd(TAG, "Successfully wrote challenge secret.");
+    }
+
+    /** Get the challenge secret associated with a device. */
+    public byte[] getChallengeSecret(@NonNull String deviceId) {
+        AssociatedDeviceChallengeSecretEntity entity =
+                mAssociatedDeviceDatabase.getAssociatedDeviceChallengeSecret(deviceId);
+        if (entity == null) {
+            logd(TAG, "Challenge secret not found!");
+            return null;
+        }
+        String[] values = entity.encryptedChallengeSecret.split(IV_SPEC_SEPARATOR, -1);
+
+        if (values.length != 2) {
+            logd(TAG, "Stored encryption key had the wrong length.");
+            return null;
+        }
+
+        byte[] encryptedSecret = Base64.decode(values[0], Base64.DEFAULT);
+        byte[] ivSpec = Base64.decode(values[1], Base64.DEFAULT);
+        return decryptWithKeyStore(KEY_ALIAS, encryptedSecret, ivSpec);
+    }
+
+    /**
+     * Hash provided value with device's challenge secret and return result. Returns {@code null} if
+     * unsuccessful.
+     */
+    @Nullable
+    public byte[] hashWithChallengeSecret(@NonNull String deviceId, @NonNull byte[] value) {
+        byte[] challengeSecret = getChallengeSecret(deviceId);
+        if (challengeSecret == null) {
+            loge(TAG, "Unable to find challenge secret for device " + deviceId + ".");
+            return null;
+        }
+
+        Mac mac;
+        try {
+            mac = Mac.getInstance(CHALLENGE_HASHING_ALGORITHM);
+        } catch (NoSuchAlgorithmException e) {
+            loge(TAG, "Unable to find hashing algorithm " + CHALLENGE_HASHING_ALGORITHM + ".", e);
+            return null;
+        }
+
+        SecretKeySpec keySpec = new SecretKeySpec(challengeSecret, CHALLENGE_HASHING_ALGORITHM);
+        try {
+            mac.init(keySpec);
+        } catch (InvalidKeyException e) {
+            loge(TAG, "Exception while initializing HMAC.", e);
+            return null;
+        }
+
+        return mac.doFinal(value);
+    }
+
+    /**
+     * Encrypt value with designated key
+     *
+     * <p>The encrypted value is of the form:
+     *
+     * <p>key + IV_SPEC_SEPARATOR + ivSpec
+     *
+     * <p>The {@code ivSpec} is needed to decrypt this key later on.
+     *
+     * @param keyAlias KeyStore alias for key to use
+     * @param value    a value to encrypt
+     * @return encrypted value, null if unable to encrypt
+     */
+    @Nullable
+    private String encryptWithKeyStore(@NonNull String keyAlias, @Nullable byte[] value) {
+        if (value == null) {
+            logw(TAG, "Received a null key value.");
+            return null;
+        }
+
+        Key key = getKeyStoreKey(keyAlias);
+        try {
+            Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            return Base64.encodeToString(cipher.doFinal(value), Base64.DEFAULT)
+                    + IV_SPEC_SEPARATOR
+                    + Base64.encodeToString(cipher.getIV(), Base64.DEFAULT);
+        } catch (IllegalBlockSizeException
+                | BadPaddingException
+                | NoSuchAlgorithmException
+                | NoSuchPaddingException
+                | IllegalStateException
+                | InvalidKeyException e) {
+            loge(TAG, "Unable to encrypt value with key " + keyAlias, e);
+            return null;
+        }
+    }
+
+    /**
+     * Decrypt value with designated key
+     *
+     * @param keyAlias KeyStore alias for key to use
+     * @param value    encrypted value
+     * @return decrypted value, null if unable to decrypt
+     */
+    @Nullable
+    private byte[] decryptWithKeyStore(
+            @NonNull String keyAlias, @Nullable byte[] value, @NonNull byte[] ivSpec) {
+        if (value == null) {
+            return null;
+        }
+
+        try {
+            Key key = getKeyStoreKey(keyAlias);
+            Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
+            cipher.init(
+                    Cipher.DECRYPT_MODE, key,
+                    new GCMParameterSpec(GCM_AUTHENTICATION_TAG_LENGTH, ivSpec));
+            return cipher.doFinal(value);
+        } catch (IllegalBlockSizeException
+                | BadPaddingException
+                | NoSuchAlgorithmException
+                | NoSuchPaddingException
+                | IllegalStateException
+                | InvalidKeyException
+                | InvalidAlgorithmParameterException e) {
+            loge(TAG, "Unable to decrypt value with key " + keyAlias, e);
+            return null;
+        }
+    }
+
+    @Nullable
+    private static Key getKeyStoreKey(@NonNull String keyAlias) {
+        KeyStore keyStore;
+        try {
+            keyStore = KeyStore.getInstance(KEYSTORE_PROVIDER);
+            keyStore.load(null);
+            if (!keyStore.containsAlias(keyAlias)) {
+                KeyGenerator keyGenerator =
+                        KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
+                                KEYSTORE_PROVIDER);
+                keyGenerator.init(
+                        new KeyGenParameterSpec.Builder(
+                                keyAlias,
+                                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .build());
+                keyGenerator.generateKey();
+            }
+            return keyStore.getKey(keyAlias, null);
+
+        } catch (KeyStoreException
+                | NoSuchAlgorithmException
+                | UnrecoverableKeyException
+                | NoSuchProviderException
+                | CertificateException
+                | IOException
+                | InvalidAlgorithmParameterException e) {
+            loge(TAG, "Unable to retrieve key " + keyAlias + " from KeyStore.", e);
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @NonNull
+    private SharedPreferences getSharedPrefs() {
+        // This should be called only after user 0 is unlocked.
+        if (mSharedPreferences != null) {
+            return mSharedPreferences;
+        }
+        mSharedPreferences = mContext.getSharedPreferences(
+                mContext.getString(R.string.connected_device_shared_preferences),
+                Context.MODE_PRIVATE);
+        return mSharedPreferences;
+
+    }
+
+    /**
+     * Get the unique id for head unit. Persists on device until factory reset. This should be
+     * called only after user 0 is unlocked.
+     *
+     * @return unique id
+     */
+    @NonNull
+    public UUID getUniqueId() {
+        if (mUniqueId != null) {
+            return mUniqueId;
+        }
+
+        SharedPreferences prefs = getSharedPrefs();
+        if (prefs.contains(UNIQUE_ID_KEY)) {
+            mUniqueId = UUID.fromString(prefs.getString(UNIQUE_ID_KEY, null));
+            logd(TAG,
+                    "Found existing trusted unique id: " + prefs.getString(UNIQUE_ID_KEY, ""));
+        }
+
+        if (mUniqueId == null) {
+            mUniqueId = UUID.randomUUID();
+            prefs.edit().putString(UNIQUE_ID_KEY, mUniqueId.toString()).apply();
+            logd(TAG,
+                    "Generated new trusted unique id: " + prefs.getString(UNIQUE_ID_KEY, ""));
+        }
+
+        return mUniqueId;
+    }
+
+    /** Store the current bluetooth adapter name. */
+    public void storeBluetoothName(@NonNull String name) {
+        getSharedPrefs().edit().putString(BT_NAME_KEY, name).apply();
+    }
+
+    /** Get the previously stored bluetooth adapter name or {@code null} if not found. */
+    @Nullable
+    public String getStoredBluetoothName() {
+        return getSharedPrefs().getString(BT_NAME_KEY, null);
+    }
+
+    /** Remove the previously stored bluetooth adapter name from storage. */
+    public void removeStoredBluetoothName() {
+        getSharedPrefs().edit().remove(BT_NAME_KEY).apply();
+    }
+
+    /**
+     * Get a list of associated devices for the given user.
+     *
+     * @param userId The identifier of the user.
+     * @return Associated device list.
+     */
+    @NonNull
+    public List<AssociatedDevice> getAssociatedDevicesForUser(@NonNull int userId) {
+        List<AssociatedDeviceEntity> entities =
+                mAssociatedDeviceDatabase.getAssociatedDevicesForUser(userId);
+
+        if (entities == null) {
+            return new ArrayList<>();
+        }
+
+        ArrayList<AssociatedDevice> userDevices = new ArrayList<>();
+        for (AssociatedDeviceEntity entity : entities) {
+            userDevices.add(entity.toAssociatedDevice());
+        }
+
+        return userDevices;
+    }
+
+    /**
+     * Get a list of associated devices for the current user.
+     *
+     * @return Associated device list.
+     */
+    @NonNull
+    public List<AssociatedDevice> getActiveUserAssociatedDevices() {
+        return getAssociatedDevicesForUser(ActivityManager.getCurrentUser());
+    }
+
+    /**
+     * Returns a list of device ids of associated devices for the given user.
+     *
+     * @param userId The user id for whom we want to know the device ids.
+     * @return List of device ids.
+     */
+    @NonNull
+    public List<String> getAssociatedDeviceIdsForUser(@NonNull int userId) {
+        List<AssociatedDevice> userDevices = getAssociatedDevicesForUser(userId);
+        ArrayList<String> userDeviceIds = new ArrayList<>();
+
+        for (AssociatedDevice device : userDevices) {
+            userDeviceIds.add(device.getDeviceId());
+        }
+
+        return userDeviceIds;
+    }
+
+    /**
+     * Returns a list of device ids of associated devices for the current user.
+     *
+     * @return List of device ids.
+     */
+    @NonNull
+    public List<String> getActiveUserAssociatedDeviceIds() {
+        return getAssociatedDeviceIdsForUser(ActivityManager.getCurrentUser());
+    }
+
+    /**
+     * Add the associated device of the given deviceId for the currently active user.
+     *
+     * @param device New associated device to be added.
+     */
+    public void addAssociatedDeviceForActiveUser(@NonNull AssociatedDevice device) {
+        addAssociatedDeviceForUser(ActivityManager.getCurrentUser(), device);
+        if (mAssociatedDeviceCallback != null) {
+            mAssociatedDeviceCallback.onAssociatedDeviceAdded(device);
+        }
+    }
+
+
+    /**
+     * Add the associated device of the given deviceId for the given user.
+     *
+     * @param userId The identifier of the user.
+     * @param device New associated device to be added.
+     */
+    public void addAssociatedDeviceForUser(int userId, @NonNull AssociatedDevice device) {
+        AssociatedDeviceEntity entity = new AssociatedDeviceEntity(userId, device,
+                /* isConnectionEnabled= */ true);
+        mAssociatedDeviceDatabase.addOrReplaceAssociatedDevice(entity);
+    }
+
+    /**
+     * Update the name for an associated device.
+     *
+     * @param deviceId The id of the associated device.
+     * @param name The name to replace with.
+     */
+    public void updateAssociatedDeviceName(@NonNull String deviceId, @NonNull String name) {
+        AssociatedDeviceEntity entity = mAssociatedDeviceDatabase.getAssociatedDevice(deviceId);
+        if (entity == null) {
+            logw(TAG, "Attempt to update name on an unrecognized device " + deviceId
+                    + ". Ignoring.");
+            return;
+        }
+        entity.name = name;
+        mAssociatedDeviceDatabase.addOrReplaceAssociatedDevice(entity);
+        if (mAssociatedDeviceCallback != null) {
+            mAssociatedDeviceCallback.onAssociatedDeviceUpdated(new AssociatedDevice(deviceId,
+                    entity.address, name, entity.isConnectionEnabled));
+        }
+    }
+
+    /**
+     * Remove the associated device of the given deviceId for the given user.
+     *
+     * @param userId The identifier of the user.
+     * @param deviceId The identifier of the device to be cleared.
+     */
+    public void removeAssociatedDevice(int userId, @NonNull String deviceId) {
+        AssociatedDeviceEntity entity = mAssociatedDeviceDatabase.getAssociatedDevice(deviceId);
+        if (entity == null || entity.userId != userId) {
+            return;
+        }
+        mAssociatedDeviceDatabase.removeAssociatedDevice(entity);
+        if (mAssociatedDeviceCallback != null) {
+            mAssociatedDeviceCallback.onAssociatedDeviceRemoved(new AssociatedDevice(deviceId,
+                    entity.address, entity.name, entity.isConnectionEnabled));
+        }
+    }
+
+    /**
+     * Clear the associated device of the given deviceId for the current user.
+     *
+     * @param deviceId The identifier of the device to be cleared.
+     */
+    public void removeAssociatedDeviceForActiveUser(@NonNull String deviceId) {
+        removeAssociatedDevice(ActivityManager.getCurrentUser(), deviceId);
+    }
+
+    /**
+     * Set if connection is enabled for an associated device.
+     *
+     * @param deviceId The id of the associated device.
+     * @param isConnectionEnabled If connection enabled for this device.
+     */
+    public void updateAssociatedDeviceConnectionEnabled(@NonNull String deviceId,
+            boolean isConnectionEnabled) {
+        AssociatedDeviceEntity entity = mAssociatedDeviceDatabase.getAssociatedDevice(deviceId);
+        if (entity == null) {
+            logw(TAG, "Attempt to enable or disable connection on an unrecognized device "
+                    + deviceId + ". Ignoring.");
+            return;
+        }
+        if (entity.isConnectionEnabled == isConnectionEnabled) {
+            return;
+        }
+        entity.isConnectionEnabled = isConnectionEnabled;
+        mAssociatedDeviceDatabase.addOrReplaceAssociatedDevice(entity);
+        if (mAssociatedDeviceCallback != null) {
+            mAssociatedDeviceCallback.onAssociatedDeviceUpdated(new AssociatedDevice(deviceId,
+                    entity.address, entity.name, isConnectionEnabled));
+        }
+    }
+
+    /** Callback for association device related events. */
+    public interface AssociatedDeviceCallback {
+        /** Triggered when an associated device has been added. */
+        void onAssociatedDeviceAdded(@NonNull AssociatedDevice device);
+
+        /** Triggered when an associated device has been removed. */
+        void onAssociatedDeviceRemoved(@NonNull AssociatedDevice device);
+
+        /** Triggered when an associated device has been updated. */
+        void onAssociatedDeviceUpdated(@NonNull AssociatedDevice device);
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/util/ByteUtils.java b/connected-device-lib/src/com/android/car/connecteddevice/util/ByteUtils.java
new file mode 100644
index 0000000..3d07227
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/util/ByteUtils.java
@@ -0,0 +1,159 @@
+/*
+ * 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.connecteddevice.util;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * Utility classes for manipulating bytes.
+ */
+public final class ByteUtils {
+    // https://developer.android.com/reference/java/util/UUID
+    private static final int UUID_LENGTH = 16;
+
+    private ByteUtils() {
+    }
+
+    /**
+     * Returns a byte buffer corresponding to the passed long argument.
+     *
+     * @param primitive data to convert format.
+     */
+    public static byte[] longToBytes(long primitive) {
+        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
+        buffer.putLong(primitive);
+        return buffer.array();
+    }
+
+    /**
+     * Returns a byte buffer corresponding to the passed long argument.
+     *
+     * @param array data to convert format.
+     */
+    public static long bytesToLong(byte[] array) {
+        ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / Byte.SIZE);
+        buffer.put(array);
+        buffer.flip();
+        long value = buffer.getLong();
+        return value;
+    }
+
+    /**
+     * Returns a String in Hex format that is formed from the bytes in the byte array Useful for
+     * debugging
+     *
+     * @param array the byte array
+     * @return the Hex string version of the input byte array
+     */
+    public static String byteArrayToHexString(byte[] array) {
+        StringBuilder sb = new StringBuilder(array.length * 2);
+        for (byte b : array) {
+            sb.append(String.format("%02x", b));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Convert UUID to Big Endian byte array
+     *
+     * @param uuid UUID to convert
+     * @return the byte array representing the UUID
+     */
+    @NonNull
+    public static byte[] uuidToBytes(@NonNull UUID uuid) {
+
+        return ByteBuffer.allocate(UUID_LENGTH)
+                .order(ByteOrder.BIG_ENDIAN)
+                .putLong(uuid.getMostSignificantBits())
+                .putLong(uuid.getLeastSignificantBits())
+                .array();
+    }
+
+    /**
+     * Convert Big Endian byte array to UUID
+     *
+     * @param bytes byte array to convert
+     * @return the UUID representing the byte array, or null if not a valid UUID
+     */
+    @Nullable
+    public static UUID bytesToUUID(@NonNull byte[] bytes) {
+        if (bytes.length != UUID_LENGTH) {
+            return null;
+        }
+
+        ByteBuffer buffer = ByteBuffer.wrap(bytes);
+        return new UUID(buffer.getLong(), buffer.getLong());
+    }
+
+    /**
+     * Generate a random zero-filled string of given length
+     *
+     * @param length of string
+     * @return generated string
+     */
+    @SuppressLint("DefaultLocale") // Should always have the same format regardless of locale
+    public static String generateRandomNumberString(int length) {
+        return String.format(
+                "%0" + length + "d",
+                ThreadLocalRandom.current().nextInt((int) Math.pow(10, length)));
+    }
+
+    /**
+     * Generate a {@link byte[]} with random bytes.
+     *
+     * @param size of array to generate.
+     * @return generated {@link byte[]}.
+     */
+    @NonNull
+    public static byte[] randomBytes(int size) {
+        byte[] array = new byte[size];
+        ThreadLocalRandom.current().nextBytes(array);
+        return array;
+    }
+
+    /**
+     * Concatentate the given 2 byte arrays
+     *
+     * @param a input array 1
+     * @param b input array 2
+     * @return concatenated array of arrays 1 and 2
+     */
+    @Nullable
+    public static byte[] concatByteArrays(@Nullable byte[] a, @Nullable byte[] b) {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            if (a != null) {
+                outputStream.write(a);
+            }
+            if (b != null) {
+                outputStream.write(b);
+            }
+        } catch (IOException e) {
+            return null;
+        }
+        return outputStream.toByteArray();
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/util/EventLog.java b/connected-device-lib/src/com/android/car/connecteddevice/util/EventLog.java
new file mode 100644
index 0000000..5dcd829
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/util/EventLog.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.util;
+
+import static com.android.car.connecteddevice.util.SafeLog.logi;
+
+import com.android.car.connecteddevice.ConnectedDeviceManager;
+
+/** Logging class for collecting metrics. */
+public class EventLog {
+
+    private static final String TAG = "ConnectedDeviceEvent";
+
+    private EventLog() { }
+
+    /** Mark in log that the service has started. */
+    public static void onServiceStarted() {
+        logi(TAG, "SERVICE_STARTED");
+    }
+
+    /** Mark in log that the {@link ConnectedDeviceManager} has started. */
+    public static void onConnectedDeviceManagerStarted() {
+        logi(TAG, "CONNECTED_DEVICE_MANAGER_STARTED");
+    }
+
+    /** Mark in the log that BLE is on. */
+    public static void onBleOn() {
+        logi(TAG, "BLE_ON");
+    }
+
+    /** Mark in the log that a search for the user's device has started. */
+    public static void onStartDeviceSearchStarted() {
+        logi(TAG, "SEARCHING_FOR_DEVICE");
+    }
+
+
+    /** Mark in the log that a device connected. */
+    public static void onDeviceConnected() {
+        logi(TAG, "DEVICE_CONNECTED");
+    }
+
+    /** Mark in the log that the device has sent its id. */
+    public static void onDeviceIdReceived() {
+        logi(TAG, "RECEIVED_DEVICE_ID");
+    }
+
+    /** Mark in the log that a secure channel has been established with a device. */
+    public static void onSecureChannelEstablished() {
+        logi(TAG, "SECURE_CHANNEL_ESTABLISHED");
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/util/RemoteCallbackBinder.java b/connected-device-lib/src/com/android/car/connecteddevice/util/RemoteCallbackBinder.java
new file mode 100644
index 0000000..e18366b
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/util/RemoteCallbackBinder.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.util;
+
+import static com.android.car.connecteddevice.util.SafeLog.logd;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import java.util.function.Consumer;
+
+/**
+ * Class that holds the binder of a remote callback and an action to be executed when this
+ * binder dies.
+ * It registers for death notification of the {@link #mCallbackBinder} and executes
+ * {@link #mOnDiedConsumer} when {@link #mCallbackBinder} dies.
+ */
+public class RemoteCallbackBinder implements IBinder.DeathRecipient {
+    private static final String TAG = "BinderClient";
+    private final IBinder mCallbackBinder;
+    private final Consumer<IBinder> mOnDiedConsumer;
+
+    public RemoteCallbackBinder(IBinder binder, Consumer<IBinder> onBinderDied) {
+        mCallbackBinder = binder;
+        mOnDiedConsumer = onBinderDied;
+        try {
+            binder.linkToDeath(this, 0);
+        } catch (RemoteException e) {
+            logd(TAG, "Cannot link death recipient to binder " + mCallbackBinder + ", "
+                    + e);
+        }
+    }
+
+    @Override
+    public void binderDied() {
+        logd(TAG, "Binder died " + mCallbackBinder);
+        mOnDiedConsumer.accept(mCallbackBinder);
+        cleanUp();
+    }
+
+    /** Clean up the client. */
+    public void cleanUp() {
+        mCallbackBinder.unlinkToDeath(this, 0);
+    }
+
+    /** Get the callback binder of the client. */
+    public IBinder getCallbackBinder() {
+        return mCallbackBinder;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return mCallbackBinder.equals(obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return mCallbackBinder.hashCode();
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/util/SafeLog.java b/connected-device-lib/src/com/android/car/connecteddevice/util/SafeLog.java
new file mode 100644
index 0000000..1efae3e
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/util/SafeLog.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.util;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+
+/**
+ * Convenience logging methods that respect whitelisted tags.
+ */
+public class SafeLog {
+
+    private SafeLog() { }
+
+    /** Log message if tag is whitelisted for {@code Log.VERBOSE}. */
+    public static void logv(@NonNull String tag, @NonNull String message) {
+        if (Log.isLoggable(tag, Log.VERBOSE)) {
+            Log.v(tag, message);
+        }
+    }
+
+    /** Log message if tag is whitelisted for {@code Log.INFO}. */
+    public static void logi(@NonNull String tag, @NonNull String message) {
+        if (Log.isLoggable(tag, Log.INFO)) {
+            Log.i(tag, message);
+        }
+    }
+
+    /** Log message if tag is whitelisted for {@code Log.DEBUG}. */
+    public static void logd(@NonNull String tag, @NonNull String message) {
+        if (Log.isLoggable(tag, Log.DEBUG)) {
+            Log.d(tag, message);
+        }
+    }
+
+    /** Log message if tag is whitelisted for {@code Log.WARN}. */
+    public static void logw(@NonNull String tag, @NonNull String message) {
+        if (Log.isLoggable(tag, Log.WARN)) {
+            Log.w(tag, message);
+        }
+    }
+
+    /** Log message if tag is whitelisted for {@code Log.ERROR}. */
+    public static void loge(@NonNull String tag, @NonNull String message) {
+        loge(tag, message, /* exception= */ null);
+    }
+
+    /** Log message and optional exception if tag is whitelisted for {@code Log.ERROR}. */
+    public static void loge(@NonNull String tag, @NonNull String message,
+            @Nullable Exception exception) {
+        if (Log.isLoggable(tag, Log.ERROR)) {
+            Log.e(tag, message, exception);
+        }
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/util/ScanDataAnalyzer.java b/connected-device-lib/src/com/android/car/connecteddevice/util/ScanDataAnalyzer.java
new file mode 100644
index 0000000..6748bba
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/util/ScanDataAnalyzer.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.util;
+
+import static com.android.car.connecteddevice.util.SafeLog.logw;
+
+import android.annotation.NonNull;
+import android.bluetooth.le.ScanResult;
+
+import java.math.BigInteger;
+
+/**
+ * Analyzer of {@link ScanResult} data to identify an Apple device that is advertising from the
+ * background.
+ */
+public class ScanDataAnalyzer {
+
+    private static final String TAG = "ScanDataAnalyzer";
+
+    private static final byte IOS_OVERFLOW_LENGTH = (byte) 0x14;
+    private static final byte IOS_ADVERTISING_TYPE = (byte) 0xff;
+    private static final int IOS_ADVERTISING_TYPE_LENGTH = 1;
+    private static final long IOS_OVERFLOW_CUSTOM_ID = 0x4c0001;
+    private static final int IOS_OVERFLOW_CUSTOM_ID_LENGTH = 3;
+    private static final int IOS_OVERFLOW_CONTENT_LENGTH =
+            IOS_OVERFLOW_LENGTH - IOS_OVERFLOW_CUSTOM_ID_LENGTH - IOS_ADVERTISING_TYPE_LENGTH;
+
+    private ScanDataAnalyzer() { }
+
+    /**
+     * Returns {@code true} if the given bytes from a [ScanResult] contains service UUIDs once the
+     * given serviceUuidMask is applied.
+     *
+     * When an iOS peripheral device goes into a background state, the service UUIDs and other
+     * identifying information are removed from the advertising data and replaced with a hashed
+     * bit in a special "overflow" area. There is no documentation on the layout of this area,
+     * and the below was compiled from experimentation and examples from others who have worked
+     * on reverse engineering iOS background peripherals.
+     *
+     * My best guess is Apple is taking the service UUID and hashing it into a bloom filter. This
+     * would allow any device with the same hashing function to filter for all devices that
+     * might contain the desired service. Since we do not have access to this hashing function,
+     * we must first advertise our service from an iOS device and manually inspect the bit that
+     * is flipped. Once known, it can be passed to serviceUuidMask and used as a filter.
+     *
+     * EXAMPLE
+     *
+     * Foreground contents:
+     * 02011A1107FB349B5F8000008000100000C53A00000709546573746572000000000000000000000000000000000000000000000000000000000000000000
+     *
+     * Background contents:
+     * 02011A14FF4C0001000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000
+     *
+     * The overflow bytes are comprised of four parts:
+     * Length -> 14
+     * Advertising type -> FF
+     * Id custom to Apple -> 4C0001
+     * Contents where hashed values are stored -> 00000000000000000000000000200000
+     *
+     * Apple's documentation on advertising from the background:
+     * https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html#//apple_ref/doc/uid/TP40013257-CH7-SW9
+     *
+     * Other similar reverse engineering:
+     * http://www.pagepinner.com/2014/04/how-to-get-ble-overflow-hash-bit-from.html
+     */
+    public static boolean containsUuidsInOverflow(@NonNull byte[] scanData,
+            @NonNull BigInteger serviceUuidMask) {
+        byte[] overflowBytes = new byte[IOS_OVERFLOW_CONTENT_LENGTH];
+        int overflowPtr = 0;
+        int outPtr = 0;
+        try {
+            while (overflowPtr < scanData.length - IOS_OVERFLOW_LENGTH) {
+                byte length = scanData[overflowPtr++];
+                if (length == 0) {
+                    break;
+                } else if (length != IOS_OVERFLOW_LENGTH) {
+                    continue;
+                }
+
+                if (scanData[overflowPtr++] != IOS_ADVERTISING_TYPE) {
+                    return false;
+                }
+
+                byte[] idBytes = new byte[IOS_OVERFLOW_CUSTOM_ID_LENGTH];
+                for (int i = 0; i < IOS_OVERFLOW_CUSTOM_ID_LENGTH; i++) {
+                    idBytes[i] = scanData[overflowPtr++];
+                }
+
+                if (!new BigInteger(idBytes).equals(BigInteger.valueOf(IOS_OVERFLOW_CUSTOM_ID))) {
+                    return false;
+                }
+
+                for (outPtr = 0; outPtr < IOS_OVERFLOW_CONTENT_LENGTH; outPtr++) {
+                    overflowBytes[outPtr] = scanData[overflowPtr++];
+                }
+                break;
+            }
+
+            if (outPtr == IOS_OVERFLOW_CONTENT_LENGTH) {
+                BigInteger overflowBytesValue = new BigInteger(overflowBytes);
+                return overflowBytesValue.and(serviceUuidMask).signum() == 1;
+            }
+
+        } catch (ArrayIndexOutOfBoundsException e) {
+            logw(TAG, "Inspecting advertisement overflow bytes went out of bounds.");
+        }
+
+        return false;
+    }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/util/ThreadSafeCallbacks.java b/connected-device-lib/src/com/android/car/connecteddevice/util/ThreadSafeCallbacks.java
new file mode 100644
index 0000000..b3d3ef1
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/util/ThreadSafeCallbacks.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.util;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Class for invoking thread-safe callbacks.
+ *
+ * @param <T> Callback type.
+ */
+public class ThreadSafeCallbacks<T> {
+
+    private final ConcurrentHashMap<T, Executor> mCallbacks = new ConcurrentHashMap<>();
+
+    /** Add a callback to be notified on its executor. */
+    public void add(@NonNull T callback, @NonNull @CallbackExecutor Executor executor) {
+        mCallbacks.put(callback, executor);
+    }
+
+    /** Remove a callback from the collection. */
+    public void remove(@NonNull T callback) {
+        mCallbacks.remove(callback);
+    }
+
+    /** Clear all callbacks from the collection. */
+    public void clear() {
+        mCallbacks.clear();
+    }
+
+    /** Return the number of callbacks in collection. */
+    public int size() {
+        return mCallbacks.size();
+    }
+
+    /** Invoke notification on all callbacks with their supplied {@link Executor}. */
+    public void invoke(Consumer<T> notification) {
+        mCallbacks.forEach((callback, executor) ->
+                executor.execute(() -> notification.accept(callback)));
+    }
+}
diff --git a/connected-device-lib/tests/unit/Android.bp b/connected-device-lib/tests/unit/Android.bp
new file mode 100644
index 0000000..e550b54
--- /dev/null
+++ b/connected-device-lib/tests/unit/Android.bp
@@ -0,0 +1,53 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_test {
+    name: "connected-device-lib-unit-tests",
+
+    srcs: ["src/**/*.java"],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+
+    static_libs: [
+        "android.car",
+        "androidx.test.core",
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "connected-device-lib",
+        "mockito-target-extended-minus-junit4",
+        "testables",
+        // TODO: remove once Android migrates to JUnit 4.13,
+        // which provides assertThrows
+        "testng",
+        "truth-prebuilt",
+    ],
+
+    jni_libs: [
+        // For mockito extended
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+
+    platform_apis: true,
+
+    certificate: "platform",
+
+    privileged: true,
+}
\ No newline at end of file
diff --git a/connected-device-lib/tests/unit/AndroidManifest.xml b/connected-device-lib/tests/unit/AndroidManifest.xml
new file mode 100644
index 0000000..9863ccf
--- /dev/null
+++ b/connected-device-lib/tests/unit/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.car.connecteddevice.tests.unit">
+
+    <!--  Needed for BLE scanning/advertising -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+
+    <!--  Needed for detecting foreground user -->
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+
+    <application android:testOnly="true"
+                 android:debuggable="true">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.car.connecteddevice.tests.unit"
+                     android:label="Connected Device Lib Test Cases" />
+</manifest>
diff --git a/connected-device-lib/tests/unit/README.md b/connected-device-lib/tests/unit/README.md
new file mode 100644
index 0000000..4543058
--- /dev/null
+++ b/connected-device-lib/tests/unit/README.md
@@ -0,0 +1,24 @@
+# Instructions for running unit tests
+
+### Build unit test module
+
+`m connected-device-lib-unit-tests`
+
+### Install resulting apk on device
+
+`adb install -r -t $OUT/testcases/connected-device-lib-unit-tests/arm64/connected-device-lib-unit-tests.apk`
+
+### Run all tests
+
+`adb shell am instrument -w com.android.car.connecteddevice.tests.unit`
+
+### Run tests in a class
+
+`adb shell am instrument -w -e class com.android.car.connecteddevice.<classPath> com.android.car.connecteddevice.tests.unit`
+
+### Run a specific test
+
+`adb shell am instrument -w -e class com.android.car.connecteddevice.<classPath>#<testMethod> com.android.car.connecteddevice.tests.unit`
+
+More general information can be found at
+http://developer.android.com/reference/android/support/test/runner/AndroidJUnitRunner.html
\ No newline at end of file
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ConnectedDeviceManagerTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ConnectedDeviceManagerTest.java
new file mode 100644
index 0000000..3e345c2
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ConnectedDeviceManagerTest.java
@@ -0,0 +1,774 @@
+/*
+ * 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.connecteddevice;
+
+import static com.android.car.connecteddevice.ConnectedDeviceManager.DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED;
+import static com.android.car.connecteddevice.ConnectedDeviceManager.DEVICE_ERROR_INVALID_SECURITY_KEY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mockitoSession;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.connecteddevice.ConnectedDeviceManager.ConnectionCallback;
+import com.android.car.connecteddevice.ConnectedDeviceManager.DeviceAssociationCallback;
+import com.android.car.connecteddevice.ConnectedDeviceManager.DeviceCallback;
+import com.android.car.connecteddevice.ConnectedDeviceManager.MessageDeliveryDelegate;
+import com.android.car.connecteddevice.ble.CarBleCentralManager;
+import com.android.car.connecteddevice.ble.CarBleManager;
+import com.android.car.connecteddevice.ble.CarBlePeripheralManager;
+import com.android.car.connecteddevice.ble.DeviceMessage;
+import com.android.car.connecteddevice.model.AssociatedDevice;
+import com.android.car.connecteddevice.model.ConnectedDevice;
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage.AssociatedDeviceCallback;
+import com.android.car.connecteddevice.util.ByteUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class ConnectedDeviceManagerTest {
+
+    private static final String TEST_DEVICE_ADDRESS = "00:11:22:33:44:55";
+
+    private static final String TEST_DEVICE_NAME = "TEST_DEVICE_NAME";
+
+
+    private final Executor mCallbackExecutor = Executors.newSingleThreadExecutor();
+
+    private final UUID mRecipientId = UUID.randomUUID();
+
+    private final List<String> mUserDeviceIds = new ArrayList<>();
+
+    private final List<AssociatedDevice> mUserDevices = new ArrayList<>();
+
+    @Mock
+    private ConnectedDeviceStorage mMockStorage;
+
+    @Mock
+    private CarBlePeripheralManager mMockPeripheralManager;
+
+    @Mock
+    private CarBleCentralManager mMockCentralManager;
+
+    private ConnectedDeviceManager mConnectedDeviceManager;
+
+    private MockitoSession mMockingSession;
+
+    private AssociatedDeviceCallback mAssociatedDeviceCallback;
+
+    @Before
+    public void setUp() {
+        mMockingSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.WARN)
+                .startMocking();
+        ArgumentCaptor<AssociatedDeviceCallback> callbackCaptor = ArgumentCaptor
+                .forClass(AssociatedDeviceCallback.class);
+        mConnectedDeviceManager = new ConnectedDeviceManager(mMockStorage, mMockCentralManager,
+            mMockPeripheralManager);
+        verify(mMockStorage).setAssociatedDeviceCallback(callbackCaptor.capture());
+        when(mMockStorage.getActiveUserAssociatedDevices()).thenReturn(mUserDevices);
+        when(mMockStorage.getActiveUserAssociatedDeviceIds()).thenReturn(mUserDeviceIds);
+        mAssociatedDeviceCallback = callbackCaptor.getValue();
+        mConnectedDeviceManager.start();
+    }
+
+    @After
+    public void tearDown() {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+    }
+
+    @Test
+    public void getActiveUserConnectedDevices_initiallyShouldReturnEmptyList() {
+        assertThat(mConnectedDeviceManager.getActiveUserConnectedDevices()).isEmpty();
+    }
+
+    @Test
+    public void getActiveUserConnectedDevices_includesNewlyConnectedDevice() {
+        String deviceId = connectNewDevice(mMockCentralManager);
+        List<ConnectedDevice> activeUserDevices =
+                mConnectedDeviceManager.getActiveUserConnectedDevices();
+        ConnectedDevice expectedDevice = new ConnectedDevice(deviceId, /* deviceName= */ null,
+                /* belongsToActiveUser= */ true, /* hasSecureChannel= */ false);
+        assertThat(activeUserDevices).containsExactly(expectedDevice);
+    }
+
+    @Test
+    public void getActiveUserConnectedDevices_excludesDevicesNotBelongingToActiveUser() {
+        String deviceId = UUID.randomUUID().toString();
+        String otherUserDeviceId = UUID.randomUUID().toString();
+        when(mMockStorage.getActiveUserAssociatedDeviceIds()).thenReturn(
+                Collections.singletonList(otherUserDeviceId));
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockCentralManager);
+        assertThat(mConnectedDeviceManager.getActiveUserConnectedDevices()).isEmpty();
+    }
+
+    @Test
+    public void getActiveUserConnectedDevices_reflectsSecureChannelEstablished() {
+        String deviceId = connectNewDevice(mMockCentralManager);
+        mConnectedDeviceManager.onSecureChannelEstablished(deviceId, mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        assertThat(connectedDevice.hasSecureChannel()).isTrue();
+    }
+
+    @Test
+    public void getActiveUserConnectedDevices_excludesDisconnectedDevice() {
+        String deviceId = connectNewDevice(mMockCentralManager);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockCentralManager);
+        assertThat(mConnectedDeviceManager.getActiveUserConnectedDevices()).isEmpty();
+    }
+
+    @Test
+    public void getActiveUserConnectedDevices_unaffectedByOtherManagerDisconnect() {
+        String deviceId = connectNewDevice(mMockCentralManager);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockPeripheralManager);
+        assertThat(mConnectedDeviceManager.getActiveUserConnectedDevices()).hasSize(1);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void sendMessageSecurely_throwsIllegalStateExceptionIfNoSecureChannel() {
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice device = mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        UUID recipientId = UUID.randomUUID();
+        byte[] message = ByteUtils.randomBytes(10);
+        mConnectedDeviceManager.sendMessageSecurely(device, recipientId, message);
+    }
+
+    @Test
+    public void sendMessageSecurely_sendsEncryptedMessage() {
+        String deviceId = connectNewDevice(mMockCentralManager);
+        mConnectedDeviceManager.onSecureChannelEstablished(deviceId, mMockCentralManager);
+        ConnectedDevice device = mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        UUID recipientId = UUID.randomUUID();
+        byte[] message = ByteUtils.randomBytes(10);
+        mConnectedDeviceManager.sendMessageSecurely(device, recipientId, message);
+        ArgumentCaptor<DeviceMessage> messageCaptor = ArgumentCaptor.forClass(DeviceMessage.class);
+        verify(mMockCentralManager).sendMessage(eq(deviceId), messageCaptor.capture());
+        assertThat(messageCaptor.getValue().isMessageEncrypted()).isTrue();
+    }
+
+    @Test
+    public void sendMessageSecurely_doesNotSendIfDeviceDisconnected() {
+        String deviceId = connectNewDevice(mMockCentralManager);
+        ConnectedDevice device = mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockCentralManager);
+        UUID recipientId = UUID.randomUUID();
+        byte[] message = ByteUtils.randomBytes(10);
+        mConnectedDeviceManager.sendMessageSecurely(device, recipientId, message);
+        verify(mMockCentralManager, times(0)).sendMessage(eq(deviceId), any(DeviceMessage.class));
+    }
+
+    @Test
+    public void sendMessageUnsecurely_sendsMessageWithoutEncryption() {
+        String deviceId = connectNewDevice(mMockCentralManager);
+        ConnectedDevice device = mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        UUID recipientId = UUID.randomUUID();
+        byte[] message = ByteUtils.randomBytes(10);
+        mConnectedDeviceManager.sendMessageUnsecurely(device, recipientId, message);
+        ArgumentCaptor<DeviceMessage> messageCaptor = ArgumentCaptor.forClass(DeviceMessage.class);
+        verify(mMockCentralManager).sendMessage(eq(deviceId), messageCaptor.capture());
+        assertThat(messageCaptor.getValue().isMessageEncrypted()).isFalse();
+    }
+
+    @Test
+    public void connectionCallback_onDeviceConnectedInvokedForNewlyConnectedDevice()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        ConnectionCallback connectionCallback = createConnectionCallback(semaphore);
+        mConnectedDeviceManager.registerActiveUserConnectionCallback(connectionCallback,
+                mCallbackExecutor);
+        String deviceId = connectNewDevice(mMockCentralManager);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        ArgumentCaptor<ConnectedDevice> deviceCaptor =
+                ArgumentCaptor.forClass(ConnectedDevice.class);
+        verify(connectionCallback).onDeviceConnected(deviceCaptor.capture());
+        ConnectedDevice connectedDevice = deviceCaptor.getValue();
+        assertThat(connectedDevice.getDeviceId()).isEqualTo(deviceId);
+        assertThat(connectedDevice.hasSecureChannel()).isFalse();
+    }
+
+    @Test
+    public void connectionCallback_onDeviceConnectedNotInvokedDeviceConnectedForDifferentUser()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        ConnectionCallback connectionCallback = createConnectionCallback(semaphore);
+        mConnectedDeviceManager.registerActiveUserConnectionCallback(connectionCallback,
+                mCallbackExecutor);
+        String deviceId = UUID.randomUUID().toString();
+        String otherUserDeviceId = UUID.randomUUID().toString();
+        when(mMockStorage.getActiveUserAssociatedDeviceIds()).thenReturn(
+                Collections.singletonList(otherUserDeviceId));
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockCentralManager);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void connectionCallback_onDeviceConnectedNotInvokedForDifferentBleManager()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        String deviceId = connectNewDevice(mMockPeripheralManager);
+        ConnectionCallback connectionCallback = createConnectionCallback(semaphore);
+        mConnectedDeviceManager.registerActiveUserConnectionCallback(connectionCallback,
+                mCallbackExecutor);
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockCentralManager);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void connectionCallback_onDeviceDisconnectedInvokedForActiveUserDevice()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        String deviceId = connectNewDevice(mMockCentralManager);
+        ConnectionCallback connectionCallback = createConnectionCallback(semaphore);
+        mConnectedDeviceManager.registerActiveUserConnectionCallback(connectionCallback,
+                mCallbackExecutor);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockCentralManager);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        ArgumentCaptor<ConnectedDevice> deviceCaptor =
+                ArgumentCaptor.forClass(ConnectedDevice.class);
+        verify(connectionCallback).onDeviceDisconnected(deviceCaptor.capture());
+        assertThat(deviceCaptor.getValue().getDeviceId()).isEqualTo(deviceId);
+    }
+
+    @Test
+    public void connectionCallback_onDeviceDisconnectedNotInvokedDeviceForDifferentUser()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        String deviceId = UUID.randomUUID().toString();
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockCentralManager);
+        ConnectionCallback connectionCallback = createConnectionCallback(semaphore);
+        mConnectedDeviceManager.registerActiveUserConnectionCallback(connectionCallback,
+                mCallbackExecutor);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockCentralManager);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void unregisterConnectionCallback_removesCallbackAndNotInvoked()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        ConnectionCallback connectionCallback = createConnectionCallback(semaphore);
+        mConnectedDeviceManager.registerActiveUserConnectionCallback(connectionCallback,
+                mCallbackExecutor);
+        mConnectedDeviceManager.unregisterConnectionCallback(connectionCallback);
+        connectNewDevice(mMockCentralManager);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void registerDeviceCallback_blacklistsDuplicateRecipientId()
+            throws InterruptedException {
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        Semaphore firstSemaphore = new Semaphore(0);
+        Semaphore secondSemaphore = new Semaphore(0);
+        Semaphore thirdSemaphore = new Semaphore(0);
+        DeviceCallback firstDeviceCallback = createDeviceCallback(firstSemaphore);
+        DeviceCallback secondDeviceCallback = createDeviceCallback(secondSemaphore);
+        DeviceCallback thirdDeviceCallback = createDeviceCallback(thirdSemaphore);
+
+        // Register three times for following chain of events:
+        // 1. First callback registered without issue.
+        // 2. Second callback with same recipientId triggers blacklisting both callbacks and issues
+        //    error callbacks on both. Both callbacks should be unregistered at this point.
+        // 3. Third callback gets rejected at registration and issues error callback.
+
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                firstDeviceCallback, mCallbackExecutor);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                secondDeviceCallback, mCallbackExecutor);
+        DeviceMessage message = new DeviceMessage(mRecipientId, false, new byte[10]);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        assertThat(tryAcquire(firstSemaphore)).isTrue();
+        assertThat(tryAcquire(secondSemaphore)).isTrue();
+        verify(firstDeviceCallback)
+                .onDeviceError(connectedDevice, DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED);
+        verify(secondDeviceCallback)
+                .onDeviceError(connectedDevice, DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED);
+        verify(firstDeviceCallback, times(0)).onMessageReceived(any(), any());
+        verify(secondDeviceCallback, times(0)).onMessageReceived(any(), any());
+
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                thirdDeviceCallback, mCallbackExecutor);
+        assertThat(tryAcquire(thirdSemaphore)).isTrue();
+        verify(thirdDeviceCallback)
+                .onDeviceError(connectedDevice, DEVICE_ERROR_INSECURE_RECIPIENT_ID_DETECTED);
+    }
+
+    @Test
+    public void deviceCallback_onSecureChannelEstablishedInvoked() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        mConnectedDeviceManager.onSecureChannelEstablished(connectedDevice.getDeviceId(),
+                mMockCentralManager);
+        connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(deviceCallback).onSecureChannelEstablished(connectedDevice);
+    }
+
+    @Test
+    public void deviceCallback_onSecureChannelEstablishedNotInvokedWithSecondBleManager()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        mConnectedDeviceManager.onSecureChannelEstablished(connectedDevice.getDeviceId(),
+                mMockCentralManager);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        mConnectedDeviceManager.onSecureChannelEstablished(connectedDevice.getDeviceId(),
+                mMockPeripheralManager);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void deviceCallback_onMessageReceivedInvokedForSameRecipientId()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        byte[] payload = ByteUtils.randomBytes(10);
+        DeviceMessage message = new DeviceMessage(mRecipientId, false, payload);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(deviceCallback).onMessageReceived(connectedDevice, payload);
+    }
+
+    @Test
+    public void deviceCallback_onMessageReceivedNotInvokedForDifferentRecipientId()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        byte[] payload = ByteUtils.randomBytes(10);
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), false, payload);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void deviceCallback_onDeviceErrorInvokedOnChannelError() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        mConnectedDeviceManager.deviceErrorOccurred(connectedDevice.getDeviceId());
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(deviceCallback).onDeviceError(connectedDevice, DEVICE_ERROR_INVALID_SECURITY_KEY);
+    }
+
+    @Test
+    public void unregisterDeviceCallback_removesCallbackAndNotInvoked()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        mConnectedDeviceManager.unregisterDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback);
+        mConnectedDeviceManager.onSecureChannelEstablished(connectedDevice.getDeviceId(),
+                mMockPeripheralManager);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void registerDeviceCallback_sendsMissedMessageAfterRegistration()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        byte[] payload = ByteUtils.randomBytes(10);
+        DeviceMessage message = new DeviceMessage(mRecipientId, false, payload);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(deviceCallback).onMessageReceived(connectedDevice, payload);
+    }
+
+    @Test
+    public void registerDeviceCallback_sendsMultipleMissedMessagesAfterRegistration()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        byte[] payload1 = ByteUtils.randomBytes(10);
+        byte[] payload2 = ByteUtils.randomBytes(10);
+        DeviceMessage message1 = new DeviceMessage(mRecipientId, false, payload1);
+        DeviceMessage message2 = new DeviceMessage(mRecipientId, false, payload2);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message1);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message2);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(deviceCallback).onMessageReceived(connectedDevice, payload1);
+        verify(deviceCallback, timeout(1000)).onMessageReceived(connectedDevice, payload2);
+    }
+
+    @Test
+    public void registerDeviceCallback_doesNotSendMissedMessageForDifferentRecipient()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        byte[] payload = ByteUtils.randomBytes(10);
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), false, payload);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void registerDeviceCallback_doesNotSendMissedMessageForDifferentDevice()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        connectNewDevice(mMockCentralManager);
+        connectNewDevice(mMockCentralManager);
+        List<ConnectedDevice> connectedDevices =
+                mConnectedDeviceManager.getActiveUserConnectedDevices();
+        ConnectedDevice connectedDevice = connectedDevices.get(0);
+        ConnectedDevice otherDevice = connectedDevices.get(1);
+        byte[] payload = ByteUtils.randomBytes(10);
+        DeviceMessage message = new DeviceMessage(mRecipientId, false, payload);
+        mConnectedDeviceManager.onMessageReceived(otherDevice.getDeviceId(), message);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void onAssociationCompleted_disconnectsOriginalDeviceAndReconnectsAsActiveUser()
+            throws InterruptedException {
+        String deviceId = UUID.randomUUID().toString();
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockPeripheralManager);
+        Semaphore semaphore = new Semaphore(0);
+        ConnectionCallback connectionCallback = createConnectionCallback(semaphore);
+        mConnectedDeviceManager.registerActiveUserConnectionCallback(connectionCallback,
+                mCallbackExecutor);
+        when(mMockStorage.getActiveUserAssociatedDeviceIds()).thenReturn(
+                Collections.singletonList(deviceId));
+        mConnectedDeviceManager.onAssociationCompleted(deviceId);
+        assertThat(tryAcquire(semaphore)).isTrue();
+    }
+
+    private boolean tryAcquire(Semaphore semaphore) throws InterruptedException {
+        return semaphore.tryAcquire(100, TimeUnit.MILLISECONDS);
+    }
+
+    @Test
+    public void deviceAssociationCallback_onAssociatedDeviceAdded() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        DeviceAssociationCallback callback = createDeviceAssociationCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceAssociationCallback(callback, mCallbackExecutor);
+        String deviceId = UUID.randomUUID().toString();
+        AssociatedDevice testDevice = new AssociatedDevice(deviceId, TEST_DEVICE_ADDRESS,
+                TEST_DEVICE_NAME, /* isConnectionEnabled= */ true);
+        mAssociatedDeviceCallback.onAssociatedDeviceAdded(testDevice);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onAssociatedDeviceAdded(eq(testDevice));
+    }
+
+    @Test
+    public void deviceAssociationCallback_onAssociationDeviceRemoved() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        DeviceAssociationCallback callback = createDeviceAssociationCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceAssociationCallback(callback, mCallbackExecutor);
+        String deviceId = UUID.randomUUID().toString();
+        AssociatedDevice testDevice = new AssociatedDevice(deviceId, TEST_DEVICE_ADDRESS,
+                TEST_DEVICE_NAME, /* isConnectionEnabled= */ true);
+        mAssociatedDeviceCallback.onAssociatedDeviceRemoved(testDevice);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onAssociatedDeviceRemoved(eq(testDevice));
+    }
+
+    @Test
+    public void deviceAssociationCallback_onAssociatedDeviceUpdated() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        DeviceAssociationCallback callback = createDeviceAssociationCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceAssociationCallback(callback, mCallbackExecutor);
+        String deviceId = UUID.randomUUID().toString();
+        AssociatedDevice testDevice = new AssociatedDevice(deviceId, TEST_DEVICE_ADDRESS,
+                TEST_DEVICE_NAME, /* isConnectionEnabled= */ true);
+        mAssociatedDeviceCallback.onAssociatedDeviceUpdated(testDevice);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onAssociatedDeviceUpdated(eq(testDevice));
+    }
+
+    @Test
+    public void removeConnectedDevice_startsAdvertisingForActiveUserDeviceOnActiveUserDisconnect() {
+        String deviceId = UUID.randomUUID().toString();
+        when(mMockStorage.getActiveUserAssociatedDeviceIds()).thenReturn(
+                Collections.singletonList(deviceId));
+        AssociatedDevice device = new AssociatedDevice(deviceId, TEST_DEVICE_ADDRESS,
+                TEST_DEVICE_NAME, /* isConnectionEnabled= */ true);
+        when(mMockStorage.getActiveUserAssociatedDevices()).thenReturn(
+                Collections.singletonList(device));
+        clearInvocations(mMockPeripheralManager);
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockPeripheralManager);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockPeripheralManager);
+        verify(mMockPeripheralManager, timeout(1000))
+                .connectToDevice(eq(UUID.fromString(deviceId)));
+    }
+
+    @Test
+    public void removeConnectedDevice_startsAdvertisingForActiveUserDeviceOnLastDeviceDisconnect() {
+        String deviceId = UUID.randomUUID().toString();
+        String userDeviceId = UUID.randomUUID().toString();
+        when(mMockStorage.getActiveUserAssociatedDeviceIds()).thenReturn(
+                Collections.singletonList(userDeviceId));
+        AssociatedDevice userDevice = new AssociatedDevice(userDeviceId, TEST_DEVICE_ADDRESS,
+                TEST_DEVICE_NAME, /* isConnectionEnabled= */ true);
+        when(mMockStorage.getActiveUserAssociatedDevices()).thenReturn(
+                Collections.singletonList(userDevice));
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockPeripheralManager);
+        clearInvocations(mMockPeripheralManager);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockPeripheralManager);
+        verify(mMockPeripheralManager, timeout(1000))
+                .connectToDevice(eq(UUID.fromString(userDeviceId)));
+    }
+
+    @Test
+    public void removeConnectedDevice__doesNotAdvertiseForNonActiveUserDeviceNotLastDevice() {
+        String deviceId = UUID.randomUUID().toString();
+        String userDeviceId = UUID.randomUUID().toString();
+        when(mMockStorage.getActiveUserAssociatedDeviceIds()).thenReturn(
+                Collections.singletonList(userDeviceId));
+        AssociatedDevice userDevice = new AssociatedDevice(userDeviceId, TEST_DEVICE_ADDRESS,
+                TEST_DEVICE_NAME, /* isConnectionEnabled= */ true);
+        when(mMockStorage.getActiveUserAssociatedDevices()).thenReturn(
+                Collections.singletonList(userDevice));
+        clearInvocations(mMockPeripheralManager);
+        mConnectedDeviceManager.addConnectedDevice(deviceId, mMockPeripheralManager);
+        mConnectedDeviceManager.addConnectedDevice(userDeviceId, mMockCentralManager);
+        mConnectedDeviceManager.removeConnectedDevice(deviceId, mMockPeripheralManager);
+        verify(mMockPeripheralManager, timeout(1000).times(0))
+                .connectToDevice(any());
+    }
+
+    @Test
+    public void removeActiveUserAssociatedDevice_deletesAssociatedDeviceFromStorage() {
+        String deviceId = UUID.randomUUID().toString();
+        mConnectedDeviceManager.removeActiveUserAssociatedDevice(deviceId);
+        verify(mMockStorage).removeAssociatedDeviceForActiveUser(deviceId);
+    }
+
+    @Test
+    public void removeActiveUserAssociatedDevice_disconnectsIfConnected() {
+        String deviceId = connectNewDevice(mMockPeripheralManager);
+        mConnectedDeviceManager.removeActiveUserAssociatedDevice(deviceId);
+        verify(mMockPeripheralManager).disconnectDevice(deviceId);
+    }
+
+    @Test
+    public void enableAssociatedDeviceConnection_enableDeviceConnectionInStorage() {
+        String deviceId = UUID.randomUUID().toString();
+        mConnectedDeviceManager.enableAssociatedDeviceConnection(deviceId);
+        verify(mMockStorage).updateAssociatedDeviceConnectionEnabled(deviceId, true);
+    }
+
+    @Test
+    public void disableAssociatedDeviceConnection_disableDeviceConnectionInStorage() {
+        String deviceId = UUID.randomUUID().toString();
+        mConnectedDeviceManager.disableAssociatedDeviceConnection(deviceId);
+        verify(mMockStorage).updateAssociatedDeviceConnectionEnabled(deviceId, false);
+    }
+
+    @Test
+    public void disableAssociatedDeviceConnection_disconnectsIfConnected() {
+        String deviceId = connectNewDevice(mMockPeripheralManager);
+        mConnectedDeviceManager.disableAssociatedDeviceConnection(deviceId);
+        verify(mMockPeripheralManager).disconnectDevice(deviceId);
+    }
+
+    @Test
+    public void onMessageReceived_deliversMessageIfDelegateIsNull() throws InterruptedException {
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        Semaphore semaphore = new Semaphore(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        DeviceMessage message = new DeviceMessage(mRecipientId, false, new byte[10]);
+        mConnectedDeviceManager.setMessageDeliveryDelegate(null);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        assertThat(tryAcquire(semaphore)).isTrue();
+    }
+
+    @Test
+    public void onMessageReceived_deliversMessageIfDelegateAccepts() throws InterruptedException {
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        Semaphore semaphore = new Semaphore(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        DeviceMessage message = new DeviceMessage(mRecipientId, false, new byte[10]);
+        MessageDeliveryDelegate delegate = device -> true;
+        mConnectedDeviceManager.setMessageDeliveryDelegate(delegate);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        assertThat(tryAcquire(semaphore)).isTrue();
+    }
+
+    @Test
+    public void onMessageReceived_doesNotDeliverMessageIfDelegateRejects()
+            throws InterruptedException {
+        connectNewDevice(mMockCentralManager);
+        ConnectedDevice connectedDevice =
+                mConnectedDeviceManager.getActiveUserConnectedDevices().get(0);
+        Semaphore semaphore = new Semaphore(0);
+        DeviceCallback deviceCallback = createDeviceCallback(semaphore);
+        mConnectedDeviceManager.registerDeviceCallback(connectedDevice, mRecipientId,
+                deviceCallback, mCallbackExecutor);
+        DeviceMessage message = new DeviceMessage(mRecipientId, false, new byte[10]);
+        MessageDeliveryDelegate delegate = device -> false;
+        mConnectedDeviceManager.setMessageDeliveryDelegate(delegate);
+        mConnectedDeviceManager.onMessageReceived(connectedDevice.getDeviceId(), message);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @NonNull
+    private String connectNewDevice(@NonNull CarBleManager carBleManager) {
+        String deviceId = UUID.randomUUID().toString();
+        AssociatedDevice device = new AssociatedDevice(deviceId, TEST_DEVICE_ADDRESS,
+                TEST_DEVICE_NAME, /* isConnectionEnabled= */ true);
+        mUserDeviceIds.add(deviceId);
+        mUserDevices.add(device);
+        mConnectedDeviceManager.addConnectedDevice(deviceId, carBleManager);
+        return deviceId;
+    }
+
+    @NonNull
+    private ConnectionCallback createConnectionCallback(@NonNull final Semaphore semaphore) {
+        return spy(new ConnectionCallback() {
+            @Override
+            public void onDeviceConnected(ConnectedDevice device) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onDeviceDisconnected(ConnectedDevice device) {
+                semaphore.release();
+            }
+        });
+    }
+
+    @NonNull
+    private DeviceCallback createDeviceCallback(@NonNull final Semaphore semaphore) {
+        return spy(new DeviceCallback() {
+            @Override
+            public void onSecureChannelEstablished(ConnectedDevice device) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onMessageReceived(ConnectedDevice device, byte[] message) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onDeviceError(ConnectedDevice device, int error) {
+                semaphore.release();
+            }
+        });
+    }
+
+    @NonNull
+    private DeviceAssociationCallback createDeviceAssociationCallback(
+            @NonNull final Semaphore semaphore) {
+        return spy(new DeviceAssociationCallback() {
+            @Override
+            public void onAssociatedDeviceAdded(AssociatedDevice device) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onAssociatedDeviceRemoved(
+                    AssociatedDevice device) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onAssociatedDeviceUpdated(AssociatedDevice device) {
+                semaphore.release();
+            }
+        });
+    }
+}
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/AssociationSecureChannelTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/AssociationSecureChannelTest.java
new file mode 100644
index 0000000..1a4941c
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/AssociationSecureChannelTest.java
@@ -0,0 +1,236 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mockitoSession;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.car.encryptionrunner.DummyEncryptionRunner;
+import android.car.encryptionrunner.EncryptionRunner;
+import android.car.encryptionrunner.EncryptionRunnerFactory;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.connecteddevice.BleStreamProtos.BleOperationProto.OperationType;
+import com.android.car.connecteddevice.ble.BleDeviceMessageStream.MessageReceivedListener;
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.util.ByteUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.util.UUID;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public final class AssociationSecureChannelTest {
+    private static final UUID CLIENT_DEVICE_ID =
+            UUID.fromString("a5645523-3280-410a-90c1-582a6c6f4969");
+    private static final UUID SERVER_DEVICE_ID =
+            UUID.fromString("a29f0c74-2014-4b14-ac02-be6ed15b545a");
+    private static final byte[] CLIENT_SECRET = ByteUtils.randomBytes(32);
+
+    @Mock
+    private BleDeviceMessageStream mStreamMock;
+    @Mock
+    private ConnectedDeviceStorage mStorageMock;
+    @Mock
+    private AssociationSecureChannel.ShowVerificationCodeListener mShowVerificationCodeListenerMock;
+    private MockitoSession mMockitoSession;
+
+    private AssociationSecureChannel mChannel;
+    private MessageReceivedListener mMessageReceivedListener;
+
+    @Before
+    public void setUp() {
+        mMockitoSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.WARN)
+                .startMocking();
+        when(mStorageMock.getUniqueId()).thenReturn(SERVER_DEVICE_ID);
+    }
+
+    @After
+    public void tearDown() {
+        if (mMockitoSession != null) {
+            mMockitoSession.finishMocking();
+        }
+    }
+
+    @Test
+    public void testEncryptionHandshake_Association() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        ChannelCallback callbackSpy = spy(new ChannelCallback(semaphore));
+        setupAssociationSecureChannel(callbackSpy, EncryptionRunnerFactory::newDummyRunner);
+        ArgumentCaptor<String> deviceIdCaptor = ArgumentCaptor.forClass(String.class);
+        ArgumentCaptor<DeviceMessage> messageCaptor =
+                ArgumentCaptor.forClass(DeviceMessage.class);
+
+        initHandshakeMessage();
+        verify(mStreamMock).writeMessage(messageCaptor.capture(), any());
+        byte[] response = messageCaptor.getValue().getMessage();
+        assertThat(response).isEqualTo(DummyEncryptionRunner.INIT_RESPONSE.getBytes());
+
+        respondToContinueMessage();
+        verify(mShowVerificationCodeListenerMock).showVerificationCode(anyString());
+
+        mChannel.notifyOutOfBandAccepted();
+        sendDeviceId();
+        assertThat(semaphore.tryAcquire(100, TimeUnit.MILLISECONDS)).isTrue();
+        verify(callbackSpy).onDeviceIdReceived(deviceIdCaptor.capture());
+        verify(mStreamMock, times(2)).writeMessage(messageCaptor.capture(), any());
+        byte[] deviceIdMessage = messageCaptor.getValue().getMessage();
+        assertThat(deviceIdMessage).isEqualTo(ByteUtils.uuidToBytes(SERVER_DEVICE_ID));
+        assertThat(deviceIdCaptor.getValue()).isEqualTo(CLIENT_DEVICE_ID.toString());
+        verify(mStorageMock).saveEncryptionKey(eq(CLIENT_DEVICE_ID.toString()), any());
+        verify(mStorageMock).saveChallengeSecret(CLIENT_DEVICE_ID.toString(), CLIENT_SECRET);
+
+        assertThat(semaphore.tryAcquire(100, TimeUnit.MILLISECONDS)).isTrue();
+        verify(callbackSpy).onSecureChannelEstablished();
+    }
+
+    @Test
+    public void testEncryptionHandshake_Association_wrongInitHandshakeMessage()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        ChannelCallback callbackSpy = spy(new ChannelCallback(semaphore));
+        setupAssociationSecureChannel(callbackSpy, EncryptionRunnerFactory::newDummyRunner);
+
+        // Wrong init handshake message
+        respondToContinueMessage();
+        assertThat(semaphore.tryAcquire(100, TimeUnit.MILLISECONDS)).isTrue();
+        verify(callbackSpy).onEstablishSecureChannelFailure(
+                eq(SecureBleChannel.CHANNEL_ERROR_INVALID_HANDSHAKE)
+        );
+    }
+
+    @Test
+    public void testEncryptionHandshake_Association_wrongRespondToContinueMessage()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        ChannelCallback callbackSpy = spy(new ChannelCallback(semaphore));
+        setupAssociationSecureChannel(callbackSpy, EncryptionRunnerFactory::newDummyRunner);
+
+        initHandshakeMessage();
+
+        // Wrong respond to continue message
+        initHandshakeMessage();
+        assertThat(semaphore.tryAcquire(100, TimeUnit.MILLISECONDS)).isTrue();
+        verify(callbackSpy).onEstablishSecureChannelFailure(
+                eq(SecureBleChannel.CHANNEL_ERROR_INVALID_HANDSHAKE)
+        );
+    }
+
+    private void setupAssociationSecureChannel(ChannelCallback callback,
+            EncryptionRunnerProvider encryptionRunnerProvider) {
+        mChannel = new AssociationSecureChannel(mStreamMock, mStorageMock,
+                encryptionRunnerProvider.getEncryptionRunner());
+        mChannel.registerCallback(callback);
+        mChannel.setShowVerificationCodeListener(mShowVerificationCodeListenerMock);
+        ArgumentCaptor<MessageReceivedListener> listenerCaptor =
+                ArgumentCaptor.forClass(MessageReceivedListener.class);
+        verify(mStreamMock).setMessageReceivedListener(listenerCaptor.capture());
+        mMessageReceivedListener = listenerCaptor.getValue();
+    }
+
+    private void sendDeviceId() {
+        DeviceMessage message = new DeviceMessage(
+                /* recipient= */ null,
+                /* isMessageEncrypted= */ true,
+                ByteUtils.concatByteArrays(ByteUtils.uuidToBytes(CLIENT_DEVICE_ID), CLIENT_SECRET)
+        );
+        mMessageReceivedListener.onMessageReceived(message, OperationType.ENCRYPTION_HANDSHAKE);
+    }
+
+    private void initHandshakeMessage() {
+        DeviceMessage message = new DeviceMessage(
+                /* recipient= */ null,
+                /* isMessageEncrypted= */ false,
+                DummyEncryptionRunner.INIT.getBytes()
+        );
+        mMessageReceivedListener.onMessageReceived(message, OperationType.ENCRYPTION_HANDSHAKE);
+    }
+
+    private void respondToContinueMessage() {
+        DeviceMessage message = new DeviceMessage(
+                /* recipient= */ null,
+                /* isMessageEncrypted= */ false,
+                DummyEncryptionRunner.CLIENT_RESPONSE.getBytes()
+        );
+        mMessageReceivedListener.onMessageReceived(message, OperationType.ENCRYPTION_HANDSHAKE);
+    }
+
+    /**
+     * Add the thread control logic into {@link SecureBleChannel.Callback} only for spy purpose.
+     *
+     * <p>The callback will release the semaphore which hold by one test when this callback
+     * is called, telling the test that it can verify certain behaviors which will only occurred
+     * after the callback is notified. This is needed mainly because of the callback is notified
+     * in a different thread.
+     */
+    private static class ChannelCallback implements SecureBleChannel.Callback {
+        private final Semaphore mSemaphore;
+
+        ChannelCallback(Semaphore semaphore) {
+            mSemaphore = semaphore;
+        }
+
+        @Override
+        public void onSecureChannelEstablished() {
+            mSemaphore.release();
+        }
+
+        @Override
+        public void onEstablishSecureChannelFailure(int error) {
+            mSemaphore.release();
+        }
+
+        @Override
+        public void onMessageReceived(DeviceMessage deviceMessage) {
+            mSemaphore.release();
+        }
+
+        @Override
+        public void onMessageReceivedError(Exception exception) {
+            mSemaphore.release();
+        }
+
+        @Override
+        public void onDeviceIdReceived(String deviceId) {
+            mSemaphore.release();
+        }
+    }
+
+    interface EncryptionRunnerProvider {
+        EncryptionRunner getEncryptionRunner();
+    }
+}
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/BleDeviceMessageStreamTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/BleDeviceMessageStreamTest.java
new file mode 100644
index 0000000..ed6fb44
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/BleDeviceMessageStreamTest.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.BleStreamProtos.BleDeviceMessageProto.BleDeviceMessage;
+import static com.android.car.connecteddevice.BleStreamProtos.BleOperationProto.OperationType;
+import static com.android.car.connecteddevice.BleStreamProtos.BlePacketProto.BlePacket;
+import static com.android.car.connecteddevice.ble.BleDeviceMessageStream.MessageReceivedErrorListener;
+import static com.android.car.connecteddevice.ble.BleDeviceMessageStream.MessageReceivedListener;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mockitoSession;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.NonNull;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattCharacteristic;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.connecteddevice.util.ByteUtils;
+import com.android.car.protobuf.ByteString;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class BleDeviceMessageStreamTest {
+
+    private static final int PACKET_SIZE = 500;
+
+    private BleDeviceMessageStream mStream;
+
+    @Mock
+    private BlePeripheralManager mMockBlePeripheralManager;
+
+    @Mock
+    private BluetoothDevice mMockBluetoothDevice;
+
+    @Mock
+    private BluetoothGattCharacteristic mMockWriteCharacteristic;
+
+    @Mock
+    private BluetoothGattCharacteristic mMockReadCharacteristic;
+
+    private MockitoSession mMockingSession;
+
+    @Before
+    public void setup() {
+        mMockingSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.LENIENT)
+                .startMocking();
+
+        mStream = new BleDeviceMessageStream(mMockBlePeripheralManager, mMockBluetoothDevice,
+                mMockWriteCharacteristic, mMockReadCharacteristic, PACKET_SIZE);
+    }
+
+    @After
+    public void cleanup() {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+    }
+
+    @Test
+    public void processPacket_notifiesWithEntireMessageForSinglePacketMessage()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        MessageReceivedListener listener = createMessageReceivedListener(semaphore);
+        mStream.setMessageReceivedListener(listener);
+        byte[] data = ByteUtils.randomBytes(5);
+        processMessage(data);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        ArgumentCaptor<DeviceMessage> messageCaptor = ArgumentCaptor.forClass(DeviceMessage.class);
+        verify(listener).onMessageReceived(messageCaptor.capture(), any());
+    }
+
+    @Test
+    public void processPacket_notifiesWithEntireMessageForMultiPacketMessage()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        MessageReceivedListener listener = createMessageReceivedListener(semaphore);
+        mStream.setMessageReceivedListener(listener);
+        byte[] data = ByteUtils.randomBytes(750);
+        processMessage(data);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        ArgumentCaptor<DeviceMessage> messageCaptor = ArgumentCaptor.forClass(DeviceMessage.class);
+        verify(listener).onMessageReceived(messageCaptor.capture(), any());
+        assertThat(Arrays.equals(data, messageCaptor.getValue().getMessage())).isTrue();
+    }
+
+    @Test
+    public void processPacket_receivingMultipleMessagesInParallelParsesSuccessfully()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        MessageReceivedListener listener = createMessageReceivedListener(semaphore);
+        mStream.setMessageReceivedListener(listener);
+        byte[] data = ByteUtils.randomBytes((int) (PACKET_SIZE * 1.5));
+        List<BlePacket> packets1 = createPackets(data);
+        List<BlePacket> packets2 = createPackets(data);
+
+        for (int i = 0; i < packets1.size(); i++) {
+            mStream.processPacket(packets1.get(i));
+            if (i == packets1.size() - 1) {
+                break;
+            }
+            mStream.processPacket(packets2.get(i));
+        }
+        assertThat(tryAcquire(semaphore)).isTrue();
+        ArgumentCaptor<DeviceMessage> messageCaptor = ArgumentCaptor.forClass(DeviceMessage.class);
+        verify(listener).onMessageReceived(messageCaptor.capture(), any());
+        assertThat(Arrays.equals(data, messageCaptor.getValue().getMessage())).isTrue();
+
+        semaphore = new Semaphore(0);
+        listener = createMessageReceivedListener(semaphore);
+        mStream.setMessageReceivedListener(listener);
+        mStream.processPacket(packets2.get(packets2.size() - 1));
+        verify(listener).onMessageReceived(messageCaptor.capture(), any());
+        assertThat(Arrays.equals(data, messageCaptor.getValue().getMessage())).isTrue();
+    }
+
+    @Test
+    public void processPacket_doesNotNotifyOfNewMessageIfNotAllPacketsReceived()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        mStream.setMessageReceivedListener(createMessageReceivedListener(semaphore));
+        mStream.setMessageReceivedErrorListener(createMessageReceivedErrorListener(semaphore));
+        byte[] data = ByteUtils.randomBytes((int) (PACKET_SIZE * 1.5));
+        List<BlePacket> packets = createPackets(data);
+        for (int i = 0; i < packets.size() - 1; i++) {
+            mStream.processPacket(packets.get(i));
+        }
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void processPacket_ignoresDuplicatePacket() {
+        Semaphore semaphore = new Semaphore(0);
+        byte[] data = ByteUtils.randomBytes((int) (PACKET_SIZE * 2.5));
+        MessageReceivedListener listener = createMessageReceivedListener(semaphore);
+        mStream.setMessageReceivedListener(listener);
+        ArgumentCaptor<DeviceMessage> messageCaptor = ArgumentCaptor.forClass(DeviceMessage.class);
+        List<BlePacket> packets = createPackets(data);
+        for (int i = 0; i < packets.size(); i++) {
+            mStream.processPacket(packets.get(i));
+            mStream.processPacket(packets.get(i)); // Process each packet twice.
+        }
+        verify(listener).onMessageReceived(messageCaptor.capture(), any());
+        assertThat(Arrays.equals(data, messageCaptor.getValue().getMessage())).isTrue();
+    }
+
+    @Test
+    public void processPacket_packetBeforeExpectedRangeNotifiesMessageError()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        mStream.setMessageReceivedErrorListener(createMessageReceivedErrorListener(semaphore));
+        List<BlePacket> packets = createPackets(ByteUtils.randomBytes((int) (PACKET_SIZE * 2.5)));
+        mStream.processPacket(packets.get(0));
+        mStream.processPacket(packets.get(1));
+        mStream.processPacket(packets.get(0));
+        assertThat(tryAcquire(semaphore)).isTrue();
+    }
+
+    @Test
+    public void processPacket_packetAfterExpectedNotifiesMessageError()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        mStream.setMessageReceivedErrorListener(createMessageReceivedErrorListener(semaphore));
+        List<BlePacket> packets = createPackets(ByteUtils.randomBytes((int) (PACKET_SIZE * 1.5)));
+        mStream.processPacket(packets.get(1));
+        assertThat(tryAcquire(semaphore)).isTrue();
+    }
+
+    @NonNull
+    private List<BlePacket> createPackets(byte[] data) {
+        try {
+            BleDeviceMessage message = BleDeviceMessage.newBuilder()
+                    .setPayload(ByteString.copyFrom(data))
+                    .setOperation(OperationType.CLIENT_MESSAGE)
+                    .build();
+            return BlePacketFactory.makeBlePackets(message.toByteArray(),
+                    ThreadLocalRandom.current().nextInt(), PACKET_SIZE);
+        } catch (Exception e) {
+            assertWithMessage("Uncaught exception while making packets.").fail();
+            return new ArrayList<>();
+        }
+    }
+
+    private void processMessage(byte[] data) {
+        List<BlePacket> packets = createPackets(data);
+        for (BlePacket packet : packets) {
+            mStream.processPacket(packet);
+        }
+    }
+
+    private boolean tryAcquire(@NonNull Semaphore semaphore) throws InterruptedException {
+        return semaphore.tryAcquire(100, TimeUnit.MILLISECONDS);
+    }
+
+    @NonNull
+    private MessageReceivedListener createMessageReceivedListener(@NonNull Semaphore semaphore) {
+        return spy((deviceMessage, operationType) -> semaphore.release());
+    }
+
+    @NonNull
+    private MessageReceivedErrorListener createMessageReceivedErrorListener(
+            @NonNull Semaphore semaphore) {
+        return exception -> semaphore.release();
+    }
+}
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/BlePacketFactoryTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/BlePacketFactoryTest.java
new file mode 100644
index 0000000..8e8682f
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/BlePacketFactoryTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.connecteddevice.BleStreamProtos.BlePacketProto.BlePacket;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+public class BlePacketFactoryTest {
+    @Test
+    public void testGetHeaderSize() {
+        // 1 byte to encode the ID, 1 byte for the field number.
+        int messageId = 1;
+        int messageIdEncodingSize = 2;
+
+        // 1 byte for the payload size, 1 byte for the field number.
+        int payloadSize = 2;
+        int payloadSizeEncodingSize = 2;
+
+        // 1 byte for total packets, 1 byte for field number.
+        int totalPackets = 5;
+        int totalPacketsEncodingSize = 2;
+
+        // Packet number if a fixed32, so 4 bytes + 1 byte for field number.
+        int packetNumberEncodingSize = 5;
+
+        int expectedHeaderSize = messageIdEncodingSize + payloadSizeEncodingSize
+                + totalPacketsEncodingSize + packetNumberEncodingSize;
+
+        assertThat(BlePacketFactory.getPacketHeaderSize(totalPackets, messageId, payloadSize))
+                .isEqualTo(expectedHeaderSize);
+    }
+
+    @Test
+    public void testGetTotalPackets_withVarintSize1_returnsCorrectPackets()
+            throws BlePacketFactoryException {
+        int messageId = 1;
+        int maxSize = 49;
+        int payloadSize = 100;
+
+        // This leaves us 40 bytes to use for the payload and its encoding size. Assuming a varint
+        // of size 1 means it takes 2 bytes to encode its value. This leaves 38 bytes for the
+        // payload. ceil(payloadSize/38) gives the total packets.
+        int expectedTotalPackets = 3;
+
+        assertThat(BlePacketFactory.getTotalPacketNumber(messageId, payloadSize, maxSize))
+                .isEqualTo(expectedTotalPackets);
+    }
+
+    @Test
+    public void testGetTotalPackets_withVarintSize2_returnsCorrectPackets()
+            throws BlePacketFactoryException {
+        int messageId = 1;
+        int maxSize = 49;
+        int payloadSize = 6000;
+
+        // This leaves us 40 bytes to use for the payload and its encoding size. Assuming a varint
+        // of size 2 means it takes 3 bytes to encode its value. This leaves 37 bytes for the
+        // payload. ceil(payloadSize/37) gives the total packets.
+        int expectedTotalPackets = 163;
+
+        assertThat(BlePacketFactory.getTotalPacketNumber(messageId, payloadSize, maxSize))
+                .isEqualTo(expectedTotalPackets);
+    }
+
+    @Test
+    public void testGetTotalPackets_withVarintSize3_returnsCorrectPackets()
+            throws BlePacketFactoryException {
+        int messageId = 1;
+        int maxSize = 49;
+        int payloadSize = 1000000;
+
+        // This leaves us 40 bytes to use for the payload and its encoding size. Assuming a varint
+        // of size 3 means it takes 4 bytes to encode its value. This leaves 36 bytes for the
+        // payload. ceil(payloadSize/36) gives the total packets.
+        int expectedTotalPackets = 27778;
+
+        assertThat(BlePacketFactory.getTotalPacketNumber(messageId, payloadSize, maxSize))
+                .isEqualTo(expectedTotalPackets);
+    }
+
+    @Test
+    public void testGetTotalPackets_withVarintSize4_returnsCorrectPackets()
+            throws BlePacketFactoryException {
+        int messageId = 1;
+        int maxSize = 49;
+        int payloadSize = 178400320;
+
+        // This leaves us 40 bytes to use for the payload and its encoding size. Assuming a varint
+        // of size 4 means it takes 5 bytes to encode its value. This leaves 35 bytes for the
+        // payload. ceil(payloadSize/35) gives the total packets.
+        int expectedTotalPackets = 5097152;
+
+        assertThat(BlePacketFactory.getTotalPacketNumber(messageId, payloadSize, maxSize))
+                .isEqualTo(expectedTotalPackets);
+    }
+
+    @Test
+    public void testMakePackets_correctlyChunksPayload() throws Exception {
+        // Payload of size 100, but maxSize of 1000 to ensure it fits.
+        byte[] payload = makePayload(/* length= */ 100);
+        int maxSize = 1000;
+
+        List<BlePacket> packets =
+                BlePacketFactory.makeBlePackets(payload, /* mesageId= */ 1, maxSize);
+
+        assertThat(packets).hasSize(1);
+
+        ByteArrayOutputStream reconstructedPayload = new ByteArrayOutputStream();
+
+        // Combine together all the payloads within the BlePackets.
+        for (BlePacket packet : packets) {
+            reconstructedPayload.write(packet.getPayload().toByteArray());
+        }
+
+        assertThat(reconstructedPayload.toByteArray()).isEqualTo(payload);
+    }
+
+    @Test
+    public void testMakePackets_correctlyChunksSplitPayload() throws Exception {
+        // Payload size of 10000 but max size of 50 to ensure the payload is split.
+        byte[] payload = makePayload(/* length= */ 10000);
+        int maxSize = 50;
+
+        List<BlePacket> packets =
+                BlePacketFactory.makeBlePackets(payload, /* mesageId= */ 1, maxSize);
+
+        assertThat(packets.size()).isGreaterThan(1);
+
+        ByteArrayOutputStream reconstructedPayload = new ByteArrayOutputStream();
+
+        // Combine together all the payloads within the BlePackets.
+        for (BlePacket packet : packets) {
+            reconstructedPayload.write(packet.getPayload().toByteArray());
+        }
+
+        assertThat(reconstructedPayload.toByteArray()).isEqualTo(payload);
+    }
+
+    /** Creates a byte array of the given length, populated with random bytes. */
+    private byte[] makePayload(int length) {
+        byte[] payload = new byte[length];
+        new Random().nextBytes(payload);
+        return payload;
+    }
+}
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/CarBlePeripheralManagerTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/CarBlePeripheralManagerTest.java
new file mode 100644
index 0000000..ac58a97
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/CarBlePeripheralManagerTest.java
@@ -0,0 +1,281 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mockitoSession;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.car.encryptionrunner.EncryptionRunnerFactory;
+import android.car.encryptionrunner.Key;
+import android.os.ParcelUuid;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.connecteddevice.AssociationCallback;
+import com.android.car.connecteddevice.model.AssociatedDevice;
+import com.android.car.connecteddevice.storage.ConnectedDeviceStorage;
+import com.android.car.connecteddevice.util.ByteUtils;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.time.Duration;
+import java.util.UUID;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class CarBlePeripheralManagerTest {
+    private static final UUID ASSOCIATION_SERVICE_UUID = UUID.randomUUID();
+    private static final UUID RECONNECT_SERVICE_UUID = UUID.randomUUID();
+    private static final UUID RECONNECT_DATA_UUID = UUID.randomUUID();
+    private static final UUID WRITE_UUID = UUID.randomUUID();
+    private static final UUID READ_UUID = UUID.randomUUID();
+    private static final int DEVICE_NAME_LENGTH_LIMIT = 8;
+    private static final String TEST_REMOTE_DEVICE_ADDRESS = "00:11:22:33:AA:BB";
+    private static final UUID TEST_REMOTE_DEVICE_ID = UUID.randomUUID();
+    private static final String TEST_VERIFICATION_CODE = "000000";
+    private static final byte[] TEST_KEY = "Key".getBytes();
+    private static final Duration RECONNECT_ADVERTISEMENT_DURATION = Duration.ofSeconds(2);
+    private static final int DEFAULT_MTU_SIZE = 23;
+
+    private static String sAdapterName;
+
+    @Mock
+    private BlePeripheralManager mMockPeripheralManager;
+    @Mock
+    private ConnectedDeviceStorage mMockStorage;
+
+    private CarBlePeripheralManager mCarBlePeripheralManager;
+
+    private MockitoSession mMockitoSession;
+
+    @BeforeClass
+    public static void beforeSetUp() {
+        sAdapterName = BluetoothAdapter.getDefaultAdapter().getName();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mMockitoSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.WARN)
+                .startMocking();
+        mCarBlePeripheralManager = new CarBlePeripheralManager(mMockPeripheralManager, mMockStorage,
+                ASSOCIATION_SERVICE_UUID, RECONNECT_SERVICE_UUID, RECONNECT_DATA_UUID,
+                WRITE_UUID, READ_UUID, RECONNECT_ADVERTISEMENT_DURATION, DEFAULT_MTU_SIZE);
+    }
+
+    @After
+    public void tearDown() {
+        if (mCarBlePeripheralManager != null) {
+            mCarBlePeripheralManager.stop();
+        }
+        if (mMockitoSession != null) {
+            mMockitoSession.finishMocking();
+        }
+    }
+
+    @AfterClass
+    public static void afterTearDown() {
+        BluetoothAdapter.getDefaultAdapter().setName(sAdapterName);
+    }
+
+    @Test
+    public void testStartAssociationAdvertisingSuccess() {
+        Semaphore semaphore = new Semaphore(0);
+        AssociationCallback callback = createAssociationCallback(semaphore);
+        String testDeviceName = getNameForAssociation();
+        startAssociation(callback, testDeviceName);
+        ArgumentCaptor<AdvertiseData> dataCaptor = ArgumentCaptor.forClass(AdvertiseData.class);
+        verify(mMockPeripheralManager, timeout(3000)).startAdvertising(any(),
+                dataCaptor.capture(), any());
+        AdvertiseData data = dataCaptor.getValue();
+        assertThat(data.getIncludeDeviceName()).isTrue();
+        ParcelUuid expected = new ParcelUuid(ASSOCIATION_SERVICE_UUID);
+        assertThat(data.getServiceUuids().get(0)).isEqualTo(expected);
+        assertThat(BluetoothAdapter.getDefaultAdapter().getName()).isEqualTo(testDeviceName);
+    }
+
+    @Test
+    public void testStartAssociationAdvertisingFailure() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        AssociationCallback callback = createAssociationCallback(semaphore);
+        startAssociation(callback, getNameForAssociation());
+        ArgumentCaptor<AdvertiseCallback> callbackCaptor =
+                ArgumentCaptor.forClass(AdvertiseCallback.class);
+        verify(mMockPeripheralManager, timeout(3000))
+                .startAdvertising(any(), any(), callbackCaptor.capture());
+        AdvertiseCallback advertiseCallback = callbackCaptor.getValue();
+        int testErrorCode = 2;
+        advertiseCallback.onStartFailure(testErrorCode);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onAssociationStartFailure();
+    }
+
+    @Test
+    public void testNotifyAssociationSuccess() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        AssociationCallback callback = createAssociationCallback(semaphore);
+        String testDeviceName = getNameForAssociation();
+        startAssociation(callback, testDeviceName);
+        ArgumentCaptor<AdvertiseCallback> callbackCaptor =
+                ArgumentCaptor.forClass(AdvertiseCallback.class);
+        verify(mMockPeripheralManager, timeout(3000))
+                .startAdvertising(any(), any(), callbackCaptor.capture());
+        AdvertiseCallback advertiseCallback = callbackCaptor.getValue();
+        AdvertiseSettings settings = new AdvertiseSettings.Builder().build();
+        advertiseCallback.onStartSuccess(settings);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onAssociationStartSuccess(eq(testDeviceName));
+    }
+
+    @Test
+    public void testShowVerificationCode() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        AssociationCallback callback = createAssociationCallback(semaphore);
+        AssociationSecureChannel channel = getChannelForAssociation(callback);
+        channel.getShowVerificationCodeListener().showVerificationCode(TEST_VERIFICATION_CODE);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onVerificationCodeAvailable(eq(TEST_VERIFICATION_CODE));
+    }
+
+    @Test
+    public void testAssociationSuccess() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        AssociationCallback callback = createAssociationCallback(semaphore);
+        SecureBleChannel channel = getChannelForAssociation(callback);
+        SecureBleChannel.Callback channelCallback = channel.getCallback();
+        assertThat(channelCallback).isNotNull();
+        channelCallback.onDeviceIdReceived(TEST_REMOTE_DEVICE_ID.toString());
+        Key key = EncryptionRunnerFactory.newDummyRunner().keyOf(TEST_KEY);
+        channelCallback.onSecureChannelEstablished();
+        ArgumentCaptor<AssociatedDevice> deviceCaptor =
+                ArgumentCaptor.forClass(AssociatedDevice.class);
+        verify(mMockStorage).addAssociatedDeviceForActiveUser(deviceCaptor.capture());
+        AssociatedDevice device = deviceCaptor.getValue();
+        assertThat(device.getDeviceId()).isEqualTo(TEST_REMOTE_DEVICE_ID.toString());
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onAssociationCompleted(eq(TEST_REMOTE_DEVICE_ID.toString()));
+    }
+
+    @Test
+    public void testAssociationFailure_channelError() throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        AssociationCallback callback = createAssociationCallback(semaphore);
+        SecureBleChannel channel = getChannelForAssociation(callback);
+        SecureBleChannel.Callback channelCallback = channel.getCallback();
+        int testErrorCode = 1;
+        assertThat(channelCallback).isNotNull();
+        channelCallback.onDeviceIdReceived(TEST_REMOTE_DEVICE_ID.toString());
+        channelCallback.onEstablishSecureChannelFailure(testErrorCode);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        verify(callback).onAssociationError(eq(testErrorCode));
+    }
+
+    @Test
+    public void connectToDevice_stopsAdvertisingAfterTimeout() {
+        when(mMockStorage.hashWithChallengeSecret(any(), any()))
+                .thenReturn(ByteUtils.randomBytes(32));
+        mCarBlePeripheralManager.connectToDevice(UUID.randomUUID());
+        ArgumentCaptor<AdvertiseCallback> callbackCaptor =
+                ArgumentCaptor.forClass(AdvertiseCallback.class);
+        verify(mMockPeripheralManager).startAdvertising(any(), any(), callbackCaptor.capture());
+        callbackCaptor.getValue().onStartSuccess(null);
+        verify(mMockPeripheralManager,
+                timeout(RECONNECT_ADVERTISEMENT_DURATION.plusSeconds(1).toMillis()))
+                .stopAdvertising(any(AdvertiseCallback.class));
+    }
+
+    private BlePeripheralManager.Callback startAssociation(AssociationCallback callback,
+            String deviceName) {
+        ArgumentCaptor<BlePeripheralManager.Callback> callbackCaptor =
+                ArgumentCaptor.forClass(BlePeripheralManager.Callback.class);
+        mCarBlePeripheralManager.startAssociation(deviceName, callback);
+        verify(mMockPeripheralManager, timeout(3000)).registerCallback(callbackCaptor.capture());
+        return callbackCaptor.getValue();
+    }
+
+    private AssociationSecureChannel getChannelForAssociation(AssociationCallback callback) {
+        BlePeripheralManager.Callback bleManagerCallback = startAssociation(callback,
+                getNameForAssociation());
+        BluetoothDevice bluetoothDevice = BluetoothAdapter.getDefaultAdapter()
+                .getRemoteDevice(TEST_REMOTE_DEVICE_ADDRESS);
+        bleManagerCallback.onRemoteDeviceConnected(bluetoothDevice);
+        return (AssociationSecureChannel) mCarBlePeripheralManager.getConnectedDeviceChannel();
+    }
+
+    private boolean tryAcquire(Semaphore semaphore) throws InterruptedException {
+        return semaphore.tryAcquire(100, TimeUnit.MILLISECONDS);
+    }
+
+    private String getNameForAssociation() {
+        return ByteUtils.generateRandomNumberString(DEVICE_NAME_LENGTH_LIMIT);
+
+    }
+
+    @NonNull
+    private AssociationCallback createAssociationCallback(@NonNull final Semaphore semaphore) {
+        return spy(new AssociationCallback() {
+            @Override
+            public void onAssociationStartSuccess(String deviceName) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onAssociationStartFailure() {
+                semaphore.release();
+            }
+
+            @Override
+            public void onAssociationError(int error) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onVerificationCodeAvailable(String code) {
+                semaphore.release();
+            }
+
+            @Override
+            public void onAssociationCompleted(String deviceId) {
+                semaphore.release();
+            }
+        });
+    }
+}
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/SecureBleChannelTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/SecureBleChannelTest.java
new file mode 100644
index 0000000..e8f4da4
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/ble/SecureBleChannelTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.connecteddevice.ble;
+
+import static com.android.car.connecteddevice.BleStreamProtos.BleOperationProto.OperationType.CLIENT_MESSAGE;
+import static com.android.car.connecteddevice.BleStreamProtos.BleOperationProto.OperationType.ENCRYPTION_HANDSHAKE;
+import static com.android.car.connecteddevice.ble.SecureBleChannel.CHANNEL_ERROR_INVALID_HANDSHAKE;
+import static com.android.car.connecteddevice.ble.SecureBleChannel.Callback;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mockitoSession;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.car.encryptionrunner.DummyEncryptionRunner;
+import android.car.encryptionrunner.EncryptionRunnerFactory;
+import android.car.encryptionrunner.HandshakeException;
+import android.car.encryptionrunner.Key;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.connecteddevice.util.ByteUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.util.UUID;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class SecureBleChannelTest {
+
+    @Mock private BleDeviceMessageStream mMockStream;
+
+    @Mock private Key mKey = spy(new Key() {
+        @Override
+        public byte[] asBytes() {
+            return new byte[0];
+        }
+
+        @Override
+        public byte[] encryptData(byte[] data) {
+            return data;
+        }
+
+        @Override
+        public byte[] decryptData(byte[] encryptedData) throws SignatureException {
+            return encryptedData;
+        }
+
+        @Override
+        public byte[] getUniqueSession() throws NoSuchAlgorithmException {
+            return new byte[0];
+        }
+    });
+
+    private MockitoSession mMockitoSession;
+
+    private SecureBleChannel mSecureBleChannel;
+
+    @Before
+    public void setUp() throws SignatureException {
+        mMockitoSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.WARN)
+                .startMocking();
+
+        mSecureBleChannel = new SecureBleChannel(mMockStream,
+                EncryptionRunnerFactory.newDummyRunner()) {
+            @Override
+            void processHandshake(byte[] message) { }
+        };
+        mSecureBleChannel.setEncryptionKey(mKey);
+    }
+
+    @After
+    public void tearDown() {
+        if (mMockitoSession != null) {
+            mMockitoSession.finishMocking();
+        }
+    }
+
+    @Test
+    public void processMessage_doesNothingForUnencryptedMessage() throws SignatureException {
+        byte[] payload = ByteUtils.randomBytes(10);
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), /* isEncrypted= */ false,
+                payload);
+        mSecureBleChannel.processMessage(message);
+        assertThat(message.getMessage()).isEqualTo(payload);
+        verify(mKey, times(0)).decryptData(any());
+    }
+
+    @Test
+    public void processMessage_decryptsEncryptedMessage() throws SignatureException {
+        byte[] payload = ByteUtils.randomBytes(10);
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), /* isEncrypted= */ true,
+                payload);
+        mSecureBleChannel.processMessage(message);
+        verify(mKey).decryptData(any());
+    }
+
+    @Test
+    public void processMessage_onMessageReceivedErrorForEncryptedMessageWithNoKey()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), /* isEncrypted= */ true,
+                ByteUtils.randomBytes(10));
+
+        mSecureBleChannel.setEncryptionKey(null);
+        mSecureBleChannel.registerCallback(new Callback() {
+            @Override
+            public void onMessageReceivedError(Exception exception) {
+                semaphore.release();
+            }
+        });
+        mSecureBleChannel.processMessage(message);
+        assertThat(tryAcquire(semaphore)).isTrue();
+        assertThat(message.getMessage()).isNull();
+    }
+
+    @Test
+    public void onMessageReceived_onEstablishSecureChannelFailureBadHandshakeMessage()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), /* isEncrypted= */ true,
+                ByteUtils.randomBytes(10));
+
+        mSecureBleChannel.setEncryptionKey(null);
+        mSecureBleChannel.registerCallback(new Callback() {
+            @Override
+            public void onEstablishSecureChannelFailure(int error) {
+                assertThat(error).isEqualTo(CHANNEL_ERROR_INVALID_HANDSHAKE);
+                semaphore.release();
+            }
+        });
+        mSecureBleChannel.onMessageReceived(message, ENCRYPTION_HANDSHAKE);
+        assertThat(tryAcquire(semaphore)).isTrue();
+    }
+
+    @Test
+    public void onMessageReceived_onMessageReceivedNotIssuedForNullMessage()
+            throws InterruptedException {
+        Semaphore semaphore = new Semaphore(0);
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), /* isEncrypted= */ false,
+                /* message= */ null);
+
+        mSecureBleChannel.registerCallback(new Callback() {
+            @Override
+            public void onMessageReceived(DeviceMessage message) {
+                semaphore.release();
+            }
+        });
+        mSecureBleChannel.onMessageReceived(message, CLIENT_MESSAGE);
+        assertThat(tryAcquire(semaphore)).isFalse();
+    }
+
+    @Test
+    public void onMessageReceived_processHandshakeExceptionIssuesSecureChannelFailureCallback()
+            throws InterruptedException {
+        SecureBleChannel secureChannel = new SecureBleChannel(mMockStream,
+                EncryptionRunnerFactory.newDummyRunner()) {
+            @Override
+            void processHandshake(byte[] message) throws HandshakeException {
+                DummyEncryptionRunner.throwHandshakeException("test");
+            }
+        };
+        Semaphore semaphore = new Semaphore(0);
+        secureChannel.registerCallback(new Callback() {
+            @Override
+            public void onEstablishSecureChannelFailure(int error) {
+                semaphore.release();
+            }
+        });
+        DeviceMessage message = new DeviceMessage(UUID.randomUUID(), /* isEncrypted= */ true,
+                /* message= */ ByteUtils.randomBytes(10));
+
+        secureChannel.onMessageReceived(message, ENCRYPTION_HANDSHAKE);
+        assertThat(tryAcquire(semaphore)).isTrue();
+    }
+
+    private boolean tryAcquire(Semaphore semaphore) throws InterruptedException {
+        return semaphore.tryAcquire(100, TimeUnit.MILLISECONDS);
+    }
+}
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorageTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorageTest.java
new file mode 100644
index 0000000..755ce64
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorageTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.connecteddevice.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+import android.util.Pair;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.connecteddevice.model.AssociatedDevice;
+import com.android.car.connecteddevice.util.ByteUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+@RunWith(AndroidJUnit4.class)
+public final class ConnectedDeviceStorageTest {
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+
+    private final int mActiveUserId = 10;
+
+    private ConnectedDeviceStorage mConnectedDeviceStorage;
+
+    private List<Pair<Integer, AssociatedDevice>> mAddedAssociatedDevices;
+
+    @Before
+    public void setUp() {
+        mConnectedDeviceStorage = new ConnectedDeviceStorage(mContext);
+        mAddedAssociatedDevices = new ArrayList<>();
+    }
+
+    @After
+    public void tearDown() {
+        // Clear any associated devices added during tests.
+        for (Pair<Integer, AssociatedDevice> device : mAddedAssociatedDevices) {
+            mConnectedDeviceStorage.removeAssociatedDevice(device.first,
+                    device.second.getDeviceId());
+        }
+    }
+
+    @Test
+    public void getAssociatedDeviceIdsForUser_includesNewlyAddedDevice() {
+        AssociatedDevice addedDevice = addRandomAssociatedDevice(mActiveUserId);
+        List<String> associatedDevices =
+                mConnectedDeviceStorage.getAssociatedDeviceIdsForUser(mActiveUserId);
+        assertThat(associatedDevices).containsExactly(addedDevice.getDeviceId());
+    }
+
+    @Test
+    public void getAssociatedDeviceIdsForUser_excludesDeviceAddedForOtherUser() {
+        addRandomAssociatedDevice(mActiveUserId);
+        List<String> associatedDevices =
+                mConnectedDeviceStorage.getAssociatedDeviceIdsForUser(mActiveUserId + 1);
+        assertThat(associatedDevices).isEmpty();
+    }
+
+    @Test
+    public void getAssociatedDeviceIdsForUser_excludesRemovedDevice() {
+        AssociatedDevice addedDevice = addRandomAssociatedDevice(mActiveUserId);
+        mConnectedDeviceStorage.removeAssociatedDevice(mActiveUserId, addedDevice.getDeviceId());
+        List<String> associatedDevices =
+                mConnectedDeviceStorage.getAssociatedDeviceIdsForUser(mActiveUserId);
+        assertThat(associatedDevices).isEmpty();
+    }
+
+    @Test
+    public void getAssociatedDevicesForUser_includesNewlyAddedDevice() {
+        AssociatedDevice addedDevice = addRandomAssociatedDevice(mActiveUserId);
+        List<AssociatedDevice> associatedDevices =
+                mConnectedDeviceStorage.getAssociatedDevicesForUser(mActiveUserId);
+        assertThat(associatedDevices).containsExactly(addedDevice);
+    }
+
+    @Test
+    public void getAssociatedDevicesForUser_excludesDeviceAddedForOtherUser() {
+        addRandomAssociatedDevice(mActiveUserId);
+        List<String> associatedDevices =
+                mConnectedDeviceStorage.getAssociatedDeviceIdsForUser(mActiveUserId + 1);
+        assertThat(associatedDevices).isEmpty();
+    }
+
+    @Test
+    public void getAssociatedDevicesForUser_excludesRemovedDevice() {
+        AssociatedDevice addedDevice = addRandomAssociatedDevice(mActiveUserId);
+        mConnectedDeviceStorage.removeAssociatedDevice(mActiveUserId, addedDevice.getDeviceId());
+        List<AssociatedDevice> associatedDevices =
+                mConnectedDeviceStorage.getAssociatedDevicesForUser(mActiveUserId);
+        assertThat(associatedDevices).isEmpty();
+    }
+
+    @Test
+    public void getEncryptionKey_returnsSavedKey() {
+        String deviceId = addRandomAssociatedDevice(mActiveUserId).getDeviceId();
+        byte[] key = ByteUtils.randomBytes(16);
+        mConnectedDeviceStorage.saveEncryptionKey(deviceId, key);
+        assertThat(mConnectedDeviceStorage.getEncryptionKey(deviceId)).isEqualTo(key);
+    }
+
+    @Test
+    public void getEncryptionKey_returnsNullForUnrecognizedDeviceId() {
+        String deviceId = addRandomAssociatedDevice(mActiveUserId).getDeviceId();
+        mConnectedDeviceStorage.saveEncryptionKey(deviceId, ByteUtils.randomBytes(16));
+        assertThat(mConnectedDeviceStorage.getEncryptionKey(UUID.randomUUID().toString())).isNull();
+    }
+
+    @Test
+    public void saveChallengeSecret_throwsForInvalidLengthSecret() {
+        byte[] invalidSecret =
+                ByteUtils.randomBytes(ConnectedDeviceStorage.CHALLENGE_SECRET_BYTES - 1);
+        assertThrows(InvalidParameterException.class,
+                () -> mConnectedDeviceStorage.saveChallengeSecret(UUID.randomUUID().toString(),
+                        invalidSecret));
+    }
+
+    private AssociatedDevice addRandomAssociatedDevice(int userId) {
+        AssociatedDevice device = new AssociatedDevice(UUID.randomUUID().toString(),
+                "00:00:00:00:00:00", "Test Device", true);
+        addAssociatedDevice(userId, device, ByteUtils.randomBytes(16));
+        return device;
+    }
+
+    private void addAssociatedDevice(int userId, AssociatedDevice device, byte[] encryptionKey) {
+        mConnectedDeviceStorage.addAssociatedDeviceForUser(userId, device);
+        mConnectedDeviceStorage.saveEncryptionKey(device.getDeviceId(), encryptionKey);
+        mAddedAssociatedDevices.add(new Pair<>(userId, device));
+    }
+}
diff --git a/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/util/ScanDataAnalyzerTest.java b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/util/ScanDataAnalyzerTest.java
new file mode 100644
index 0000000..92e8d34
--- /dev/null
+++ b/connected-device-lib/tests/unit/src/com/android/car/connecteddevice/util/ScanDataAnalyzerTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.connecteddevice.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigInteger;
+
+@RunWith(AndroidJUnit4.class)
+public class ScanDataAnalyzerTest {
+    private static final BigInteger CORRECT_DATA =
+            new BigInteger(
+                    "02011A14FF4C000100000000000000000000000000200000000000000000000000000000"
+                            + "0000000000000000000000000000000000000000000000000000",
+                    16);
+
+    private static final BigInteger CORRECT_MASK =
+            new BigInteger("00000000000000000000000000200000", 16);
+
+    private static final BigInteger MULTIPLE_BIT_MASK =
+            new BigInteger("00000000000000000100000000200000", 16);
+
+    @Test
+    public void containsUuidsInOverflow_correctBitFlipped_shouldReturnTrue() {
+        assertThat(
+                ScanDataAnalyzer.containsUuidsInOverflow(CORRECT_DATA.toByteArray(), CORRECT_MASK))
+                .isTrue();
+    }
+
+    @Test
+    public void containsUuidsInOverflow_bitNotFlipped_shouldReturnFalse() {
+        assertThat(
+                ScanDataAnalyzer.containsUuidsInOverflow(
+                        CORRECT_DATA.negate().toByteArray(), CORRECT_MASK))
+                .isFalse();
+    }
+
+    @Test
+    public void containsUuidsInOverflow_maskWithMultipleBitsIncompleteMatch_shouldReturnTrue() {
+        assertThat(
+                ScanDataAnalyzer.containsUuidsInOverflow(CORRECT_DATA.toByteArray(),
+                        MULTIPLE_BIT_MASK))
+                .isTrue();
+    }
+
+    @Test
+    public void containsUuidsInOverflow_incorrectLengthByte_shouldReturnFalse() {
+        // Incorrect length of 0x20
+        byte[] data =
+                new BigInteger(
+                        "02011A20FF4C00010000000000000000000000000020000000000000000000000000000000"
+                                + "00000000000000000000000000000000000000000000000000",
+                        16)
+                        .toByteArray();
+        BigInteger mask = new BigInteger("00000000000000000000000000200000", 16);
+        assertThat(ScanDataAnalyzer.containsUuidsInOverflow(data, mask)).isFalse();
+    }
+
+    @Test
+    public void containsUuidsInOverflow_incorrectAdTypeByte_shouldReturnFalse() {
+        // Incorrect advertising type of 0xEF
+        byte[] data =
+                new BigInteger(
+                        "02011A14EF4C00010000000000000000000000000020000000000000000000000000000000"
+                                + "00000000000000000000000000000000000000000000000000",
+                        16)
+                        .toByteArray();
+        assertThat(ScanDataAnalyzer.containsUuidsInOverflow(data, CORRECT_MASK)).isFalse();
+    }
+
+    @Test
+    public void containsUuidsInOverflow_incorrectCustomId_shouldReturnFalse() {
+        // Incorrect custom id of 0x4C1001
+        byte[] data =
+                new BigInteger(
+                        "02011A14FF4C10010000000000000000000000000020000000000000000000000000000000"
+                                + "00000000000000000000000000000000000000000000000000",
+                        16)
+                        .toByteArray();
+        assertThat(ScanDataAnalyzer.containsUuidsInOverflow(data, CORRECT_MASK)).isFalse();
+    }
+
+    @Test
+    public void containsUuidsInOverflow_incorrectContentLength_shouldReturnFalse() {
+        byte[] data = new BigInteger("02011A14FF4C1001000000000000000000000000002", 16)
+                .toByteArray();
+        assertThat(ScanDataAnalyzer.containsUuidsInOverflow(data, CORRECT_MASK)).isFalse();
+    }
+}
diff --git a/encryption-runner/Android.bp b/encryption-runner/Android.bp
index 4e59864..2522d2d 100644
--- a/encryption-runner/Android.bp
+++ b/encryption-runner/Android.bp
@@ -12,21 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_library {
     name: "encryption-runner",
-    sdk_version: "current",
-    min_sdk_version: "28",
+    min_sdk_version: "23",
     product_variables: {
         pdk: {
             enabled: false,
         },
     },
     static_libs: [
-      "androidx.annotation_annotation",
       "ukey2",
     ],
     srcs: [
@@ -34,3 +28,4 @@
     ],
     installable: true,
 }
+
diff --git a/encryption-runner/src/android/car/encryptionrunner/DummyEncryptionRunner.java b/encryption-runner/src/android/car/encryptionrunner/DummyEncryptionRunner.java
new file mode 100644
index 0000000..d247967
--- /dev/null
+++ b/encryption-runner/src/android/car/encryptionrunner/DummyEncryptionRunner.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.encryptionrunner;
+
+import android.annotation.IntDef;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An encryption runner that doesn't actually do encryption. Useful for debugging. Do not use in
+ * production environments.
+ */
+@VisibleForTesting
+public class DummyEncryptionRunner implements EncryptionRunner {
+
+    private static final String KEY = "key";
+    private static final byte[] DUMMY_MESSAGE = "Dummy Message".getBytes();
+    @VisibleForTesting
+    public static final String INIT = "init";
+    @VisibleForTesting
+    public static final String INIT_RESPONSE = "initResponse";
+    @VisibleForTesting
+    public static final String CLIENT_RESPONSE = "clientResponse";
+    public static final String VERIFICATION_CODE = "1234";
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({Mode.UNKNOWN, Mode.CLIENT, Mode.SERVER})
+    private @interface Mode {
+
+        int UNKNOWN = 0;
+        int CLIENT = 1;
+        int SERVER = 2;
+    }
+
+    private boolean mIsReconnect;
+    private boolean mInitReconnectVerification;
+    private Key mCurrentDummyKey;
+    @Mode
+    private int mMode;
+    @HandshakeMessage.HandshakeState
+    private int mState;
+
+    @Override
+    public HandshakeMessage initHandshake() {
+        checkRunnerIsNew();
+        mMode = Mode.CLIENT;
+        mState = HandshakeMessage.HandshakeState.IN_PROGRESS;
+        return HandshakeMessage.newBuilder()
+                .setHandshakeState(mState)
+                .setNextMessage(INIT.getBytes())
+                .build();
+    }
+
+    @Override
+    public HandshakeMessage respondToInitRequest(byte[] initializationRequest)
+            throws HandshakeException {
+        checkRunnerIsNew();
+        mMode = Mode.SERVER;
+        if (!new String(initializationRequest).equals(INIT)) {
+            throw new HandshakeException("Unexpected initialization request");
+        }
+        mState = HandshakeMessage.HandshakeState.IN_PROGRESS;
+        return HandshakeMessage.newBuilder()
+                .setHandshakeState(HandshakeMessage.HandshakeState.IN_PROGRESS)
+                .setNextMessage(INIT_RESPONSE.getBytes())
+                .build();
+    }
+
+    private void checkRunnerIsNew() {
+        if (mState != HandshakeMessage.HandshakeState.UNKNOWN) {
+            throw new IllegalStateException("runner already initialized.");
+        }
+    }
+
+    @Override
+    public HandshakeMessage continueHandshake(byte[] response) throws HandshakeException {
+        if (mState != HandshakeMessage.HandshakeState.IN_PROGRESS) {
+            throw new HandshakeException("not waiting for response but got one");
+        }
+        switch (mMode) {
+            case Mode.SERVER:
+                if (!CLIENT_RESPONSE.equals(new String(response))) {
+                    throw new HandshakeException("unexpected response: " + new String(response));
+                }
+                mState = HandshakeMessage.HandshakeState.VERIFICATION_NEEDED;
+                if (mIsReconnect) {
+                    verifyPin();
+                    mState = HandshakeMessage.HandshakeState.RESUMING_SESSION;
+                }
+                return HandshakeMessage.newBuilder()
+                        .setVerificationCode(VERIFICATION_CODE)
+                        .setHandshakeState(mState)
+                        .build();
+            case Mode.CLIENT:
+                if (!INIT_RESPONSE.equals(new String(response))) {
+                    throw new HandshakeException("unexpected response: " + new String(response));
+                }
+                mState = HandshakeMessage.HandshakeState.VERIFICATION_NEEDED;
+                if (mIsReconnect) {
+                    verifyPin();
+                    mState = HandshakeMessage.HandshakeState.RESUMING_SESSION;
+                }
+                return HandshakeMessage.newBuilder()
+                        .setHandshakeState(mState)
+                        .setNextMessage(CLIENT_RESPONSE.getBytes())
+                        .setVerificationCode(VERIFICATION_CODE)
+                        .build();
+            default:
+                throw new IllegalStateException("unexpected role: " + mMode);
+        }
+    }
+
+    @Override
+    public HandshakeMessage authenticateReconnection(byte[] message, byte[] previousKey)
+            throws HandshakeException {
+        mCurrentDummyKey = new DummyKey();
+        // Blindly verify the reconnection because this is a dummy encryption runner.
+        return HandshakeMessage.newBuilder()
+                .setHandshakeState(HandshakeMessage.HandshakeState.FINISHED)
+                .setKey(mCurrentDummyKey)
+                .setNextMessage(mInitReconnectVerification ? null : DUMMY_MESSAGE)
+                .build();
+    }
+
+    @Override
+    public HandshakeMessage initReconnectAuthentication(byte[] previousKey)
+            throws HandshakeException {
+        mInitReconnectVerification = true;
+        mState = HandshakeMessage.HandshakeState.RESUMING_SESSION;
+        return HandshakeMessage.newBuilder()
+                .setHandshakeState(mState)
+                .setNextMessage(DUMMY_MESSAGE)
+                .build();
+    }
+
+    @Override
+    public Key keyOf(byte[] serialized) {
+        return new DummyKey();
+    }
+
+    @Override
+    public HandshakeMessage verifyPin() throws HandshakeException {
+        if (mState != HandshakeMessage.HandshakeState.VERIFICATION_NEEDED) {
+            throw new IllegalStateException("asking to verify pin, state = " + mState);
+        }
+        mState = HandshakeMessage.HandshakeState.FINISHED;
+        return HandshakeMessage.newBuilder().setKey(new DummyKey()).setHandshakeState(
+                mState).build();
+    }
+
+    @Override
+    public void invalidPin() {
+        mState = HandshakeMessage.HandshakeState.INVALID;
+    }
+
+    @Override
+    public void setIsReconnect(boolean isReconnect) {
+        mIsReconnect = isReconnect;
+    }
+
+    /** Method to throw a HandshakeException for testing. */
+    public static void throwHandshakeException(String message) throws HandshakeException {
+        throw new HandshakeException(message);
+    }
+
+    private class DummyKey implements Key {
+        @Override
+        public byte[] asBytes() {
+            return KEY.getBytes();
+        }
+
+        @Override
+        public byte[] encryptData(byte[] data) {
+            return data;
+        }
+
+        @Override
+        public byte[] decryptData(byte[] encryptedData) {
+            return encryptedData;
+        }
+
+        @Override
+        public byte[] getUniqueSession() {
+            return KEY.getBytes();
+        }
+    }
+}
diff --git a/encryption-runner/src/android/car/encryptionrunner/EncryptionRunner.java b/encryption-runner/src/android/car/encryptionrunner/EncryptionRunner.java
index 6a2b6d6..5721218 100644
--- a/encryption-runner/src/android/car/encryptionrunner/EncryptionRunner.java
+++ b/encryption-runner/src/android/car/encryptionrunner/EncryptionRunner.java
@@ -16,7 +16,7 @@
 
 package android.car.encryptionrunner;
 
-import androidx.annotation.NonNull;
+import android.annotation.NonNull;
 
 /**
  * A generalized interface that allows for generating shared secrets as well as encrypting
diff --git a/encryption-runner/src/android/car/encryptionrunner/EncryptionRunnerFactory.java b/encryption-runner/src/android/car/encryptionrunner/EncryptionRunnerFactory.java
index b479b50..d11ed4e 100644
--- a/encryption-runner/src/android/car/encryptionrunner/EncryptionRunnerFactory.java
+++ b/encryption-runner/src/android/car/encryptionrunner/EncryptionRunnerFactory.java
@@ -16,8 +16,9 @@
 
 package android.car.encryptionrunner;
 
-import androidx.annotation.IntDef;
-import androidx.annotation.VisibleForTesting;
+import android.annotation.IntDef;
+
+import com.android.internal.annotations.VisibleForTesting;
 
 /**
  * Factory that creates encryption runner.
@@ -28,12 +29,10 @@
         // prevent instantiation.
     }
 
-    @IntDef({EncryptionRunnerType.UKEY2, EncryptionRunnerType.OOB_UKEY2})
+    @IntDef({EncryptionRunnerType.UKEY2})
     public @interface EncryptionRunnerType {
         /** Use Ukey2 as underlying key exchange. */
         int UKEY2 = 0;
-        /** Use Ukey2 and an out of band channel as underlying key exchange. */
-        int OOB_UKEY2 = 1;
     }
 
     /**
@@ -43,8 +42,6 @@
         switch (type) {
             case EncryptionRunnerType.UKEY2:
                 return new Ukey2EncryptionRunner();
-            case EncryptionRunnerType.OOB_UKEY2:
-                return new OobUkey2EncryptionRunner();
             default:
                 throw new IllegalArgumentException("Unknown EncryptionRunnerType: " + type);
         }
@@ -65,16 +62,7 @@
      * for testing.
      */
     @VisibleForTesting
-    public static EncryptionRunner newFakeRunner() {
-        return new FakeEncryptionRunner();
-    }
-
-    /**
-     * Creates a new {@link EncryptionRunner} that doesn't actually do encryption but is useful
-     * for out of band association testing.
-     */
-    @VisibleForTesting
-    public static EncryptionRunner newOobFakeRunner() {
-        return new OobFakeEncryptionRunner();
+    public static EncryptionRunner newDummyRunner() {
+        return new DummyEncryptionRunner();
     }
 }
diff --git a/encryption-runner/src/android/car/encryptionrunner/FakeEncryptionRunner.java b/encryption-runner/src/android/car/encryptionrunner/FakeEncryptionRunner.java
deleted file mode 100644
index 5fd1ff2..0000000
--- a/encryption-runner/src/android/car/encryptionrunner/FakeEncryptionRunner.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.car.encryptionrunner;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * An encryption runner that doesn't actually do encryption. Useful for debugging. Do not use in
- * production environments.
- */
-@VisibleForTesting
-public class FakeEncryptionRunner implements EncryptionRunner {
-
-    private static final String KEY = "key";
-    private static final byte[] PLACEHOLDER_MESSAGE = "Placeholder Message".getBytes();
-    @VisibleForTesting
-    public static final String INIT = "init";
-    @VisibleForTesting
-    public static final String INIT_RESPONSE = "initResponse";
-    @VisibleForTesting
-    public static final String CLIENT_RESPONSE = "clientResponse";
-    public static final String VERIFICATION_CODE = "1234";
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({Mode.UNKNOWN, Mode.CLIENT, Mode.SERVER})
-    @interface Mode {
-
-        int UNKNOWN = 0;
-        int CLIENT = 1;
-        int SERVER = 2;
-    }
-
-    private boolean mIsReconnect;
-    private boolean mInitReconnectVerification;
-    private Key mCurrentFakeKey;
-    @Mode
-    private int mMode;
-    @HandshakeMessage.HandshakeState
-    private int mState;
-
-    @Override
-    public HandshakeMessage initHandshake() {
-        checkRunnerIsNew();
-        mMode = Mode.CLIENT;
-        mState = HandshakeMessage.HandshakeState.IN_PROGRESS;
-        return HandshakeMessage.newBuilder()
-                .setHandshakeState(mState)
-                .setNextMessage(INIT.getBytes())
-                .build();
-    }
-
-    @Override
-    public HandshakeMessage respondToInitRequest(byte[] initializationRequest)
-            throws HandshakeException {
-        checkRunnerIsNew();
-        mMode = Mode.SERVER;
-        if (!new String(initializationRequest).equals(INIT)) {
-            throw new HandshakeException("Unexpected initialization request");
-        }
-        mState = HandshakeMessage.HandshakeState.IN_PROGRESS;
-        return HandshakeMessage.newBuilder()
-                .setHandshakeState(HandshakeMessage.HandshakeState.IN_PROGRESS)
-                .setNextMessage(INIT_RESPONSE.getBytes())
-                .build();
-    }
-
-    @Mode
-    protected int getMode() {
-        return mMode;
-    }
-
-    @HandshakeMessage.HandshakeState
-    protected int getState() {
-        return mState;
-    }
-
-    protected void setState(@HandshakeMessage.HandshakeState int state) {
-        mState = state;
-    }
-
-    private void checkRunnerIsNew() {
-        if (mState != HandshakeMessage.HandshakeState.UNKNOWN) {
-            throw new IllegalStateException("runner already initialized.");
-        }
-    }
-
-    @Override
-    public HandshakeMessage continueHandshake(byte[] response) throws HandshakeException {
-        if (mState != HandshakeMessage.HandshakeState.IN_PROGRESS) {
-            throw new HandshakeException("not waiting for response but got one");
-        }
-        switch (mMode) {
-            case Mode.SERVER:
-                if (!CLIENT_RESPONSE.equals(new String(response))) {
-                    throw new HandshakeException("unexpected response: " + new String(response));
-                }
-                mState = HandshakeMessage.HandshakeState.VERIFICATION_NEEDED;
-                if (mIsReconnect) {
-                    verifyPin();
-                    mState = HandshakeMessage.HandshakeState.RESUMING_SESSION;
-                }
-                return HandshakeMessage.newBuilder()
-                        .setVerificationCode(VERIFICATION_CODE)
-                        .setHandshakeState(mState)
-                        .build();
-            case Mode.CLIENT:
-                if (!INIT_RESPONSE.equals(new String(response))) {
-                    throw new HandshakeException("unexpected response: " + new String(response));
-                }
-                mState = HandshakeMessage.HandshakeState.VERIFICATION_NEEDED;
-                if (mIsReconnect) {
-                    verifyPin();
-                    mState = HandshakeMessage.HandshakeState.RESUMING_SESSION;
-                }
-                return HandshakeMessage.newBuilder()
-                        .setHandshakeState(mState)
-                        .setNextMessage(CLIENT_RESPONSE.getBytes())
-                        .setVerificationCode(VERIFICATION_CODE)
-                        .build();
-            default:
-                throw new IllegalStateException("unexpected role: " + mMode);
-        }
-    }
-
-    @Override
-    public HandshakeMessage authenticateReconnection(byte[] message, byte[] previousKey)
-            throws HandshakeException {
-        mCurrentFakeKey = new FakeKey();
-        // Blindly verify the reconnection because this is a fake encryption runner.
-        return HandshakeMessage.newBuilder()
-                .setHandshakeState(HandshakeMessage.HandshakeState.FINISHED)
-                .setKey(mCurrentFakeKey)
-                .setNextMessage(mInitReconnectVerification ? null : PLACEHOLDER_MESSAGE)
-                .build();
-    }
-
-    @Override
-    public HandshakeMessage initReconnectAuthentication(byte[] previousKey)
-            throws HandshakeException {
-        mInitReconnectVerification = true;
-        mState = HandshakeMessage.HandshakeState.RESUMING_SESSION;
-        return HandshakeMessage.newBuilder()
-                .setHandshakeState(mState)
-                .setNextMessage(PLACEHOLDER_MESSAGE)
-                .build();
-    }
-
-    @Override
-    public Key keyOf(byte[] serialized) {
-        return new FakeKey();
-    }
-
-    @Override
-    public HandshakeMessage verifyPin() throws HandshakeException {
-        if (mState != HandshakeMessage.HandshakeState.VERIFICATION_NEEDED) {
-            throw new IllegalStateException("asking to verify pin, state = " + mState);
-        }
-        mState = HandshakeMessage.HandshakeState.FINISHED;
-        return HandshakeMessage.newBuilder().setKey(new FakeKey()).setHandshakeState(
-                mState).build();
-    }
-
-    @Override
-    public void invalidPin() {
-        mState = HandshakeMessage.HandshakeState.INVALID;
-    }
-
-    @Override
-    public void setIsReconnect(boolean isReconnect) {
-        mIsReconnect = isReconnect;
-    }
-
-    /** Method to throw a HandshakeException for testing. */
-    public static void throwHandshakeException(String message) throws HandshakeException {
-        throw new HandshakeException(message);
-    }
-
-    class FakeKey implements Key {
-        @Override
-        public byte[] asBytes() {
-            return KEY.getBytes();
-        }
-
-        @Override
-        public byte[] encryptData(byte[] data) {
-            return data;
-        }
-
-        @Override
-        public byte[] decryptData(byte[] encryptedData) {
-            return encryptedData;
-        }
-
-        @Override
-        public byte[] getUniqueSession() {
-            return KEY.getBytes();
-        }
-    }
-}
diff --git a/encryption-runner/src/android/car/encryptionrunner/HandshakeMessage.java b/encryption-runner/src/android/car/encryptionrunner/HandshakeMessage.java
index a79c64e..d7c9765 100644
--- a/encryption-runner/src/android/car/encryptionrunner/HandshakeMessage.java
+++ b/encryption-runner/src/android/car/encryptionrunner/HandshakeMessage.java
@@ -16,12 +16,11 @@
 
 package android.car.encryptionrunner;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.text.TextUtils;
 
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
diff --git a/encryption-runner/src/android/car/encryptionrunner/Key.java b/encryption-runner/src/android/car/encryptionrunner/Key.java
index e80be25..e13585f 100644
--- a/encryption-runner/src/android/car/encryptionrunner/Key.java
+++ b/encryption-runner/src/android/car/encryptionrunner/Key.java
@@ -16,7 +16,7 @@
 
 package android.car.encryptionrunner;
 
-import androidx.annotation.NonNull;
+import android.annotation.NonNull;
 
 import java.security.NoSuchAlgorithmException;
 import java.security.SignatureException;
diff --git a/encryption-runner/src/android/car/encryptionrunner/OobFakeEncryptionRunner.java b/encryption-runner/src/android/car/encryptionrunner/OobFakeEncryptionRunner.java
deleted file mode 100644
index 3ab17d2..0000000
--- a/encryption-runner/src/android/car/encryptionrunner/OobFakeEncryptionRunner.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.car.encryptionrunner;
-
-/**
- * An encryption runner that doesn't actually do encryption. Useful for debugging out of band
- * association. Do not use in production environments.
- */
-public class OobFakeEncryptionRunner extends FakeEncryptionRunner {
-
-    @Override
-    public HandshakeMessage continueHandshake(byte[] response) throws HandshakeException {
-        if (getState() != HandshakeMessage.HandshakeState.IN_PROGRESS) {
-            throw new HandshakeException("not waiting for response but got one");
-        }
-
-        @HandshakeMessage.HandshakeState int newState =
-                HandshakeMessage.HandshakeState.OOB_VERIFICATION_NEEDED;
-        switch (getMode()) {
-            case Mode.SERVER:
-                if (!CLIENT_RESPONSE.equals(new String(response))) {
-                    throw new HandshakeException("unexpected response: " + new String(response));
-                }
-                setState(newState);
-                return HandshakeMessage.newBuilder()
-                        .setOobVerificationCode(VERIFICATION_CODE.getBytes())
-                        .setHandshakeState(newState)
-                        .build();
-            case Mode.CLIENT:
-                if (!INIT_RESPONSE.equals(new String(response))) {
-                    throw new HandshakeException("unexpected response: " + new String(response));
-                }
-                setState(newState);
-                return HandshakeMessage.newBuilder()
-                        .setHandshakeState(newState)
-                        .setNextMessage(CLIENT_RESPONSE.getBytes())
-                        .setOobVerificationCode(VERIFICATION_CODE.getBytes())
-                        .build();
-            default:
-                throw new IllegalStateException("unexpected role: " + getMode());
-        }
-    }
-
-    @Override
-    public HandshakeMessage verifyPin() throws HandshakeException {
-        @HandshakeMessage.HandshakeState int state = getState();
-        if (state != HandshakeMessage.HandshakeState.OOB_VERIFICATION_NEEDED) {
-            throw new IllegalStateException("asking to verify pin, state = " + state);
-        }
-        state = HandshakeMessage.HandshakeState.FINISHED;
-        return HandshakeMessage.newBuilder().setKey(new FakeKey()).setHandshakeState(
-                state).build();
-    }
-}
diff --git a/encryption-runner/src/android/car/encryptionrunner/OobUkey2EncryptionRunner.java b/encryption-runner/src/android/car/encryptionrunner/OobUkey2EncryptionRunner.java
deleted file mode 100644
index 9474bd4..0000000
--- a/encryption-runner/src/android/car/encryptionrunner/OobUkey2EncryptionRunner.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.car.encryptionrunner;
-
-import com.google.security.cryptauth.lib.securegcm.Ukey2Handshake;
-
-/**
- * An {@link EncryptionRunner} that uses Ukey2 as the underlying implementation, and generates a
- * longer token for the out of band verification step.
- *
- * <p>To use this class:
- *
- * <p>1. As a client.
- *
- * <p>{@code
- * HandshakeMessage initialClientMessage = clientRunner.initHandshake();
- * sendToServer(initialClientMessage.getNextMessage());
- * byte message = getServerResponse();
- * HandshakeMessage message = clientRunner.continueHandshake(message);
- * }
- *
- * <p>If it is a first-time connection,
- *
- * <p>{@code message.getHandshakeState()} should be OOB_VERIFICATION_NEEDED. Wait for an encrypted
- * message sent from the server, and decrypt that message with an out of band key that was generated
- * before the start of the handshake.
- *
- * <p>After confirming that the decrypted message matches the verification code, send an encrypted
- * message back to the server, and call {@code HandshakeMessage lastMessage =
- * clientRunner.verifyPin();} otherwise {@code clientRunner.invalidPin(); }
- *
- * <p>Use {@code lastMessage.getKey()} to get the key for encryption.
- *
- * <p>If it is a reconnection,
- *
- * <p>{@code message.getHandshakeState()} should be RESUMING_SESSION, PIN has been verified blindly,
- * send the authentication message over to server, then authenticate the message from server.
- *
- * <p>{@code
- * clientMessage = clientRunner.initReconnectAuthentication(previousKey)
- * sendToServer(clientMessage.getNextMessage());
- * HandshakeMessage lastMessage = clientRunner.authenticateReconnection(previousKey, message)
- * }
- *
- * <p>{@code lastMessage.getHandshakeState()} should be FINISHED if reconnection handshake is done.
- *
- * <p>2. As a server.
- *
- * <p>{@code
- * byte[] initialMessage = getClientMessageBytes();
- * HandshakeMessage message = serverRunner.respondToInitRequest(initialMessage);
- * sendToClient(message.getNextMessage());
- * byte[] clientMessage = getClientResponse();
- * HandshakeMessage message = serverRunner.continueHandshake(clientMessage);}
- *
- * <p>if it is a first-time connection,
- *
- * <p>{@code message.getHandshakeState()} should be OOB_VERIFICATION_NEEDED, send the verification
- * code to the client, encrypted using an out of band key generated before the start of the
- * handshake, and wait for a response from the client.
- * If the decrypted message from the client matches the verification code, call {@code
- * HandshakeMessage lastMessage = serverRunner.verifyPin}, otherwise
- * {@code clientRunner.invalidPin(); }
- * Use {@code lastMessage.getKey()} to get the key for encryption.
- *
- * <p>If it is a reconnection,
- *
- * <p>{@code message.getHandshakeState()} should be RESUMING_SESSION,PIN has been verified blindly,
- * waiting for client message.
- * After client message been received,
- * {@code serverMessage = serverRunner.authenticateReconnection(previousKey, message);
- * sendToClient(serverMessage.getNextMessage());}
- * {@code serverMessage.getHandshakeState()} should be FINISHED if reconnection handshake is done.
- *
- * <p>Also see {@link EncryptionRunnerTest} for examples.
- */
-public final class OobUkey2EncryptionRunner extends Ukey2EncryptionRunner {
-    // Choose max verification string length supported by Ukey2
-    private static final int VERIFICATION_STRING_LENGTH = 32;
-
-    @Override
-    public HandshakeMessage continueHandshake(byte[] response) throws HandshakeException {
-        checkInitialized();
-
-        Ukey2Handshake uKey2Client = getUkey2Client();
-
-        try {
-            if (uKey2Client.getHandshakeState() != Ukey2Handshake.State.IN_PROGRESS) {
-                throw new IllegalStateException(
-                        "handshake is not in progress, state =" + uKey2Client.getHandshakeState());
-            }
-            uKey2Client.parseHandshakeMessage(response);
-
-            // Not obvious from ukey2 api, but getting the next message can change the state.
-            // calling getNext message might go from in progress to verification needed, on
-            // the assumption that we already send this message to the peer.
-            byte[] nextMessage = null;
-            if (uKey2Client.getHandshakeState() == Ukey2Handshake.State.IN_PROGRESS) {
-                nextMessage = uKey2Client.getNextHandshakeMessage();
-            }
-
-            byte[] verificationCode = null;
-            if (uKey2Client.getHandshakeState() == Ukey2Handshake.State.VERIFICATION_NEEDED) {
-                // getVerificationString() needs to be called before notifyPinVerified().
-                verificationCode = uKey2Client.getVerificationString(VERIFICATION_STRING_LENGTH);
-                if (isReconnect()) {
-                    HandshakeMessage handshakeMessage = verifyPin();
-                    return HandshakeMessage.newBuilder()
-                            .setHandshakeState(handshakeMessage.getHandshakeState())
-                            .setNextMessage(nextMessage)
-                            .build();
-                }
-            }
-
-            return HandshakeMessage.newBuilder()
-                    .setHandshakeState(HandshakeMessage.HandshakeState.OOB_VERIFICATION_NEEDED)
-                    .setNextMessage(nextMessage)
-                    .setOobVerificationCode(verificationCode)
-                    .build();
-        } catch (com.google.security.cryptauth.lib.securegcm.HandshakeException
-                | Ukey2Handshake.AlertException e) {
-            throw new HandshakeException(e);
-        }
-    }
-}
diff --git a/encryption-runner/src/android/car/encryptionrunner/Ukey2EncryptionRunner.java b/encryption-runner/src/android/car/encryptionrunner/Ukey2EncryptionRunner.java
index ac1bf91..f4ee5a7 100644
--- a/encryption-runner/src/android/car/encryptionrunner/Ukey2EncryptionRunner.java
+++ b/encryption-runner/src/android/car/encryptionrunner/Ukey2EncryptionRunner.java
@@ -16,12 +16,12 @@
 
 package android.car.encryptionrunner;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.util.Log;
 
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
+import com.android.internal.annotations.VisibleForTesting;
 
 import com.google.security.cryptauth.lib.securegcm.D2DConnectionContext;
 import com.google.security.cryptauth.lib.securegcm.Ukey2Handshake;
diff --git a/resource_generator.py b/resource_generator.py
new file mode 100755
index 0000000..290fa10
--- /dev/null
+++ b/resource_generator.py
@@ -0,0 +1,287 @@
+#!/usr/bin/python3
+
+##
+# A good background read on how Android handles alternative resources is here:
+# https://developer.android.com/guide/topics/resources/providing-resources.html
+#
+# This uses lxml so you may need to install it manually if your distribution
+# does not ordinarily ship with it. On Ubuntu, you can run:
+#
+# sudo apt-get install python-lxml
+#
+# Example invocation:
+# ./resource_generator.py --csv specs/keylines.csv --resdir car-stream-ui-lib/res --type dimens
+##
+
+import argparse
+import csv
+import datetime
+import os
+import pprint
+
+import lxml.etree as et
+
+DBG = False
+
+class ResourceGenerator:
+    def __init__(self):
+        self.COLORS = "colors"
+        self.DIMENS = "dimens"
+
+        self.TAG_DIMEN = "dimen"
+
+        self.resource_handlers = {
+            self.COLORS : self.HandleColors,
+            self.DIMENS : self.HandleDimens,
+        }
+
+        self.ENCODING = "utf-8"
+        self.XML_HEADER = '<?xml version="1.0" encoding="%s"?>' % self.ENCODING
+        # The indentation looks off but it needs to be otherwise the indentation will end up in the
+        # string itself, which we don't want. So much for pythons indentation policy.
+        self.AOSP_HEADER = """
+<!-- Copyright (C) %d 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.
+-->
+""" % datetime.datetime.now().year
+        self.EMPTY_XML = "<resources/>"
+
+
+    def HandleColors(self, reader, resource_dir):
+        raise Exception("Not yet implemented")
+
+
+    ##
+    # Validate the header row of the csv. Getting this wrong would mean that the resources wouldn't
+    # actually work, so find any mistakes ahead of time.
+    ##
+    def ValidateHeader(self, header):
+        # TODO: Validate the header values based on the ordering of modifiers in table 2.
+        pass
+
+
+    ##
+    # Given a list of resource modifers, create the appropriate directories and xml files for
+    # them to be populated in.
+    # Returns a tuple of maps of the form  ({ modifier : xml file } , { modifier : xml object })
+    ##
+    def CreateOrOpenResourceFiles(self, resource_dir, resource_type, modifiers):
+        filenames = { }
+        xmltrees = { }
+        dir_prefix = "values"
+        qualifier_separator = "-"
+        file_extension = ".xml"
+        for modifier in modifiers:
+            # We're using the keyword none to specify that there are no modifiers and so the
+            # values specified here goes into the default file.
+            directory = resource_dir + os.path.sep + dir_prefix
+            if modifier != "none":
+                directory = directory + qualifier_separator + modifier
+
+            if not os.path.exists(directory):
+                if DBG:
+                    print("Creating directory %s" % directory)
+                os.mkdir(directory)
+
+            filename = directory + os.path.sep + resource_type + file_extension
+            if not os.path.exists(filename):
+                if DBG:
+                    print("Creating file %s" % filename)
+                with open(filename, "w") as xmlfile:
+                    xmlfile.write(self.XML_HEADER)
+                    xmlfile.write(self.AOSP_HEADER)
+                    xmlfile.write(self.EMPTY_XML)
+
+            filenames[modifier] = filename
+            if DBG:
+                print("Parsing %s" % (filename))
+            parser = et.XMLParser(remove_blank_text=True)
+            xmltrees[modifier] = et.parse(filename, parser)
+        return filenames, xmltrees
+
+
+    ##
+    # Updates a resource value in the xmltree if it exists, adds it in if not.
+    ##
+    def AddOrUpdateValue(self, xmltree, tag, resource_name, resource_value):
+        root = xmltree.getroot()
+        found = False
+        resource_node = None
+        attr_name = "name"
+        # Look for the value that we want.
+        for elem in root:
+            if elem.tag == tag and elem.attrib[attr_name] == resource_name:
+                resource_node = elem
+                found = True
+                break
+        # If it doesn't exist yet, create one.
+        if not found:
+            resource_node = et.SubElement(root, tag)
+            resource_node.attrib[attr_name] = resource_name
+        # Update the value.
+        resource_node.text = resource_value
+
+
+    ##
+    # lxml formats xml with 2 space indentation. Android convention says 4 spaces. Multiply any
+    # leading spaces by 2 and re-generate the string.
+    ##
+    def FixupIndentation(self, xml_string):
+        reformatted_xml = ""
+        for line in xml_string.splitlines():
+            stripped = line.lstrip()
+            # Special case for multiline comments. These usually are hand aligned with something
+            # so we don't want to reformat those.
+            if not stripped.startswith("<"):
+                leading_spaces = 0
+            else:
+                leading_spaces = len(line) - len(stripped)
+            reformatted_xml += " " * leading_spaces + line + os.linesep
+        return reformatted_xml
+
+
+    ##
+    # Read all the lines that appear before the <resources.*> tag so that they can be replicated
+    # while writing out the file again. We can't simply re-generate the aosp header because it's
+    # apparently not a good thing to change the date on a copyright notice to something more
+    # recent.
+    # Returns a string of the lines that appear before the resources tag.
+    ##
+    def ReadStartingLines(self, filename):
+        with open(filename) as f:
+            starting_lines = ""
+            for line in f.readlines():
+                # Yes, this will fail if you start a line inside a comment with <resources>.
+                # It's more work than it's worth to handle that case.
+                if line.lstrip().startswith("<resources"):
+                    break;
+                starting_lines += line
+        return starting_lines
+
+    ##
+    # Take a map of resources and a directory and update the xml files within it with the new
+    # values. Will create any directories and files as necessary.
+    ##
+    def ModifyXml(self, resources, resource_type, resource_dir, tag):
+        # Create a deduplicated list of the resource modifiers that we will need.
+        modifiers = set()
+        for resource_values in resources.values():
+            for modifier in resource_values.keys():
+                modifiers.add(modifier)
+        if DBG:
+            pp = pprint.PrettyPrinter()
+            pp.pprint(modifiers)
+            pp.pprint(resources)
+
+        # Update each of the trees with their respective values.
+        filenames, xmltrees = self.CreateOrOpenResourceFiles(resource_dir, resource_type, modifiers)
+        for resource_name, resource_values in resources.items():
+            if DBG:
+                print(resource_name)
+                print(resource_values)
+            for modifier, value in resource_values.items():
+                xmltree = xmltrees[modifier]
+                self.AddOrUpdateValue(xmltree, tag, resource_name, value)
+
+        # Finally write out all the trees.
+        for modifier, xmltree in xmltrees.items():
+            if DBG:
+                print("Writing out %s" % filenames[modifier])
+            # ElementTree.write() doesn't allow us to place the aosp header at the top
+            # of the file so bounce it through a string.
+            starting_lines = self.ReadStartingLines(filenames[modifier])
+            with open(filenames[modifier], "wt", encoding=self.ENCODING) as xmlfile:
+                xml = et.tostring(xmltree.getroot(), pretty_print=True).decode("utf-8")
+                formatted_xml = self.FixupIndentation(xml)
+                if DBG:
+                    print(formatted_xml)
+                xmlfile.write(starting_lines)
+                xmlfile.write(formatted_xml)
+
+
+    ##
+    # Read in a csv file that contains dimensions and update the resources, creating any necessary
+    # files and directories along the way.
+    ##
+    def HandleDimens(self, reader, resource_dir):
+        read_header = False
+        header = []
+        resources = { }
+        # Create nested maps of the form { resource_name : { modifier : value } }
+        for row in reader:
+            # Skip any empty lines.
+            if len(row) == 0:
+                continue
+
+            trimmed = [cell.strip() for cell in row]
+            # Skip any comment lines.
+            if trimmed[0].startswith("#"):
+                continue
+
+            # Store away the header row. We'll need it later to create and/or modify the xml files.
+            if not read_header:
+                self.ValidateHeader(trimmed)  # Will raise if it fails.
+                header = trimmed
+                read_header = True
+                continue
+
+            if (len(trimmed) != len(header)):
+                raise ValueError("Missing commas in csv file!")
+
+            var_name = trimmed[0]
+            var_values = { }
+            for idx in range(1, len(trimmed)):
+                cell = trimmed[idx]
+                # Only deal with cells that actually have content in them.
+                if len(cell) > 0:
+                    var_values[header[idx]] = cell
+
+            if len(var_values.keys()) > 0:
+                resources[var_name] = var_values
+
+        self.ModifyXml(resources, self.DIMENS, resource_dir, self.TAG_DIMEN)
+
+
+    ##
+    # Validate the command line arguments that we have been passed. Will raise an exception if
+    # there are any invalid arguments.
+    ##
+    def ValidateArgs(self, csv, resource_dir, resource_type):
+        if not os.path.isfile(csv):
+            raise ValueError("%s is not a valid path" % csv)
+        if not os.path.isdir(resource_dir):
+            raise ValueError("%s is not a valid resource directory" % resource_dir)
+        if not resource_type in self.resource_handlers:
+            raise ValueError("%s is not a supported resource type" % resource_type)
+
+
+    ##
+    # The logical entry point of this application.
+    ##
+    def Main(self, csv_file, resource_dir, resource_type):
+        self.ValidateArgs(csv_file, resource_dir, resource_type)  # Will raise if it fails.
+        with open(csv_file, 'r') as handle:
+            reader = csv.reader(handle)  # Defaults to the excel dialect of csv.
+            self.resource_handlers[resource_type](reader, resource_dir)
+        print("Done!")
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Convert a CSV into android resources')
+    parser.add_argument('--csv', action='store', dest='csv')
+    parser.add_argument('--resdir', action='store', dest='resdir')
+    parser.add_argument('--type', action='store', dest='type')
+    args = parser.parse_args()
+    app = ResourceGenerator()
+    app.Main(args.csv, args.resdir, args.type)