[automerger skipped] Merge "Import translations. DO NOT MERGE ANYWHERE" into stage-aosp-master am: 529855066b -s ours

am skip reason: subject contains skip directive

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Car/libs/+/13164974

Change-Id: I15a58488a5386807bad4238b4e33d906f401c187
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 2c6e1f2..09bd38a 100644
--- a/car-apps-common/res/drawable/control_bar_button_background.xml
+++ b/car-apps-common/res/drawable/control_bar_button_background.xml
@@ -17,6 +17,15 @@
   ~
  -->
 <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"/>
diff --git a/car-apps-common/res/drawable/hero_button_background.xml b/car-apps-common/res/drawable/hero_button_background.xml
index e036f4a..e5aeec5 100644
--- a/car-apps-common/res/drawable/hero_button_background.xml
+++ b/car-apps-common/res/drawable/hero_button_background.xml
@@ -14,6 +14,14 @@
 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"/>
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 88d4dae..4181867 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,6 +16,8 @@
 
 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;
@@ -29,6 +31,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.widget.FrameLayout;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
@@ -90,6 +93,10 @@
     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;
@@ -160,6 +167,15 @@
         mDefaultExpandCollapseView.setContentDescription(context.getString(
                 R.string.control_bar_expand_collapse_button));
         mDefaultExpandCollapseView.setOnClickListener(v -> onExpandCollapse());
+
+        // Collapse the control bar when it is expanded and loses focus.
+        getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) -> {
+            boolean hasFocus = hasFocus();
+            if (mHasFocus && !hasFocus && mIsExpanded) {
+                onExpandCollapse();
+            }
+            mHasFocus = hasFocus;
+        });
     }
 
     private int getSlotIndex(@SlotPosition int slotPosition) {
@@ -310,12 +326,34 @@
                 .addTransition(new Fade())
                 .setDuration(animationDuration)
                 .setInterpolator(new FastOutSlowInInterpolator());
-        TransitionManager.beginDelayedTransition(this, set);
+        maybeInitTransitionRoot();
+        TransitionManager.beginDelayedTransition(mTransitionRoot, 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-assist-client-lib/res/values-iw/strings.xml b/car-assist-client-lib/res/values-iw/strings.xml
index dc96640..510432d 100644
--- a/car-assist-client-lib/res/values-iw/strings.xml
+++ b/car-assist-client-lib/res/values-iw/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">"לא ניתן לבקש מה-Assistant לבצע פעולה!"</string>
     <string name="says" msgid="8575666015622916107">"רוצה להודיע כי"</string>
 </resources>
diff --git a/car-broadcastradio-support/res/values-bs/strings.xml b/car-broadcastradio-support/res/values-bs/strings.xml
index e29e90e..42ff388 100644
--- a/car-broadcastradio-support/res/values-bs/strings.xml
+++ b/car-broadcastradio-support/res/values-bs/strings.xml
@@ -20,5 +20,5 @@
     <string name="radio_fm_text" msgid="1973045042281933494">"FM"</string>
     <string name="radio_dab_text" msgid="8456449462266648979">"DAB"</string>
     <string name="program_list_text" msgid="4414150317304422313">"Stanice"</string>
-    <string name="favorites_list_text" msgid="7829827713977109155">"Omiljeno"</string>
+    <string name="favorites_list_text" msgid="7829827713977109155">"Omiljeni"</string>
 </resources>
diff --git a/car-broadcastradio-support/res/values-is/strings.xml b/car-broadcastradio-support/res/values-is/strings.xml
index b7e9135..1a2074a 100644
--- a/car-broadcastradio-support/res/values-is/strings.xml
+++ b/car-broadcastradio-support/res/values-is/strings.xml
@@ -20,5 +20,5 @@
     <string name="radio_fm_text" msgid="1973045042281933494">"FM"</string>
     <string name="radio_dab_text" msgid="8456449462266648979">"DAB"</string>
     <string name="program_list_text" msgid="4414150317304422313">"Stöðvar"</string>
-    <string name="favorites_list_text" msgid="7829827713977109155">"Uppáhald"</string>
+    <string name="favorites_list_text" msgid="7829827713977109155">"Eftirlæti"</string>
 </resources>
diff --git a/car-broadcastradio-support/res/values-ky/strings.xml b/car-broadcastradio-support/res/values-ky/strings.xml
index ee67f46..4640491 100644
--- a/car-broadcastradio-support/res/values-ky/strings.xml
+++ b/car-broadcastradio-support/res/values-ky/strings.xml
@@ -20,5 +20,5 @@
     <string name="radio_fm_text" msgid="1973045042281933494">"FM"</string>
     <string name="radio_dab_text" msgid="8456449462266648979">"DAB"</string>
     <string name="program_list_text" msgid="4414150317304422313">"Станциялар"</string>
-    <string name="favorites_list_text" msgid="7829827713977109155">"Тандалмалар"</string>
+    <string name="favorites_list_text" msgid="7829827713977109155">"Сүйүктүүлөр"</string>
 </resources>
diff --git a/car-broadcastradio-support/res/values-uz/strings.xml b/car-broadcastradio-support/res/values-uz/strings.xml
index bfb89d7..5ff7a60 100644
--- a/car-broadcastradio-support/res/values-uz/strings.xml
+++ b/car-broadcastradio-support/res/values-uz/strings.xml
@@ -20,5 +20,5 @@
     <string name="radio_fm_text" msgid="1973045042281933494">"FM"</string>
     <string name="radio_dab_text" msgid="8456449462266648979">"Raqamli radio"</string>
     <string name="program_list_text" msgid="4414150317304422313">"Radiostansiyalar"</string>
-    <string name="favorites_list_text" msgid="7829827713977109155">"Saralangan"</string>
+    <string name="favorites_list_text" msgid="7829827713977109155">"Saralanganlar"</string>
 </resources>
diff --git a/car-media-common/res/drawable/fab_empty_foreground.xml b/car-media-common/res/drawable/fab_empty_foreground.xml
deleted file mode 100644
index d9fb901..0000000
--- a/car-media-common/res/drawable/fab_empty_foreground.xml
+++ /dev/null
@@ -1,20 +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.
--->
-<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/layout/minimized_play_pause_stop_button_layout.xml b/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml
index 38389b0..1d70c72 100644
--- 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
@@ -20,11 +20,9 @@
     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/play_pause_stop_button_layout.xml b/car-media-common/res/layout/play_pause_stop_button_layout.xml
index f7700fe..f61a821 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,11 +20,9 @@
     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/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 4f1df52..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">"Reproduciranje tog sadržaja je već u toku"</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 b5894cb..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">"Damit du diese App verwenden kannst, musst du dich zuerst anmelden"</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 48d6213..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 cola"</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 eb784b4..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">"Un accès payant est 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 0225852..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 5eed37d..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 2a295f8..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 usar 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 3bcb08d..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. Încercați din nou."</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 1b50b13..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/src/com/android/car/media/common/ControlBarHelper.java b/car-media-common/src/com/android/car/media/common/ControlBarHelper.java
index 0f011fd..4e3b7b9 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.setProgress((int) progress.getProgress());
                     progressBar.setMax((int) progress.getMaxProgress());
+                    progressBar.setProgress((int) progress.getProgress());
                 });
     }
 }
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 68ed3aa..c52cc56 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
@@ -373,9 +373,9 @@
     public static String constructGroupConversationHeader(String senderName, String groupName,
             String delimiter, BidiFormatter bidiFormatter) {
         String formattedSenderName = bidiFormatter.unicodeWrap(senderName,
-                TextDirectionHeuristics.FIRSTSTRONG_LTR);
+                TextDirectionHeuristics.FIRSTSTRONG_LTR, /* isolate= */ true);
         String formattedGroupName = bidiFormatter.unicodeWrap(groupName,
-                TextDirectionHeuristics.LOCALE);
+                TextDirectionHeuristics.FIRSTSTRONG_LTR, /* isolate= */ true);
         String title = String.join(delimiter, formattedSenderName, formattedGroupName);
         return bidiFormatter.unicodeWrap(title, TextDirectionHeuristics.LOCALE);
     }
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
index acdffbd..c64703a 100644
--- 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
@@ -200,4 +200,17 @@
 
         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/res/values-af/strings.xml b/car-telephony-common/res/values-af/strings.xml
index 56aebcf..7e19555 100644
--- a/car-telephony-common/res/values-af/strings.xml
+++ b/car-telephony-common/res/values-af/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Koppel tans …"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Bel tans …"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Hou aan"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Oproep beëindig"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Hou aan"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Oproep beëindig"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Gekoppel"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Lui tans …"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Ontkoppel tans …"</string>
diff --git a/car-telephony-common/res/values-am/strings.xml b/car-telephony-common/res/values-am/strings.xml
index 2714928..6d0315e 100644
--- a/car-telephony-common/res/values-am/strings.xml
+++ b/car-telephony-common/res/values-am/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"በመገናኘት ላይ…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"በመደወል ላይ"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ያዝና ቆይ"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"ጥሪ አብቅቷል"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ያዝናቆይ"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"ጥሪ አብቅቷል"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"ተገናኝቷል"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"በመጥራት ላይ…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"ግንኝነትን በማቋረጥ ላይ…"</string>
diff --git a/car-telephony-common/res/values-ar/strings.xml b/car-telephony-common/res/values-ar/strings.xml
index aa5ceca..fcc72fb 100644
--- a/car-telephony-common/res/values-ar/strings.xml
+++ b/car-telephony-common/res/values-ar/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"جارٍ الاتصال…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"جارٍ طلب الرقم…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"قيد الانتظار"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"تم إنهاء المكالمة"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"قيد الانتظار"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"انتهت المكالمة"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"متّصل"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"جارٍ إطلاق الرنين…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"جارٍ قطع الاتصال…"</string>
diff --git a/car-telephony-common/res/values-as/strings.xml b/car-telephony-common/res/values-as/strings.xml
index c2d94c4..a4c90ae 100644
--- a/car-telephony-common/res/values-as/strings.xml
+++ b/car-telephony-common/res/values-as/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"সংযোগ কৰি থকা হৈছে…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ডায়েল কৰি থকা হৈছে…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"হ’ল্ডত আছে"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"কলটো সমাপ্ত হ’ল"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"হ’ল্ডত আছে"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"কল শেষ হৈছে"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"সংযোগ কৰা হ’ল"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"ৰিং কৰি আছে…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"সংযোগ ছেদ হৈ আছে…"</string>
diff --git a/car-telephony-common/res/values-az/strings.xml b/car-telephony-common/res/values-az/strings.xml
index 6882db1..d29aeab 100644
--- a/car-telephony-common/res/values-az/strings.xml
+++ b/car-telephony-common/res/values-az/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Qoşulur…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Nömrə yığılır…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Xətdə"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Zəng bitdi"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Gözləmədə"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Zəng sona çatdı"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Qoşuldu"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Zəng çalır…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Bağlantı kəsilir…"</string>
diff --git a/car-telephony-common/res/values-b+sr+Latn/strings.xml b/car-telephony-common/res/values-b+sr+Latn/strings.xml
index 04dcbbe..d05ef72 100644
--- a/car-telephony-common/res/values-b+sr+Latn/strings.xml
+++ b/car-telephony-common/res/values-b+sr+Latn/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Povezuje se…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Poziva se…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Na čekanju"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Poziv je završen"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Na čekanju"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Poziv je završen"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Povezan"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Zvoni…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Prekida se veza…"</string>
diff --git a/car-telephony-common/res/values-be/strings.xml b/car-telephony-common/res/values-be/strings.xml
index 49e9f44..1e1bcdf 100644
--- a/car-telephony-common/res/values-be/strings.xml
+++ b/car-telephony-common/res/values-be/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Ідзе падключэнне…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Ідзе набор нумара…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"На ўтрыманні"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Выклік завершаны"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"На ўтрыманні"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Выклік скончаны"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Падключана"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ідзе празвон…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Ідзе адключэнне…"</string>
diff --git a/car-telephony-common/res/values-bg/strings.xml b/car-telephony-common/res/values-bg/strings.xml
index 99d16bd..1f38d61 100644
--- a/car-telephony-common/res/values-bg/strings.xml
+++ b/car-telephony-common/res/values-bg/strings.xml
@@ -20,9 +20,9 @@
     <string name="voicemail" msgid="2125552157407909509">"Гласова поща"</string>
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Свързва се…"</string>
-    <string name="call_state_dialing" msgid="1534599871716648114">"Набиране…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Задържане на обаждането"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Обаждането завърши"</string>
+    <string name="call_state_dialing" msgid="1534599871716648114">"Набира се…"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Задържано"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Обаждането завърши"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Установена е връзка"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Звъни се…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Връзката се прекр…"</string>
diff --git a/car-telephony-common/res/values-bn/strings.xml b/car-telephony-common/res/values-bn/strings.xml
index 65f38ef..4855b6e 100644
--- a/car-telephony-common/res/values-bn/strings.xml
+++ b/car-telephony-common/res/values-bn/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"কানেক্ট হচ্ছে…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ডায়াল করা হচ্ছে…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"হোল্ডে রয়েছে"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"কল শেষ হয়েছে"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"হোল্ডে আছে"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"কল শেষ হয়েছে"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"কানেক্ট করা হয়েছে"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"রিং হচ্ছে…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"ডিসকানেক্ট করা হচ্ছে…"</string>
diff --git a/car-telephony-common/res/values-bs/strings.xml b/car-telephony-common/res/values-bs/strings.xml
index fbfb012..1d6a8b8 100644
--- a/car-telephony-common/res/values-bs/strings.xml
+++ b/car-telephony-common/res/values-bs/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Povezivanje…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Biranje…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Na čekanju"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Poziv je završen"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Na čekanju"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Poziv je završen"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Povezan"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Zvoni…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Prekidanje veze…"</string>
diff --git a/car-telephony-common/res/values-ca/strings.xml b/car-telephony-common/res/values-ca/strings.xml
index 1ff8957..356f31c 100644
--- a/car-telephony-common/res/values-ca/strings.xml
+++ b/car-telephony-common/res/values-ca/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"S\'està connectant…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"S\'està marcant…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"En espera"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Trucada finalitzada"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"En espera"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Trucada finalitzada"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Connectat"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Està sonant…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"S\'està desconnectant…"</string>
diff --git a/car-telephony-common/res/values-cs/strings.xml b/car-telephony-common/res/values-cs/strings.xml
index 7b6e1d7..41a29b5 100644
--- a/car-telephony-common/res/values-cs/strings.xml
+++ b/car-telephony-common/res/values-cs/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Připojování…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Vytáčení…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Přidržený hovor"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Hovor byl ukončen"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Podrženo"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Hovor byl ukončen"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Připojeno"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Vyzvánění…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Odpojování…"</string>
diff --git a/car-telephony-common/res/values-da/strings.xml b/car-telephony-common/res/values-da/strings.xml
index c1507fe..dcd52a0 100644
--- a/car-telephony-common/res/values-da/strings.xml
+++ b/car-telephony-common/res/values-da/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Tilslutter…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Ringer op…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"På hold"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Opkaldet er slut"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Afventer"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Opkaldet er slut"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Der er forbindelse"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ringer…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Afbryder…"</string>
diff --git a/car-telephony-common/res/values-de/strings.xml b/car-telephony-common/res/values-de/strings.xml
index 131fc08..a5257d3 100644
--- a/car-telephony-common/res/values-de/strings.xml
+++ b/car-telephony-common/res/values-de/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Verbinden…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Rufaufbau…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Anruf wird gehalten"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Anruf beendet"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Warten"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Anruf beendet"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Verbunden"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Klingelt…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Verbindung wird getrennt…"</string>
diff --git a/car-telephony-common/res/values-el/strings.xml b/car-telephony-common/res/values-el/strings.xml
index 6392460..40d1716 100644
--- a/car-telephony-common/res/values-el/strings.xml
+++ b/car-telephony-common/res/values-el/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Σύνδεση…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Κλήση…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Σε αναμονή"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Η κλήση τερματίστηκε"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Σε αναμονή"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Η κλήση τερματίστηκε"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Συνδέθηκε"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Κλήση…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Αποσύνδεση…"</string>
diff --git a/car-telephony-common/res/values-en-rAU/strings.xml b/car-telephony-common/res/values-en-rAU/strings.xml
index cc8a536..06d1973 100644
--- a/car-telephony-common/res/values-en-rAU/strings.xml
+++ b/car-telephony-common/res/values-en-rAU/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Connecting…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Dialling…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"On hold"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Call ended"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"On Hold"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Call Ended"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Connected"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ringing…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Disconnecting…"</string>
diff --git a/car-telephony-common/res/values-en-rCA/strings.xml b/car-telephony-common/res/values-en-rCA/strings.xml
index cc8a536..06d1973 100644
--- a/car-telephony-common/res/values-en-rCA/strings.xml
+++ b/car-telephony-common/res/values-en-rCA/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Connecting…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Dialling…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"On hold"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Call ended"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"On Hold"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Call Ended"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Connected"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ringing…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Disconnecting…"</string>
diff --git a/car-telephony-common/res/values-en-rGB/strings.xml b/car-telephony-common/res/values-en-rGB/strings.xml
index cc8a536..06d1973 100644
--- a/car-telephony-common/res/values-en-rGB/strings.xml
+++ b/car-telephony-common/res/values-en-rGB/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Connecting…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Dialling…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"On hold"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Call ended"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"On Hold"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Call Ended"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Connected"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ringing…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Disconnecting…"</string>
diff --git a/car-telephony-common/res/values-en-rIN/strings.xml b/car-telephony-common/res/values-en-rIN/strings.xml
index cc8a536..06d1973 100644
--- a/car-telephony-common/res/values-en-rIN/strings.xml
+++ b/car-telephony-common/res/values-en-rIN/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Connecting…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Dialling…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"On hold"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Call ended"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"On Hold"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Call Ended"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Connected"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ringing…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Disconnecting…"</string>
diff --git a/car-telephony-common/res/values-en-rXC/strings.xml b/car-telephony-common/res/values-en-rXC/strings.xml
index 43e60e9..b80f8fa 100644
--- a/car-telephony-common/res/values-en-rXC/strings.xml
+++ b/car-telephony-common/res/values-en-rXC/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎  ·  ‎‏‎‎‏‏‎<xliff:g id="DURATION">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎Connecting…‎‏‎‎‏‎"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎Dialing…‎‏‎‎‏‎"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎On hold‎‏‎‎‏‎"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‎‎Call ended‎‏‎‎‏‎"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎On Hold‎‏‎‎‏‎"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‎Call Ended‎‏‎‎‏‎"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎Connected‎‏‎‎‏‎"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎Ringing…‎‏‎‎‏‎"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‏‏‏‏‎‏‏‏‎Disconnecting…‎‏‎‎‏‎"</string>
diff --git a/car-telephony-common/res/values-es-rUS/strings.xml b/car-telephony-common/res/values-es-rUS/strings.xml
index 12fb629..2e71140 100644
--- a/car-telephony-common/res/values-es-rUS/strings.xml
+++ b/car-telephony-common/res/values-es-rUS/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Conectando…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Marcando…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"En espera"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Llamada finalizada"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"En espera"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Llamada finalizada"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Conectado"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Sonando…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Desconectando…"</string>
diff --git a/car-telephony-common/res/values-es/strings.xml b/car-telephony-common/res/values-es/strings.xml
index 6cff2e2..390354f 100644
--- a/car-telephony-common/res/values-es/strings.xml
+++ b/car-telephony-common/res/values-es/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Conectando…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Marcando…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"En espera"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Llamada finalizada"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"En espera"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Llamada finalizada"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Conectado"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Sonando…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Desconectando…"</string>
diff --git a/car-telephony-common/res/values-et/strings.xml b/car-telephony-common/res/values-et/strings.xml
index 9926364..ee65909 100644
--- a/car-telephony-common/res/values-et/strings.xml
+++ b/car-telephony-common/res/values-et/strings.xml
@@ -21,9 +21,9 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Ühendamine …"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Valimine …"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Ootel"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Kõne lõpetati"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Ootel"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Kõne lõpetati"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Ühendatud"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Heliseb …"</string>
-    <string name="call_state_call_ending" msgid="5037498349965472247">"Ühenduse katkestamine…"</string>
+    <string name="call_state_call_ending" msgid="5037498349965472247">"Ühenduse katkest. …"</string>
 </resources>
diff --git a/car-telephony-common/res/values-eu/strings.xml b/car-telephony-common/res/values-eu/strings.xml
index ff34106..ddaec85 100644
--- a/car-telephony-common/res/values-eu/strings.xml
+++ b/car-telephony-common/res/values-eu/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Konektatzen…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Markatzen…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Zain"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Amaitu da deia"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Zain"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Deia amaituta"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Konektatuta"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Deitzen…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Deskonektatzen…"</string>
diff --git a/car-telephony-common/res/values-fa/strings.xml b/car-telephony-common/res/values-fa/strings.xml
index 0418d6e..092b944 100644
--- a/car-telephony-common/res/values-fa/strings.xml
+++ b/car-telephony-common/res/values-fa/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"درحال اتصال…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"درحال شماره‌گیری"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"درانتظار"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"تماس پایان یافت"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"در انتظار"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"تماس پایان یافت"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"متصل"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"درحال زنگ زدن…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"درحال قطع اتصال…"</string>
diff --git a/car-telephony-common/res/values-fi/strings.xml b/car-telephony-common/res/values-fi/strings.xml
index bf46e0b..ce6ff53 100644
--- a/car-telephony-common/res/values-fi/strings.xml
+++ b/car-telephony-common/res/values-fi/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Yhdistetään…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Soitetaan…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Pidossa"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Puhelu lopetettu"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Pidossa"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Puhelu päättyi"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Yhdistetty"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Soi…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Katkaistaan…"</string>
diff --git a/car-telephony-common/res/values-fr-rCA/strings.xml b/car-telephony-common/res/values-fr-rCA/strings.xml
index bed5d9d..cef9278 100644
--- a/car-telephony-common/res/values-fr-rCA/strings.xml
+++ b/car-telephony-common/res/values-fr-rCA/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g> : <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Connexion en cours…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Composition…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"En attente"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Appel terminé"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"En attente"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Appel terminé"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Connecté"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Sonnerie en cours…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Déconnexion…"</string>
diff --git a/car-telephony-common/res/values-fr/strings.xml b/car-telephony-common/res/values-fr/strings.xml
index 35833e0..164f23d 100644
--- a/car-telephony-common/res/values-fr/strings.xml
+++ b/car-telephony-common/res/values-fr/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Connexion…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Composition numéro…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"En attente"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Appel terminé"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"En attente"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Appel terminé"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Appel en cours"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Sonnerie…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Déconnexion…"</string>
diff --git a/car-telephony-common/res/values-gl/strings.xml b/car-telephony-common/res/values-gl/strings.xml
index 2058cad..2251c16 100644
--- a/car-telephony-common/res/values-gl/strings.xml
+++ b/car-telephony-common/res/values-gl/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Conectando…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Marcando…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"En espera"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Chamada finalizada"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"En espera"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Chamada finalizada"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Conectado"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Facendo soar…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Desconectando…"</string>
diff --git a/car-telephony-common/res/values-gu/strings.xml b/car-telephony-common/res/values-gu/strings.xml
index 7040087..04cf443 100644
--- a/car-telephony-common/res/values-gu/strings.xml
+++ b/car-telephony-common/res/values-gu/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"કનેક્ટ થઈ રહ્યું છે…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ડાયલ કરી રહ્યાં છે…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"હોલ્ડ પર"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"કૉલ સમાપ્ત થયો"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"હોલ્ડ પર"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"કૉલ સમાપ્ત થયો"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"કનેક્ટેડ"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"રિંગ વાગી રહી છે…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"ડિસ્કનેક્ટ થાય છે…"</string>
diff --git a/car-telephony-common/res/values-hi/strings.xml b/car-telephony-common/res/values-hi/strings.xml
index 418e776..5fdb213 100644
--- a/car-telephony-common/res/values-hi/strings.xml
+++ b/car-telephony-common/res/values-hi/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"कनेक्ट हो रहा है…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"डायल किया जा रहा है…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"होल्ड पर है"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"कॉल खत्म हुआ"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"कॉल होल्ड पर है"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"कॉल खत्म हो गया"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"जुड़ गया है"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"घंटी बज रही है…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"डिसकनेक्ट हो रहा है…"</string>
diff --git a/car-telephony-common/res/values-hr/strings.xml b/car-telephony-common/res/values-hr/strings.xml
index 6a35140..5e0f4d7 100644
--- a/car-telephony-common/res/values-hr/strings.xml
+++ b/car-telephony-common/res/values-hr/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Povezivanje…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Biranje broja…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Na čekanju"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Poziv je završio"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Na čekanju"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Poziv je završio"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Povezano"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Zvonjenje…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Isključivanje…"</string>
diff --git a/car-telephony-common/res/values-hu/strings.xml b/car-telephony-common/res/values-hu/strings.xml
index 26e0165..fa95e1a 100644
--- a/car-telephony-common/res/values-hu/strings.xml
+++ b/car-telephony-common/res/values-hu/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Csatlakozás…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Tárcsázás…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Várakoztatva"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"A hívás befejeződött"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Várakoztatva"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"A hívás befejeződött"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Csatlakozva"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Csörgés…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Kapcsolat bontása…"</string>
diff --git a/car-telephony-common/res/values-hy/strings.xml b/car-telephony-common/res/values-hy/strings.xml
index 9a0cdeb..c8d7ea9 100644
--- a/car-telephony-common/res/values-hy/strings.xml
+++ b/car-telephony-common/res/values-hy/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Միացում…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Համարհավաքում…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Զանգը սպասման մեջ է"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Զանգն ավարտվեց"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Սպասում"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Զանգն ավարտվեց"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Միացած է"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Զանգ…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Անջատվում է…"</string>
diff --git a/car-telephony-common/res/values-in/strings.xml b/car-telephony-common/res/values-in/strings.xml
index 7450656..53a7831 100644
--- a/car-telephony-common/res/values-in/strings.xml
+++ b/car-telephony-common/res/values-in/strings.xml
@@ -21,9 +21,9 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Menghubungkan…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Memanggil…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Ditangguhkan"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Panggilan diakhiri"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Harap Tunggu"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Panggilan Diakhiri"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Terhubung"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Berdering…"</string>
-    <string name="call_state_call_ending" msgid="5037498349965472247">"Memutus sambungan..."</string>
+    <string name="call_state_call_ending" msgid="5037498349965472247">"Memutus hubungan..."</string>
 </resources>
diff --git a/car-telephony-common/res/values-is/strings.xml b/car-telephony-common/res/values-is/strings.xml
index e330acb..b91a805 100644
--- a/car-telephony-common/res/values-is/strings.xml
+++ b/car-telephony-common/res/values-is/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Tengist…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Hringir…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Í bið"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Lagt á"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Í bið"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Símtali lokið"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Tengt"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Hringir…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Aftengist…"</string>
diff --git a/car-telephony-common/res/values-it/strings.xml b/car-telephony-common/res/values-it/strings.xml
index 47b659c..cb4bc61 100644
--- a/car-telephony-common/res/values-it/strings.xml
+++ b/car-telephony-common/res/values-it/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Connessione…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Chiamata…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"In attesa"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Chiamata terminata"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"In attesa"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Chiamata terminata"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Connesso"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Sta squillando…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Disconnessione…"</string>
diff --git a/car-telephony-common/res/values-iw/strings.xml b/car-telephony-common/res/values-iw/strings.xml
index 67620e7..0d1cd68 100644
--- a/car-telephony-common/res/values-iw/strings.xml
+++ b/car-telephony-common/res/values-iw/strings.xml
@@ -20,9 +20,9 @@
     <string name="voicemail" msgid="2125552157407909509">"דואר קולי"</string>
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"מתחבר…"</string>
-    <string name="call_state_dialing" msgid="1534599871716648114">"החיוג מתבצע…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"בהמתנה"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"השיחה הסתיימה"</string>
+    <string name="call_state_dialing" msgid="1534599871716648114">"מחייג…"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"בהמתנה"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"השיחה הסתיימה"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"מתבצעת שיחה"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"מצלצל…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"מתנתק…"</string>
diff --git a/car-telephony-common/res/values-ja/strings.xml b/car-telephony-common/res/values-ja/strings.xml
index a231047..4c0a6c1 100644
--- a/car-telephony-common/res/values-ja/strings.xml
+++ b/car-telephony-common/res/values-ja/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"接続中…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"発信中…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"保留中"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"通話終了"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"保留中"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"通話終了"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"接続済み"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"着信中…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"切断中…"</string>
diff --git a/car-telephony-common/res/values-ka/strings.xml b/car-telephony-common/res/values-ka/strings.xml
index 6db5a44..858ffa3 100644
--- a/car-telephony-common/res/values-ka/strings.xml
+++ b/car-telephony-common/res/values-ka/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"დაკავშირება…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"მიმდინარეობს აკრეფა…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"შეყოვნების რეჟიმში"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"ზარი დასრულდა"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"შეყოვნების რეჟიმში"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"ზარი დასრულდა"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"დაკავშირებულია"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"ირეკება…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"კავშირი წყდება…"</string>
diff --git a/car-telephony-common/res/values-kk/strings.xml b/car-telephony-common/res/values-kk/strings.xml
index 0e767dd..48eba3d 100644
--- a/car-telephony-common/res/values-kk/strings.xml
+++ b/car-telephony-common/res/values-kk/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Жалғануда…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Терілуде…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Күтуде"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Қоңырау аяқталды"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Күтуде"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Қоңырау аяқталды"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Жалғанды"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Шылдырлату…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Ажыратылуда…"</string>
diff --git a/car-telephony-common/res/values-km/strings.xml b/car-telephony-common/res/values-km/strings.xml
index 44b7870..a483de3 100644
--- a/car-telephony-common/res/values-km/strings.xml
+++ b/car-telephony-common/res/values-km/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"កំពុងភ្ជាប់…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"កំពុងហៅ…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"កំពុងរង់ចាំ"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"បានបញ្ចប់​ការហៅទូរសព្ទ"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"រង់ចាំ"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"បាន​បញ្ចប់​ការ​ហៅ"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"បានភ្ជាប់"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"កំពុង​រោទ៍…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"កំពុង​ផ្ដាច់…"</string>
diff --git a/car-telephony-common/res/values-kn/strings.xml b/car-telephony-common/res/values-kn/strings.xml
index 2f04e28..7b57804 100644
--- a/car-telephony-common/res/values-kn/strings.xml
+++ b/car-telephony-common/res/values-kn/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ಡಯಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ಹೋಲ್ಡ್‌ ಮಾಡಲಾಗಿದೆ"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"ಕರೆ ಅಂತ್ಯಗೊಂಡಿದೆ"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ಹೋಲ್ಡ್‌ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"ಕರೆ ಅಂತ್ಯಗೊಂಡಿದೆ"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"ರಿಂಗ್‍ ಆಗುತ್ತಿದೆ…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾ…"</string>
diff --git a/car-telephony-common/res/values-ko/strings.xml b/car-telephony-common/res/values-ko/strings.xml
index b210c69..1171186 100644
--- a/car-telephony-common/res/values-ko/strings.xml
+++ b/car-telephony-common/res/values-ko/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"연결 중…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"전화 거는 중..."</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"대기 중"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"통화 종료됨"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"대기 중"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"통화 종료됨"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"연결됨"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"벨소리 울리는 중…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"연결 해제 중..."</string>
diff --git a/car-telephony-common/res/values-ky/strings.xml b/car-telephony-common/res/values-ky/strings.xml
index 599ca63..b76e748 100644
--- a/car-telephony-common/res/values-ky/strings.xml
+++ b/car-telephony-common/res/values-ky/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Туташууда…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Терилүүдө…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Күтүү режиминде"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Чалуу аяктады"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Күтүү режиминде"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Чалуу аяктады"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Туташты"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Шыңгырап жатат…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Ажыратылууда…"</string>
diff --git a/car-telephony-common/res/values-lo/strings.xml b/car-telephony-common/res/values-lo/strings.xml
index ec95f01..b6cc9df 100644
--- a/car-telephony-common/res/values-lo/strings.xml
+++ b/car-telephony-common/res/values-lo/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"ກຳລັງເຊື່ອມຕໍ່…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ກຳລັງໂທ…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ພັກສາຍ"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"ວາງສາຍແລ້ວ"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ຖືສາຍລໍຖ້າ"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"ວາງສາຍແລ້ວ"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"ເຊື່ອມຕໍ່ແລ້ວ"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"ກຳລັງດັງ…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"ກຳລັງຕັດການເຊື່ອມຕໍ່…"</string>
diff --git a/car-telephony-common/res/values-lt/strings.xml b/car-telephony-common/res/values-lt/strings.xml
index 550d875..ea0508a 100644
--- a/car-telephony-common/res/values-lt/strings.xml
+++ b/car-telephony-common/res/values-lt/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Prisijungiama…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Renkamas numeris…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Sulaikyta"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Skambutis baigtas"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Sulaikyta"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Skambutis baigtas"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Sujungta"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Skambinama…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Atsijungiama…"</string>
diff --git a/car-telephony-common/res/values-lv/strings.xml b/car-telephony-common/res/values-lv/strings.xml
index 184c937..28e49f5 100644
--- a/car-telephony-common/res/values-lv/strings.xml
+++ b/car-telephony-common/res/values-lv/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Veido savienojumu…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Sastāda numuru…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Aizturēts"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Zvans pabeigts"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Aizturēts"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Zvans ir pabeigts"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Savienots"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Zvana…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Notiek atvienošana…"</string>
diff --git a/car-telephony-common/res/values-mk/strings.xml b/car-telephony-common/res/values-mk/strings.xml
index c3ef6eb..b6053e3 100644
--- a/car-telephony-common/res/values-mk/strings.xml
+++ b/car-telephony-common/res/values-mk/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Се поврзува…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Бирање…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"На чекање"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Повикот заврши"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"На чекање"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Повикот заврши"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Поврзан"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ѕвони…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Се исклучува…"</string>
diff --git a/car-telephony-common/res/values-ml/strings.xml b/car-telephony-common/res/values-ml/strings.xml
index 85d886c..e940e9b 100644
--- a/car-telephony-common/res/values-ml/strings.xml
+++ b/car-telephony-common/res/values-ml/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"കണക്റ്റ് ചെയ്യുന്നു…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ഡയൽ ചെയ്യുന്നു…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ഹോൾഡിലാണ്"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"കോൾ അവസാനിച്ചു"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ഹോള്‍ഡിലാണ്"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"കോൾ അവസാനിച്ചു"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"കണക്‌റ്റ് ചെയ്‌തു"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"റിംഗ് ചെയ്യുന്നു…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"വിച്ഛേദിക്കുന്നു…"</string>
diff --git a/car-telephony-common/res/values-mn/strings.xml b/car-telephony-common/res/values-mn/strings.xml
index 74956f3..5fdc776 100644
--- a/car-telephony-common/res/values-mn/strings.xml
+++ b/car-telephony-common/res/values-mn/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Холбогдож байна…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Залгаж байна…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Хүлээлгэд байгаа"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Дуудлага дууссан"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Хүлээлгэнд байна"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Дуудлагыг тасалсан"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Холбогдсон"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Дуугарч байна…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Салгаж байна…"</string>
diff --git a/car-telephony-common/res/values-mr/strings.xml b/car-telephony-common/res/values-mr/strings.xml
index d3036e1..9c7f085 100644
--- a/car-telephony-common/res/values-mr/strings.xml
+++ b/car-telephony-common/res/values-mr/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"कनेक्ट करत आहे…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"डायल करत आहे…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"होल्डवर आहे"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"कॉल संपला आहे"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"होल्ड वर"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"कॉल संपला"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"कनेक्ट केले"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"रिंग होत आहे…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"डिस्कनेक्ट करत आहे…"</string>
diff --git a/car-telephony-common/res/values-ms/strings.xml b/car-telephony-common/res/values-ms/strings.xml
index 038ac0c..1c1d5de 100644
--- a/car-telephony-common/res/values-ms/strings.xml
+++ b/car-telephony-common/res/values-ms/strings.xml
@@ -21,9 +21,9 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Menyambung…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Mendail…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Ditunda"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Panggilan tamat"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Ditunda"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Panggilan Tamat"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Disambungkan"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Berdering…"</string>
-    <string name="call_state_call_ending" msgid="5037498349965472247">"Memutuskan sambungan…"</string>
+    <string name="call_state_call_ending" msgid="5037498349965472247">"Memutuskan sambungn…"</string>
 </resources>
diff --git a/car-telephony-common/res/values-my/strings.xml b/car-telephony-common/res/values-my/strings.xml
index e2d5565..130935a 100644
--- a/car-telephony-common/res/values-my/strings.xml
+++ b/car-telephony-common/res/values-my/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"ချိတ်ဆက်နေသည်…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ခေါ်ဆိုနေသည်…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ဖုန်းကိုင်ထားသည်"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"ခေါ်ဆိုမှု ပြီးသွားပါပြီ"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ဖုန်းကိုင်ထားသည်"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"ခေါ်ဆိုမှု ပြီးပါပြီ"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"ချိတ်ဆက်ထားသည်"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"အသံမြည်နေသည်…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"အဆက်အသွယ် ဖြတ်နေသည်…"</string>
diff --git a/car-telephony-common/res/values-nb/strings.xml b/car-telephony-common/res/values-nb/strings.xml
index e6e90b3..119f352 100644
--- a/car-telephony-common/res/values-nb/strings.xml
+++ b/car-telephony-common/res/values-nb/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Kobler til …"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Slår nummeret …"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"På vent"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Anropet er avsluttet"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"På vent"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Anropet er avsluttet"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Tilkoblet"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ringer …"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Kobler fra …"</string>
diff --git a/car-telephony-common/res/values-ne/strings.xml b/car-telephony-common/res/values-ne/strings.xml
index 2283a98..b021f11 100644
--- a/car-telephony-common/res/values-ne/strings.xml
+++ b/car-telephony-common/res/values-ne/strings.xml
@@ -21,9 +21,9 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"जोड्दै…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"डायल गर्दै…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"होल्डमा छ"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"कल समाप्त भयो"</string>
-    <string name="call_state_call_active" msgid="2769644783657864202">"कनेक्ट गरिएको छ"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"होल्डमा छ"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"कल समाप्त भयो"</string>
+    <string name="call_state_call_active" msgid="2769644783657864202">"जडान गरिएको छ"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"घन्टी बज्दै छ…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"विच्छेद गर्दै…"</string>
 </resources>
diff --git a/car-telephony-common/res/values-nl/strings.xml b/car-telephony-common/res/values-nl/strings.xml
index c1f4c00..7d00163 100644
--- a/car-telephony-common/res/values-nl/strings.xml
+++ b/car-telephony-common/res/values-nl/strings.xml
@@ -21,9 +21,9 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Verbinden…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Kiezen…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"In de wacht"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Gesprek beëindigd"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"In de wacht"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Gesprek beëindigd"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Verbonden"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Gaat over…"</string>
-    <string name="call_state_call_ending" msgid="5037498349965472247">"Verbreken…"</string>
+    <string name="call_state_call_ending" msgid="5037498349965472247">"Verb. verbreken…"</string>
 </resources>
diff --git a/car-telephony-common/res/values-or/strings.xml b/car-telephony-common/res/values-or/strings.xml
index c95fa40..775e33c 100644
--- a/car-telephony-common/res/values-or/strings.xml
+++ b/car-telephony-common/res/values-or/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"ସଂଯୋଗ ହେଉଛି…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ଡାଏଲ୍ କରାଯାଉଛି…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ହୋଲ୍ଡରେ ଅଛି"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"କଲ୍ ଶେଷ ହୋଇଛି"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ହୋଲ୍ଡରେ ଅଛି"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"କଲ୍ ସମାପ୍ତ ହେଲା"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"ସଂଯୋଗ ହୋଇଛି"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"ରିଙ୍ଗ ହେଉଛି…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"ବିଚ୍ଛିନ୍ନ ହେଉଛି…"</string>
diff --git a/car-telephony-common/res/values-pa/strings.xml b/car-telephony-common/res/values-pa/strings.xml
index dcad72f..129276b 100644
--- a/car-telephony-common/res/values-pa/strings.xml
+++ b/car-telephony-common/res/values-pa/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"ਕਨੈਕਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ਡਾਇਲ ਹੋ ਰਿਹਾ ਹੈ…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ਰੋਕ ਕੇ ਰੱਖੀ ਗਈ"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"ਕਾਲ ਸਮਾਪਤ ਹੋਈ"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ਰੋਕ ਕੇ ਰੱਖੀ ਗਈ"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"ਕਾਲ ਸਮਾਪਤ ਹੋਈ"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"ਕਨੈਕਟ ਹੈ"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"ਘੰਟੀ ਵੱਜ ਰਹੀ ਹੈ…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"ਡਿਸਕਨੈਕਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
diff --git a/car-telephony-common/res/values-pl/strings.xml b/car-telephony-common/res/values-pl/strings.xml
index 7b87eef..1212857 100644
--- a/car-telephony-common/res/values-pl/strings.xml
+++ b/car-telephony-common/res/values-pl/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Łączę…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Wybieram numer…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Oczekujące"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Połączenie zakończone"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Oczekujące"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Koniec połączenia"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Połączono"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Dzwonię…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Rozłączam…"</string>
diff --git a/car-telephony-common/res/values-pt-rPT/strings.xml b/car-telephony-common/res/values-pt-rPT/strings.xml
index b0577d0..3b518e6 100644
--- a/car-telephony-common/res/values-pt-rPT/strings.xml
+++ b/car-telephony-common/res/values-pt-rPT/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"A ligar…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"A marcar…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Em espera"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Chamada terminada"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Em espera"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Chamada terminada"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Ligado"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"A tocar…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"A desligar…"</string>
diff --git a/car-telephony-common/res/values-pt/strings.xml b/car-telephony-common/res/values-pt/strings.xml
index f56f6ad..7531adb 100644
--- a/car-telephony-common/res/values-pt/strings.xml
+++ b/car-telephony-common/res/values-pt/strings.xml
@@ -20,9 +20,9 @@
     <string name="voicemail" msgid="2125552157407909509">"Correio de voz"</string>
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Conectando…"</string>
-    <string name="call_state_dialing" msgid="1534599871716648114">"Chamando...…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Em espera"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Chamada encerrada"</string>
+    <string name="call_state_dialing" msgid="1534599871716648114">"Discando…"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Em espera"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Chamada encerrada"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Conectado"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Tocando…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Desconectando…"</string>
diff --git a/car-telephony-common/res/values-ro/strings.xml b/car-telephony-common/res/values-ro/strings.xml
index 7d78d46..a9883de 100644
--- a/car-telephony-common/res/values-ro/strings.xml
+++ b/car-telephony-common/res/values-ro/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Se conectează…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Se apelează…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"În așteptare"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Apel încheiat"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"În așteptare"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Apel încheiat"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Conectat"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Sună…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Se deconectează…"</string>
diff --git a/car-telephony-common/res/values-ru/strings.xml b/car-telephony-common/res/values-ru/strings.xml
index 6731414..2e37211 100644
--- a/car-telephony-common/res/values-ru/strings.xml
+++ b/car-telephony-common/res/values-ru/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Подключение…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Набор номера…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Вызов на удержании"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Вызов завершен"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"На удержании"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Вызов завершен"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Подключено"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Вызов…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Отключение…"</string>
diff --git a/car-telephony-common/res/values-si/strings.xml b/car-telephony-common/res/values-si/strings.xml
index b0ac2e8..399c8d8 100644
--- a/car-telephony-common/res/values-si/strings.xml
+++ b/car-telephony-common/res/values-si/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"සබැඳෙමින්…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"අමතමින්…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"රඳවා ගනිමින්"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"ඇමතුම අවසන් විය"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"රඳවා ඇත"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"ඇමතුම නිමා විය"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"සම්බන්ධයි"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"නාද වෙමින්…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"විසන්ධි වෙමින්…"</string>
diff --git a/car-telephony-common/res/values-sk/strings.xml b/car-telephony-common/res/values-sk/strings.xml
index 0aeef23..83721d3 100644
--- a/car-telephony-common/res/values-sk/strings.xml
+++ b/car-telephony-common/res/values-sk/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Pripája sa…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Vytáča sa…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Podržaný hovor"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Hovor bol ukončený"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Podržané"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Hovor bol ukončený"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Pripojené"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Prezváňa sa…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Odpája sa…"</string>
diff --git a/car-telephony-common/res/values-sl/strings.xml b/car-telephony-common/res/values-sl/strings.xml
index ce84056..03a7063 100644
--- a/car-telephony-common/res/values-sl/strings.xml
+++ b/car-telephony-common/res/values-sl/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Povezovanje …"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Klicanje …"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Na čakanju"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Klic je končan"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Zadržan"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Klic je bil končan"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Povezano"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Zvonjenje …"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Prekin. povezave …"</string>
diff --git a/car-telephony-common/res/values-sq/strings.xml b/car-telephony-common/res/values-sq/strings.xml
index 87af7f4..f6439eb 100644
--- a/car-telephony-common/res/values-sq/strings.xml
+++ b/car-telephony-common/res/values-sq/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Po lidhet…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Po formon numrin…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Në pritje"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Telefonata përfundoi"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Në pritje"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Telefonata përfundoi"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Lidhur"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Po bie zilja…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Po shkëputet…"</string>
diff --git a/car-telephony-common/res/values-sr/strings.xml b/car-telephony-common/res/values-sr/strings.xml
index 4b48d1a..1f3837f 100644
--- a/car-telephony-common/res/values-sr/strings.xml
+++ b/car-telephony-common/res/values-sr/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Повезује се…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Позива се…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"На чекању"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Позив је завршен"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"На чекању"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Позив је завршен"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Повезан"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Звони…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Прекида се веза…"</string>
diff --git a/car-telephony-common/res/values-sv/strings.xml b/car-telephony-common/res/values-sv/strings.xml
index 2aff4e7..f4b9b1a 100644
--- a/car-telephony-common/res/values-sv/strings.xml
+++ b/car-telephony-common/res/values-sv/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Ansluter …"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Ringer upp …"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Parkerat"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Samtal avslutat"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Parkerat"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Samtal avslutat"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Ansluten"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Ringer …"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Kopplar från …"</string>
diff --git a/car-telephony-common/res/values-sw/strings.xml b/car-telephony-common/res/values-sw/strings.xml
index 28a496b..f6adbc1 100644
--- a/car-telephony-common/res/values-sw/strings.xml
+++ b/car-telephony-common/res/values-sw/strings.xml
@@ -20,10 +20,10 @@
     <string name="voicemail" msgid="2125552157407909509">"Ujumbe wa sauti"</string>
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Inaunganisha…"</string>
-    <string name="call_state_dialing" msgid="1534599871716648114">"Inapiga…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Imesitishwa"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Simu imekamilika"</string>
+    <string name="call_state_dialing" msgid="1534599871716648114">"Inapigia…"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Inangoja"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Simu Imekamilika"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Imeunganisha"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Inalia…"</string>
-    <string name="call_state_call_ending" msgid="5037498349965472247">"Inakata…"</string>
+    <string name="call_state_call_ending" msgid="5037498349965472247">"Inaondoa…"</string>
 </resources>
diff --git a/car-telephony-common/res/values-ta/strings.xml b/car-telephony-common/res/values-ta/strings.xml
index d6bb4c9..d835fab 100644
--- a/car-telephony-common/res/values-ta/strings.xml
+++ b/car-telephony-common/res/values-ta/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"இணைக்கிறது…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"டயல் செய்கிறது…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ஹோல்டில் உள்ளது"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"அழைப்பு முடிந்தது"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"காத்திருப்பில்"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"அழைப்பு முடிந்தது"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"இணைக்கப்பட்டது"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"அழைக்கிறது…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"துண்டிக்கிறது…"</string>
diff --git a/car-telephony-common/res/values-te/strings.xml b/car-telephony-common/res/values-te/strings.xml
index 39975e4..2ebcb08 100644
--- a/car-telephony-common/res/values-te/strings.xml
+++ b/car-telephony-common/res/values-te/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"కనెక్ట్ అవుతోంది…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"డయల్ చేస్తోంది…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"హోల్డ్‌లో ఉంది"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"కాల్ ముగిసింది"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"హోల్డ్‌లో ఉంది"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"కాల్ ముగిసింది"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"కనెక్ట్ చేయబడింది"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"రింగ్ అవుతోంది…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"డిస్కనెక్టవుతోంది…"</string>
diff --git a/car-telephony-common/res/values-th/strings.xml b/car-telephony-common/res/values-th/strings.xml
index 6b5a368..7af5876 100644
--- a/car-telephony-common/res/values-th/strings.xml
+++ b/car-telephony-common/res/values-th/strings.xml
@@ -21,9 +21,9 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"กำลังเชื่อมต่อ…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"กำลังโทรออก…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"พักสาย"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"วางสายแล้ว"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"พักสาย"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"วางสายแล้ว"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"เชื่อมต่อแล้ว"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"กำลังส่งเสียง…"</string>
-    <string name="call_state_call_ending" msgid="5037498349965472247">"ยกเลิกการโทรออก…"</string>
+    <string name="call_state_call_ending" msgid="5037498349965472247">"ยกเลิกการเชื่อมต่อ…"</string>
 </resources>
diff --git a/car-telephony-common/res/values-tl/strings.xml b/car-telephony-common/res/values-tl/strings.xml
index 2bdda5c..f5f02ef 100644
--- a/car-telephony-common/res/values-tl/strings.xml
+++ b/car-telephony-common/res/values-tl/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Kumokonekta…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Dina-dial…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Naka-hold"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Tinapos ang tawag"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Naka-hold"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Natapos ang Tawag"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Nakakonekta"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Nagri-ring…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Dinidiskonekta…"</string>
diff --git a/car-telephony-common/res/values-tr/strings.xml b/car-telephony-common/res/values-tr/strings.xml
index dc05ebf..8da8d62 100644
--- a/car-telephony-common/res/values-tr/strings.xml
+++ b/car-telephony-common/res/values-tr/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Bağlanıyor…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Numara çevriliyor…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Beklemede"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Çağrı sonlandırıldı"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Beklemede"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Çağrı Sonlandırıldı"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Bağlandı"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Zil çaldırılıyor…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Bağlantı kesiliyor…"</string>
diff --git a/car-telephony-common/res/values-uk/strings.xml b/car-telephony-common/res/values-uk/strings.xml
index f72fa83..6c05db2 100644
--- a/car-telephony-common/res/values-uk/strings.xml
+++ b/car-telephony-common/res/values-uk/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"З’єднання…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Набір номера…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Утримується"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Виклик завершено"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Утримується"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Виклик завершено"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Під’єднано"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Дзвінок…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Від’єднання…"</string>
diff --git a/car-telephony-common/res/values-ur/strings.xml b/car-telephony-common/res/values-ur/strings.xml
index 3deac0b..92dfe09 100644
--- a/car-telephony-common/res/values-ur/strings.xml
+++ b/car-telephony-common/res/values-ur/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"منسلک ہو رہا ہے…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"ڈائل کر رہا ہے…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"ہولڈ پر ہے"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"کال ختم ہو گئی"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"ہولڈ پر ہے"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"کال ختم ہوگئی"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"منسلک ہے"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"گھنٹی بج رہی ہے…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"غیر منسلک ہو رہا ہے…"</string>
diff --git a/car-telephony-common/res/values-uz/strings.xml b/car-telephony-common/res/values-uz/strings.xml
index a818836..2683304 100644
--- a/car-telephony-common/res/values-uz/strings.xml
+++ b/car-telephony-common/res/values-uz/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Ulanmoqda…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Raqam terilmoqda…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Pauzada"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Chaqiruv tugadi"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Kutish holatida"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Chaqiruv yakunlandi"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Ulandi"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Jiringlamoqda…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Uzilmoqda…"</string>
diff --git a/car-telephony-common/res/values-vi/strings.xml b/car-telephony-common/res/values-vi/strings.xml
index d0dc77b..e52194a 100644
--- a/car-telephony-common/res/values-vi/strings.xml
+++ b/car-telephony-common/res/values-vi/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Đang kết nối…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Đang quay số..."</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Đang giữ máy"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Cuộc gọi đã kết thúc"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Đang chờ"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Cuộc gọi đã kết thúc"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Đã kết nối"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Đang đổ chuông..."</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Đang ngắt kết nối…"</string>
diff --git a/car-telephony-common/res/values-zh-rCN/strings.xml b/car-telephony-common/res/values-zh-rCN/strings.xml
index 0c2fc09..1a6a652 100644
--- a/car-telephony-common/res/values-zh-rCN/strings.xml
+++ b/car-telephony-common/res/values-zh-rCN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="unknown" msgid="3237922751873109097">"未知"</string>
-    <string name="voicemail" msgid="2125552157407909509">"语音信息"</string>
+    <string name="voicemail" msgid="2125552157407909509">"语音邮件"</string>
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"正在连接…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"正在拨号…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"保持"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"通话已结束"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"呼叫等待"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"通话已结束"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"已连接"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"正在响铃…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"正在断开连接…"</string>
diff --git a/car-telephony-common/res/values-zh-rHK/strings.xml b/car-telephony-common/res/values-zh-rHK/strings.xml
index 6872577..c92766e 100644
--- a/car-telephony-common/res/values-zh-rHK/strings.xml
+++ b/car-telephony-common/res/values-zh-rHK/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"正在連接…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"正在撥號…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"保留通話"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"通話已結束"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"保留通話"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"通話已結束"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"已連接"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"正在發出鈴聲…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"正在解除連接…"</string>
diff --git a/car-telephony-common/res/values-zh-rTW/strings.xml b/car-telephony-common/res/values-zh-rTW/strings.xml
index 41928bb..decc1db 100644
--- a/car-telephony-common/res/values-zh-rTW/strings.xml
+++ b/car-telephony-common/res/values-zh-rTW/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"連線中…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"撥號中…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"保留中"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"通話已結束"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"保留中"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"通話結束"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"已連線"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"鈴響中…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"正在中斷連線…"</string>
diff --git a/car-telephony-common/res/values-zu/strings.xml b/car-telephony-common/res/values-zu/strings.xml
index fa90708..0978e00 100644
--- a/car-telephony-common/res/values-zu/strings.xml
+++ b/car-telephony-common/res/values-zu/strings.xml
@@ -21,8 +21,8 @@
     <string name="phone_label_with_info" msgid="4652109530699808645">"<xliff:g id="LABEL">%1$s</xliff:g>  ·  <xliff:g id="DURATION">%2$s</xliff:g>"</string>
     <string name="call_state_connecting" msgid="5930724746375294866">"Iyaxhuma…"</string>
     <string name="call_state_dialing" msgid="1534599871716648114">"Iyadayela…"</string>
-    <string name="call_state_hold" msgid="8063542005458186874">"Ibambile"</string>
-    <string name="call_state_call_ended" msgid="1432127342949555464">"Ikholi iqediwe"</string>
+    <string name="call_state_hold" msgid="6834028102796624100">"Ibanjiwe"</string>
+    <string name="call_state_call_ended" msgid="4159349597599886429">"Ikholi iqediwe"</string>
     <string name="call_state_call_active" msgid="2769644783657864202">"Ixhunyiwe"</string>
     <string name="call_state_call_ringing" msgid="4618803402954375017">"Iyakhala…"</string>
     <string name="call_state_call_ending" msgid="5037498349965472247">"Iyanqamula…"</string>
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 dac0aa3..8ed7e73 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
@@ -25,8 +25,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.Transformations;
 
 import com.android.car.apps.common.log.L;
 
@@ -59,10 +59,9 @@
     private final Map<String, Map<String, Contact>> mLookupKeyContactMap = new HashMap<>();
 
     /**
-     * A map which divides contacts LiveData by account.
+     * A map which divides contacts by account.
      */
-    private final Map<String, MutableLiveData<List<Contact>>> mAccountContactsLiveDataMap =
-            new ArrayMap<>();
+    private final Map<String, List<Contact>> mAccountContactsMap = new ArrayMap<>();
     private boolean mIsLoaded = false;
 
     /**
@@ -160,10 +159,8 @@
      *                    Bluetooth address.
      */
     public LiveData<List<Contact>> getContactsLiveDataByAccount(String accountName) {
-        if (!mAccountContactsLiveDataMap.containsKey(accountName)) {
-            mAccountContactsLiveDataMap.put(accountName, new MutableLiveData<>());
-        }
-        return mAccountContactsLiveDataMap.get(accountName);
+        return Transformations.map(mContactListAsyncQueryLiveData,
+                contacts -> contacts == null ? null : mAccountContactsMap.get(accountName));
     }
 
     /**
@@ -252,12 +249,13 @@
             subMap.put(lookupKey, Contact.fromCursor(mContext, cursor, subMap.get(lookupKey)));
         }
 
+        mAccountContactsMap.clear();
         for (String accountName : contactMap.keySet()) {
             Map<String, Contact> subMap = contactMap.get(accountName);
             contactList.addAll(subMap.values());
-            MutableLiveData<List<Contact>> accountContactsLiveData =
-                    (MutableLiveData<List<Contact>>) getContactsLiveDataByAccount(accountName);
-            accountContactsLiveData.postValue(new ArrayList<>(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 b3c1fb1..394b6d4 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
@@ -50,9 +50,9 @@
 
     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,6 +65,7 @@
             @NonNull ContentResolver cr,
             @NonNull OnQueryFinishedListener listener) {
         mAsyncQueryHandler = new AsyncQueryHandlerImpl(this, cr);
+        mContentResolver = cr;
         mContentObserver = new ContentObserver(mAsyncQueryHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -83,6 +84,7 @@
     public void startQuery() {
         L.d(TAG, "startQuery");
         mAsyncQueryHandler.cancelOperation(mToken); // Cancel the query task.
+        mContentResolver.unregisterContentObserver(mContentObserver);
 
         mToken++;
         QueryParam queryParam = mQueryParamProvider.getQueryParam();
@@ -95,6 +97,7 @@
                     queryParam.mSelection,
                     queryParam.mSelectionArgs,
                     queryParam.mOrderBy);
+            mContentResolver.registerContentObserver(queryParam.mUri, false, mContentObserver);
         } else {
             mOnQueryFinishedListener.onQueryFinished(null);
         }
@@ -109,7 +112,7 @@
     public void stopQuery() {
         L.d(TAG, "stopQuery");
         mIsActive = false;
-        cleanupCursorIfNecessary();
+        mContentResolver.unregisterContentObserver(mContentObserver);
         mAsyncQueryHandler.cancelOperation(mToken); // Cancel the query task.
     }
 
@@ -118,23 +121,11 @@
             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/TelecomUtils.java b/car-telephony-common/src/com/android/car/telephony/common/TelecomUtils.java
index a790318..40d93a7 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
@@ -129,11 +129,10 @@
         }
 
         String countryIso = getCurrentCountryIsoFromLocale(context);
-        L.d(TAG, "PhoneNumberUtils.formatNumberToE16, number: "
-                    + piiLog(number) + ", country: " + countryIso);
+        L.d(TAG, "PhoneNumberUtils.formatNumber, number: " + piiLog(number)
+                + ", country: " + countryIso);
 
-        String e164 = PhoneNumberUtils.formatNumberToE164(number, countryIso);
-        String formattedNumber = PhoneNumberUtils.formatNumber(number, e164, countryIso);
+        String formattedNumber = PhoneNumberUtils.formatNumber(number, countryIso);
         formattedNumber = TextUtils.isEmpty(formattedNumber) ? number : formattedNumber;
         L.d(TAG, "getFormattedNumber, result: " + piiLog(formattedNumber));
 
@@ -509,6 +508,24 @@
      * 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.");
@@ -525,21 +542,22 @@
         where.append(CallLog.Calls.TYPE);
         where.append(" = ?");
         selectionArgs.add(Integer.toString(CallLog.Calls.MISSED_TYPE));
-        if (!TextUtils.isEmpty(phoneNumberString)) {
+        if (!TextUtils.isEmpty(columnName) && !TextUtils.isEmpty(selectionArg)) {
             where.append(" AND ");
-            where.append(CallLog.Calls.NUMBER);
+            where.append(columnName);
             where.append(" = ?");
-            selectionArgs.add(phoneNumberString);
+            selectionArgs.add(selectionArg);
         }
         String[] selectionArgsArray = new String[0];
         try {
-            context
-                    .getContentResolver()
-                    .update(
-                            CallLog.Calls.CONTENT_URI,
-                            contentValues,
-                            where.toString(),
-                            selectionArgs.toArray(selectionArgsArray));
+            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);
         } catch (IllegalArgumentException e) {
             L.e(TAG, "markCallLogAsRead failed", e);
         }
diff --git a/car-ui-lib/.gitignore b/car-ui-lib/.gitignore
index a6be7ed..57df0a4 100644
--- a/car-ui-lib/.gitignore
+++ b/car-ui-lib/.gitignore
@@ -16,3 +16,6 @@
 
 # Android studio's layout inspector captures
 captures/
+
+# A file created when launching android emulators
+read-snapshot.txt
diff --git a/car-ui-lib/build.gradle b/car-ui-lib/build.gradle
index 9744622..28633d9 100644
--- a/car-ui-lib/build.gradle
+++ b/car-ui-lib/build.gradle
@@ -23,7 +23,7 @@
 
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.6.1'
+        classpath 'com.android.tools.build:gradle:4.0.2'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git a/car-ui-lib/car-ui-lib/build.gradle b/car-ui-lib/car-ui-lib/build.gradle
index 5c6ce32..201a8d6 100644
--- a/car-ui-lib/car-ui-lib/build.gradle
+++ b/car-ui-lib/car-ui-lib/build.gradle
@@ -60,20 +60,20 @@
     api 'androidx.core:core:1.2.0'
     implementation 'com.android.support:support-annotations:28.0.0'
 
-    testImplementation "androidx.test.ext:junit:1.1.1"
-    testImplementation 'org.robolectric:robolectric:4.4'
+    testImplementation "androidx.test.ext:junit:1.1.2"
+    testImplementation 'org.robolectric:robolectric:4.3.1'
     testImplementation "org.mockito:mockito-core:2.19.0"
     testImplementation "com.google.truth:truth:0.29"
     testImplementation "org.testng:testng:6.9.9"
 
     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 'androidx.test.espresso:espresso-core:3.3.0'
+    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.3.0'
     androidTestImplementation "com.google.truth:truth:0.29"
-    androidTestImplementation "androidx.test.ext:junit:1.1.1"
+    androidTestImplementation "androidx.test.ext:junit:1.1.2"
     androidTestImplementation "org.mockito:mockito-core:2.19.0"
-    androidTestImplementation 'androidx.test:runner:1.1.0'
-    androidTestImplementation 'androidx.test:rules:1.1.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'
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/AndroidManifest.xml b/car-ui-lib/car-ui-lib/src/androidTest/AndroidManifest.xml
index 81df306..79b51bb 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/AndroidManifest.xml
+++ b/car-ui-lib/car-ui-lib/src/androidTest/AndroidManifest.xml
@@ -16,14 +16,19 @@
 -->
 <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">
+    <application android:debuggable="true" android:theme="@style/Theme.CarUi.NoToolbar">
         <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.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" />
         <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"/>
     </application>
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
new file mode 100644
index 0000000..0aaa250
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/AlertDialogBuilderTest.java
@@ -0,0 +1,256 @@
+/*
+ * 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 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 done = new AtomicBoolean(false);
+        AlertDialog[] result = new AlertDialog[1];
+        mActivityRule.runOnUiThread(() -> {
+            try {
+                result[0] = builder.create();
+                result[0].show();
+            } catch (RuntimeException e) {
+                assert e.getMessage() != null;
+                assert e.getMessage().contains(
+                        "must have at least one button to disable the dismiss button");
+
+                assert shouldExist;
+                done.set(true);
+            }
+        });
+
+        if (done.get()) {
+            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
new file mode 100644
index 0000000..d6bc4e1
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FakeCursor.java
@@ -0,0 +1,77 @@
+/*
+ * 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 List<String> mRows;
+    private 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[] { mColumnName };
+    }
+
+    @Override
+    public String getString(int column) {
+        return mRows.get(getPosition());
+    }
+
+    @Override
+    public short getShort(int column) {
+        return 0;
+    }
+
+    @Override
+    public int getInt(int column) {
+        return 0;
+    }
+
+    @Override
+    public long getLong(int column) {
+        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 mRows.get(getPosition()) == null;
+    }
+}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
index 9c1ce88..b0e7c88 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
@@ -16,24 +16,36 @@
 
 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 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.ui.test.R;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -41,7 +53,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-/** Unit tests for {@link FocusArea}. */
+/** Unit tests for {@link FocusArea} not in touch mode. */
 public class FocusAreaTest {
     private static final long WAIT_TIME_MS = 3000;
 
@@ -50,82 +62,365 @@
             new ActivityTestRule<>(FocusAreaTestActivity.class);
 
     private FocusAreaTestActivity mActivity;
-    private TestFocusArea mFocusArea;
+    private TestFocusArea mFocusArea1;
     private TestFocusArea mFocusArea2;
-    private View mChild;
-    private View mDefaultFocus;
-    private View mNonChild;
-    private View mChild1;
-    private View mChild2;
+    private TestFocusArea mFocusArea3;
+    private TestFocusArea mFocusArea4;
+    private FocusParkingView mFpv;
+    private View mView1;
+    private Button mButton1;
+    private View mView2;
+    private View mDefaultFocus2;
+    private View mView3;
+    private View mNudgeShortcut3;
+    private View mView4;
 
     @Before
     public void setUp() {
         mActivity = mActivityRule.getActivity();
-        mFocusArea = mActivity.findViewById(R.id.focus_area);
-        mFocusArea.enableForegroundHighlight();
+        mFocusArea1 = mActivity.findViewById(R.id.focus_area1);
         mFocusArea2 = mActivity.findViewById(R.id.focus_area2);
-        mChild = mActivity.findViewById(R.id.child);
-        mDefaultFocus = mActivity.findViewById(R.id.default_focus);
-        mNonChild = mActivity.findViewById(R.id.non_child);
-        mChild1 = mActivity.findViewById(R.id.child1);
-        mChild2 = mActivity.findViewById(R.id.child2);
+        mFocusArea3 = mActivity.findViewById(R.id.focus_area3);
+        mFocusArea4 = mActivity.findViewById(R.id.focus_area4);
+        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);
     }
 
     @Test
-    public void testLoseFocus() throws Exception {
-        mChild.post(() -> {
-            mChild.requestFocus();
-        });
-        mFocusArea.setOnDrawCalled(false);
-        mFocusArea.setDrawCalled(false);
-
-        // FocusArea lost focus.
+    public void testDrawMethodsCalled() throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
-        mNonChild.post(() -> {
-            mNonChild.requestFocus();
-            mNonChild.post(() -> {
-                latch.countDown();
-            });
+        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());
         });
-        assertDrawMethodsCalled(latch);
+
+        // The methods should be called when a FocusArea gains or loses focus.
+        assertDrawMethodsCalled(mFocusArea1, latch);
+        assertDrawMethodsCalled(mFocusArea2, latch);
     }
 
     @Test
-    public void testGetFocus() throws Exception {
-        mNonChild.post(() -> {
-            mNonChild.requestFocus();
-        });
-        mFocusArea.setOnDrawCalled(false);
-        mFocusArea.setDrawCalled(false);
+    public void testPerformAccessibilityAction_actionNudgeShortcut() {
+        mFocusArea1.post(() -> {
+            // Nudge to the nudgeShortcut view.
+            mView3.requestFocus();
+            assertThat(mView3.isFocused()).isTrue();
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
+            mFocusArea3.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
+            assertThat(mNudgeShortcut3.isFocused()).isTrue();
 
-        // FocusArea got focus.
-        CountDownLatch latch = new CountDownLatch(1);
-        mChild.post(() -> {
-            mChild.requestFocus();
-            mChild.post(() -> {
-                latch.countDown();
-            });
+            // nudgeShortcutDirection doesn't match. The focus should stay the same.
+            mView3.requestFocus();
+            assertThat(mView3.isFocused()).isTrue();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea3.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
+            assertThat(mView3.isFocused()).isTrue();
+
+            // No nudgeShortcut view in the current FocusArea. The focus should stay the same.
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_RIGHT);
+            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_SHORTCUT, arguments);
+            assertThat(mView1.isFocused()).isTrue();
         });
-        assertDrawMethodsCalled(latch);
+    }
+
+
+    @Test
+    public void testPerformAccessibilityAction_actionFocus() {
+        mFocusArea1.post(() -> {
+            mFocusArea1.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mView1.isFocused()).isTrue();
+
+            // It should focus on the default or the first view in the FocusArea.
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+        });
     }
 
     @Test
-    public void testFocusOnDefaultFocus() throws Exception {
-        assertThat(mDefaultFocus.isFocused()).isFalse();
+    public void testPerformAccessibilityAction_actionFocus_enabledFocusCache() {
+        mFocusArea1.post(() -> {
+            RotaryCache cache =
+                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
+            mFocusArea1.setRotaryCache(cache);
 
-        Bundle bundle = new Bundle();
-        CountDownLatch latch = new CountDownLatch(1);
-        mFocusArea.post(() -> {
-            mFocusArea.performAccessibilityAction(ACTION_FOCUS, bundle);
-            latch.countDown();
+            mButton1.requestFocus();
+            assertThat(mButton1.isFocused()).isTrue();
+            mView2.requestFocus();
+            assertThat(mView2.isFocused()).isTrue();
+
+            // With cache, it should focus on the lastly focused view in the FocusArea.
+            mFocusArea1.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mButton1.isFocused()).isTrue();
         });
-        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mDefaultFocus.isFocused()).isTrue();
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionFocus_disabledFocusCache() {
+        mFocusArea1.post(() -> {
+            RotaryCache cache = new RotaryCache(CACHE_TYPE_DISABLED, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
+            mFocusArea1.setRotaryCache(cache);
+
+            mButton1.requestFocus();
+            assertThat(mButton1.isFocused()).isTrue();
+            mView2.requestFocus();
+            assertThat(mView2.isFocused()).isTrue();
+
+            // Without cache, it should focus on the default or the first view in the FocusArea.
+            mFocusArea1.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mView1.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionFocus_lastFocusedViewRemoved() {
+        mFocusArea1.post(() -> {
+            // Focus on mDefaultFocus2 in mFocusArea2, then mView1 in mFocusArea21.
+            mDefaultFocus2.requestFocus();
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            // Remove mDefaultFocus2, then Perform ACTION_FOCUS on mFocusArea2.
+            mFocusArea2.removeView(mDefaultFocus2);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
+
+            // mView2 in mFocusArea2 should get focused.
+            assertThat(mView2.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_enabledCache() {
+        mFocusArea1.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, then nudge to mFocusArea2.
+            mButton1.requestFocus();
+            assertThat(mButton1.isFocused()).isTrue();
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+
+            // 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);
+            assertThat(mButton1.isFocused()).isTrue();
+
+            // 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);
+            assertThat(mButton1.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_mixedCache() {
+        mFocusArea1.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, then nudge to mFocusArea2.
+            mButton1.requestFocus();
+            assertThat(mButton1.isFocused()).isTrue();
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+
+            // 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);
+            assertThat(mView1.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_mixedCache2() {
+        mFocusArea1.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();
+            assertThat(mButton1.isFocused()).isTrue();
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+
+            // 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);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionNudgeToAnotherFocusArea_specifiedTarget() {
+        mFocusArea1.post(() -> {
+            // Nudge to specified FocusArea.
+            mView4.requestFocus();
+            assertThat(mView4.isFocused()).isTrue();
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_LEFT);
+            mFocusArea4.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+
+            // Direction doesn't match specified FocusArea. The focus should stay the same.
+            mView4.requestFocus();
+            assertThat(mView4.isFocused()).isTrue();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
+            mFocusArea4.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
+            assertThat(mView4.isFocused()).isTrue();
+
+            // The FocusArea doesn't specify a target FocusArea. The focus should stay the same.
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_LEFT);
+            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
+            assertThat(mView1.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testDefaultFocusOverridesHistory_override() {
+        mFocusArea1.post(() -> {
+            RotaryCache cache =
+                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
+            mFocusArea2.setRotaryCache(cache);
+            mFocusArea2.setDefaultFocusOverridesHistory(true);
+
+            mView2.requestFocus();
+            assertThat(mView2.isFocused()).isTrue();
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            // The focused view should be the default focus view rather than the cached view.
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testDefaultFocusOverridesHistory_notOverride() {
+        mFocusArea1.post(() -> {
+            RotaryCache cache =
+                    new RotaryCache(CACHE_TYPE_NEVER_EXPIRE, 0, CACHE_TYPE_NEVER_EXPIRE, 0);
+            mFocusArea2.setRotaryCache(cache);
+            mFocusArea2.setDefaultFocusOverridesHistory(false);
+
+            mView2.requestFocus();
+            assertThat(mView2.isFocused()).isTrue();
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            // The focused view should be the cached view rather than the default focus view.
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mView2.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testClearFocusAreaHistoryWhenRotating_clear() {
+        mFocusArea1.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();
+            assertThat(mView1.isFocused()).isTrue();
+
+            // Nudging down from mFocusArea1 to mFocusArea2.
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+            // Rotate.
+            mView2.requestFocus();
+            assertThat(mView2.isFocused()).isTrue();
+            // Since nudge history is cleared, nudging up should fail and the focus should stay
+            // the same.
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
+            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
+            assertThat(mView2.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testClearFocusAreaHistoryWhenRotating_notClear() {
+        mFocusArea1.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();
+            assertThat(mView1.isFocused()).isTrue();
+
+            // Nudging down from mFocusArea1 to mFocusArea2.
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+            // Rotate.
+            mView2.requestFocus();
+            assertThat(mView2.isFocused()).isTrue();
+            // 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);
+            assertThat(mView1.isFocused()).isTrue();
+        });
     }
 
     @Test
     public void testBoundsOffset() {
-        assertThat(mFocusArea.getLayoutDirection()).isEqualTo(LAYOUT_DIRECTION_LTR);
+        assertThat(mFocusArea1.getLayoutDirection()).isEqualTo(LAYOUT_DIRECTION_LTR);
 
         // FocusArea's bounds offset specified in layout file:
         // 10dp(start), 20dp(end), 30dp(top), 40dp(bottom).
@@ -133,36 +428,33 @@
         int right = dp2Px(20);
         int top = dp2Px(30);
         int bottom = dp2Px(40);
-        AccessibilityNodeInfo node = mFocusArea.createAccessibilityNodeInfo();
+        AccessibilityNodeInfo node = mFocusArea1.createAccessibilityNodeInfo();
         assertBoundsOffset(node, left, top, right, bottom);
         node.recycle();
     }
 
     @Test
-    public void testBoundsOffsetWithRtl() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
-        mFocusArea.post(() -> {
-            mFocusArea.setLayoutDirection(LAYOUT_DIRECTION_RTL);
-            latch.countDown();
-        });
-        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusArea.getLayoutDirection()).isEqualTo(LAYOUT_DIRECTION_RTL);
+    public void testBoundsOffsetWithRtl() {
+        mFocusArea1.post(() -> {
+            mFocusArea1.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+            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 = mFocusArea.createAccessibilityNodeInfo();
-        assertBoundsOffset(node, left, top, right, bottom);
-        node.recycle();
+            // 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() {
-        mFocusArea.setBoundsOffset(50, 60, 70, 80);
-        AccessibilityNodeInfo node = mFocusArea.createAccessibilityNodeInfo();
+        mFocusArea1.setBoundsOffset(50, 60, 70, 80);
+        AccessibilityNodeInfo node = mFocusArea1.createAccessibilityNodeInfo();
         assertBoundsOffset(node, 50, 60, 70, 80);
         node.recycle();
     }
@@ -181,20 +473,37 @@
     }
 
     @Test
-    public void testLastFocusedViewRemoved() {
-        mChild1.post(() -> {
-            // Focus on mChild1 in mFocusArea2, then mChild in mFocusArea .
-            mChild1.requestFocus();
-            assertThat(mChild1.isFocused()).isTrue();
-            mChild.requestFocus();
-            assertThat(mChild.isFocused()).isTrue();
+    public void testBug170423337() {
+        mFocusArea1.post(() -> {
+            // Focus on app bar (assume mFocusArea1 is app bar).
+            mView1.requestFocus();
 
-            // Remove mChild1 in mFocusArea2, then Perform ACTION_FOCUS on mFocusArea2.
-            mFocusArea2.removeView(mChild1);
-            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
+            // Nudge down to browse list (assume mFocusArea2 is browse list).
+            Bundle arguments = new Bundle();
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
 
-            // mChild2 in mFocusArea2 should get focused.
-            assertThat(mChild2.isFocused()).isTrue();
+            // Nudge down to playback control bar (assume mFocusArea3 is playback control bar).
+            mFocusArea3.performAccessibilityAction(ACTION_FOCUS, arguments);
+            assertThat(mView3.isFocused()).isTrue();
+
+            // 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);
+            assertThat(mView3.isFocused()).isTrue();
+
+            // Nudge up to browse list.
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
+            mFocusArea3.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
+            assertThat(mDefaultFocus2.isFocused()).isTrue();
+
+            // Nudge up, and it should focus on app bar.
+            mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
+            assertThat(mView1.isFocused()).isTrue();
         });
     }
 
@@ -212,9 +521,10 @@
         return (int) (dp * mActivity.getResources().getDisplayMetrics().density + 0.5f);
     }
 
-    private void assertDrawMethodsCalled(CountDownLatch latch) throws Exception {
+    private void assertDrawMethodsCalled(@NonNull TestFocusArea focusArea, CountDownLatch latch)
+            throws Exception {
         latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        assertThat(mFocusArea.onDrawCalled()).isTrue();
-        assertThat(mFocusArea.drawCalled()).isTrue();
+        assertThat(focusArea.onDrawCalled()).isTrue();
+        assertThat(focusArea.drawCalled()).isTrue();
     }
 }
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTouchModeTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTouchModeTest.java
new file mode 100644
index 0000000..5c06f84
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTouchModeTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ui.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-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTest.java
index 887ac8e..e706ae1 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTest.java
@@ -16,64 +16,242 @@
 
 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.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.ui.recyclerview.TestContentLimitingAdapter;
 import com.android.car.ui.test.R;
+import com.android.car.ui.utils.CarUiUtils;
 
 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}. */
+/** Unit test for {@link FocusParkingView} not in touch mode. */
 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 TestContentLimitingAdapter(NUM_ITEMS));
+            CarUiUtils.setRotaryScrollEnabled(mList, /* isVertical= */ true);
+        });
     }
 
     @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();
+    public void testGetWidthAndHeight() {
+        assertThat(mFpv.getWidth()).isEqualTo(1);
+        assertThat(mFpv.getHeight()).isEqualTo(1);
     }
+
     @Test
-    public void testFocusParkingViewFocusedWhenWindowLostFocus() throws Exception {
-        FocusParkingView focusParkingView = mActivity.findViewById(R.id.focus_parking);
-        assertThat(focusParkingView.isFocused()).isFalse();
+    public void testRequestFocus_focusOnDefaultFocus() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
 
-        CountDownLatch latch = new CountDownLatch(1);
-        focusParkingView.post(() -> {
-            focusParkingView.onWindowFocusChanged(false);
-            focusParkingView.post(() -> {
-                latch.countDown();
-            });
+            mFpv.requestFocus();
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
         });
-        latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+    }
 
-        assertThat(focusParkingView.isFocused()).isTrue();
+    @Test
+    public void testRestoreDefaultFocus_focusOnDefaultFocus() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            mFpv.restoreDefaultFocus();
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testOnWindowFocusChanged_loseFocus() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            mFpv.onWindowFocusChanged(false);
+            assertThat(mFpv.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testOnWindowFocusChanged_focusOnDefaultFocus() {
+        mFpv.post(() -> {
+            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mFpv.isFocused()).isTrue();
+
+            mFpv.onWindowFocusChanged(true);
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionRestoreDefaultFocus() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            mFpv.performAccessibilityAction(ACTION_RESTORE_DEFAULT_FOCUS, null);
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testPerformAccessibilityAction_actionFocus() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            mFpv.performAccessibilityAction(ACTION_FOCUS, null);
+            assertThat(mFpv.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testRestoreFocusInRoot_recyclerViewItemRemoved() {
+        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();
+
+                        ViewGroup parent = (ViewGroup) firstItem.getParent();
+                        parent.removeView(firstItem);
+                        assertThat(mFocusedByDefault.isFocused()).isTrue();
+                    }
+                })
+        );
+    }
+
+    @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() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            ViewGroup parent = (ViewGroup) mView1.getParent();
+            parent.removeView(mView1);
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testRestoreFocusInRoot_focusedViewDisabled() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            mView1.setEnabled(false);
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testRestoreFocusInRoot_focusedViewBecomesInvisible() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            mView1.setVisibility(View.INVISIBLE);
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testRestoreFocusInRoot_focusedViewParentBecomesInvisible() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+
+            mParent1.setVisibility(View.INVISIBLE);
+            assertThat(mFocusedByDefault.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testRequestFocus_focusesFpvWhenShouldRestoreFocusIsFalse() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+            mFpv.setShouldRestoreFocus(false);
+
+            mFpv.requestFocus();
+            assertThat(mFpv.isFocused()).isTrue();
+        });
+    }
+
+    @Test
+    public void testRestoreDefaultFocus_focusesFpvWhenShouldRestoreFocusIsFalse() {
+        mFpv.post(() -> {
+            mView1.requestFocus();
+            assertThat(mView1.isFocused()).isTrue();
+            mFpv.setShouldRestoreFocus(false);
+
+            mFpv.restoreDefaultFocus();
+            assertThat(mFpv.isFocused()).isTrue();
+        });
     }
 }
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java
new file mode 100644
index 0000000..d872bb6
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.ui.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-ui-lib/src/androidTest/java/com/android/car/ui/RotaryCacheTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/RotaryCacheTest.java
new file mode 100644
index 0000000..b1b9b59
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/RotaryCacheTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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-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
new file mode 100644
index 0000000..11d33f4
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenControllerTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+
+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 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.when;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.inputmethodservice.ExtractEditText;
+import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.InputMethodService.Insets;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.FrameLayout;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.rule.ActivityTestRule;
+
+import com.android.car.ui.test.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link CarUiImeWideScreenController}.
+ */
+public class CarUiImeWideScreenControllerTest {
+
+    private Context mContext = ApplicationProvider.getApplicationContext();
+
+    @Mock
+    Context mMockContext;
+
+    @Mock
+    InputMethodService mInputMethodService;
+
+    @Mock
+    Dialog mDialog;
+
+    @Mock
+    Window mWindow;
+
+    private CarUiImeWideScreenTestActivity mActivity;
+
+    @Rule
+    public ActivityTestRule<CarUiImeWideScreenTestActivity> mActivityRule =
+            new ActivityTestRule<>(CarUiImeWideScreenTestActivity.class);
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mActivity = mActivityRule.getActivity();
+    }
+
+    @After
+    public void destroy() {
+        mActivity.finish();
+    }
+
+    @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_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(mInputMethodService.getWindow()).thenReturn(mDialog);
+        when(mDialog.getWindow()).thenReturn(mWindow);
+        View view = new FrameLayout(mContext);
+        view.setTop(0);
+        view.setBottom(200);
+        when(mWindow.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(mInputMethodService.getWindow()).thenReturn(mDialog);
+        when(mDialog.getWindow()).thenReturn(mWindow);
+        View view = new FrameLayout(mContext);
+        view.setTop(0);
+        view.setBottom(200);
+        when(mWindow.getDecorView()).thenReturn(view);
+
+        View imeInputView = LayoutInflater.from(mContext)
+                .inflate(R.layout.test_ime_input_view, null, false);
+        CarUiImeWideScreenController carUiImeWideScreenController = getController();
+        carUiImeWideScreenController.setExtractEditText(new ExtractEditText(mContext));
+        carUiImeWideScreenController.createWideScreenImeView(imeInputView);
+
+        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));
+    }
+
+    private CarUiImeWideScreenController getController() {
+        return new CarUiImeWideScreenController(mContext, mInputMethodService) {
+            @Override
+            public boolean isWideScreenMode() {
+                return true;
+            }
+        };
+    }
+}
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
new file mode 100644
index 0000000..8ffd5a2
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenTestActivity.java
@@ -0,0 +1,54 @@
+/*
+ * 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.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+
+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;
+            }
+        };
+
+        View imeInputView = LayoutInflater.from(this)
+                .inflate(R.layout.test_ime_input_view, null, false);
+
+        View templateView = sCarUiImeWideScreenController.createWideScreenImeView(imeInputView);
+
+        root.addView(templateView);
+    }
+}
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
new file mode 100644
index 0000000..5ab1a86
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/PaddingMatcher.java
@@ -0,0 +1,81 @@
+/*
+ * 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/ViewMatchers.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/matchers/ViewMatchers.java
index 74ce4fa..cdef653 100644
--- 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
@@ -18,6 +18,8 @@
 
 import android.view.View;
 
+import com.android.car.ui.matchers.PaddingMatcher.Side;
+
 import org.hamcrest.Matcher;
 
 public class ViewMatchers {
@@ -32,4 +34,12 @@
     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);
+    }
 }
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
new file mode 100644
index 0000000..33aaa18
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/preference/NonFullscreenPreferenceFragmentTest.java
@@ -0,0 +1,200 @@
+/*
+ * 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.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);
+
+            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());
+            } else {
+                // No-op marker for the preference fragment to handle it
+            }
+        }
+    }
+
+    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
+        protected boolean isFullScreenFragment() {
+            return mIsFullScreen;
+        }
+    }
+}
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
index bd21173..da446e1 100644
--- 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
@@ -29,13 +29,10 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
 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.R;
@@ -43,7 +40,6 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -242,7 +238,8 @@
 
         CarUiContentListItem.OnClickListener clickListener = mock(
                 CarUiContentListItem.OnClickListener.class);
-        View.OnClickListener supplementalIconClickListener = mock(View.OnClickListener.class);
+        CarUiContentListItem.OnClickListener supplementalIconClickListener = mock(
+                CarUiContentListItem.OnClickListener.class);
 
         CarUiContentListItem item = new CarUiContentListItem(
                 CarUiContentListItem.Action.ICON);
@@ -262,18 +259,14 @@
         // listener.
         onView(withId(R.id.title)).perform(click());
         verify(clickListener, times(1)).onClick(item);
-        verify(supplementalIconClickListener, times(0)).onClick(any());
+        verify(supplementalIconClickListener, times(0)).onClick(item);
 
-        ArgumentCaptor<View> iconCaptor = ArgumentCaptor.forClass(View.class);
         onView(withId(R.id.supplemental_icon)).perform(click());
         // Check that icon is argument for single call to click listener.
-        verify(supplementalIconClickListener, times(1)).onClick(iconCaptor.capture());
+        verify(supplementalIconClickListener, times(1)).onClick(item);
 
         // Verify that the standard click listener wasn't also fired.
         verify(clickListener, times(1)).onClick(item);
-
-        View icon = mCarUiRecyclerView.findViewById(R.id.supplemental_icon);
-        assertEquals(icon, iconCaptor.getValue());
     }
 
     @Test
@@ -282,7 +275,8 @@
 
         CarUiContentListItem.OnClickListener mockedItemOnClickListener = mock(
                 CarUiContentListItem.OnClickListener.class);
-        View.OnClickListener mockedIconListener = mock(View.OnClickListener.class);
+        CarUiContentListItem.OnClickListener mockedIconListener = mock(
+                CarUiContentListItem.OnClickListener.class);
 
         CarUiContentListItem item = new CarUiContentListItem(
                 CarUiContentListItem.Action.ICON);
@@ -306,7 +300,7 @@
         // Clicks anywhere on the icon should invoke both listeners.
         onView(withId(R.id.action_container)).perform(click());
         verify(mockedItemOnClickListener, times(1)).onClick(item);
-        verify(mockedIconListener, times(1)).onClick(any(View.class));
+        verify(mockedIconListener, times(1)).onClick(item);
     }
 
     @Test
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
index 79a26f1..ea4a8c3 100644
--- 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
@@ -41,8 +41,10 @@
 
 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;
@@ -159,6 +161,9 @@
         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 CarUiRecyclerView(mTestableContext);
         ViewGroup container = mActivity.findViewById(R.id.test_container);
         TestAdapter adapter = new TestAdapter(4);
@@ -203,6 +208,9 @@
         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 CarUiRecyclerView(mTestableContext);
         ViewGroup container = mActivity.findViewById(R.id.test_container);
         TestAdapter adapter = new TestAdapter(4);
@@ -328,7 +336,14 @@
         onView(withId(R.id.list)).check(matches(isDisplayed()));
 
         CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
-        FixedSizeTestAdapter adapter = new FixedSizeTestAdapter(50, carUiRecyclerView.getHeight());
+
+        // 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));
@@ -337,6 +352,9 @@
         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());
 
@@ -507,46 +525,48 @@
         });
 
         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;
+        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));
-
-        onView(withText(adapter.getItemText(longItemPosition))).check(matches(isDisplayed()));
+        // 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(carUiRecyclerView.getTop())));
+                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(0)));
+        assertThat(orientationHelper.getDecoratedStart(longItem),
+                is(equalTo(orientationHelper.getStartAfterPadding())));
         assertThat(orientationHelper.getDecoratedEnd(longItem),
-                is(greaterThan(carUiRecyclerView.getBottom())));
+                is(greaterThan(orientationHelper.getEndAfterPadding())));
 
         // Set a limit to avoid test stuck in non-moving state.
-        while (orientationHelper.getDecoratedEnd(longItem) > carUiRecyclerView.getBottom()) {
+        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(carUiRecyclerView.getHeight())));
+                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(carUiRecyclerView.getTop())));
+                is(lessThan(orientationHelper.getStartAfterPadding())));
     }
 
     @Test
@@ -575,6 +595,7 @@
         });
 
         IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
 
         OrientationHelper orientationHelper =
                 OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -589,9 +610,8 @@
         View longItem = getLongItem(carUiRecyclerView);
         // Making sure we've reached end of the recyclerview, after
         // adding bottom padding
-        assertThat(orientationHelper.getDecoratedEnd(longItem)
-                        + carUiRecyclerView.getPaddingBottom(),
-                is(equalTo(carUiRecyclerView.getHeight())));
+        assertThat(orientationHelper.getDecoratedEnd(longItem),
+                is(equalTo(orientationHelper.getEndAfterPadding())));
     }
 
     @Test
@@ -615,6 +635,7 @@
         });
 
         IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
 
         OrientationHelper orientationHelper =
                 OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -624,27 +645,25 @@
 
         // Verify long item is off-screen.
         View longItem = getLongItem(carUiRecyclerView);
+
         assertThat(
                 orientationHelper.getDecoratedEnd(longItem),
-                is(greaterThan(carUiRecyclerView.getTop())));
+                is(lessThanOrEqualTo(orientationHelper.getEndAfterPadding())));
 
-        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) {
+        if (orientationHelper.getStartAfterPadding() - orientationHelper.getDecoratedStart(longItem)
+                < orientationHelper.getTotalSpace()) {
             onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-            decoratedStart = orientationHelper.getDecoratedStart(longItem);
-        }
+            assertThat(orientationHelper.getDecoratedStart(longItem),
+                    is(greaterThanOrEqualTo(orientationHelper.getStartAfterPadding())));
+        } else {
+            int topBeforeClick = orientationHelper.getDecoratedStart(longItem);
 
-        // Verify long item top is aligned to top.
-        assertThat(orientationHelper.getDecoratedStart(longItem), is(equalTo(0)));
+            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
@@ -668,6 +687,7 @@
         });
 
         IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
 
         OrientationHelper orientationHelper =
                 OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -685,20 +705,21 @@
         View longItem = getLongItem(carUiRecyclerView);
         assertThat(
                 orientationHelper.getDecoratedStart(longItem),
-                is(greaterThan(carUiRecyclerView.getTop())));
+                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(0)));
+        assertThat(orientationHelper.getDecoratedStart(longItem),
+                is(equalTo(orientationHelper.getStartAfterPadding())));
         assertThat(orientationHelper.getDecoratedEnd(longItem),
-                is(greaterThan(carUiRecyclerView.getBottom())));
+                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(carUiRecyclerView.getHeight())));
+                not(equalTo(orientationHelper.getEndAfterPadding())));
     }
 
     @Test
@@ -727,6 +748,7 @@
         });
 
         IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+        onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
 
         OrientationHelper orientationHelper =
                 OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -741,12 +763,10 @@
         View longItem = getLongItem(carUiRecyclerView);
         // Making sure we've reached end of the recyclerview, after
         // adding bottom padding
-        assertThat(orientationHelper.getDecoratedEnd(longItem)
-                        + carUiRecyclerView.getPaddingBottom(),
-                is(equalTo(carUiRecyclerView.getHeight())));
+        assertThat(orientationHelper.getDecoratedEnd(longItem),
+                is(equalTo(orientationHelper.getEndAfterPadding())));
     }
 
-
     @Test
     public void testPageDownMaintainsMinimumScrollThumbTrackHeight() {
         mActivity.runOnUiThread(
@@ -849,6 +869,58 @@
         assertThat(mCarUiRecyclerView.getPaddingEnd(), is(equalTo(10)));
     }
 
+    @Test
+    public void testSetAlphaToRecyclerViewWithoutScrollbar() {
+        doReturn(false).when(mTestableResources).getBoolean(R.bool.car_ui_scrollbar_enable);
+
+        CarUiRecyclerView mCarUiRecyclerView = new CarUiRecyclerView(mTestableContext);
+
+        assertThat(mCarUiRecyclerView.getAlpha(), is(equalTo(1.0f)));
+
+        mCarUiRecyclerView.setAlpha(0.5f);
+
+        assertThat(mCarUiRecyclerView.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 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()));
+
+        ViewGroup recyclerViewContainer = (ViewGroup) carUiRecyclerView.getParent().getParent();
+
+        assertThat(carUiRecyclerView.animate(), is(equalTo(recyclerViewContainer.animate())));
+    }
+
     /**
      * 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
@@ -857,10 +929,12 @@
      * @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);
+        OrientationHelper orientationHelper =
+                OrientationHelper.createVerticalHelper(recyclerView.getLayoutManager());
+        for (int i = 0; i < recyclerView.getLayoutManager().getChildCount(); i++) {
+            View item = recyclerView.getLayoutManager().getChildAt(i);
 
-            if (item.getHeight() > recyclerView.getHeight()) {
+            if (item.getHeight() > orientationHelper.getTotalSpace()) {
                 return item;
             }
         }
@@ -941,16 +1015,29 @@
         }
     }
 
-    private static class FixedSizeTestAdapter extends RecyclerView.Adapter<TestViewHolder> {
+    private static class PerfectFitTestAdapter extends RecyclerView.Adapter<TestViewHolder> {
 
-        private static final int ITEMS_PER_PAGE = 5;
+        private static final int MIN_HEIGHT = 30;
         private final List<String> mData;
         private final int mItemHeight;
 
-        FixedSizeTestAdapter(int itemCount, int recyclerViewHeight) {
-            mData = new ArrayList<>(itemCount);
-            mItemHeight = recyclerViewHeight / ITEMS_PER_PAGE;
+        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));
             }
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
index a65be43..1af9a70 100644
--- 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
@@ -31,7 +31,7 @@
 
     private final List<String> mItems;
 
-    TestContentLimitingAdapter(int numItems) {
+    public TestContentLimitingAdapter(int numItems) {
         mItems = new ArrayList<>();
         for (int i = 0; i < numItems; i++) {
             mItems.add("Item " + i);
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTest.java
new file mode 100644
index 0000000..3cc9b7e
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTest.java
@@ -0,0 +1,485 @@
+/*
+ * 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 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.google.common.truth.Truth.assertThat;
+
+import android.view.View;
+import android.view.ViewTreeObserver;
+
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.test.rule.ActivityTestRule;
+
+import com.android.car.ui.FocusArea;
+import com.android.car.ui.FocusParkingView;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.recyclerview.TestContentLimitingAdapter;
+import com.android.car.ui.test.R;
+
+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 CarUiRecyclerView 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 TestContentLimitingAdapter(/* numItems= */ 2));
+            CarUiUtils.setRotaryScrollEnabled(mList5, /* isVertical= */ true);
+        });
+    }
+
+    @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 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 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-ui-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTestActivity.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTestActivity.java
new file mode 100644
index 0000000..87434d4
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/utils/ViewUtilsTestActivity.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.utils;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.car.ui.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-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
new file mode 100644
index 0000000..e260300
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/car_ui_ime_wide_screen_test_activity.xml
@@ -0,0 +1,22 @@
+<?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/focus_area_test_activity.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_area_test_activity.xml
index 524de8d..da1255d 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_area_test_activity.xml
+++ b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_area_test_activity.xml
@@ -18,52 +18,79 @@
     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">
-    <View
-        android:focusable="true"
-        android:layout_width="100dp"
-        android:layout_height="100dp"/>
+    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_area"
+        android:id="@+id/focus_area1"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        app:defaultFocus="@+id/default_focus"
         app:startBoundOffset="10dp"
         app:endBoundOffset="20dp"
         app:topBoundOffset="30dp"
         app:bottomBoundOffset="40dp">
         <View
-            android:id="@+id/child"
+            android:id="@+id/view1"
             android:focusable="true"
             android:layout_width="100dp"
             android:layout_height="100dp"/>
-        <View
-            android:id="@+id/default_focus"
-            android:focusable="true"
+        <Button
+            android:id="@+id/button1"
             android:layout_width="100dp"
             android:layout_height="100dp"/>
     </com.android.car.ui.TestFocusArea>
-    <View
-        android:id="@+id/non_child"
-        android:focusable="true"
-        android:layout_width="100dp"
-        android:layout_height="100dp"/>
     <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/child1"
+            android:id="@+id/view2"
             android:focusable="true"
             android:layout_width="100dp"
             android:layout_height="100dp"/>
         <View
-            android:id="@+id/child2"
+            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"/>
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_parking_view_test_activity.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_parking_view_test_activity.xml
index f3f623d..02d7326 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_parking_view_test_activity.xml
+++ b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_parking_view_test_activity.xml
@@ -14,18 +14,32 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
+<LinearLayout
     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: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"/>
-</FrameLayout>
+</LinearLayout>
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
index 7e8717e..8297f6b 100644
--- 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
@@ -18,7 +18,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:focusable="true">
 
     <TextView
         android:layout_width="wrap_content"
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
new file mode 100644
index 0000000..6b1fcb8
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/test_ime_input_view.xml
@@ -0,0 +1,22 @@
+<?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
index e789145..1fab70e 100644
--- 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
@@ -18,7 +18,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:focusable="true">
 
     <TextView
         android:layout_width="wrap_content"
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/view_utils_test_activity.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/view_utils_test_activity.xml
new file mode 100644
index 0000000..72c2366
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/view_utils_test_activity.xml
@@ -0,0 +1,92 @@
+<?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">
+        <com.android.car.ui.recyclerview.CarUiRecyclerView
+            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-ui-lib/src/androidTest/res/values/strings.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/values/strings.xml
index 21f4ee4..7926d9c 100644
--- 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
@@ -31,4 +31,10 @@
     <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-array name="test_string_array">
+        <item>Item 1</item>
+        <item>Item 2</item>
+        <item>Item 3</item>
+    </string-array>
 </resources>
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
index a025e9e..ed508d3 100644
--- 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
@@ -15,12 +15,20 @@
  */
 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.InputFilter;
 import android.text.TextUtils;
 import android.text.TextWatcher;
@@ -28,6 +36,7 @@
 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;
@@ -60,6 +69,41 @@
     private CharSequence mSubtitle;
     private Drawable mIcon;
     private boolean mIconTinted;
+    private boolean mAllowDismissButton = true;
+    private boolean mHasSingleChoiceBodyButton = false;
+    private EditText mCarUiEditText;
+    private InputMethodManager mInputMethodManager;
+    private String mWideScreenTitle;
+    private String mWideScreenTitleDesc;
+    private ViewGroup mRoot;
+
+    // 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.
@@ -68,6 +112,8 @@
 
     public AlertDialogBuilder(Context context, int themeResId) {
         mBuilder = new AlertDialog.Builder(context, themeResId);
+        mInputMethodManager = (InputMethodManager)
+                context.getSystemService(Context.INPUT_METHOD_SERVICE);
         mContext = context;
     }
 
@@ -329,6 +375,7 @@
     public AlertDialogBuilder setItems(@ArrayRes int itemsId,
             final DialogInterface.OnClickListener listener) {
         mBuilder.setItems(itemsId, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -341,6 +388,7 @@
     public AlertDialogBuilder setItems(CharSequence[] items,
             final DialogInterface.OnClickListener listener) {
         mBuilder.setItems(items, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -353,6 +401,7 @@
     public AlertDialogBuilder setAdapter(final ListAdapter adapter,
             final DialogInterface.OnClickListener listener) {
         mBuilder.setAdapter(adapter, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -363,6 +412,7 @@
      */
     public AlertDialogBuilder setAdapter(final CarUiListItemAdapter adapter) {
         setCustomList(adapter);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -390,6 +440,7 @@
             final DialogInterface.OnClickListener listener,
             String labelColumn) {
         mBuilder.setCursor(cursor, listener, labelColumn);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -413,6 +464,7 @@
     public AlertDialogBuilder setMultiChoiceItems(@ArrayRes int itemsId, boolean[] checkedItems,
             final DialogInterface.OnMultiChoiceClickListener listener) {
         mBuilder.setMultiChoiceItems(itemsId, checkedItems, listener);
+        mHasSingleChoiceBodyButton = false;
         return this;
     }
 
@@ -435,6 +487,7 @@
     public AlertDialogBuilder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,
             final DialogInterface.OnMultiChoiceClickListener listener) {
         mBuilder.setMultiChoiceItems(items, checkedItems, listener);
+        mHasSingleChoiceBodyButton = false;
         return this;
     }
 
@@ -460,6 +513,7 @@
             String labelColumn,
             final DialogInterface.OnMultiChoiceClickListener listener) {
         mBuilder.setMultiChoiceItems(cursor, isCheckedColumn, labelColumn, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -480,6 +534,7 @@
     public AlertDialogBuilder setSingleChoiceItems(@ArrayRes int itemsId, int checkedItem,
             final DialogInterface.OnClickListener listener) {
         mBuilder.setSingleChoiceItems(itemsId, checkedItem, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -502,6 +557,7 @@
             String labelColumn,
             final DialogInterface.OnClickListener listener) {
         mBuilder.setSingleChoiceItems(cursor, checkedItem, labelColumn, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -521,6 +577,7 @@
     public AlertDialogBuilder setSingleChoiceItems(CharSequence[] items, int checkedItem,
             final DialogInterface.OnClickListener listener) {
         mBuilder.setSingleChoiceItems(items, checkedItem, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -534,6 +591,7 @@
     public AlertDialogBuilder setSingleChoiceItems(ListAdapter adapter, int checkedItem,
             final DialogInterface.OnClickListener listener) {
         mBuilder.setSingleChoiceItems(adapter, checkedItem, listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -548,13 +606,13 @@
      * 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;
     }
 
@@ -570,6 +628,7 @@
      */
     public AlertDialogBuilder setSingleChoiceItems(CarUiRadioButtonListItemAdapter adapter) {
         setCustomList(adapter);
+        mHasSingleChoiceBodyButton = false;
         return this;
     }
 
@@ -583,6 +642,7 @@
     public AlertDialogBuilder setOnItemSelectedListener(
             final AdapterView.OnItemSelectedListener listener) {
         mBuilder.setOnItemSelectedListener(listener);
+        mHasSingleChoiceBodyButton = true;
         return this;
     }
 
@@ -602,19 +662,19 @@
         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);
+        mCarUiEditText = CarUiUtils.requireViewByRefId(contentView, R.id.textbox);
+        mCarUiEditText.setText(prompt);
 
         if (textChangedListener != null) {
-            editText.addTextChangedListener(textChangedListener);
+            mCarUiEditText.addTextChangedListener(textChangedListener);
         }
 
         if (inputFilters != null) {
-            editText.setFilters(inputFilters);
+            mCarUiEditText.setFilters(inputFilters);
         }
 
         if (inputType != 0) {
-            editText.setInputType(inputType);
+            mCarUiEditText.setInputType(inputType);
         }
 
         mBuilder.setView(contentView);
@@ -635,6 +695,35 @@
         return setEditBox(prompt, textChangedListener, inputFilters, 0);
     }
 
+    /**
+     * 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;
+    }
+
+    /**
+     * 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;
+    }
 
     /** Final steps common to both {@link #create()} and {@link #show()} */
     private void prepareDialog() {
@@ -659,7 +748,14 @@
         }
         mBuilder.setCustomTitle(customTitle);
 
-        if (!mNeutralButtonSet && !mNegativeButtonSet && !mPositiveButtonSet) {
+        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) -> {
@@ -683,9 +779,13 @@
         // 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();
+        mRoot = (ViewGroup) alertDialog.getWindow().getDecorView().getRootView();
         FocusParkingView fpv = new FocusParkingView(mContext);
-        root.addView(fpv);
+        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;
     }
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
index f5c6c1d..0488d28 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
@@ -25,11 +25,14 @@
 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.android.car.ui.utils.ViewUtils.NO_FOCUS;
+import static com.android.car.ui.utils.ViewUtils.REGULAR_FOCUS;
 
 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;
@@ -38,7 +41,6 @@
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.LinearLayout;
 
@@ -282,13 +284,14 @@
 
     /**
      * Updates {@link #mPreviousFocusArea} when the focus has moved from another FocusArea to this
-     * FocusArea.
+     * FocusArea, and sets it to {@code null} in any other cases.
      */
     private void maybeUpdatePreviousFocusArea(boolean hasFocus, View oldFocus) {
-        if (mHasFocus || !hasFocus || oldFocus == null) {
+        if (mHasFocus || !hasFocus || oldFocus == null || oldFocus instanceof FocusParkingView) {
+            mPreviousFocusArea = null;
             return;
         }
-        mPreviousFocusArea = getAncestorFocusArea(oldFocus);
+        mPreviousFocusArea = ViewUtils.getAncestorFocusArea(oldFocus);
         if (mPreviousFocusArea == null) {
             Log.w(TAG, "No parent FocusArea for " + oldFocus);
         }
@@ -305,7 +308,7 @@
         if (!hasFocus || oldFocus == null) {
             return;
         }
-        FocusArea oldFocusArea = getAncestorFocusArea(oldFocus);
+        FocusArea oldFocusArea = ViewUtils.getAncestorFocusArea(oldFocus);
         if (oldFocusArea != this) {
             return;
         }
@@ -456,6 +459,28 @@
     }
 
     @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 from the currently focused view if one of this
+        // FocusArea's descendants is a better focus candidate than the currently focused view.
+        if (hasWindowFocus && !isInTouchMode()) {
+            maybeAdjustFocus();
+        }
+        super.onWindowFocusChanged(hasWindowFocus);
+    }
+
+    /**
+     * Focuses on another 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:
@@ -480,12 +505,6 @@
     }
 
     private boolean focusOnDescendant() {
-        if (focusOnFocusedByDefaultView()) {
-            return true;
-        }
-        if (focusOnPrimaryFocusView()) {
-            return true;
-        }
         if (mDefaultFocusOverridesHistory) {
             // Check mDefaultFocus before last focused view.
             if (focusDefaultFocusView() || focusOnLastFocusedView()) {
@@ -500,28 +519,26 @@
         return focusOnFirstFocusableView();
     }
 
-    private boolean focusOnFocusedByDefaultView() {
-        View focusedByDefaultView = ViewUtils.findFocusedByDefaultView(this);
-        return requestFocus(focusedByDefaultView);
-    }
-
-    private boolean focusOnPrimaryFocusView() {
-        View primaryFocus = ViewUtils.findPrimaryFocusView(this);
-        return requestFocus(primaryFocus);
-    }
-
     private boolean focusDefaultFocusView() {
-        return requestFocus(mDefaultFocusView);
+        return ViewUtils.adjustFocus(this, /* currentLevel= */ REGULAR_FOCUS);
+    }
+
+    /**
+     * Gets the {@code app:defaultFocus} view.
+     *
+     * @hidden
+     */
+    public View getDefaultFocusView() {
+        return mDefaultFocusView;
     }
 
     private boolean focusOnLastFocusedView() {
         View lastFocusedView = mRotaryCache.getFocusedView(SystemClock.uptimeMillis());
-        return requestFocus(lastFocusedView);
+        return ViewUtils.requestFocus(lastFocusedView);
     }
 
     private boolean focusOnFirstFocusableView() {
-        View firstFocusableView = ViewUtils.findFocusableDescendant(this);
-        return requestFocus(firstFocusableView);
+        return ViewUtils.adjustFocus(this, /* currentLevel= */ NO_FOCUS);
     }
 
     private boolean nudgeToShortcutView(Bundle arguments) {
@@ -540,7 +557,7 @@
             // nudge to another FocusArea.
             return false;
         }
-        return requestFocus(mNudgeShortcutView);
+        return ViewUtils.requestFocus(mNudgeShortcutView);
     }
 
     private boolean nudgeToAnotherFocusArea(Bundle arguments) {
@@ -557,9 +574,6 @@
             success = targetFocusArea != null && targetFocusArea.focusOnDescendant();
         }
 
-        if (success) {
-            saveFocusAreaHistory(direction, this, targetFocusArea, elapsedRealtime);
-        }
         return success;
     }
 
@@ -569,14 +583,15 @@
                 : arguments.getInt(NUDGE_DIRECTION, INVALID_DIRECTION);
     }
 
-    /** Saves bidirectional FocusArea nudge history. */
     private void saveFocusAreaHistory(int direction, @NonNull FocusArea sourceFocusArea,
             @NonNull FocusArea targetFocusArea, long elapsedRealtime) {
-        sourceFocusArea.mRotaryCache.saveFocusArea(direction, targetFocusArea, elapsedRealtime);
-
-        int oppositeDirection = getOppositeDirection(direction);
-        targetFocusArea.mRotaryCache.saveFocusArea(oppositeDirection, sourceFocusArea,
-                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} */
@@ -596,17 +611,6 @@
                 + "FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, or FOCUS_RIGHT.");
     }
 
-    private 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;
-    }
-
     @Nullable
     private FocusArea getSpecifiedFocusArea(int direction) {
         maybeInitializeSpecifiedFocusAreas();
@@ -660,6 +664,19 @@
         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;
@@ -672,16 +689,11 @@
         }
     }
 
-    private boolean requestFocus(@Nullable View view) {
-        if (view == null || !view.isAttachedToWindow()) {
-            return false;
-        }
-        // 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, null);
-    }
-
-    /** Sets the padding (in pixels) of the FocusArea highlight. */
+    /**
+     * 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) {
@@ -694,7 +706,13 @@
         invalidate();
     }
 
-    /** Sets the offset (in pixels) of the FocusArea's bounds. */
+    /**
+     * 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;
@@ -702,8 +720,28 @@
         mBottomOffset = bottom;
     }
 
+    /** Sets the default focus view in this FocusArea. */
+    public void setDefaultFocus(@NonNull View defaultFocus) {
+        mDefaultFocusView = defaultFocus;
+    }
+
     @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-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java
index 8a42cea..9d5cfeb 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java
@@ -15,28 +15,34 @@
  */
 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.TypedArray;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 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. Each {@link
- * android.view.Window} should have one FocusParkingView as the first focusable view in the view
- * tree, and outside of all {@link FocusArea}s. If multiple FocusParkingView are added in the
- * window, only the first one will be focusable.
+ * 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
@@ -45,41 +51,67 @@
  * 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.
+ * <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 {
-    private static final String TAG = "FocusParkingView";
+
+    /**
+     * 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 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
+     * an {@code ActivityView}. The default value is true.
+     */
+    private boolean mShouldRestoreFocus;
 
     public FocusParkingView(Context context) {
         super(context);
-        init();
+        init(context, /* attrs= */ null);
     }
 
     public FocusParkingView(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
-        init();
+        init(context, attrs);
     }
 
     public FocusParkingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        init();
+        init(context, attrs);
     }
 
     public FocusParkingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        init();
+        init(context, attrs);
     }
 
-    private void init() {
+    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);
@@ -94,6 +126,12 @@
 
         // Prevent Android from drawing the default focus highlight for this view when it's focused.
         setDefaultFocusHighlightEnabled(false);
+
+        // Keep track of the focused view so that we can recover focus when it's removed.
+        getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) -> {
+            mFocusedView = newFocus instanceof FocusParkingView ? null : newFocus;
+            mScrollableContainer = ViewUtils.getAncestorScrollableContainer(mFocusedView);
+        });
     }
 
     @Override
@@ -107,12 +145,21 @@
     @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();
+            // 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.
+            mFocusedView = null;
+            mScrollableContainer = 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);
     }
@@ -126,21 +173,7 @@
     public boolean performAccessibilityAction(int action, Bundle arguments) {
         switch (action) {
             case ACTION_RESTORE_DEFAULT_FOCUS:
-                View root = getRootView();
-
-                // If there is a view focused by default and it can take focus, move focus to it.
-                View defaultFocus = ViewUtils.findFocusedByDefaultView(root);
-                if (defaultFocus != null) {
-                    return defaultFocus.requestFocus();
-                }
-
-                // If there is a primary focus view, move focus to it.
-                View primaryFocus = ViewUtils.findPrimaryFocusView(root);
-                if (primaryFocus != null) {
-                    return primaryFocus.requestFocus();
-                }
-
-                return false;
+                return restoreFocusInRoot(/* checkForTouchMode= */ false);
             case ACTION_HIDE_IME:
                 InputMethodManager inputMethodManager =
                         getContext().getSystemService(InputMethodManager.class);
@@ -149,33 +182,93 @@
             case ACTION_FOCUS:
                 // Don't leave this to View to handle as it will exit touch mode.
                 if (!hasFocus()) {
-                    return requestFocus();
+                    return super.requestFocus(FOCUS_DOWN, null);
                 }
-                break;
+                return false;
         }
         return super.performAccessibilityAction(action, arguments);
     }
 
     @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
+    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);
+    }
 
-        // If there is a FocusParkingView already, make the one after in the view tree
-        // non-focusable.
-        boolean []isBefore = new boolean[1];
-        View anotherFpv = ViewUtils.depthFirstSearch(getRootView(), v -> {
-            if (this == v) {
-                isBefore[0] = true;
-            }
-            return v != this && v instanceof FocusParkingView && v.isFocusable();
-        });
-        if (anotherFpv != null) {
-            Log.w(TAG, "There should be only one FocusParkingView in the window");
-            if (isBefore[0]) {
-                anotherFpv.setFocusable(false);
-            } else {
-                setFocusable(false);
+    @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 an {@code ActivityView}.  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;
+        }
+        // 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.
+        if (ViewUtils.adjustFocus(getRootView(), /* currentFocus= */ null)) {
+            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 ViewTreeObserver.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-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
index 1a8360e..1e5a46c 100644
--- 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
@@ -23,7 +23,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
 
 import androidx.annotation.LayoutRes;
@@ -47,7 +46,7 @@
  * It also exposes a {@link ToolbarController} to access the toolbar. This may be null if
  * used with a base layout without a Toolbar.
  */
-public class BaseLayoutController {
+final class BaseLayoutController {
 
     private static final Map<Activity, BaseLayoutController> sBaseLayoutMap = new WeakHashMap<>();
 
@@ -180,7 +179,6 @@
         }
 
         InsetsUpdater insetsUpdater = new InsetsUpdater(activity, baseLayout, contentView);
-        insetsUpdater.installListeners();
 
         return Pair.create(toolbarController, insetsUpdater);
     }
@@ -208,7 +206,7 @@
      * 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 ViewTreeObserver.OnGlobalLayoutListener {
+    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
@@ -228,7 +226,6 @@
         private final View mBottomInsetView;
         private InsetsChangedListener mInsetsChangedListenerDelegate;
 
-        private boolean mInsetsDirty = true;
         @NonNull
         private Insets mInsets = new Insets();
 
@@ -240,7 +237,7 @@
          * @param baseLayout  The root view of the base layout
          * @param contentView The android.R.id.content View
          */
-        public InsetsUpdater(
+        InsetsUpdater(
                 @Nullable Activity activity,
                 @NonNull View baseLayout,
                 @NonNull View contentView) {
@@ -259,7 +256,7 @@
                             int oldLeft, int oldTop, int oldRight, int oldBottom) -> {
                         if (left != oldLeft || top != oldTop
                                 || right != oldRight || bottom != oldBottom) {
-                            mInsetsDirty = true;
+                            recalcInsets();
                         }
                     };
 
@@ -279,17 +276,6 @@
             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);
-        }
-
         @NonNull
         Insets getInsets() {
             return mInsets;
@@ -300,13 +286,9 @@
         }
 
         /**
-         * onGlobalLayout() should recalculate the amount of insets we need, and then dispatch them.
+         * Recalculate the amount of insets we need, and then dispatch them.
          */
-        @Override
-        public void onGlobalLayout() {
-            if (!mInsetsDirty) {
-                return;
-            }
+        public void recalcInsets() {
 
             // Calculate how much each inset view overlays the content view
 
@@ -339,7 +321,6 @@
             }
             Insets insets = new Insets(left, top, right, bottom);
 
-            mInsetsDirty = false;
             if (!insets.equals(mInsets)) {
                 mInsets = insets;
                 dispatchNewInsets(insets);
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
new file mode 100644
index 0000000..8476869
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeSearchListItem.java
@@ -0,0 +1,102 @@
+/*
+ * 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;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+
+/**
+ * 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
new file mode 100644
index 0000000..bf7d2bf
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/imewidescreen/CarUiImeWideScreenController.java
@@ -0,0 +1,806 @@
+/*
+ * 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.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.inputmethodservice.ExtractEditText;
+import android.inputmethodservice.InputMethodService;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.SurfaceControlViewHost.SurfacePackage;
+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.VisibleForTesting;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.ui.R;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+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";
+    // 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 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";
+    // Key used to provide the list of titles for each search item. Value format is
+    // ArrayList<String>
+    public static final String SEARCH_RESULT_TITLE_LIST = "search_result_title_list";
+    // Key used to provide the list of sub titles for each search item. Value format is
+    // ArrayList<String>
+    public static final String SEARCH_RESULT_SUB_TITLE_LIST = "search_result_sub_title_list";
+    // Key used to provide the list of resource id for each primary image in search item.
+    // ArrayList<Integer>. If bitmap and res id both are provided than bitmap will take
+    // precedence over res id.
+    public static final String SEARCH_RESULT_ICON_RES_ID_LIST =
+            "search_result_icon_res_id_list";
+    // Key used to provide the list of bitmap for each primary image in search item.
+    // ArrayList<Integer>. If bitmap and res id both are provided than bitmap will take
+    // precedence over res id.
+    public static final String SEARCH_RESULT_ICON_BITMAP_LIST =
+            "search_result_icon_bitmap_list";
+    // Key used to provide the list of bitmap for each secondary image in search item.
+    // ArrayList<Integer>. If bitmap and res id both are provided than bitmap will take
+    // precedence over res id.
+    public static final String SEARCH_RESULT_SUPPLEMENTAL_ICON_BITMAP_LIST =
+            "search_result_supplemental_icon_bitmap_list";
+    // Key used to provide the list of id for each secondary image in search item.
+    // ArrayList<String>. If bitmap and res id both are provided than bitmap will take
+    // precedence over res id.
+    public static final String SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST =
+            "search_result_supplemental_icon_id_list";
+    // Key used to provide the list of resource id for each secondary image in search item.
+    // ArrayList<Integer>
+    public static final String SEARCH_RESULT_SUPPLEMENTAL_ICON_RES_ID_LIST =
+            "search_result_supplemental_icon_res_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 RecyclerView mRecyclerView;
+    @Nullable
+    private ImageView mWideScreenExtractedTextIcon;
+    private boolean mIsExtractIconProvidedByApp;
+    @NonNull
+    private FrameLayout mInputFrame;
+    @NonNull
+    private ExtractEditText mExtractEditText;
+    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;
+        }
+        mRootView = View.inflate(mContext, 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.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.
+     *
+     * 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.
+     */
+    public void onAppPrivateCommand(String action, Bundle data) {
+        if (!isWideScreenMode() || !WIDE_SCREEN_ACTION.equals(action)) {
+            return;
+        }
+        resetAutomotiveWideScreenViews();
+        if (data == null) {
+            return;
+        }
+        if (mAllowAppToHideContentArea || (mInputEditorInfo != null && isPackageAuthorized(
+                mInputEditorInfo.packageName))) {
+            mImeRendersAllContent = data.getBoolean(REQUEST_RENDER_CONTENT_AREA, true);
+        }
+
+        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);
+        }
+
+        loadSearchItems(data);
+
+        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(Bundle data) {
+        ArrayList<String> itemIdList = data.getStringArrayList(SEARCH_RESULT_ITEM_ID_LIST);
+        ArrayList<String> titleList = data.getStringArrayList(SEARCH_RESULT_TITLE_LIST);
+        ArrayList<String> subTitleList = data.getStringArrayList(SEARCH_RESULT_SUB_TITLE_LIST);
+        ArrayList<Bitmap> bitmapList = data.getParcelableArrayList(
+                SEARCH_RESULT_ICON_BITMAP_LIST);
+        ArrayList<Integer> primaryImageResIdList =
+                data.getIntegerArrayList(SEARCH_RESULT_ICON_RES_ID_LIST);
+        ArrayList<Bitmap> secondaryBitmapList = data.getParcelableArrayList(
+                SEARCH_RESULT_SUPPLEMENTAL_ICON_BITMAP_LIST);
+        ArrayList<String> secondaryImageIdList =
+                data.getStringArrayList(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST);
+        ArrayList<Integer> secondaryImageResIdList =
+                data.getIntegerArrayList(SEARCH_RESULT_SUPPLEMENTAL_ICON_RES_ID_LIST);
+        if (itemIdList == null) {
+            return;
+        }
+        mAutomotiveSearchItems = new ArrayList<>();
+        for (int i = 0; i < itemIdList.size(); i++) {
+            int index = i;
+            CarUiContentListItem searchItem;
+            if (secondaryImageIdList == null) {
+                searchItem = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+            } else {
+                searchItem = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
+            }
+
+            searchItem.setOnItemClickedListener(v -> {
+                Bundle bundle = new Bundle();
+                bundle.putString(SEARCH_RESULT_ITEM_ID_LIST, itemIdList.get(index));
+                mInputConnection.performPrivateCommand(WIDE_SCREEN_ACTION, bundle);
+            });
+
+            if (titleList != null) {
+                searchItem.setTitle(titleList.get(i));
+            }
+
+            if (subTitleList != null) {
+                searchItem.setBody(subTitleList.get(i));
+            }
+
+            if (primaryImageResIdList != null) {
+                searchItem.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT);
+                if (bitmapList != null && bitmapList.get(i) != null) {
+                    searchItem.setIcon(
+                            new BitmapDrawable(mContext.getResources(), bitmapList.get(i)));
+                } else {
+                    searchItem.setIcon(loadDrawableFromPackage(primaryImageResIdList.get(i)));
+                }
+            }
+
+            if (secondaryBitmapList != null && secondaryBitmapList.get(i) != null) {
+                searchItem.setSupplementalIcon(
+                        new BitmapDrawable(mContext.getResources(), secondaryBitmapList.get(i)));
+            } else if (secondaryImageResIdList != null && secondaryImageIdList != null) {
+                searchItem.setSupplementalIcon(
+                        loadDrawableFromPackage(secondaryImageResIdList.get(i)), v -> {
+                            Bundle bundle = new Bundle();
+                            bundle.putString(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST,
+                                    secondaryImageIdList.get(index));
+                            mInputConnection.performPrivateCommand(WIDE_SCREEN_ACTION, bundle);
+                        });
+            }
+
+            mAutomotiveSearchItems.add(searchItem);
+        }
+    }
+
+    /**
+     * 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)}
+     */
+    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);
+        }
+        if (!mImeRendersAllContent) {
+            mContentAreaAutomotive.setVisibility(View.GONE);
+        } else {
+            mContentAreaAutomotive.setVisibility(View.VISIBLE);
+        }
+
+        // This view is rendered by the framework when IME is in full screen mode. For more info
+        // see {@link #onEvaluateFullscreenMode}
+        mExtractEditText = mRootView.getRootView().requireViewById(
+                android.R.id.inputExtractEditText);
+
+        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);
+        }
+
+        sendSurfaceInfo();
+    }
+
+    /**
+     * 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.
+     */
+    private void sendSurfaceInfo() {
+        if (!mAllowAppToHideContentArea && !(mInputEditorInfo != null
+                && isPackageAuthorized(mInputEditorInfo.packageName))) {
+            return;
+        }
+        int displayId = mContentAreaSurfaceView.getDisplay().getDisplayId();
+        IBinder 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);
+    }
+
+    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.
+     *
+     * 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>
+     *
+     * 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 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 void setExtractedEditTextBackground(int drawableResId) {
+        mExtractEditText.setBackgroundTintList(mContext.getColorStateList(drawableResId));
+    }
+
+    @VisibleForTesting
+    void setExtractEditText(ExtractEditText editText) {
+        mExtractEditText = editText;
+    }
+
+    /**
+     * 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(
+                                mInputEditorInfo.packageName));
+            } else {
+                mIsExtractIconProvidedByApp = true;
+                mWideScreenExtractedTextIcon.setImageDrawable(
+                        mContext.createPackageContext(mInputEditorInfo.packageName, 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);
+        }
+    }
+
+    /**
+     * Called when IME window closes. Reset all the views once that happens.
+     */
+    public void onFinishInputView() {
+        if (!isWideScreenMode()) {
+            return;
+        }
+        resetAutomotiveWideScreenViews();
+    }
+
+    private void resetAutomotiveWideScreenViews() {
+        mWideScreenDescriptionTitle.setVisibility(View.GONE);
+        mContentAreaSurfaceView.setVisibility(View.GONE);
+        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 = new ArrayList<>();
+    }
+
+    /**
+     * 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);
+    }
+
+    private Drawable loadDrawableFromPackage(int resId) {
+        try {
+            if (mInputEditorInfo != null) {
+                return mContext.createPackageContext(mInputEditorInfo.packageName, 0)
+                        .getDrawable(resId);
+            }
+        } catch (PackageManager.NameNotFoundException ex) {
+            Log.e(TAG, "loadDrawableFromPackage: package name not found: ", ex);
+        } catch (Resources.NotFoundException ex) {
+            Log.w(TAG, "loadDrawableFromPackage: resource not found with id " + resId, ex);
+        }
+        return null;
+    }
+}
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
index 5a34dcd..b9ad789 100644
--- 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
@@ -30,6 +30,7 @@
 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;
@@ -51,20 +52,23 @@
  */
 public class ListPreferenceFragment extends Fragment implements InsetsChangedListener {
 
-    private ToolbarController mToolbar;
+    private static final String ARG_FULLSCREEN = "fullscreen";
+
     private ListPreference mPreference;
     private CarUiContentListItem mSelectedItem;
     private int mSelectedIndex = -1;
+    private boolean mFullScreen;
 
     /**
      * Returns a new instance of {@link ListPreferenceFragment} for the {@link ListPreference} with
      * the given {@code key}.
      */
     @NonNull
-    static ListPreferenceFragment newInstance(String key) {
+    static ListPreferenceFragment newInstance(String key, boolean fullScreen) {
         ListPreferenceFragment fragment = new ListPreferenceFragment();
         Bundle b = new Bundle(/* capacity= */ 1);
         b.putString(ARG_KEY, key);
+        b.putBoolean(ARG_FULLSCREEN, fullScreen);
         fragment.setArguments(b);
         return fragment;
     }
@@ -85,29 +89,40 @@
     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());
+        mFullScreen = requireArguments().getBoolean(ARG_FULLSCREEN, true);
+        ToolbarController toolbar = mFullScreen ? CarUi.getToolbar(getActivity()) : null;
 
         // 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;
+        if (toolbar == null) {
+            Toolbar toolbarView = CarUiUtils.findViewByRefId(view, R.id.toolbar);
+            toolbar = toolbarView;
 
-            carUiRecyclerView.setPadding(0, toolbarView.getHeight(), 0, 0);
-            toolbarView.registerToolbarHeightChangeListener(newHeight -> {
-                if (carUiRecyclerView.getPaddingTop() == newHeight) {
-                    return;
-                }
+            if (toolbarView != null) {
+                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);
-            });
+                    int oldHeight = carUiRecyclerView.getPaddingTop();
+                    carUiRecyclerView.setPadding(0, newHeight, 0, 0);
+                    carUiRecyclerView.scrollBy(0, oldHeight - newHeight);
+
+                    FocusArea focusArea = view.findViewById(R.id.car_ui_focus_area);
+                    if (focusArea != null) {
+                        focusArea.setHighlightPadding(0, newHeight, 0, 0);
+                        focusArea.setBoundsOffset(0, newHeight, 0, 0);
+                    }
+                });
+            }
         }
 
         carUiRecyclerView.setClipToPadding(false);
         mPreference = getListPreference();
-        mToolbar.setTitle(mPreference.getTitle());
-        mToolbar.setState(Toolbar.State.SUBPAGE);
+        if (toolbar != null) {
+            toolbar.setTitle(mPreference.getTitle());
+            toolbar.setState(Toolbar.State.SUBPAGE);
+        }
 
         CharSequence[] entries = mPreference.getEntries();
         CharSequence[] entryValues = mPreference.getEntryValues();
@@ -178,11 +193,7 @@
     }
 
     private ListPreference getListPreference() {
-        if (getArguments() == null) {
-            throw new IllegalStateException("Preference arguments cannot be null");
-        }
-
-        String key = getArguments().getString(ARG_KEY);
+        String key = requireArguments().getString(ARG_KEY);
         DialogPreference.TargetFragment fragment =
                 (DialogPreference.TargetFragment) getTargetFragment();
 
@@ -210,9 +221,17 @@
 
     @Override
     public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        if (!mFullScreen) {
+            return;
+        }
         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
index 44c5f43..f9cf8a2 100644
--- 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
@@ -29,6 +29,7 @@
 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;
@@ -52,19 +53,23 @@
  */
 public class MultiSelectListPreferenceFragment extends Fragment implements InsetsChangedListener {
 
+    private static final String ARG_FULLSCREEN = "fullscreen";
+
     private CarUiMultiSelectListPreference mPreference;
     private Set<String> mNewValues;
     private ToolbarController mToolbar;
+    private boolean mFullScreen;
 
     /**
      * Returns a new instance of {@link MultiSelectListPreferenceFragment} for the {@link
      * CarUiMultiSelectListPreference} with the given {@code key}.
      */
     @NonNull
-    static MultiSelectListPreferenceFragment newInstance(String key) {
+    static MultiSelectListPreferenceFragment newInstance(String key, boolean fullScreen) {
         MultiSelectListPreferenceFragment fragment = new MultiSelectListPreferenceFragment();
         Bundle b = new Bundle(/* capacity= */ 1);
         b.putString(ARG_KEY, key);
+        b.putBoolean(ARG_FULLSCREEN, fullScreen);
         fragment.setArguments(b);
         return fragment;
     }
@@ -85,30 +90,41 @@
     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());
+        mFullScreen = requireArguments().getBoolean(ARG_FULLSCREEN, true);
+        mToolbar = mFullScreen ? CarUi.getToolbar(requireActivity()) : null;
 
         // 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);
+            Toolbar toolbarView = CarUiUtils.findViewByRefId(view, R.id.toolbar);
             mToolbar = toolbarView;
 
-            recyclerView.setPadding(0, toolbarView.getHeight(), 0, 0);
-            toolbarView.registerToolbarHeightChangeListener(newHeight -> {
-                if (recyclerView.getPaddingTop() == newHeight) {
-                    return;
-                }
+            if (toolbarView != null) {
+                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);
-            });
+                    int oldHeight = recyclerView.getPaddingTop();
+                    recyclerView.setPadding(0, newHeight, 0, 0);
+                    recyclerView.scrollBy(0, oldHeight - newHeight);
+
+                    FocusArea focusArea = view.findViewById(R.id.car_ui_focus_area);
+                    if (focusArea != null) {
+                        focusArea.setHighlightPadding(0, newHeight, 0, 0);
+                        focusArea.setBoundsOffset(0, newHeight, 0, 0);
+                    }
+                });
+            }
         }
 
         mPreference = getPreference();
 
         recyclerView.setClipToPadding(false);
-        mToolbar.setTitle(mPreference.getTitle());
-        mToolbar.setState(Toolbar.State.SUBPAGE);
+        if (mToolbar != null) {
+            mToolbar.setTitle(mPreference.getTitle());
+            mToolbar.setState(Toolbar.State.SUBPAGE);
+        }
 
         mNewValues = new HashSet<>(mPreference.getValues());
         CharSequence[] entries = mPreference.getEntries();
@@ -205,9 +221,17 @@
 
     @Override
     public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        if (!mFullScreen) {
+            return;
+        }
         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
index fbd6856..3f5b5cb 100644
--- 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
@@ -72,15 +72,29 @@
     private static final String DIALOG_FRAGMENT_TAG =
             "com.android.car.ui.PreferenceFragment.DIALOG";
 
+    /**
+     * This method can be overridden to indicate whether or not this fragment covers the
+     * whole screen. When it returns false, the preference fragment will not attempt to change
+     * the CarUi base layout toolbar (but will still have its own toolbar and change it when using
+     * non-baselayout toolbars), and will also not take into account CarUi insets.
+     *
+     * @return Whether to PreferenceFragment takes up the whole app's space. Defaults to true.
+     */
+    protected boolean isFullScreenFragment() {
+        return true;
+    }
+
     @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());
+        if (isFullScreenFragment()) {
+            ToolbarController baseLayoutToolbar = CarUi.getToolbar(getActivity());
+            if (baseLayoutToolbar != null) {
+                baseLayoutToolbar.setState(Toolbar.State.SUBPAGE);
+                if (getPreferenceScreen() != null) {
+                    baseLayoutToolbar.setTitle(getPreferenceScreen().getTitle());
+                }
             }
         }
 
@@ -103,6 +117,7 @@
 
             FocusArea focusArea = CarUiUtils.requireViewByRefId(view, R.id.car_ui_focus_area);
             focusArea.setHighlightPadding(0, newHeight, 0, 0);
+            focusArea.setBoundsOffset(0, newHeight, 0, 0);
         });
 
         recyclerView.setClipToPadding(false);
@@ -122,9 +137,14 @@
 
     @Override
     public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        if (!isFullScreenFragment()) {
+            return;
+        }
+
         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);
@@ -158,9 +178,10 @@
         if (preference instanceof EditTextPreference) {
             f = EditTextPreferenceDialogFragment.newInstance(preference.getKey());
         } else if (preference instanceof ListPreference) {
-            f = ListPreferenceFragment.newInstance(preference.getKey());
+            f = ListPreferenceFragment.newInstance(preference.getKey(), isFullScreenFragment());
         } else if (preference instanceof MultiSelectListPreference) {
-            f = MultiSelectListPreferenceFragment.newInstance(preference.getKey());
+            f = MultiSelectListPreferenceFragment
+                    .newInstance(preference.getKey(), isFullScreenFragment());
         } else if (preference instanceof CarUiSeekBarDialogPreference) {
             f = SeekbarPreferenceDialogFragment.newInstance(preference.getKey());
         } else {
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
index 71f5d1a..e6a14d7 100644
--- 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
@@ -17,7 +17,6 @@
 package com.android.car.ui.recyclerview;
 
 import android.graphics.drawable.Drawable;
-import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -114,7 +113,7 @@
     private boolean mIsActivated;
     private OnClickListener mOnClickListener;
     private OnCheckedChangeListener mOnCheckedChangeListener;
-    private View.OnClickListener mSupplementalIconOnClickListener;
+    private OnClickListener mSupplementalIconOnClickListener;
 
 
     public CarUiContentListItem(Action action) {
@@ -301,7 +300,7 @@
      * @param listener the callback that is invoked when the icon is clicked.
      */
     public void setSupplementalIcon(@Nullable Drawable icon,
-            @Nullable View.OnClickListener listener) {
+            @Nullable OnClickListener listener) {
         if (mAction != Action.ICON) {
             throw new IllegalStateException(
                     "Cannot set supplemental icon on list item that does not have an action of "
@@ -313,7 +312,7 @@
     }
 
     @Nullable
-    public View.OnClickListener getSupplementalIconOnClickListener() {
+    public OnClickListener getSupplementalIconOnClickListener() {
         return mSupplementalIconOnClickListener;
     }
 
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
index 8bc39eb..a45b1e8 100644
--- 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
@@ -283,6 +283,7 @@
                 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
@@ -309,8 +310,7 @@
                         mActionContainerTouchInterceptor.setOnClickListener(
                                 (container) -> {
                                     if (item.getSupplementalIconOnClickListener() != null) {
-                                        item.getSupplementalIconOnClickListener().onClick(
-                                                mSupplementalIcon);
+                                        item.getSupplementalIconOnClickListener().onClick(item);
                                     }
                                 });
                         mTouchInterceptor.setVisibility(View.GONE);
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
index 627ab95..93b7736 100644
--- 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
@@ -16,6 +16,7 @@
 package com.android.car.ui.recyclerview;
 
 import static com.android.car.ui.utils.CarUiUtils.findViewByRefId;
+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;
 
@@ -25,8 +26,6 @@
 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;
@@ -36,7 +35,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
+import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
@@ -53,15 +52,16 @@
 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.CarUiUtils;
 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.
+ * 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 {
 
@@ -77,22 +77,21 @@
     private String mScrollBarClass;
     private int mScrollBarPaddingTop;
     private int mScrollBarPaddingBottom;
-    private boolean mHasScrolledToTop = false;
 
     @Nullable
     private ScrollBar mScrollBar;
 
-    @NonNull
+    @Nullable
     private GridOffsetItemDecoration mTopOffsetItemDecorationGrid;
-    @NonNull
+    @Nullable
     private GridOffsetItemDecoration mBottomOffsetItemDecorationGrid;
-    @NonNull
+    @Nullable
     private RecyclerView.ItemDecoration mTopOffsetItemDecorationLinear;
-    @NonNull
+    @Nullable
     private RecyclerView.ItemDecoration mBottomOffsetItemDecorationLinear;
-    @NonNull
+    @Nullable
     private GridDividerItemDecoration mDividerItemDecorationGrid;
-    @NonNull
+    @Nullable
     private RecyclerView.ItemDecoration mDividerItemDecorationLinear;
     private int mNumOfColumns;
     private boolean mInstallingExtScrollBar = false;
@@ -104,22 +103,24 @@
     @Nullable
     private LinearLayout mContainer;
 
+    // Set to true when when styled attributes are read and initialized.
+    private boolean mIsInitialized;
     private boolean mEnableDividers;
     private int mTopOffset;
     private int mBottomOffset;
 
-    private ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener = () -> {
-        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;
+    private boolean mHasScrolled = false;
+
+    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);
+            }
         }
     };
 
-
     /**
      * The possible values for setScrollBarPosition. The default value is actually {@link
      * CarUiRecyclerViewLayout#LINEAR}.
@@ -131,13 +132,15 @@
     @Retention(SOURCE)
     public @interface CarUiRecyclerViewLayout {
         /**
-         * Arranges items either horizontally in a single row or vertically in a single column.
-         * This is default.
+         * 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;
+        /**
+         * Arranges items in a Grid.
+         */
+        int GRID = 1;
     }
 
     /**
@@ -164,8 +167,7 @@
 
         /**
          * Sets the maximum number of items available in the adapter. A value less than '0' means
-         * the
-         * list should not be capped.
+         * the list should not be capped.
          */
         void setMaxItems(int maxItems);
     }
@@ -186,13 +188,13 @@
     }
 
     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);
+        initRotaryScroll(a);
 
         mScrollBarEnabled = context.getResources().getBoolean(R.bool.car_ui_scrollbar_enable);
 
@@ -229,19 +231,26 @@
         mBottomOffsetItemDecorationGrid =
                 new GridOffsetItemDecoration(mBottomOffset, mNumOfColumns,
                         OffsetPosition.END);
-        if (carUiRecyclerViewLayout == CarUiRecyclerViewLayout.LINEAR) {
+
+        mIsInitialized = true;
+
+        // Check if a layout manager has already been set via XML
+        boolean isLayoutMangerSet = getLayoutManager() != null;
+        if (!isLayoutMangerSet && carUiRecyclerViewLayout == CarUiRecyclerViewLayout.LINEAR) {
             setLayoutManager(new LinearLayoutManager(getContext()));
-        } else {
+        } else if (!isLayoutMangerSet && carUiRecyclerViewLayout == CarUiRecyclerViewLayout.GRID) {
             setLayoutManager(new GridLayoutManager(getContext(), mNumOfColumns));
         }
+        addOnScrollListener(mOnScrollListener);
 
         a.recycle();
 
-
         if (!mScrollBarEnabled) {
             return;
         }
 
+        mContainer = new LinearLayout(getContext());
+
         setVerticalScrollBarEnabled(false);
         setHorizontalScrollBarEnabled(false);
 
@@ -249,59 +258,65 @@
     }
 
     @Override
-    public void setLayoutManager(@Nullable LayoutManager layout) {
-        addItemDecorations(layout);
-        super.setLayoutManager(layout);
+    public void setLayoutManager(@Nullable LayoutManager layoutManager) {
+        // Cannot setup item decorations before stylized attributes have been read.
+        if (mIsInitialized) {
+            addItemDecorations(layoutManager);
+        }
+        super.setLayoutManager(layoutManager);
     }
 
-    private void addItemDecorations(LayoutManager layout) {
-        // remove existing Item decorations
-        removeItemDecoration(mDividerItemDecorationGrid);
-        removeItemDecoration(mTopOffsetItemDecorationGrid);
-        removeItemDecoration(mBottomOffsetItemDecorationGrid);
-        removeItemDecoration(mDividerItemDecorationLinear);
-        removeItemDecoration(mTopOffsetItemDecorationLinear);
-        removeItemDecoration(mBottomOffsetItemDecorationLinear);
+    // 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 (layout instanceof GridLayoutManager) {
+        if (layoutManager instanceof GridLayoutManager) {
             if (mEnableDividers) {
-                addItemDecoration(mDividerItemDecorationGrid);
+                addItemDecoration(Objects.requireNonNull(mDividerItemDecorationGrid));
             }
-            addItemDecoration(mTopOffsetItemDecorationGrid);
-            addItemDecoration(mBottomOffsetItemDecorationGrid);
-            setNumOfColumns(((GridLayoutManager) layout).getSpanCount());
+            addItemDecoration(Objects.requireNonNull(mTopOffsetItemDecorationGrid));
+            addItemDecoration(Objects.requireNonNull(mBottomOffsetItemDecorationGrid));
+            setNumOfColumns(((GridLayoutManager) layoutManager).getSpanCount());
         } else {
             if (mEnableDividers) {
-                addItemDecoration(mDividerItemDecorationLinear);
+                addItemDecoration(Objects.requireNonNull(mDividerItemDecorationLinear));
             }
-            addItemDecoration(mTopOffsetItemDecorationLinear);
-            addItemDecoration(mBottomOffsetItemDecorationLinear);
+            addItemDecoration(Objects.requireNonNull(mTopOffsetItemDecorationLinear));
+            addItemDecoration(Objects.requireNonNull(mBottomOffsetItemDecorationLinear));
         }
     }
 
     /**
-     * If this view's content description isn't set to opt out of scrolling via the rotary
-     * controller, initialize it accordingly.
+     * 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(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,
+    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.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;
+            CarUiUtils.setRotaryScrollEnabled(
+                    this, /* isVertical= */ orientation == LinearLayout.VERTICAL);
+        } else {
+            CharSequence contentDescription = getContentDescription();
+            rotaryScrollEnabled = contentDescription != null
+                    && (ROTARY_HORIZONTALLY_SCROLLABLE.contentEquals(contentDescription)
+                    || ROTARY_VERTICALLY_SCROLLABLE.contentEquals(contentDescription));
         }
 
-        // Convert SOURCE_ROTARY_ENCODER scroll events into SOURCE_MOUSE scroll events that
-        // RecyclerView knows how to handle.
-        setOnGenericMotionListener((v, event) -> {
+        // 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);
@@ -311,11 +326,11 @@
                 }
             }
             return false;
-        });
+        } : null);
 
-        // Mark this view as focusable. This view will be focused when no focusable elements are
-        // visible.
-        setFocusable(true);
+        // 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.
@@ -324,15 +339,20 @@
         // Disable the default focus highlight. No highlight should appear when this view is
         // focused.
         setDefaultFocusHighlightEnabled(false);
+
+        // 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, we don't want
-        // to do the initial scroll to top
-        mHasScrolledToTop = true;
+        // If we're restoring an existing RecyclerView, consider
+        // it as having already scrolled some.
+        mHasScrolled = true;
     }
 
     @Override
@@ -369,7 +389,6 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mCarUxRestrictionsUtil.register(mListener);
-        this.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
         if (mInstallingExtScrollBar || !mScrollBarEnabled) {
             return;
         }
@@ -385,11 +404,10 @@
 
     /**
      * 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.
+     * 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);
@@ -444,10 +462,23 @@
     }
 
     @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);
-        this.getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
     }
 
     @Override
@@ -455,6 +486,13 @@
         mContainerPaddingRelative = null;
         if (mScrollBarEnabled) {
             super.setPadding(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);
+            }
             mContainerPadding = new Rect(left, 0, right, 0);
             if (mContainer != null) {
                 mContainer.setPadding(left, 0, right, 0);
@@ -470,6 +508,13 @@
         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);
@@ -481,8 +526,8 @@
     }
 
     /**
-     * Sets the scrollbar's padding top and bottom.
-     * This padding is applied in addition to the padding of the RecyclerView.
+     * 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) {
@@ -518,6 +563,12 @@
         removeItemDecoration(mDividerItemDecorationGrid);
     }
 
+    @Override
+    public void setContentDescription(CharSequence contentDescription) {
+        super.setContentDescription(contentDescription);
+        initRotaryScroll(/* styledAttributes= */ null);
+    }
+
     private static RuntimeException andLog(String msg, Throwable t) {
         Log.e(TAG, msg, t);
         throw new RuntimeException(msg, t);
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
index 136dc6e..fd532b5 100644
--- 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
@@ -246,7 +246,7 @@
      * @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) {
+    static float getPercentageVisible(View view, OrientationHelper helper) {
         int start = helper.getStartAfterPadding();
         int end = helper.getEndAfterPadding();
 
@@ -340,6 +340,80 @@
     }
 
     /**
+     * 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 (int) 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.
+     */
+    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) {
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
index b27aab0..2bed61c 100644
--- 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
@@ -19,6 +19,7 @@
 
 import android.content.res.Resources;
 import android.os.Handler;
+import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateDecelerateInterpolator;
@@ -26,6 +27,7 @@
 
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.OrientationHelper;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -35,8 +37,8 @@
 /**
  * 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.
+ * <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 {
 
@@ -59,6 +61,9 @@
 
     private OrientationHelper mOrientationHelper;
 
+    private OnContinuousScrollListener mPageUpOnContinuousScrollListener;
+    private OnContinuousScrollListener mPageDownOnContinuousScrollListener;
+
     @Override
     public void initialize(RecyclerView rv, View scrollView) {
         mRecyclerView = rv;
@@ -77,14 +82,17 @@
         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));
+        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);
-        mDownButton.setOnTouchListener(
-                new OnContinuousScrollListener(rv.getContext(), 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);
@@ -131,6 +139,13 @@
      * @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);
     }
@@ -141,6 +156,13 @@
      * @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);
     }
@@ -160,10 +182,9 @@
      * 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.
+     * The values should also be positive.
      *
-     * @param range The range of the scrollbar's thumb
+     * @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
      */
@@ -199,7 +220,7 @@
      * 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 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.
      */
@@ -213,9 +234,9 @@
      * 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 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.
      */
@@ -230,7 +251,9 @@
                 : mScrollTrack.getHeight() - thumbLength);
     }
 
-    /** Moves the given view to the specified 'y' position. */
+    /**
+     * Moves the given view to the specified 'y' position.
+     */
     private void moveY(final View view, float newPosition) {
         view.animate()
                 .y(newPosition)
@@ -239,13 +262,93 @@
                 .start();
     }
 
+    private boolean mIsAdapterChangeObserverRegistered = false;
+    @Nullable
+    private RecyclerView.Adapter mCurrentAdapter;
     private final RecyclerView.OnScrollListener mRecyclerViewOnScrollListener =
             new RecyclerView.OnScrollListener() {
                 @Override
                 public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                     updatePaginationButtons();
+                    cacheChildrenHeight(recyclerView.getLayoutManager());
+                    if (mCurrentAdapter != recyclerView.getAdapter()) {
+                        mIsAdapterChangeObserverRegistered = false;
+                        if (mCurrentAdapter != null) {
+                            mCurrentAdapter.unregisterAdapterDataObserver(mAdapterChangeObserver);
+                        }
+                    }
+                    if (!mIsAdapterChangeObserverRegistered
+                            && recyclerView.getAdapter() != null) {
+                        mIsAdapterChangeObserverRegistered = true;
+                        mCurrentAdapter = recyclerView.getAdapter();
+                        mCurrentAdapter.registerAdapterDataObserver(mAdapterChangeObserver);
+                    }
                 }
             };
+    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(mRecyclerView.getLayoutManager());
+    }
+
+    private void cacheChildrenHeight(RecyclerView.LayoutManager layoutManager) {
+        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) {
@@ -260,49 +363,52 @@
      * {@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
+     * 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) {
+        RecyclerView.LayoutManager layoutManager = getRecyclerView().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(getRecyclerView().getLayoutManager());
+        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
         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.
+
+        View currentPosView = getFirstMostVisibleChild(orientationHelper);
+        int currentPos = currentPosView != null ? mRecyclerView.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.
+            mRecyclerView.smoothScrollBy(0, -scrollDistance);
+        } else {
+            mRecyclerView.smoothScrollToPosition(Math.max(0, currentPos + nextPos));
+        }
+    }
+
+    private View getFirstMostVisibleChild(OrientationHelper helper) {
+        float mostVisiblePercent = 0;
+        View mostVisibleView = null;
+
+        for (int i = 0; i < getRecyclerView().getLayoutManager().getChildCount(); i++) {
+            View child = getRecyclerView().getLayoutManager().getChildAt(i);
+            float visiblePercentage = CarUiSnapHelper.getPercentageVisible(child, helper);
+            if (visiblePercentage == 1f) {
+                mostVisibleView = child;
                 break;
+            } else if (visiblePercentage > mostVisiblePercent) {
+                mostVisiblePercent = visiblePercentage;
+                mostVisibleView = child;
             }
         }
-        // Distance should always be positive. Negate its value to scroll up.
-        mRecyclerView.smoothScrollBy(0, -scrollDistance);
+
+        return mostVisibleView;
     }
 
     /**
@@ -314,53 +420,55 @@
      * scrolled the length of a page, but not snapped to.
      */
     void pageDown() {
-        if (getRecyclerView().getLayoutManager() == null
-                || getRecyclerView().getChildCount() == 0) {
+        RecyclerView.LayoutManager layoutManager = getRecyclerView().getLayoutManager();
+        if (layoutManager == null || layoutManager.getChildCount() == 0) {
             return;
         }
 
-        OrientationHelper orientationHelper =
-                getOrientationHelper(getRecyclerView().getLayoutManager());
+        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
         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)
-                    - orientationHelper.getStartAfterPadding();
-            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;
-            }
+        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());
         }
 
-        // 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)
-                        - orientationHelper.getStartAfterPadding() > 0) {
-                    // Child view top is entering screen. Align its top with parent top.
-                    scrollDistance = orientationHelper.getDecoratedStart(lastChild)
+        // 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 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;
+                } else {
+                    scrollDistance = orientationHelper.getDecoratedStart(child)
+                            - orientationHelper.getStartAfterPadding();
                 }
-                // 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;
             }
         }
@@ -371,12 +479,9 @@
     /**
      * 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.
+     * 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() {
 
@@ -387,6 +492,7 @@
         // 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 {
@@ -412,12 +518,16 @@
         mScrollView.invalidate();
     }
 
-    /** Returns {@code true} if the RecyclerView is completely displaying the first item. */
+    /**
+     * 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. */
+    /**
+     * 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/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
index 4fafc8d..48570c6 100644
--- 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
@@ -28,16 +28,15 @@
 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.
+ * 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 Handler mHandler = new Handler();
+    private final int mInitialDelay;
+    private final int mRepeatInterval;
     private final OnClickListener mOnClickListener;
     private View mTouchedView;
     private boolean mIsLongPressed;
@@ -45,7 +44,7 @@
     /**
      * Notifies listener and self schedules to be re-run at next callback interval.
      */
-    private Runnable mPeriodicRunnable = new Runnable() {
+    private final Runnable mPeriodicRunnable = new Runnable() {
         @Override
         public void run() {
             if (mTouchedView.isEnabled()) {
@@ -59,14 +58,12 @@
     };
 
     /**
-     * @param clickListener The OnClickListener, that will be called
-     *                      periodically
+     * @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);
 
@@ -76,6 +73,15 @@
         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;
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
index abb90ca..5eb090a 100644
--- 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
@@ -25,6 +25,8 @@
 
 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 {
 
@@ -89,7 +91,9 @@
      * @param parent The RecyclerView onto which dividers are being added
      */
     private void drawHorizontalDividers(Canvas canvas, RecyclerView parent) {
-        int childCount = parent.getChildCount();
+        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);
@@ -102,8 +106,9 @@
                 lastRowChildIndex = i + ((rowCount - 1) * mNumColumns);
             }
 
-            View firstRowChild = parent.getChildAt(i);
-            View lastRowChild = parent.getChildAt(lastRowChildIndex);
+
+            View firstRowChild = layoutManager.getChildAt(i);
+            View lastRowChild = layoutManager.getChildAt(lastRowChildIndex);
 
             int dividerTop =
                     firstRowChild.getTop() + (int) parent.getContext().getResources().getDimension(
@@ -130,7 +135,9 @@
      * @param parent The RecyclerView onto which dividers are being added
      */
     private void drawVerticalDividers(Canvas canvas, RecyclerView parent) {
-        double childCount = parent.getChildCount();
+        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++) {
@@ -144,8 +151,8 @@
                 rightmostChildIndex = (i * mNumColumns) - 1;
             }
 
-            View leftmostChild = parent.getChildAt(mNumColumns * (i - 1));
-            View rightmostChild = parent.getChildAt(rightmostChildIndex);
+            View leftmostChild = layoutManager.getChildAt(mNumColumns * (i - 1));
+            View rightmostChild = layoutManager.getChildAt(rightmostChildIndex);
 
             // draws on top of each row.
             int dividerLeft =
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
index 4d5e6bd..3ab24aa 100644
--- 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
@@ -104,9 +104,10 @@
                 - (int) parent.getContext().getResources().getDimension(
                 R.dimen.car_ui_recyclerview_divider_bottom_margin);
 
-        int childCount = parent.getChildCount();
+        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
+        int childCount = layoutManager.getChildCount();
         for (int i = 0; i < childCount - 1; i++) {
-            View child = parent.getChildAt(i);
+            View child = layoutManager.getChildAt(i);
 
             RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
 
@@ -133,9 +134,10 @@
                 - (int) parent.getContext().getResources().getDimension(
                 R.dimen.car_ui_recyclerview_divider_end_margin);
 
-        int childCount = parent.getChildCount();
+        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
+        int childCount = layoutManager.getChildCount();
         for (int i = 0; i < childCount - 1; i++) {
-            View child = parent.getChildAt(i);
+            View child = layoutManager.getChildAt(i);
 
             RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
 
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
index 33e14db..62d361e 100644
--- 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
@@ -169,7 +169,8 @@
         if (mOffsetPosition == OffsetPosition.START) {
             parentLeft = parent.getPaddingLeft();
         } else {
-            View lastChild = parent.getChildAt(parent.getChildCount() - 1);
+            RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
+            View lastChild = layoutManager.getChildAt(layoutManager.getChildCount() - 1);
             RecyclerView.LayoutParams lastChildLayoutParams =
                     (RecyclerView.LayoutParams) lastChild.getLayoutParams();
             parentLeft = lastChild.getRight() + lastChildLayoutParams.rightMargin;
@@ -190,7 +191,8 @@
         if (mOffsetPosition == OffsetPosition.START) {
             parentTop = parent.getPaddingTop();
         } else {
-            View lastChild = parent.getChildAt(parent.getChildCount() - 1);
+            RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
+            View lastChild = layoutManager.getChildAt(layoutManager.getChildCount() - 1);
             RecyclerView.LayoutParams lastChildLayoutParams =
                     (RecyclerView.LayoutParams) lastChild.getLayoutParams();
             parentTop = lastChild.getBottom() + lastChildLayoutParams.bottomMargin;
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
new file mode 100644
index 0000000..1f1a07c
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/CarUiEditText.java
@@ -0,0 +1,119 @@
+/*
+ * 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.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_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_CLEAR_DATA_ACTION;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.AttributeSet;
+import android.widget.EditText;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * 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
+ */
+class CarUiEditText extends EditText {
+
+    private final Set<PrivateImeCommandCallback> mPrivateImeCommandCallback = new HashSet<>();
+
+    // 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 (WIDE_SCREEN_CLEAR_DATA_ACTION.equals(action)) {
+            // clear the text.
+            setText("");
+        }
+
+        if (data == null || mPrivateImeCommandCallback == null) {
+            return false;
+        }
+
+        if (data.getString(SEARCH_RESULT_ITEM_ID_LIST) != null) {
+            for (PrivateImeCommandCallback listener : mPrivateImeCommandCallback) {
+                listener.onItemClicked(data.getString(SEARCH_RESULT_ITEM_ID_LIST));
+            }
+        }
+
+        if (data.getString(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST) != null) {
+            for (PrivateImeCommandCallback listener : mPrivateImeCommandCallback) {
+                listener.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) {
+            for (PrivateImeCommandCallback listener : mPrivateImeCommandCallback) {
+                listener.onSurfaceInfo(displayId, binder, height, width);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Registers a new {@link PrivateImeCommandCallback} to the list of
+     * listeners.
+     */
+    public void registerOnPrivateImeCommandListener(PrivateImeCommandCallback listener) {
+        mPrivateImeCommandCallback.add(listener);
+    }
+
+    /**
+     * Unregisters an existing {@link PrivateImeCommandCallback} from the list
+     * of listeners.
+     */
+    public boolean unregisterOnPrivateImeCommandListener(PrivateImeCommandCallback listener) {
+        return mPrivateImeCommandCallback.remove(listener);
+    }
+}
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
index 6ee35d3..27f8140 100644
--- 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
@@ -54,6 +54,7 @@
     private final boolean mIsSearch;
     private final boolean mShowIconAndTitle;
     private final boolean mIsTinted;
+    private final boolean mIsPrimary;
     @CarUxRestrictions.CarUxRestrictionsInfo
 
     private int mId;
@@ -88,6 +89,7 @@
         mIsSearch = builder.mIsSearch;
         mShowIconAndTitle = builder.mShowIconAndTitle;
         mIsTinted = builder.mIsTinted;
+        mIsPrimary = builder.mIsPrimary;
         mUxRestrictions = builder.mUxRestrictions;
 
         mCurrentRestrictions = CarUxRestrictionsUtil.getInstance(mContext).getCurrentRestrictions();
@@ -300,6 +302,14 @@
                 : 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 has special behavior when searching */
     boolean isSearch() {
         return mIsSearch;
@@ -329,6 +339,7 @@
         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;
 
@@ -508,6 +519,14 @@
         }
 
         /**
+         * 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.
          */
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
index 85141f1..41b6bef 100644
--- 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
@@ -32,6 +32,7 @@
 import android.widget.Switch;
 import android.widget.TextView;
 
+import androidx.annotation.LayoutRes;
 import androidx.annotation.XmlRes;
 import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
 import androidx.core.util.Consumer;
@@ -98,7 +99,10 @@
 
     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,
+        @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;
 
@@ -149,6 +153,8 @@
             mSwitch.setChecked(mMenuItem.isChecked());
             mSwitch.setVisibility(View.VISIBLE);
             if (mIsRotaryEnabledLayout) {
+                textContainerVisibility = View.VISIBLE;
+            } else {
                 iconContainerVisibility = View.VISIBLE;
             }
         } else if (hasText && hasIcon && textAndIcon) {
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/PrivateImeCommandCallback.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/PrivateImeCommandCallback.java
new file mode 100644
index 0000000..49e7fa4
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/toolbar/PrivateImeCommandCallback.java
@@ -0,0 +1,52 @@
+/*
+ * 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.os.IBinder;
+
+/**
+ * Interface for {@link CarUiEditText} to support different actions and callbacks from IME
+ * when running in wide screen mode.
+ */
+public interface PrivateImeCommandCallback {
+    /**
+     * Called when user clicks on an item in the search results.
+     *
+     * @param itemId the id of the item clicked. This will be the same id that was passed by the
+     *               application to the IMS template to display search results.
+     */
+    void onItemClicked(String itemId);
+
+    /**
+     * Called when user clicks on a secondary image within item in the search results.
+     *
+     * @param secondaryImageId the id of the secondary image clicked. This will be the same id
+     *                         that was passed by the application to the IMS template to display
+     *                         search results.
+     */
+    void onSecondaryImageClicked(String secondaryImageId);
+
+    /**
+     * Called when the edit text is clicked and IME is about to launch. IME provides the surface
+     * view information through this call that applications can use to display a view on the
+     * IME surface.
+     *
+     * This method will NOT be called if an OEM has not allowed an application to hide the
+     * content area.
+     */
+    void onSurfaceInfo(int displayId, IBinder binder, int height, int width);
+}
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
index 9506fe1..62511f0 100644
--- 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
@@ -15,16 +15,39 @@
  */
 package com.android.car.ui.toolbar;
 
+import static android.view.WindowInsets.Type.ime;
+
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.CONTENT_AREA_SURFACE_PACKAGE;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_ICON_BITMAP_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_ICON_RES_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_ITEM_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUB_TITLE_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUPPLEMENTAL_ICON_BITMAP_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUPPLEMENTAL_ICON_RES_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_TITLE_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.WIDE_SCREEN_ACTION;
 import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
 
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
+import android.view.Display;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.SurfaceControlViewHost;
 import android.view.View;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
@@ -32,11 +55,19 @@
 import android.widget.ImageView;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.constraintlayout.widget.ConstraintLayout;
 
 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 java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -50,6 +81,16 @@
     private final int mStartPaddingWithoutIcon;
     private final int mStartPadding;
     private final int mEndPadding;
+    @Nullable
+    private View mWideScreenImeContentAreaView;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    private SurfaceControlViewHost mSurfaceControlViewHost;
+    private int mSurfaceHeight;
+    private int mSurfaceWidth;
+    private List<? extends CarUiImeSearchListItem> mWideScreenSearchItemList;
+    private final Map<String, CarUiImeSearchListItem> mIdToListItem = new HashMap<>();
+
     private Set<Toolbar.OnSearchListener> mSearchListeners = Collections.emptySet();
     private Set<Toolbar.OnSearchCompletedListener> mSearchCompletedListeners =
             Collections.emptySet();
@@ -82,7 +123,7 @@
         super(context, attrs, defStyleAttr);
 
         mInputMethodManager = (InputMethodManager)
-            getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 
         LayoutInflater inflater = LayoutInflater.from(context);
         inflater.inflate(R.layout.car_ui_toolbar_search_view, this, true);
@@ -128,6 +169,46 @@
             }
             return false;
         });
+
+        if (mSearchText instanceof CarUiEditText) {
+            ((CarUiEditText) mSearchText).registerOnPrivateImeCommandListener(
+                    new SearchViewImeCallback());
+        }
+    }
+
+    /**
+     * Apply window inset listener to the search container.
+     */
+    void installWindowInsetsListener(View searchContainer) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            // WindowInsets.isVisible() is only available on R or above
+            return;
+        }
+
+        searchContainer.getRootView().setOnApplyWindowInsetsListener((v, insets) -> {
+            if (insets.isVisible(ime())) {
+                displaySearchWideScreen();
+                mHandler.post(() -> {
+                    if (mSurfaceControlViewHost != null && mWideScreenImeContentAreaView != null
+                            && mSurfaceControlViewHost.getView() == null) {
+                        mSurfaceControlViewHost.setView(
+                                mWideScreenImeContentAreaView, mSurfaceWidth, mSurfaceHeight);
+                    }
+                });
+            }
+            return v.onApplyWindowInsets(insets);
+        });
+    }
+
+    void setViewToImeWideScreenSurface(View view) {
+        if (view == null && mSurfaceControlViewHost != null) {
+            mSurfaceControlViewHost.release();
+        }
+
+        if (view != null && view.getParent() != null) {
+            throw new IllegalStateException("view should not have a parent");
+        }
+        mWideScreenImeContentAreaView = view;
     }
 
     private boolean isEnter(KeyEvent event) {
@@ -164,28 +245,83 @@
     }
 
     /**
-     * Adds a listener for the search text changing.
-     * See also {@link #unregisterOnSearchListener(Toolbar.OnSearchListener)}
+     * Sets a listener for the search text changing.
      */
     public void setSearchListeners(Set<Toolbar.OnSearchListener> listeners) {
         mSearchListeners = listeners;
     }
 
     /**
-     * Removes a search listener.
-     * See also {@link #registerOnSearchListener(Toolbar.OnSearchListener)}
+     * 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> listeners) {
         mSearchCompletedListeners = listeners;
     }
 
     /**
-     * Sets the search hint.
-     *
-     * @param resId A string resource id of the search hint.
+     * Sets list of search item {@link CarUiListItem} to be displayed in the IMS
+     * template.
      */
-    public void setHint(int resId) {
-        mSearchText.setHint(resId);
+    public void setSearchItemsForWideScreen(List<? extends CarUiImeSearchListItem> searchItems) {
+        mWideScreenSearchItemList = searchItems != null ? new ArrayList<>(searchItems) : null;
+        displaySearchWideScreen();
+    }
+
+    private void displaySearchWideScreen() {
+        mIdToListItem.clear();
+        // mWideScreenImeContentAreaView will only be set when running in widescreen mode and
+        // apps allowed by OEMs are trying to set their own view. In that case we did not want to
+        // send the information to IME for templatized solution.
+        if (mWideScreenImeContentAreaView != null) {
+            return;
+        }
+
+        if (mWideScreenSearchItemList == null) {
+            mInputMethodManager.sendAppPrivateCommand(mSearchText, WIDE_SCREEN_ACTION, null);
+            return;
+        }
+
+        ArrayList<String> itemIdList = new ArrayList<>();
+        ArrayList<String> titleList = new ArrayList<>();
+        ArrayList<String> subTitleList = new ArrayList<>();
+        ArrayList<Bitmap> primaryImageBitmapList = new ArrayList<>();
+        ArrayList<Integer> primaryImageResId = new ArrayList<>();
+        ArrayList<Bitmap> secondaryImageBitmapList = new ArrayList<>();
+        ArrayList<String> secondaryItemId = new ArrayList<>();
+        ArrayList<Integer> secondaryImageResId = new ArrayList<>();
+        int id = 0;
+        for (CarUiImeSearchListItem item : mWideScreenSearchItemList) {
+            String idString = String.valueOf(id);
+            itemIdList.add(idString);
+            titleList.add(item.getTitle() != null ? item.getTitle().toString() : null);
+            subTitleList.add(item.getBody() != null ? item.getBody().toString() : null);
+            primaryImageResId.add(item.getIconResId());
+            secondaryItemId.add(idString);
+            secondaryImageResId.add(item.getSupplementalIconResId());
+            BitmapDrawable icon = (BitmapDrawable) item.getIcon();
+            primaryImageBitmapList.add(icon != null ? icon.getBitmap() : null);
+            BitmapDrawable supplementalIcon = (BitmapDrawable) item.getSupplementalIcon();
+            secondaryImageBitmapList.add(
+                    supplementalIcon != null ? supplementalIcon.getBitmap() : null);
+
+            mIdToListItem.put(idString, item);
+            id++;
+        }
+
+        Bundle bundle = new Bundle();
+        bundle.putStringArrayList(SEARCH_RESULT_ITEM_ID_LIST, itemIdList);
+        bundle.putStringArrayList(SEARCH_RESULT_TITLE_LIST, titleList);
+        bundle.putStringArrayList(SEARCH_RESULT_SUB_TITLE_LIST, subTitleList);
+        bundle.putParcelableArrayList(SEARCH_RESULT_ICON_BITMAP_LIST,
+                primaryImageBitmapList);
+        bundle.putParcelableArrayList(SEARCH_RESULT_SUPPLEMENTAL_ICON_BITMAP_LIST,
+                secondaryImageBitmapList);
+        bundle.putIntegerArrayList(SEARCH_RESULT_ICON_RES_ID_LIST, primaryImageResId);
+        bundle.putStringArrayList(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST, secondaryItemId);
+        bundle.putIntegerArrayList(SEARCH_RESULT_SUPPLEMENTAL_ICON_RES_ID_LIST,
+                secondaryImageResId);
+        mInputMethodManager.sendAppPrivateCommand(mSearchText, WIDE_SCREEN_ACTION, bundle);
     }
 
     /**
@@ -197,11 +333,6 @@
         mSearchText.setHint(hint);
     }
 
-    /** Gets the search hint */
-    public CharSequence getHint() {
-        return mSearchText.getHint();
-    }
-
     /**
      * Sets a custom icon to display in the search box.
      */
@@ -261,4 +392,62 @@
         mSearchText.setText(query);
         mSearchText.setSelection(mSearchText.getText().length());
     }
+
+    private class SearchViewImeCallback implements PrivateImeCommandCallback {
+
+        @Override
+        public void onItemClicked(String itemId) {
+            CarUiImeSearchListItem item = mIdToListItem.get(itemId);
+            if (item != null) {
+                CarUiContentListItem.OnClickListener listener =
+                        item.getOnClickListener();
+                if (listener != null) {
+                    listener.onClick(item);
+                }
+            }
+        }
+
+        @Override
+        public void onSecondaryImageClicked(String secondaryImageId) {
+            CarUiImeSearchListItem item = mIdToListItem.get(secondaryImageId);
+            if (item != null) {
+                CarUiContentListItem.OnClickListener listener =
+                        item.getSupplementalIconOnClickListener();
+                if (listener != null) {
+                    listener.onClick(item);
+                }
+            }
+        }
+
+        @Override
+        public void onSurfaceInfo(int displayId, IBinder binder, int height,
+                int width) {
+            if (Build.VERSION.SDK_INT < VERSION_CODES.R
+                    || mWideScreenImeContentAreaView == null) {
+                // SurfaceControlViewHost is only available on R and above
+                return;
+            }
+
+            DisplayManager dm = (DisplayManager) getContext().getSystemService(
+                    Context.DISPLAY_SERVICE);
+
+            Display display = dm.getDisplay(displayId);
+
+            if (mSurfaceControlViewHost != null) {
+                mSurfaceControlViewHost.release();
+            }
+
+            mSurfaceControlViewHost = new SurfaceControlViewHost(getContext(),
+                    display, binder);
+
+            mSurfaceHeight = height;
+            mSurfaceWidth = width;
+
+            Bundle bundle = new Bundle();
+            bundle.putParcelable(CONTENT_AREA_SURFACE_PACKAGE,
+                    mSurfaceControlViewHost.getSurfacePackage());
+            mInputMethodManager.sendAppPrivateCommand(mSearchText,
+                    WIDE_SCREEN_ACTION, bundle);
+        }
+    }
 }
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
index b069fb0..e527a52 100644
--- 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
@@ -22,6 +22,7 @@
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.View;
 import android.widget.FrameLayout;
 
 import androidx.annotation.DrawableRes;
@@ -31,6 +32,8 @@
 import androidx.annotation.XmlRes;
 
 import com.android.car.ui.R;
+import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
 
 import java.util.List;
 
@@ -42,8 +45,12 @@
  * {@link android.app.Activity#setActionBar(android.widget.Toolbar)} with it)
  *
  * <p>The toolbar supports a navigation button, title, tabs, search, and {@link MenuItem MenuItems}
+ *
+ * @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)}
  */
-public class Toolbar extends FrameLayout implements ToolbarController {
+@Deprecated
+public final class Toolbar extends FrameLayout implements ToolbarController {
 
     /** Callback that will be issued whenever the height of toolbar is changed. */
     public interface OnHeightChangedListener {
@@ -268,13 +275,33 @@
 
     /**
      * Gets the {@link TabLayout} for this toolbar.
+     *
+     * @deprecated Use other tab-related functions in the ToolbarController interface.
      */
+    @Deprecated
     @Override
     public TabLayout getTabLayout() {
         return mController.getTabLayout();
     }
 
     /**
+     * Gets the number of tabs in the toolbar. The tabs can be retrieved using
+     * {@link #getTab(int)}.
+     */
+    @Override
+    public int getTabCount() {
+        return mController.getTabCount();
+    }
+
+    /**
+     * Gets the index of the tab.
+     */
+    @Override
+    public int getTabPosition(TabLayout.Tab tab) {
+        return mController.getTabPosition(tab);
+    }
+
+    /**
      * Adds a tab to this toolbar. You can listen for when it is selected via
      * {@link #registerOnTabSelectedListener(OnTabSelectedListener)}.
      */
@@ -628,6 +655,50 @@
         return mController.unregisterOnSearchListener(listener);
     }
 
+    /**
+     * 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.
+     */
+    @Override
+    public boolean canShowSearchResultItems() {
+        return mController.canShowSearchResultItems();
+    }
+
+    /**
+     * Returns true if the app is allowed to set search results view.
+     */
+    @Override
+    public boolean canShowSearchResultsView() {
+        return mController.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 #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) {
+        mController.setSearchResultsView(view);
+    }
+
+    /**
+     * 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 #canShowSearchResultItems()}
+     * Else, this method will throw an {@link IllegalStateException}
+     */
+    @Override
+    public void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems) {
+        mController.setSearchResultItems(searchItems);
+    }
+
     /** Registers a new {@link OnSearchCompletedListener} to the list of listeners. */
     @Override
     public void registerOnSearchCompletedListener(OnSearchCompletedListener listener) {
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
index 4eb009d..6b38718 100644
--- 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
@@ -17,6 +17,7 @@
 package com.android.car.ui.toolbar;
 
 import android.graphics.drawable.Drawable;
+import android.view.View;
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
@@ -24,6 +25,9 @@
 import androidx.annotation.StringRes;
 import androidx.annotation.XmlRes;
 
+import com.android.car.ui.imewidescreen.CarUiImeSearchListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+
 import java.util.List;
 
 /**
@@ -77,10 +81,24 @@
 
     /**
      * Gets the {@link TabLayout} for this toolbar.
+     *
+     * @deprecated Use other tab-related functions in this interface.
      */
+    @Deprecated
     TabLayout getTabLayout();
 
     /**
+     * Gets the number of tabs in the toolbar. The tabs can be retrieved using
+     * {@link #getTab(int)}.
+     */
+    int getTabCount();
+
+    /**
+     * Gets the index of the tab.
+     */
+    int getTabPosition(TabLayout.Tab tab);
+
+    /**
      * Adds a tab to this toolbar. You can listen for when it is selected via
      * {@link #registerOnTabSelectedListener(Toolbar.OnTabSelectedListener)}.
      */
@@ -242,8 +260,10 @@
      */
     void registerToolbarHeightChangeListener(Toolbar.OnHeightChangedListener listener);
 
-    /** Unregisters an existing {@link Toolbar.OnHeightChangedListener} from the list of
-     * listeners. */
+    /**
+     * 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. */
@@ -258,11 +278,45 @@
     /** Unregisters an existing {@link Toolbar.OnSearchListener} from the list of listeners. */
     boolean unregisterOnSearchListener(Toolbar.OnSearchListener listener);
 
+    /**
+     * 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.
+     */
+    boolean canShowSearchResultItems();
+
+    /**
+     * Returns true if the app is allowed to set search results view.
+     */
+    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 #canShowSearchResultsView()}. If the app is not allowed this method will throw an
+     * {@link IllegalStateException}
+     *
+     * @param view to be added in the container.
+     */
+    void setSearchResultsView(View view);
+
+    /**
+     * 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 #canShowSearchResultItems()}
+     * Else, this method will throw an {@link IllegalStateException}
+     */
+    void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems);
+
     /** 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. */
+    /**
+     * 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. */
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
index 413beaa..02b3a1a 100644
--- 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
@@ -21,6 +21,7 @@
 import static android.view.View.VISIBLE;
 
 import static com.android.car.ui.utils.CarUiUtils.findViewByRefId;
+import static com.android.car.ui.utils.CarUiUtils.getBooleanSystemProperty;
 import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId;
 
 import android.app.Activity;
@@ -43,6 +44,7 @@
 
 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;
@@ -50,6 +52,7 @@
 import com.android.car.ui.utils.CarUxRestrictionsUtil;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -61,7 +64,7 @@
  * 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 {
+public final class ToolbarControllerImpl implements ToolbarController {
     private static final String TAG = "CarUiToolbarController";
 
     @Nullable
@@ -111,7 +114,9 @@
     private AlertDialog mOverflowDialog;
     private boolean mNavIconSpaceReserved;
     private boolean mLogoFillsNavIconSpace;
+    private View mViewForContentAreaInWideScreenMode;
     private boolean mShowLogo;
+    private List<? extends CarUiImeSearchListItem> mSearchItems;
     private final ProgressBarController mProgressBar;
     private final MenuItem.Listener mOverflowItemListener = item -> {
         updateOverflowDialog(item);
@@ -266,13 +271,33 @@
 
     /**
      * Gets the {@link TabLayout} for this toolbar.
+     *
+     * @deprecated Use other tab-related functions in the ToolbarController interface.
      */
+    @Deprecated
     @Override
     public TabLayout getTabLayout() {
         return mTabLayout;
     }
 
     /**
+     * Gets the number of tabs in the toolbar. The tabs can be retrieved using
+     * {@link #getTab(int)}.
+     */
+    @Override
+    public int getTabCount() {
+        return mTabLayout.getTabCount();
+    }
+
+    /**
+     * Gets the index of the tab.
+     */
+    @Override
+    public int getTabPosition(TabLayout.Tab tab) {
+        return mTabLayout.getTabPosition(tab);
+    }
+
+    /**
      * Adds a tab to this toolbar. You can listen for when it is selected via
      * {@link #registerOnTabSelectedListener(Toolbar.OnTabSelectedListener)}.
      */
@@ -693,6 +718,15 @@
                     ViewGroup.LayoutParams.MATCH_PARENT,
                     ViewGroup.LayoutParams.MATCH_PARENT);
             mSearchViewContainer.addView(searchView, layoutParams);
+            if (canShowSearchResultsView()) {
+                searchView.setViewToImeWideScreenSurface(mViewForContentAreaInWideScreenMode);
+            }
+
+            searchView.installWindowInsetsListener(mSearchViewContainer);
+
+            if (mSearchItems != null) {
+                searchView.setSearchItemsForWideScreen(mSearchItems);
+            }
 
             mSearchView = searchView;
         }
@@ -790,13 +824,94 @@
         mOverflowButton.setVisible(showButtons && countVisibleOverflowItems() > 0);
     }
 
+    /**
+     * Return the list of package names allowed to hide the content area in wide screen IME.
+     */
+    private List<String> allowPackageList(Context context) {
+        String[] packages = context.getResources()
+                .getStringArray(R.array.car_ui_ime_wide_screen_allowed_package_list);
+        return Arrays.asList(packages);
+    }
+
+    /**
+     * 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.
+     */
+    @Override
+    public boolean canShowSearchResultItems() {
+        return isWideScreenMode(mContext);
+    }
+
+    /**
+     * Returns whether or not system is running in a wide screen mode.
+     */
+    private static boolean isWideScreenMode(Context context) {
+        return getBooleanSystemProperty(context.getResources(),
+                R.string.car_ui_ime_wide_screen_system_property_name, false);
+    }
+
+    /**
+     * Returns true if the app is allowed to set search results view.
+     */
+    @Override
+    public boolean canShowSearchResultsView() {
+        boolean allowAppsToHideContentArea = mContext.getResources().getBoolean(
+                R.bool.car_ui_ime_wide_screen_allow_app_hide_content_area);
+        return isWideScreenMode(mContext) && (allowPackageList(mContext).contains(
+                mContext.getPackageName()) || allowAppsToHideContentArea);
+    }
+
+    /**
+     * 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 #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 (!canShowSearchResultsView()) {
+            throw new IllegalStateException(
+                    "not allowed to add view to wide screen IME, package name: "
+                            + mContext.getPackageName());
+        }
+
+        if (mSearchView != null) {
+            mSearchView.setViewToImeWideScreenSurface(view);
+        }
+
+        mViewForContentAreaInWideScreenMode = view;
+    }
+
+    /**
+     * 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 #canShowSearchResultItems()}
+     * Else, this method will throw an {@link IllegalStateException}
+     */
+    @Override
+    public void setSearchResultItems(List<? extends CarUiImeSearchListItem> searchItems) {
+        if (!canShowSearchResultItems()) {
+            throw new IllegalStateException(
+                    "system not in wide screen mode, not allowed to set search result items ");
+        }
+        mSearchItems = searchItems;
+        if (mSearchView != null) {
+            mSearchView.setSearchItemsForWideScreen(searchItems);
+        }
+    }
+
+
     /** 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
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
index b27a81a..ffa191b 100644
--- 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
@@ -15,13 +15,22 @@
  */
 package com.android.car.ui.utils;
 
+import static com.android.car.ui.utils.RotaryConstants.ROTARY_HORIZONTALLY_SCROLLABLE;
+import static com.android.car.ui.utils.RotaryConstants.ROTARY_VERTICALLY_SCROLLABLE;
+
 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;
@@ -34,10 +43,18 @@
 import androidx.annotation.UiThread;
 import androidx.core.view.ViewCompat;
 
+import java.lang.reflect.Method;
+
 /**
  * Collection of utility methods
  */
 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<>();
+
     /** This is a utility class */
     private CarUiUtils() {
     }
@@ -46,7 +63,7 @@
      * 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 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) {
@@ -134,11 +151,11 @@
     /**
      * Updates the ripple state on the given preference.
      *
-     * @param isEnabled whether the preference is enabled or not
+     * @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
+     *                                             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) {
@@ -153,6 +170,19 @@
     }
 
     /**
+     * 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);
+    }
+
+    /**
      * It behaves similarly to {@link View#findViewById(int)}, except that on Q and below,
      * it will first resolve the id to whatever it references.
      *
@@ -199,4 +229,105 @@
         }
         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;
+    }
 }
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
index 99154df..e6c62c9 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
@@ -23,19 +23,47 @@
  */
 public final class RotaryConstants {
     /**
-     * Content description indicating that the rotary controller should scroll this view
-     * horizontally.
+     * 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 rotary controller should scroll this view
-     * vertically.
+     * 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";
@@ -70,7 +98,7 @@
     /** 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 default focus. */
+    /** 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. */
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
index 6dd993b..62c189f 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
@@ -16,17 +16,28 @@
 
 package com.android.car.ui.utils;
 
-import static android.view.View.VISIBLE;
+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
@@ -36,50 +47,350 @@
  */
 public final class ViewUtils {
 
-    /** This is a utility class */
+    /**
+     * No view is focused, the focused view is not shown, or the focused view is a FocusParkingView.
+     */
+    public static final int NO_FOCUS = 1;
+
+    /** A scrollable container is focused. */
+    public 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.
+     */
+    public static final int REGULAR_FOCUS = 3;
+
+    /**
+     * An implicit default focus view (i.e., the first focusable item in a scrollable container) is
+     * focused.
+     */
+    public static final int IMPLICIT_DEFAULT_FOCUS = 4;
+
+    /** The {@code app:defaultFocus} view is focused. */
+    public static final int DEFAULT_FOCUS = 5;
+
+    /** The {@code android:focusedByDefault} view is focused. */
+    public 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)
+    public @interface FocusLevel {
+    }
+
+    /** This is a utility class. */
     private ViewUtils() {
     }
 
     /**
-     * Searches the {@code view} and its descendants in depth first order, and returns the first
-     * view that is focused by default, can take focus, but has no invisible ancestors. Returns null
-     * if not found.
+     * 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);
+    }
+
+    /** 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 View findFocusedByDefaultView(@NonNull View view) {
-        return depthFirstSearch(view,
-                /* targetPredicate= */ v -> v.isFocusedByDefault() && canTakeFocus(v),
-                /* skipPredicate= */ v -> v.getVisibility() != VISIBLE);
+    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.
+     *
+     * @return whether the view is focused
+     */
+    public static boolean adjustFocus(@NonNull View root, @Nullable View currentFocus) {
+        @FocusLevel int level = getFocusLevel(currentFocus);
+        return adjustFocus(root, level);
+    }
+
+    /**
+     * 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
+     */
+    public static boolean adjustFocus(@NonNull View root, @FocusLevel int currentLevel) {
+        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;
+        }
+        if (currentLevel < REGULAR_FOCUS && focusOnFirstRegularView(root)) {
+            return true;
+        }
+        if (currentLevel < SCROLLABLE_CONTAINER_FOCUS) {
+            return focusOnScrollableContainer(root);
+        }
+        return false;
+    }
+
+    @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 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 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
-     * primary focus view, i.e., the first focusable item in a scrollable container. Returns null
-     * if not found.
+     * {@code android:focusedByDefault} view that can take focus. Returns null if not found.
      */
-    public static View findPrimaryFocusView(@NonNull View view) {
-        View scrollableContainer = findScrollableContainer(view);
-        return scrollableContainer == null ? null : findFocusableDescendant(scrollableContainer);
+    @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 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);
+        return rotaryContainer == null
+                ? null
+                : findFirstFocusableDescendant(rotaryContainer);
     }
 
     /**
      * Searches the {@code view}'s descendants in depth first order, and returns the first view
-     * that can take focus but has no invisible ancestors, or null if not found.
+     * that can take focus, or null if not found.
      */
+    @VisibleForTesting
     @Nullable
-    public static View findFocusableDescendant(@NonNull View view) {
+    static View findFirstFocusableDescendant(@NonNull View view) {
         return depthFirstSearch(view,
                 /* targetPredicate= */ v -> v != view && canTakeFocus(v),
-                /* skipPredicate= */ v -> v.getVisibility() != VISIBLE);
+                /* skipPredicate= */ v -> !v.isShown());
     }
 
     /**
      * Searches the {@code view} and its descendants in depth first order, and returns the first
-     * view that meets the given condition. Returns null if not found.
+     * rotary container shown on the screen. Returns null if not found.
      */
     @Nullable
-    public static View depthFirstSearch(@NonNull View view, @NonNull Predicate<View> predicate) {
-        return depthFirstSearch(view, predicate, /* skipPredicate= */ null);
+    private static View findRotaryContainer(@NonNull View view) {
+        return depthFirstSearch(view,
+                /* targetPredicate= */ v -> isRotaryContainer(v),
+                /* skipPredicate= */ v -> !v.isShown());
     }
 
     /**
@@ -90,7 +401,7 @@
     @Nullable
     private static View depthFirstSearch(@NonNull View view,
             @NonNull Predicate<View> targetPredicate,
-            @NonNull Predicate<View> skipPredicate) {
+            @Nullable Predicate<View> skipPredicate) {
         if (skipPredicate != null && skipPredicate.test(view)) {
             return null;
         }
@@ -110,35 +421,14 @@
         return null;
     }
 
-    /**
-     * 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
-     */
-    public interface Predicate<T> {
-        /** Evaluates this predicate on the given argument. */
-        boolean test(@NonNull T t);
-    }
-
-    /**
-     * Searches the {@code view} and its descendants in depth first order, and returns the first
-     * scrollable container that has no invisible ancestors. Returns null if not found.
-     */
-    @Nullable
-    private static View findScrollableContainer(@NonNull View view) {
-        return depthFirstSearch(view,
-                /* targetPredicate= */ v -> {
-                    CharSequence contentDescription = v.getContentDescription();
-                    return TextUtils.equals(contentDescription, ROTARY_VERTICALLY_SCROLLABLE)
-                            || TextUtils.equals(contentDescription, ROTARY_HORIZONTALLY_SCROLLABLE);
-                },
-                /* skipPredicate= */ v -> v.getVisibility() != VISIBLE);
-    }
-
     /** Returns whether {@code view} can be focused. */
     private static boolean canTakeFocus(@NonNull View view) {
-        return view.isFocusable() && view.isEnabled() && view.getVisibility() == VISIBLE
-                && view.getWidth() > 0 && view.getHeight() > 0;
+        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);
     }
 }
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
index e9b706d..3ad5398 100644
--- 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
@@ -16,6 +16,7 @@
 <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"/>
@@ -70,11 +71,14 @@
       <item type="attr" name="layout_optimizationLevel"/>
       <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_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_escrow_check_components_automatically"/>
       <item type="bool" name="car_ui_focus_area_default_focus_overrides_history"/>
+      <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_show_full_screen"/>
       <item type="bool" name="car_ui_preference_show_chevron"/>
@@ -87,6 +91,12 @@
       <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"/>
@@ -94,6 +104,8 @@
       <item type="color" name="car_ui_ripple_color"/>
       <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_stroke_color"/>
       <item type="color" name="car_ui_rotary_focus_stroke_color"/>
       <item type="color" name="car_ui_rotary_focus_stroke_secondary_color"/>
       <item type="color" name="car_ui_scrollbar_thumb"/>
@@ -120,6 +132,37 @@
       <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_margin_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"/>
@@ -173,6 +216,7 @@
       <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_rotary_focus_pressed_stroke_width"/>
       <item type="dimen" name="car_ui_rotary_focus_stroke_width"/>
       <item type="dimen" name="car_ui_scrollbar_button_size"/>
       <item type="dimen" name="car_ui_scrollbar_container_width"/>
@@ -231,12 +275,19 @@
       <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"/>
@@ -245,6 +296,7 @@
       <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_recycler_view_ime_wide_screen_thumb"/>
       <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"/>
@@ -266,7 +318,14 @@
       <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_contentAreaAutomotive"/>
       <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_surface"/>
+      <item type="id" name="car_ui_inputExtractActionAutomotive"/>
+      <item type="id" name="car_ui_inputExtractEditTextContainer"/>
       <item type="id" name="car_ui_list_item_end_guideline"/>
       <item type="id" name="car_ui_list_item_start_guideline"/>
       <item type="id" name="car_ui_list_limiting_message"/>
@@ -310,6 +369,14 @@
       <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="checkbox_widget"/>
       <item type="id" name="container"/>
       <item type="id" name="content_icon"/>
@@ -351,6 +418,7 @@
       <item type="layout" name="car_ui_base_layout_toolbar"/>
       <item type="layout" name="car_ui_base_layout_toolbar_legacy"/>
       <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_limiting_message"/>
       <item type="layout" name="car_ui_list_preference"/>
@@ -372,6 +440,7 @@
       <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"/>
@@ -383,6 +452,7 @@
       <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"/>
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
new file mode 100644
index 0000000..b0f4a34
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_icon_error.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.
+  -->
+
+<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_list_item_background.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml
index f10416e..4d33475 100644
--- 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
@@ -13,22 +13,20 @@
      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">
-        <layer-list>
-            <item>
-                <shape android:shape="rectangle">
-                    <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
-                </shape>
-            </item>
-            <item>
-                <shape android:shape="rectangle">
-                    <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
-                            android:color="@color/car_ui_rotary_focus_stroke_color"/>
-                </shape>
-            </item>
-        </layer-list>
+        <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>
         <ripple android:color="?android:attr/colorControlHighlight">
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recycler_view_ime_wide_screen_thumb.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recycler_view_ime_wide_screen_thumb.xml
new file mode 100644
index 0000000..5cb78e4
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_recycler_view_ime_wide_screen_thumb.xml
@@ -0,0 +1,21 @@
+<?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.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient android:startColor="#60A8F0" android:endColor="#60A8F0"
+              android:angle="45"/>
+    <corners android:radius="6dp" />
+</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
index d654b2b..985b7d8 100644
--- 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
@@ -16,7 +16,7 @@
   -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
-    <EditText
+    <com.android.car.ui.toolbar.CarUiEditText
               android:id="@+id/textbox"
               android:layout_width="match_parent"
               android:layout_height="@dimen/car_ui_dialog_edittext_height"
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
index 51204de..7ac4732 100644
--- 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
@@ -46,6 +46,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/car_ui_header_list_item_text_start_margin"
+            android:textDirection="locale"
             android:textAppearance="@style/TextAppearance.CarUi.ListItem.Header" />
 
         <TextView
@@ -53,6 +54,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/car_ui_list_item_text_no_icon_start_margin"
+            android:textDirection="locale"
             android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body" />
     </LinearLayout>
 
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
new file mode 100644
index 0000000..fd7539b
--- /dev/null
+++ b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_ims_wide_screen_input_view.xml
@@ -0,0 +1,187 @@
+<?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: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_margin_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: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"/>
+
+    <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">
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@id/car_ui_wideScreenSearchResultList"
+            android:scrollbarThumbVertical="@drawable/car_ui_recycler_view_ime_wide_screen_thumb"
+            android:scrollbars="vertical"
+            android:requiresFadingEdge="vertical"
+            android:paddingTop="@dimen/car_ui_ime_wide_screen_recycler_view_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
index 8b5b281..d0f179e 100644
--- 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
@@ -109,12 +109,14 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:singleLine="@bool/car_ui_list_item_single_line_title"
+            android:textDirection="locale"
             android:textAppearance="@style/TextAppearance.CarUi.ListItem" />
 
         <TextView
             android:id="@+id/body"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:textDirection="locale"
             android:textAppearance="@style/TextAppearance.CarUi.ListItem.Body" />
     </LinearLayout>
 
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
index 70bf96d..d56fb38 100644
--- 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
@@ -22,11 +22,16 @@
     android:layout_height="match_parent"
     android:background="@drawable/car_ui_activity_background">
 
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/list"
+    <com.android.car.ui.FocusArea
+        android:id="@+id/car_ui_focus_area"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:tag="carUiPreferenceRecyclerView"
-        app:enableDivider="true" />
+        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_list_preference_with_toolbar.xml b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_preference_with_toolbar.xml
index f42c9f1..c83528b 100644
--- a/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_preference_with_toolbar.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res/layout/car_ui_list_preference_with_toolbar.xml
@@ -16,23 +16,32 @@
   -->
 
 <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">
+             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"
+    <com.android.car.ui.FocusArea
+        android:id="@+id/car_ui_focus_area"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:tag="carUiPreferenceRecyclerView"
-        app:enableDivider="true" />
+        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>
 
-    <com.android.car.ui.toolbar.Toolbar
-        android:id="@+id/toolbar"
+    <com.android.car.ui.FocusArea
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:car_ui_state="subpage" />
+        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"
+            app:car_ui_state="subpage"/>
+    </com.android.car.ui.FocusArea>
 
 </FrameLayout>
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
index 04c1c37..86474a9 100644
--- 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
@@ -33,7 +33,7 @@
         android:layout_marginEnd="@dimen/car_ui_preference_edit_text_dialog_message_margin_end"
         android:visibility="gone"/>
 
-    <EditText
+    <com.android.car.ui.toolbar.CarUiEditText
         android:id="@android:id/edit"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
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
index 1aa70fa..a0c955f 100644
--- 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
@@ -20,7 +20,7 @@
 
     <com.android.car.ui.recyclerview.CarUiRecyclerViewContainer
         android:id="@+id/car_ui_recycler_view"
-        android:layout_width="0dp"
+        android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_marginEnd="@dimen/car_ui_scrollbar_margin"
         android:tag="carUiRecyclerView"
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
index c3ad68d..6a3d9ec 100644
--- 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
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <EditText
+    <com.android.car.ui.toolbar.CarUiEditText
         android:id="@+id/car_ui_toolbar_search_bar"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
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
index e823bdf..0ca5abe 100644
--- 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
@@ -113,6 +113,13 @@
         <!-- Bottom offset for car ui recycler view for linear layout. -->
         <attr name="bottomOffset" format="integer" />
 
+        <!-- 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" />
 
@@ -147,9 +154,30 @@
 
     <!-- Attributes for FocusArea. -->
     <declare-styleable name="FocusArea">
-        <!-- The ID of a focusable descendant view which should be focused when the user nudges to
-             this FocusArea, if there was no view focused in the FocusArea or
-             car_ui_focus_area_default_focus_overrides_history is true. -->
+        <!-- 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 first focusable item in a scrollable container, if any
+                   4. previously focused view, if any and the cache is not stale
+                   5. the first focusable view, if any
+                 Note that 4 will be prioritized over 1&2&3 when
+                 car_ui_focus_area_default_focus_overrides_history is false.
+             (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 first focusable item in a scrollable container, if any
+                   4. 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"/>
 
         <!-- The paddings of FocusArea highlight. It does't impact the paddings on its child views,
@@ -215,4 +243,12 @@
         <!-- The ID of the target FocusArea when nudging down. -->
         <attr name="nudgeDown" format="reference"/>
     </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-ui-lib/src/main/res/values/bools.xml b/car-ui-lib/car-ui-lib/src/main/res/values/bools.xml
index 67efdca..b34d620 100644
--- 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
@@ -63,4 +63,13 @@
 
     <!--  Whether to log the escrow components check automatically for all the activities or not.  -->
     <bool name="car_ui_escrow_check_components_automatically">false</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>
+    <!-- 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>
 </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
index d943920..b407cb6 100644
--- 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
@@ -48,6 +48,17 @@
 
     <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>
+
+    <!-- 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
index f0c2a8b..d355f99 100644
--- 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
@@ -210,5 +210,41 @@
     <!-- Rotary focus highlight  -->
 
     <dimen name="car_ui_rotary_focus_stroke_width">8dp</dimen>
+    <dimen name="car_ui_rotary_focus_pressed_stroke_width">4dp</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_margin_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>
 </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
index 181846c..34ee538 100644
--- 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
@@ -36,4 +36,25 @@
     <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>
+
+    <!-- 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
index 3f0c9b1..44a162e 100644
--- 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
@@ -19,4 +19,21 @@
 
     <!-- Id used for in car_ui_toolbar_menu_item.xml -->
     <item name="car_ui_toolbar_menu_item_text_container" type="id"/>
+
+    <!-- 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
index b2c737b..976a634 100644
--- 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
@@ -25,7 +25,7 @@
     <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">10000</integer>
+    <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
@@ -33,5 +33,5 @@
     <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">10000</integer>
+    <integer name="car_ui_focus_area_history_expiration_period_ms">3000</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
index 46a29fe..a3f0539 100644
--- 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
@@ -39,9 +39,11 @@
     <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>
+    <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>
+    <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] -->
@@ -61,4 +63,18 @@
     <!-- 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>
 </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
index 34bbf3c..a599fa0 100644
--- 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
@@ -155,6 +155,7 @@
         <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>
 
@@ -204,6 +205,9 @@
 
         <!-- Used by CarUiRecyclerView -->
         <item name="carUiRecyclerViewStyle">@style/Widget.CarUi.CarUiRecyclerView</item>
+
+        <!-- textAppearance -->
+        <item name="android:textAppearance">@style/TextAppearance.CarUi</item>
     </style>
 
     <!-- TODO(b/150230923) remove this when other apps are ready -->
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
index 82a4d65..35f033c 100644
--- 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
@@ -19,6 +19,7 @@
     <!-- 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>
+    <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/paintbooth/AndroidManifest-gradle.xml b/car-ui-lib/paintbooth/AndroidManifest-gradle.xml
index 3184bd7..36823ec 100644
--- a/car-ui-lib/paintbooth/AndroidManifest-gradle.xml
+++ b/car-ui-lib/paintbooth/AndroidManifest-gradle.xml
@@ -49,18 +49,27 @@
         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=".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">
-      <meta-data android:name="distractionOptimized" android:value="true"/>
-    </activity>
+        android:theme="@style/Theme.CarUi"/>
     <activity
         android:name=".overlays.OverlayActivity"
         android:exported="false"
diff --git a/car-ui-lib/paintbooth/AndroidManifest.xml b/car-ui-lib/paintbooth/AndroidManifest.xml
index c277ff5..9763b47 100644
--- a/car-ui-lib/paintbooth/AndroidManifest.xml
+++ b/car-ui-lib/paintbooth/AndroidManifest.xml
@@ -72,6 +72,12 @@
         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=".toolbar.ToolbarActivity"
         android:exported="false"
         android:parentActivityName=".MainActivity">
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
index 02b8088..bf50162 100644
--- 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
@@ -46,6 +46,7 @@
 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.widescreenime.WideScreenImeActivity;
 import com.android.car.ui.paintbooth.widgets.WidgetActivity;
 import com.android.car.ui.recyclerview.CarUiRecyclerView;
 import com.android.car.ui.toolbar.ToolbarController;
@@ -76,6 +77,7 @@
             new ActivityElement("Old toolbar sample", OldToolbarActivity.class),
             new ActivityElement("No CarUiToolbar sample", NoCarUiToolbarActivity.class),
             new ActivityElement("Widget sample", WidgetActivity.class),
+            new ActivityElement("Wide Screen IME", WideScreenImeActivity.class),
             new ActivityElement("ListItem sample", CarUiListItemActivity.class));
 
     private abstract static class ViewHolder extends RecyclerView.ViewHolder {
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
index 63a2aed..b3dfeb1 100644
--- 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
@@ -106,15 +106,12 @@
         int screenHeight = displayMetrics.heightPixels;
         int screenWidth = displayMetrics.widthPixels;
         LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
-        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+        final 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.TYPE_SYSTEM_ALERT,
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                 PixelFormat.TRANSLUCENT);
 
         params.packageName = this.getPackageName();
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
index 1819427..68ec45b 100644
--- 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
@@ -191,6 +191,11 @@
 
         item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
         item.setTitle("Supplemental icon with listener");
+        item.setPrimaryIconType(CarUiContentListItem.IconType.CONTENT);
+        item.setIcon(getDrawable(R.drawable.ic_launcher));
+        item.setBody("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());
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
index 7cf1cce..3d390fc 100644
--- 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
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.util.Pair;
@@ -35,6 +36,8 @@
 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;
@@ -83,6 +86,8 @@
                 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,
@@ -142,6 +147,7 @@
         new AlertDialogBuilder(this)
                 .setTitle("Standard Alert Dialog")
                 .setEditBox("Edit me please", null, null)
+                .setEditTextTitleAndDescForWideScreen("title", "desc from app")
                 .setPositiveButton("OK", (dialogInterface, i) -> {
                 })
                 .show();
@@ -199,6 +205,35 @@
                 .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("My Title!")
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
index f32818a..b9a9daa 100644
--- 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
@@ -159,6 +159,30 @@
             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)
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
new file mode 100644
index 0000000..8fd206d
--- /dev/null
+++ b/car-ui-lib/paintbooth/src/main/java/com/android/car/ui/paintbooth/widescreenime/WideScreenImeActivity.java
@@ -0,0 +1,357 @@
+/*
+ * 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.SEARCH_RESULT_ICON_RES_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_ITEM_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUB_TITLE_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_SUPPLEMENTAL_ICON_RES_ID_LIST;
+import static com.android.car.ui.imewidescreen.CarUiImeWideScreenController.SEARCH_RESULT_TITLE_LIST;
+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.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.View;
+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.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.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.Toolbar;
+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 = "WideScreenImeActivity";
+
+    private final List<MenuItem> mMenuItems = new ArrayList<>();
+    private final List<Pair<CharSequence, View.OnFocusChangeListener>> mEditText =
+            new ArrayList<>();
+
+    private final ArrayList<String> mItemIdList = new ArrayList<>();
+    private final ArrayList<String> mTitleList = new ArrayList<>();
+    private final ArrayList<String> mSubTitleList = new ArrayList<>();
+    private final ArrayList<Integer> mPrimaryImageResId = new ArrayList<>();
+    private final ArrayList<String> mSecondaryItemId = new ArrayList<>();
+    private final ArrayList<Integer> mSecondaryImageResId = 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 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;
+                });
+
+        CarUiContentListItem.OnClickListener mainClickListener = i ->
+                Toast.makeText(this, "Item clicked!", Toast.LENGTH_SHORT).show();
+
+        CarUiContentListItem.OnClickListener secondaryClickListener = i ->
+                Toast.makeText(this, "Item's secondary action clicked!", Toast.LENGTH_SHORT).show();
+
+        final int[] count = {1};
+        CarUiImeSearchListItem item = new CarUiImeSearchListItem(CarUiContentListItem.Action.ICON);
+        item.setTitle("Title " + count[0]);
+        item.setBody("Sub title " + count[0]);
+        item.setIconResId(R.drawable.ic_launcher);
+        item.setSupplementalIconResId(R.drawable.ic_launcher);
+        item.setSupplementalIcon(getDrawable(R.drawable.ic_launcher), secondaryClickListener);
+        item.setOnItemClickedListener(mainClickListener);
+
+        List<CarUiImeSearchListItem> searchItems = new ArrayList<>();
+
+        searchItems.add(item);
+
+        // initial list to display in search view.
+        if (toolbar.canShowSearchResultItems()) {
+            toolbar.setSearchResultItems(searchItems);
+        }
+
+        LayoutInflater inflater = LayoutInflater.from(this);
+        View contentArea = inflater.inflate(R.layout.ime_wide_screen_dummy_view, null, true);
+
+        if (toolbar.canShowSearchResultsView()) {
+            toolbar.setSearchResultsView(contentArea);
+        }
+
+        contentArea.findViewById(R.id.button_1).setOnClickListener(v ->
+                Toast.makeText(this, "Button 1 clicked", Toast.LENGTH_SHORT).show()
+        );
+
+        contentArea.findViewById(R.id.button_2).setOnClickListener(v -> {
+                    Toast.makeText(this, "Clearing the view...", Toast.LENGTH_SHORT).show();
+                    toolbar.setSearchResultsView(null);
+                }
+        );
+
+        toolbar.registerOnSearchListener((query) -> {
+            count[0]++;
+            CarUiImeSearchListItem item1 = new CarUiImeSearchListItem(
+                    CarUiContentListItem.Action.ICON);
+            item1.setTitle("Title " + count[0]);
+            item1.setBody("Sub title " + count[0]);
+            item1.setIconResId(R.drawable.ic_launcher);
+            item1.setSupplementalIconResId(R.drawable.ic_launcher);
+            item1.setSupplementalIcon(getDrawable(R.drawable.ic_launcher), secondaryClickListener);
+            item1.setOnItemClickedListener(mainClickListener);
+            searchItems.add(item1);
+
+            if (toolbar.canShowSearchResultItems()) {
+                toolbar.setSearchResultItems(searchItems);
+            }
+        });
+
+        mMenuItems.add(MenuItem.builder(this)
+                .setToSearch()
+                .setOnClickListener(i -> {
+                    toolbar.setState(Toolbar.State.SEARCH);
+                })
+                .build());
+
+        toolbar.setMenuItems(mMenuItems);
+
+        mEditText.add(Pair.create("Default Input Edit Text field", null));
+
+        mEditText.add(Pair.create("Add Desc to content area",
+                this::addDescToContentArea));
+
+        mEditText.add(Pair.create("Hide the content area",
+                this::hideContentArea));
+
+        mEditText.add(Pair.create("Hide extraction view",
+                this::hideExtractionView));
+
+        for (int i = 0; i < 7; i++) {
+            mItemIdList.add("itemId" + i);
+            mTitleList.add("Title " + i);
+            mSubTitleList.add("subtitle " + i);
+            mPrimaryImageResId.add(R.drawable.ic_launcher);
+            mSecondaryItemId.add("imageId" + i);
+            mSecondaryImageResId.add(R.drawable.ic_launcher);
+        }
+
+        mEditText.add(Pair.create("Show IME list view", this::showImeListView));
+
+        mEditText.add(Pair.create("Add icon to extracted view", this::addIconToExtractedView));
+
+        mEditText.add(
+                Pair.create("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 showImeListView(View view, boolean hasFocus) {
+        if (!hasFocus) {
+            return;
+        }
+
+        Bundle bundle = new Bundle();
+
+        EditText editText = (EditText) view;
+        editText.addTextChangedListener(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) {
+
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mItemIdList.add("itemId " + s.toString());
+                mTitleList.add("Title " + s.toString());
+                mSubTitleList.add("subtitle ");
+                mPrimaryImageResId.add(R.drawable.ic_launcher);
+                mSecondaryItemId.add("imageId" + s.toString());
+                mSecondaryImageResId.add(R.drawable.ic_launcher);
+
+                bundle.putStringArrayList(SEARCH_RESULT_TITLE_LIST, mTitleList);
+                bundle.putStringArrayList(SEARCH_RESULT_SUB_TITLE_LIST, mSubTitleList);
+                bundle.putIntegerArrayList(SEARCH_RESULT_ICON_RES_ID_LIST,
+                        mPrimaryImageResId);
+                mInputMethodManager.sendAppPrivateCommand(view, WIDE_SCREEN_ACTION, bundle);
+            }
+        });
+
+        bundle.putStringArrayList(SEARCH_RESULT_ITEM_ID_LIST, mItemIdList);
+        bundle.putStringArrayList(SEARCH_RESULT_TITLE_LIST, mTitleList);
+        bundle.putStringArrayList(SEARCH_RESULT_SUB_TITLE_LIST, mSubTitleList);
+        bundle.putStringArrayList(SEARCH_RESULT_SUPPLEMENTAL_ICON_ID_LIST, mSecondaryItemId);
+        bundle.putIntegerArrayList(SEARCH_RESULT_ICON_RES_ID_LIST, mPrimaryImageResId);
+        bundle.putIntegerArrayList(SEARCH_RESULT_SUPPLEMENTAL_ICON_RES_ID_LIST,
+                mSecondaryImageResId);
+        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 static class ViewHolder extends RecyclerView.ViewHolder {
+
+        private final EditText mEditText;
+
+        ViewHolder(View itemView) {
+            super(itemView);
+            mEditText = itemView.requireViewById(R.id.edit_text);
+        }
+
+        public void bind(CharSequence title, View.OnFocusChangeListener listener) {
+            mEditText.setText(title);
+            mEditText.setOnFocusChangeListener(listener);
+        }
+    }
+
+    private final RecyclerView.Adapter<ViewHolder> mAdapter =
+            new RecyclerView.Adapter<ViewHolder>() {
+                @Override
+                public int getItemCount() {
+                    return mEditText.size();
+                }
+
+                @Override
+                public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
+                    View item =
+                            LayoutInflater.from(parent.getContext())
+                                    .inflate(R.layout.edit_text_list_item,
+                                            parent, false);
+
+                    return new ViewHolder(item);
+                }
+
+                @Override
+                public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+                    Pair<CharSequence, View.OnFocusChangeListener> pair = mEditText.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/res/layout/edit_text_list_item.xml b/car-ui-lib/paintbooth/src/main/res/layout/edit_text_list_item.xml
new file mode 100644
index 0000000..a04edd7
--- /dev/null
+++ b/car-ui-lib/paintbooth/src/main/res/layout/edit_text_list_item.xml
@@ -0,0 +1,29 @@
+<?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/ime_wide_screen_dummy_view.xml b/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml
new file mode 100644
index 0000000..1118ce9
--- /dev/null
+++ b/car-ui-lib/paintbooth/src/main/res/layout/ime_wide_screen_dummy_view.xml
@@ -0,0 +1,47 @@
+<?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/values/strings.xml b/car-ui-lib/paintbooth/src/main/res/values/strings.xml
index f347784..5965d68 100644
--- a/car-ui-lib/paintbooth/src/main/res/values/strings.xml
+++ b/car-ui-lib/paintbooth/src/main/res/values/strings.xml
@@ -180,6 +180,13 @@
   <!-- 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>
 
@@ -270,6 +277,9 @@
   <!-- 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>
 
diff --git a/car-ui-lib/referencedesign/Android.mk b/car-ui-lib/referencedesign/Android.mk
index ac85df4..ef0ad97 100644
--- a/car-ui-lib/referencedesign/Android.mk
+++ b/car-ui-lib/referencedesign/Android.mk
@@ -20,12 +20,14 @@
     com.android.car.settings \
     com.android.car.voicecontrol \
     com.android.car.faceenroll \
-    com.android.permissioncontroller \
+    com.android.managedprovisioning \
     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.carassistant \
     com.google.android.tts \
@@ -39,9 +41,12 @@
 CAR_UI_RRO_TARGETS := \
     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.vending \
diff --git a/car-ui-lib/referencedesign/AndroidManifest-overlayable.xml b/car-ui-lib/referencedesign/AndroidManifest-overlayable.xml
index 214755c..1b0585a 100644
--- a/car-ui-lib/referencedesign/AndroidManifest-overlayable.xml
+++ b/car-ui-lib/referencedesign/AndroidManifest-overlayable.xml
@@ -6,6 +6,6 @@
         android:targetName="car-ui-lib"
         android:resourcesMap="@xml/overlays"
         android:isStatic="true"
-        android:requiredSystemPropertyName="ro.build.characteristics"
-        android:requiredSystemPropertyValue="automotive"/>
+        android:requiredSystemPropertyName="ro.build.car_ui_rros_enabled"
+        android:requiredSystemPropertyValue="true"/>
 </manifest>
diff --git a/car-ui-lib/referencedesign/AndroidManifest.xml b/car-ui-lib/referencedesign/AndroidManifest.xml
index a6dbae3..0994382 100644
--- a/car-ui-lib/referencedesign/AndroidManifest.xml
+++ b/car-ui-lib/referencedesign/AndroidManifest.xml
@@ -5,6 +5,6 @@
         android:targetPackage="{{TARGET_PACKAGE_NAME}}"
         android:resourcesMap="@xml/overlays"
         android:isStatic="true"
-        android:requiredSystemPropertyName="ro.build.characteristics"
-        android:requiredSystemPropertyValue="automotive"/>
+        android:requiredSystemPropertyName="ro.build.car_ui_rros_enabled"
+        android:requiredSystemPropertyValue="true"/>
 </manifest>
diff --git a/car-ui-lib/referencedesign/product.mk b/car-ui-lib/referencedesign/product.mk
index 92e0bea..e834714 100644
--- a/car-ui-lib/referencedesign/product.mk
+++ b/car-ui-lib/referencedesign/product.mk
@@ -17,15 +17,17 @@
     googlecarui-com-android-car-settings \
     googlecarui-com-android-car-voicecontrol \
     googlecarui-com-android-car-faceenroll \
-    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-carassistant \
     googlecarui-com-google-android-tts \
+    googlecarui-com-android-managedprovisioning \
     googlecarui-com-android-vending \
 
 
@@ -33,9 +35,16 @@
 PRODUCT_PACKAGES += \
     googlecarui-overlayable-com-google-android-apps-automotive-inputmethod \
     googlecarui-overlayable-com-google-android-apps-automotive-inputmethod-dev \
+    googlecarui-overlayable-com-google-android-apps-automotive-templates-host \
     googlecarui-overlayable-com-google-android-embedded-projection \
     googlecarui-overlayable-com-google-android-gms \
+    googlecarui-overlayable-com-google-android-gsf \
     googlecarui-overlayable-com-google-android-packageinstaller \
+    googlecarui-overlayable-com-google-android-permissioncontroller \
     googlecarui-overlayable-com-google-android-carassistant \
     googlecarui-overlayable-com-google-android-tts \
     googlecarui-overlayable-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/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 1f89ff2..14f6cd0 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
@@ -17,6 +17,15 @@
   ~
  -->
 <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"/>
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
index 18f2e16..be95cc1 100644
--- 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
@@ -38,14 +38,6 @@
             android:layout_gravity="center"
             android:tint="@color/car_ui_toolbar_menu_item_icon_color"
             android:tintMode="src_in"/>
-        <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:background="@null"
-            android:focusable="false"
-            android:clickable="false"/>
     </FrameLayout>
 
     <FrameLayout
@@ -55,6 +47,14 @@
         android:layout_height="wrap_content"
         android:background="?android:attr/selectableItemBackground">
         <!-- These buttons must have clickable="false" or they will steal the click events from the container -->
+        <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:background="@null"
+            android:focusable="false"
+            android:clickable="false"/>
         <com.android.car.ui.uxr.DrawableStateButton
             android:id="@+id/car_ui_toolbar_menu_item_text"
             style="@style/Widget.CarUi.Toolbar.TextButton"
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
new file mode 100644
index 0000000..4364271
--- /dev/null
+++ b/car-ui-lib/referencedesign/res/layout/car_ui_toolbar_menu_item_primary.xml
@@ -0,0 +1,74 @@
+<?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:background="@drawable/car_ui_toolbar_menu_item_icon_ripple">
+        <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"/>
+        <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:background="@null"
+            android:focusable="false"
+            android:clickable="false"/>
+    </FrameLayout>
+
+    <FrameLayout
+        android:id="@+id/car_ui_toolbar_menu_item_text_container"
+        style="@style/Widget.CarUi.Toolbar.MenuItem.IndividualContainer"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <!-- 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="match_parent"
+            android:layout_gravity="center"
+            android:focusable="false"
+            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="match_parent"
+            android:layout_gravity="center"
+            android:focusable="false"
+            android:clickable="false"/>
+    </FrameLayout>
+</FrameLayout>
diff --git a/car-ui-lib/referencedesign/res/values/styles.xml b/car-ui-lib/referencedesign/res/values/styles.xml
index 433911c..ba37aac 100644
--- a/car-ui-lib/referencedesign/res/values/styles.xml
+++ b/car-ui-lib/referencedesign/res/values/styles.xml
@@ -41,6 +41,9 @@
     <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>
@@ -51,6 +54,12 @@
         <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 -->
diff --git a/car-ui-lib/referencedesign/res/xml/overlays.xml b/car-ui-lib/referencedesign/res/xml/overlays.xml
index cc9b092..363d389 100644
--- a/car-ui-lib/referencedesign/res/xml/overlays.xml
+++ b/car-ui-lib/referencedesign/res/xml/overlays.xml
@@ -3,6 +3,7 @@
     <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="layout/car_ui_toolbar_menu_item" value="@layout/car_ui_toolbar_menu_item"/>
+    <item target="layout/car_ui_toolbar_menu_item_primary" value="@layout/car_ui_toolbar_menu_item_primary"/>
     <item target="layout/car_ui_preference_widget_seekbar" value="@layout/car_ui_preference_widget_seekbar"/>
 
     <item target="drawable/car_ui_icon_arrow_back" value="@drawable/car_ui_icon_arrow_back"/>
diff --git a/car-ui-lib/tests/apitest/current.xml b/car-ui-lib/tests/apitest/current.xml
index 76eb5a2..461ce2c 100644
--- a/car-ui-lib/tests/apitest/current.xml
+++ b/car-ui-lib/tests/apitest/current.xml
@@ -1,15 +1,19 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <!--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="state_ux_restricted"/>
+  <public type="bool" name="car_ui_alert_dialog_force_dismiss_button"/>
   <public type="bool" name="car_ui_clear_focus_area_history_when_rotating"/>
   <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_escrow_check_components_automatically"/>
   <public type="bool" name="car_ui_focus_area_default_focus_overrides_history"/>
+  <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_list_item_single_line_title"/>
   <public type="bool" name="car_ui_preference_list_show_full_screen"/>
   <public type="bool" name="car_ui_preference_show_chevron"/>
@@ -22,6 +26,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"/>
@@ -29,6 +39,8 @@
   <public type="color" name="car_ui_ripple_color"/>
   <public type="color" name="car_ui_rotary_focus_fill_color"/>
   <public type="color" name="car_ui_rotary_focus_fill_secondary_color"/>
+  <public type="color" name="car_ui_rotary_focus_pressed_fill_color"/>
+  <public type="color" name="car_ui_rotary_focus_pressed_stroke_color"/>
   <public type="color" name="car_ui_rotary_focus_stroke_color"/>
   <public type="color" name="car_ui_rotary_focus_stroke_secondary_color"/>
   <public type="color" name="car_ui_scrollbar_thumb"/>
@@ -55,6 +67,37 @@
   <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_margin_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"/>
@@ -108,6 +151,7 @@
   <public type="dimen" name="car_ui_recyclerview_divider_height"/>
   <public type="dimen" name="car_ui_recyclerview_divider_start_margin"/>
   <public type="dimen" name="car_ui_recyclerview_divider_top_margin"/>
+  <public type="dimen" name="car_ui_rotary_focus_pressed_stroke_width"/>
   <public type="dimen" name="car_ui_rotary_focus_stroke_width"/>
   <public type="dimen" name="car_ui_scrollbar_button_size"/>
   <public type="dimen" name="car_ui_scrollbar_container_width"/>
@@ -166,12 +210,19 @@
   <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"/>
@@ -180,6 +231,7 @@
   <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"/>
+  <public type="drawable" name="car_ui_recycler_view_ime_wide_screen_thumb"/>
   <public type="drawable" name="car_ui_recyclerview_button_ripple_background"/>
   <public type="drawable" name="car_ui_recyclerview_divider"/>
   <public type="drawable" name="car_ui_recyclerview_ic_down"/>
@@ -201,7 +253,14 @@
   <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_contentAreaAutomotive"/>
   <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_surface"/>
+  <public type="id" name="car_ui_inputExtractActionAutomotive"/>
+  <public type="id" name="car_ui_inputExtractEditTextContainer"/>
   <public type="id" name="car_ui_list_item_end_guideline"/>
   <public type="id" name="car_ui_list_item_start_guideline"/>
   <public type="id" name="car_ui_list_limiting_message"/>
@@ -245,6 +304,14 @@
   <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="checkbox_widget"/>
   <public type="id" name="container"/>
   <public type="id" name="content_icon"/>
@@ -286,6 +353,7 @@
   <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_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_limiting_message"/>
   <public type="layout" name="car_ui_list_preference"/>
@@ -307,6 +375,7 @@
   <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"/>
@@ -318,6 +387,7 @@
   <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"/>
diff --git a/car-ui-lib/tests/apitest/resource_utils.py b/car-ui-lib/tests/apitest/resource_utils.py
index 763c5a0..7da5642 100755
--- a/car-ui-lib/tests/apitest/resource_utils.py
+++ b/car-ui-lib/tests/apitest/resource_utils.py
@@ -108,6 +108,8 @@
 
         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')