[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 813de42e38 -s ours

am skip reason: subject contains skip directive

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

Change-Id: I079a5802c59aba8fb4cf2446053ae95e4c374d7f
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bdb2b9b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# Python
+*.pyc
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index c7536fc..152ef44 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 android_app {
     name: "CarMediaApp",
 
@@ -21,7 +25,7 @@
 
     resource_dirs: ["res"],
 
-    required: ["privapp_whitelist_com.android.car.media"],
+    required: ["allowed_privapp_com.android.car.media"],
 
     certificate: "platform",
 
@@ -44,6 +48,7 @@
         "car-apps-common",
         "car-media-common",
         "car-ui-lib",
+        "car-uxr-client-lib",
     ],
 
     product_variables: {
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 43e1fbe..4d823c4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -53,11 +53,14 @@
         <activity
             android:name=".MediaDispatcherActivity"
             android:theme="@android:style/Theme.NoDisplay"
+            android:exported="true"
             android:launchMode="singleTask">
             <meta-data android:name="distractionOptimized" android:value="true"/>
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.INFO" />
+                <category android:name="android.intent.category.APP_MUSIC" />
             </intent-filter>
             <intent-filter>
                 <action android:name="android.car.intent.action.MEDIA_TEMPLATE" />
@@ -66,7 +69,8 @@
         </activity>
 
         <service
-            android:name=".service.MediaConnectorService">
+            android:name=".service.MediaConnectorService"
+            android:exported="true">
             <intent-filter>
                 <action android:name="com.android.car.media.MEDIA_CONNECTION"/>
             </intent-filter>
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
new file mode 100644
index 0000000..e91b525
--- /dev/null
+++ b/PREUPLOAD.cfg
@@ -0,0 +1,8 @@
+[Hook Scripts]
+checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
+ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py -f ${PREUPLOAD_FILES}
+overlayable_resource_hook = ${REPO_ROOT}/packages/apps/Car/tests/tools/rro/verify-overlayable.py -r res -e res/values/overlayable.xml res/xml/automotive_app_desc.xml -o res/values/overlayable.xml
+
+[Builtin Hooks]
+commit_msg_changeid_field = true
+commit_msg_test_field = true
diff --git a/res/color/progress_bar_thumb_inner_ring_color.xml b/res/color/progress_bar_thumb_inner_ring_color.xml
new file mode 100644
index 0000000..d3a9d4e
--- /dev/null
+++ b/res/color/progress_bar_thumb_inner_ring_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="@color/car_ui_rotary_focus_fill_color"/>
+    <item android:color="@android:color/transparent"/>
+</selector>
diff --git a/res/color/progress_bar_thumb_outer_ring_color.xml b/res/color/progress_bar_thumb_outer_ring_color.xml
new file mode 100644
index 0000000..1bc1926
--- /dev/null
+++ b/res/color/progress_bar_thumb_outer_ring_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="@color/car_ui_rotary_focus_stroke_color"/>
+    <item android:color="@android:color/transparent"/>
+</selector>
diff --git a/res/drawable/grid_item_background.xml b/res/drawable/grid_item_background.xml
deleted file mode 100644
index 0b57a5c..0000000
--- a/res/drawable/grid_item_background.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/car_card_ripple_background">
-    <item android:id="@android:id/mask">
-        <shape android:shape="rectangle">
-            <solid android:color="@android:color/white"/>
-            <corners android:radius="@dimen/media_browse_grid_item_background_radius"/>
-        </shape>
-    </item>
-</ripple>
\ No newline at end of file
diff --git a/res/drawable/seekbar_foreground.xml b/res/drawable/seekbar_foreground.xml
new file mode 100644
index 0000000..3942e21
--- /dev/null
+++ b/res/drawable/seekbar_foreground.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020, The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- SeekBar highlight is drawn when it's focused but not in direct manipulation mode. When
+         in direct manipulation mode (android:state_selected="true"), the highlight is drawn on
+         the thumb instead. -->
+    <item android:state_selected="false" android:state_focused="true">
+        <shape android:shape="rectangle">
+            <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
+            <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
+                    android:color="@color/car_ui_rotary_focus_stroke_color"/>
+        </shape>
+    </item>
+</selector>
diff --git a/res/drawable/seekbar_background.xml b/res/drawable/seekbar_progress.xml
similarity index 95%
rename from res/drawable/seekbar_background.xml
rename to res/drawable/seekbar_progress.xml
index ec08455..3e68a73 100644
--- a/res/drawable/seekbar_background.xml
+++ b/res/drawable/seekbar_progress.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  Copyright 2016, The Android Open Source Project
+  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.
diff --git a/res/drawable/seekbar_thumb.xml b/res/drawable/seekbar_thumb.xml
index 1d0b4a1..eb0c253 100644
--- a/res/drawable/seekbar_thumb.xml
+++ b/res/drawable/seekbar_thumb.xml
@@ -14,10 +14,28 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="oval">
-    <solid android:color="@color/progress_bar_thumb_color"/>
-    <size
-        android:width="@dimen/playback_seekbar_thumb_width"
-        android:height="@dimen/playback_seekbar_thumb_height"/>
-</shape>
\ No newline at end of file
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/thumb_center">
+        <shape android:shape="oval">
+            <solid android:color="@color/progress_bar_thumb_color"/>
+            <size android:width="@dimen/playback_seekbar_thumb_width"
+                  android:height="@dimen/playback_seekbar_thumb_height"/>
+        </shape>
+    </item>
+    <item>
+        <shape android:shape="ring"
+               android:innerRadius="@dimen/playback_seekbar_thumb_inner_ring_inner_radius"
+               android:thickness="@dimen/playback_seekbar_thumb_inner_ring_thickness"
+               android:useLevel="false">
+            <solid android:color="@color/progress_bar_thumb_inner_ring_color"/>
+        </shape>
+    </item>
+    <item>
+        <shape android:shape="ring"
+               android:innerRadius="@dimen/playback_seekbar_thumb_outer_ring_inner_radius"
+               android:thickness="@dimen/playback_seekbar_thumb_outer_ring_thickness"
+               android:useLevel="false">
+            <solid android:color="@color/progress_bar_thumb_outer_ring_color"/>
+        </shape>
+    </item>
+</layer-list>
diff --git a/res/layout/browse_node.xml b/res/layout/browse_node.xml
new file mode 100644
index 0000000..11cdaf5
--- /dev/null
+++ b/res/layout/browse_node.xml
@@ -0,0 +1,80 @@
+<?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">
+
+    <!-- Clone the top guideline since we don't need the others here. -->
+    <Space
+        android:id="@+id/ui_content_top_guideline2"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginTop="@dimen/car_ui_toolbar_first_row_height"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+    />
+
+    <ImageView
+        android:id="@+id/error_icon"
+        android:layout_width="@dimen/missing_permission_icon_size"
+        android:layout_height="@dimen/missing_permission_icon_size"
+        app:layout_constraintTop_toBottomOf="@+id/ui_content_top_guideline2"
+        app:layout_constraintBottom_toTopOf="@+id/error_message"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintVertical_chainStyle="packed"
+        android:src="@drawable/error_illustration"
+        android:visibility="gone"
+        android:tint="@color/icon_tint"/>
+
+    <TextView
+        android:id="@+id/error_message"
+        android:layout_width="wrap_content"
+        style="@style/ErrorTextStyle"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/browse_state_error_margin_top"
+        app:layout_constraintTop_toBottomOf="@+id/error_icon"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:maxLines="3"
+        android:text="@string/nothing_to_play"
+        android:visibility="gone"/>
+
+    <com.android.car.ui.FocusArea
+        android:id="@+id/focus_area"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent">
+        <com.android.car.ui.recyclerview.CarUiRecyclerView
+            android:id="@+id/browse_list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:clickable="true"
+            android:clipToPadding="false"
+            android:visibility="gone"
+            app:layoutStyle="grid"
+            app:numOfColumns="@integer/num_browse_columns"/>
+    </com.android.car.ui.FocusArea>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/fragment_browse.xml b/res/layout/fragment_browse.xml
index 60216a9..597c48c 100644
--- a/res/layout/fragment_browse.xml
+++ b/res/layout/fragment_browse.xml
@@ -15,56 +15,21 @@
   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">
+    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">
 
-    <ImageView
-        android:id="@+id/error_icon"
-        android:layout_width="@dimen/missing_permission_icon_size"
-        android:layout_height="@dimen/missing_permission_icon_size"
-        app:layout_constraintTop_toBottomOf="@+id/app_bar"
-        app:layout_constraintBottom_toTopOf="@+id/error_message"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintVertical_chainStyle="packed"
-        android:src="@drawable/error_illustration"
-        android:visibility="gone"
-        android:tint="@color/icon_tint"/>
+    <include layout="@layout/ui_guides"/>
 
-    <TextView
-        android:id="@+id/error_message"
-        android:layout_width="wrap_content"
-        style="@style/ErrorTextStyle"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/browse_state_error_margin_top"
-        app:layout_constraintTop_toBottomOf="@+id/error_icon"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        android:maxLines="3"
-        android:text="@string/nothing_to_play"
-        android:visibility="gone" />
-
-    <com.android.car.ui.recyclerview.CarUiRecyclerView
-        android:id="@+id/browse_list"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clickable="true"
-        android:focusable="true"
-        android:clipToPadding="false"
-        android:visibility="gone"
-        app:layoutStyle="grid"
-        app:numOfColumns="@integer/num_browse_columns"
-    />
-
-    <com.android.car.media.widgets.AppBarView
-        android:id="@+id/app_bar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+    <FrameLayout
+        android:id="@+id/browse_content_area"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintStart_toStartOf="@+id/ui_content_start_guideline"
+        app:layout_constraintEnd_toEndOf="@+id/ui_content_end_guideline"
         app:layout_constraintTop_toTopOf="parent"
-        app:showMenuItemsWhileSearching="false"
+        app:layout_constraintBottom_toTopOf="@+id/ui_content_bottom_guideline"
     />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/fragment_error.xml b/res/layout/fragment_error.xml
index 872adc2..ab06840 100644
--- a/res/layout/fragment_error.xml
+++ b/res/layout/fragment_error.xml
@@ -17,38 +17,48 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/error_fragment"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <com.android.car.apps.common.UxrTextView
-        android:id="@+id/error_message"
-        style="@style/FullScreenErrorMessageStyle"
-        android:layout_marginHorizontal="@dimen/fragment_error_message_margin_x"
+    <include layout="@layout/ui_guides"/>
+
+    <com.android.car.ui.FocusArea
+        android:layout_width="0dp"
+        android:layout_height="0dp"
         app:layout_constraintVertical_chainStyle="packed"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/app_bar"
-        app:layout_constraintBottom_toTopOf="@+id/error_button"
-    />
+        app:layout_constraintStart_toStartOf="@+id/ui_content_start_guideline"
+        app:layout_constraintEnd_toEndOf="@+id/ui_content_end_guideline"
+        app:layout_constraintTop_toBottomOf="@+id/ui_content_top_guideline"
+        app:layout_constraintBottom_toBottomOf="@+id/ui_content_bottom_guideline">
 
-    <com.android.car.apps.common.UxrButton
-        android:id="@+id/error_button"
-        style="@style/FullScreenErrorButtonStyle"
-        android:layout_marginTop="@dimen/fragment_error_button_margin_top"
-        android:layout_marginBottom="@dimen/fragment_error_button_margin_bottom"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/error_message"
-        app:layout_constraintBottom_toBottomOf="parent"
-    />
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            app:layout_constraintVertical_chainStyle="packed">
 
-    <com.android.car.media.widgets.AppBarView
-        android:id="@+id/app_bar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toTopOf="parent"
-        app:showMenuItemsWhileSearching="false"
-    />
+            <com.android.car.apps.common.UxrTextView
+                android:id="@+id/error_message"
+                style="@style/FullScreenErrorMessageStyle"
+                android:layout_marginHorizontal="@dimen/fragment_error_message_margin_x"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toTopOf="@+id/error_button"
+            />
+
+            <com.android.car.apps.common.UxrButton
+                android:id="@+id/error_button"
+                style="@style/FullScreenErrorButtonStyle"
+                android:layout_marginTop="@dimen/fragment_error_button_margin_top"
+                android:layout_marginBottom="@dimen/fragment_error_button_margin_bottom"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toBottomOf="@id/error_message"
+                app:layout_constraintBottom_toBottomOf="parent"
+            />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+    </com.android.car.ui.FocusArea>
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/fragment_playback.xml b/res/layout/fragment_playback.xml
index 50eeb3e..d9503c1 100644
--- a/res/layout/fragment_playback.xml
+++ b/res/layout/fragment_playback.xml
@@ -21,12 +21,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/app_bar_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        app:layout_constraintGuide_begin="@dimen/car_ui_toolbar_first_row_height"/>
+    <include layout="@layout/ui_guides"/>
 
     <Space
         android:id="@+id/control_bar_first_row_guideline"
@@ -50,30 +45,22 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"/>
 
-    <com.android.car.ui.toolbar.Toolbar
-        android:id="@+id/toolbar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:title="@string/fragment_playback_title"
-        app:layout_constraintTop_toTopOf="parent"
-        app:car_ui_state="subpage"/>
-
     <include
         style="@style/MetadataContainerStyle"
         android:id="@+id/metadata_container"
         layout="@layout/metadata_normal"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/app_bar_guideline"
+        app:layout_constraintTop_toBottomOf="@id/ui_content_top_guideline"
         app:layout_constraintBottom_toTopOf="@+id/control_bar_first_row_guideline"/>
 
-    <!-- @id/seek_bar should be hidden when @id/control_bar_scrim is expanded, and shown when the
-    scrim is collapsed. Since its visibility is also controlled by MetadataController, it could
-    become visible again even if the scrim is still expanded. To solve that we add a wrapper around
-    it and hide/show the wrapper when the scrim is expanded/collapsed.-->
-    <FrameLayout
+    <!-- @id/playback_seek_bar should be hidden when @id/control_bar_scrim is expanded, and shown
+    when the scrim is collapsed. Since its visibility is also controlled by MetadataController, it
+    could become visible again even if the scrim is still expanded. To solve that we add a wrapper
+    around it and hide/show the wrapper when the scrim is expanded/collapsed.-->
+    <com.android.car.ui.FocusArea
         style="@style/SeekBarStyle"
-        android:id="@+id/seek_bar_container"
+        android:id="@+id/playback_seek_bar_container"
         android:layout_gravity="center"
         android:layout_marginStart="@dimen/playback_seekbar_margin_x"
         android:layout_marginEnd="@dimen/playback_seekbar_margin_x"
@@ -82,27 +69,26 @@
         app:layout_constraintTop_toBottomOf="@+id/metadata_container"
         app:layout_constraintBottom_toTopOf="@+id/control_bar_first_row_guideline">
         <SeekBar
-            android:id="@+id/seek_bar"
+            android:id="@+id/playback_seek_bar"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:clickable="false"
-            android:focusable="false"
             android:paddingEnd="@dimen/playback_seekbar_padding_x"
             android:paddingStart="@dimen/playback_seekbar_padding_x"
-            android:progressDrawable="@drawable/seekbar_background"
+            android:progressDrawable="@drawable/seekbar_progress"
             android:thumb="@drawable/seekbar_thumb"
             android:thumbOffset="@dimen/playback_seekbar_thumb_offset"
             android:splitTrack="false"
             android:progressTint="@color/progress_bar_highlight"
             android:progressBackgroundTint="@color/progress_bar_background"
-            android:background="@null"/>
-    </FrameLayout>
+            android:foreground="@drawable/seekbar_foreground"/>
+    </com.android.car.ui.FocusArea>
 
     <Space
         android:id="@+id/queue_list_top_constraint"
         android:layout_width="match_parent"
         android:layout_height="@dimen/fragment_playback_queue_overlap_top"
-        app:layout_constraintBottom_toBottomOf="@+id/app_bar_guideline"/>
+        app:layout_constraintBottom_toBottomOf="@+id/ui_content_top_guideline"/>
 
     <Space
         android:id="@+id/queue_list_bottom_constraint"
@@ -110,8 +96,7 @@
         android:layout_height="@dimen/fragment_playback_queue_overlap_bottom"
         app:layout_constraintTop_toTopOf="@+id/control_bar_first_row_guideline"/>
 
-    <!-- The queue_container is a workaround for a bug in PagedRecyclerView (b/136669451). -->
-    <RelativeLayout
+    <com.android.car.ui.FocusArea
         android:id="@+id/queue_container"
         android:layout_width="match_parent"
         android:layout_height="0dp"
@@ -125,7 +110,7 @@
             android:fadeScrollbars="true"
             android:requiresFadingEdge="vertical"
             android:fadingEdgeLength="@dimen/queue_fading_edge_length"/>
-    </RelativeLayout>
+    </com.android.car.ui.FocusArea>
 
     <include
         layout="@layout/scrim_overlay"
@@ -137,14 +122,18 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"/>
 
-    <com.android.car.media.common.PlaybackControlsActionBar
-        android:id="@+id/playback_controls"
-        style="@style/ControlBar"
+    <com.android.car.ui.FocusArea
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_marginHorizontal="@dimen/control_bar_margin_x"
         android:layout_marginBottom="@dimen/control_bar_margin_bottom"
-        app:columns="5"
-        app:enableOverflow="true"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
+        app:layout_constraintEnd_toEndOf="parent">
+        <com.android.car.media.common.PlaybackControlsActionBar
+            android:id="@+id/playback_controls"
+            style="@style/ControlBar"
+            app:columns="5"
+            app:enableOverflow="true"/>
+    </com.android.car.ui.FocusArea>
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/media_activity.xml b/res/layout/media_activity.xml
index fd4a687..2cd6e34 100644
--- a/res/layout/media_activity.xml
+++ b/res/layout/media_activity.xml
@@ -20,6 +20,12 @@
     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"
+    />
+
     <FrameLayout
         android:id="@+id/fragment_container"
         android:layout_width="match_parent"
@@ -28,27 +34,24 @@
     />
 
     <FrameLayout
-        android:id="@+id/search_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone"
-    />
-
-    <FrameLayout
         android:id="@+id/error_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:visibility="gone"
     />
 
-    <com.android.car.media.common.MinimizedPlaybackControlBar
-        android:id="@+id/minimized_playback_controls"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+    <com.android.car.ui.FocusArea
+        style="@style/MinimizedControlBar"
         android:layout_marginHorizontal="@dimen/minimized_control_bar_margin_x"
         android:layout_marginBottom="@dimen/minimized_control_bar_margin_bottom"
-        android:layout_gravity="bottom"
-    />
+        android:layout_gravity="center|bottom">
+        <com.android.car.media.common.MinimizedPlaybackControlBar
+            android:id="@+id/minimized_playback_controls"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone"
+        />
+    </com.android.car.ui.FocusArea>
 
     <FrameLayout
         android:id="@+id/playback_container"
diff --git a/res/layout/media_browse_grid_icons_item.xml b/res/layout/media_browse_grid_icons_item.xml
index 6445c03..6e0887a 100644
--- a/res/layout/media_browse_grid_icons_item.xml
+++ b/res/layout/media_browse_grid_icons_item.xml
@@ -17,23 +17,29 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     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="wrap_content"
-    android:focusable="true"
-    android:clickable="true"
-    android:foreground="@drawable/grid_item_background"
     android:padding="@dimen/media_browse_grid_item_padding"
     android:layout_marginBottom="@dimen/media_browse_grid_item_margin_bottom">
 
-    <ImageView
-        android:id="@+id/thumbnail"
-        android:layout_width="@dimen/media_browse_grid_icons_item_art_size"
-        android:layout_height="@dimen/media_browse_grid_icons_item_art_size"
-        android:scaleType="centerCrop"
+    <FrameLayout
+        android:id="@+id/item_container"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:clickable="true"
+        android:focusable="true"
+        android:foreground="?android:attr/selectableItemBackground"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <ImageView
+            android:id="@+id/thumbnail"
+            android:layout_width="@dimen/media_browse_grid_icons_item_art_size"
+            android:layout_height="@dimen/media_browse_grid_icons_item_art_size"
+            android:scaleType="centerCrop"/>
+
+    </FrameLayout>
 
     <ImageView
         android:id="@+id/download_icon_with_title"
@@ -69,7 +75,7 @@
         android:includeFontPadding="false"
         android:duplicateParentState="true"
         app:layout_constraintStart_toEndOf="@+id/explicit_icon_with_title"
-        app:layout_constraintTop_toBottomOf="@+id/thumbnail"
+        app:layout_constraintTop_toBottomOf="@+id/item_container"
         app:layout_constraintEnd_toEndOf="parent"/>
 
     <ImageView
diff --git a/res/layout/media_browse_grid_item.xml b/res/layout/media_browse_grid_item.xml
index 1a96024..229a674 100644
--- a/res/layout/media_browse_grid_item.xml
+++ b/res/layout/media_browse_grid_item.xml
@@ -17,24 +17,30 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     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="wrap_content"
-    android:focusable="true"
-    android:clickable="true"
-    android:foreground="@drawable/grid_item_background"
     android:padding="@dimen/media_browse_grid_item_padding"
     android:layout_marginBottom="@dimen/media_browse_grid_item_margin_bottom">
 
-    <com.android.car.media.common.FixedRatioImageView
-        android:id="@+id/thumbnail"
+    <FrameLayout
+        android:id="@+id/item_container"
         android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:scaleType="centerCrop"
-        app:aspect_ratio="1"
-        app:layout_constraintTop_toTopOf="parent"
+        android:layout_height="wrap_content"
+        android:clickable="true"
+        android:focusable="true"
+        android:foreground="?android:attr/selectableItemBackground"
+        app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
+        app:layout_constraintTop_toTopOf="parent">
+
+        <com.android.car.media.common.FixedRatioImageView
+            android:id="@+id/thumbnail"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:scaleType="centerCrop"
+            app:aspect_ratio="1"/>
+
+    </FrameLayout>
 
     <ImageView
         android:id="@+id/download_icon_with_title"
@@ -68,7 +74,7 @@
         android:includeFontPadding="false"
         android:duplicateParentState="true"
         app:layout_constraintStart_toEndOf="@+id/explicit_icon_with_title"
-        app:layout_constraintTop_toBottomOf="@+id/thumbnail"
+        app:layout_constraintTop_toBottomOf="@+id/item_container"
         app:layout_constraintEnd_toEndOf="parent"/>
 
     <ImageView
diff --git a/res/layout/media_browse_header_item.xml b/res/layout/media_browse_header_item.xml
index 3e17f98..1fa6d47 100644
--- a/res/layout/media_browse_header_item.xml
+++ b/res/layout/media_browse_header_item.xml
@@ -16,7 +16,7 @@
 -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/container"
+    android:id="@+id/item_container"
     android:layout_width="match_parent"
     android:layout_height="@dimen/media_browse_header_item_height"
     android:layout_marginHorizontal="@dimen/media_browse_header_item_margin_x">
diff --git a/res/layout/media_browse_list_icons_item.xml b/res/layout/media_browse_list_icons_item.xml
index a5db077..9c8d972 100644
--- a/res/layout/media_browse_list_icons_item.xml
+++ b/res/layout/media_browse_list_icons_item.xml
@@ -17,7 +17,7 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/container"
+    android:id="@+id/item_container"
     android:layout_width="match_parent"
     android:layout_height="@dimen/media_browse_list_item_height"
     android:paddingStart="@dimen/media_browse_list_item_icon_margin_start"
diff --git a/res/layout/media_browse_list_item.xml b/res/layout/media_browse_list_item.xml
index bd71f8f..52c2d50 100644
--- a/res/layout/media_browse_list_item.xml
+++ b/res/layout/media_browse_list_item.xml
@@ -17,7 +17,7 @@
 <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/container"
+    android:id="@+id/item_container"
     android:layout_width="match_parent"
     android:layout_height="@dimen/media_browse_list_item_height"
     android:paddingStart="@dimen/media_browse_list_item_icon_margin_start"
diff --git a/res/layout/queue_list_item.xml b/res/layout/queue_list_item.xml
index e4b77c8..a77187c 100644
--- a/res/layout/queue_list_item.xml
+++ b/res/layout/queue_list_item.xml
@@ -16,7 +16,7 @@
 -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/container"
+    android:id="@+id/item_container"
     android:layout_width="match_parent"
     android:layout_height="@dimen/queue_list_item_height"
     android:paddingEnd="@dimen/queue_list_item_padding_x"
diff --git a/res/layout/ui_guides.xml b/res/layout/ui_guides.xml
new file mode 100644
index 0000000..a2312f7
--- /dev/null
+++ b/res/layout/ui_guides.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<merge
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <Space
+        android:id="@+id/ui_content_start_guideline"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="0dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+    />
+
+    <Space
+        android:id="@+id/ui_content_top_guideline"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginTop="@dimen/car_ui_toolbar_first_row_height"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+    />
+
+    <Space
+        android:id="@+id/ui_content_end_guideline"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_marginRight="0dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+    />
+
+    <Space
+        android:id="@+id/ui_content_bottom_guideline"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginBottom="0dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+    />
+
+</merge>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index e42042a..b01f0df 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Soek liedjies, kunstenaars, en meer …"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Wat Speel"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Iets is fout. Probeer later."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Kan dit nie op die oomblik doen nie"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Hierdie program kan nie dit doen nie"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Meld aan om hierdie program te gebruik"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premiumtoegang word vereis"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Luister tans op te veel toestelle"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Daardie inhoud word geblokkeer"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Kan nie daardie inhoud hier kry nie"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Speel reeds daardie inhoud"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Kan nie meer snitte oorslaan nie"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Kon nie voltooi word nie. Probeer weer."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Daar is niks anders op die waglys nie"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Koppel tans aan media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Klankinstellings"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Wissel programme"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 73a9e28..c6842b1 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"ማህደረ መረጃ"</string>
     <string name="search_hint" msgid="5401750426238148416">"ዘፈኖችን፣ አርቲስቶችን እና ተጨማሪ ይፈልጉ..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"አሁን እየተጫወተ ያለ"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"የሆነ ችግር አለ። በኋላ ይሞክሩ።"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"አሁን ይህን ማድረግ አይቻልም"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ይህ መተግበሪያ ይህን ማድረግ አይችልም"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ይህን መተግበሪያ ለመጠቀም በመለያ ይግቡ"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ፕሪሚየም መዳረሻ ያስፈልጋል"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"በጣም ብዙ መሣሪያዎችን በማዳመጥ ላይ"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ይዘቱ ታግዷል"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ይዘቱን እዚህ ማግኘት አልተቻለም"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ይዘቱ አስቀድሞ በመጫወት ላይ"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ተጨማሪ ትራኮችን መዝለል አአይቻልም"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"መጨረስ አልተቻለም። እንደገና ይሞክሩ።"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"ሌላ ምንም ነገር ወረፋ አልያዘም"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"ከሚዲያ ጋር በመገናኘት ላይ"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"የድምፅ ቅንብሮች"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"መተግበሪያዎችን ቀያይር"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 4638554..5a3c04e 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"الوسائط"</string>
     <string name="search_hint" msgid="5401750426238148416">"البحث في الأغاني والفنانين والمزيد..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"التعرُّف التلقائي على الموسيقى"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"حدث خطأ. يُرجى المحاولة لاحقًا."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"يتعذر على التطبيق تنفيذ هذا الإجراء في الوقت الحالي."</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"يتعذّر على التطبيق تنفيذ هذا الإجراء."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"سجّل دخولك لاستخدام هذا التطبيق."</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"مطلوب الحصول على إذن الوصول المميَّز."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"يتم الآن الاستماع على أجهزة أكثر من الحد المسموح به."</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"تم حظر هذا المحتوى."</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"لا يمكن الحصول على هذا المحتوى من هنا."</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"جارٍ تشغيل هذا المحتوى."</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"لا يمكن تخطي المزيد من المقاطع الصوتية."</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"تعذر الإنهاء. يُرجى إعادة المحاولة."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"لم يتم وضع أي مقطع صوتي آخر في قائمة الانتظار."</string>
     <string name="service_notification_title" msgid="8085444675783592744">"الاتصال بالوسائط"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"إعدادات الصوت"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"تبديل التطبيقات"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index ed1aa09..b3c4830 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"মিডিয়া"</string>
     <string name="search_hint" msgid="5401750426238148416">"গান, শিল্পী আৰু অধিক..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"এতিয়া এয়া প্লে\' হৈ আছে"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"কিবা ভুল হ’ল। পাছত চেষ্টা কৰক।"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"সেইটো এই মুহূৰ্তত কৰিব নোৱাৰি"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"এই এপ্‌টোৱে সেইটো কৰিব নোৱাৰে"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"এই এপ্‌টো ব্যৱহাৰ কৰিবলৈ ছাইন ইন কৰক"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"প্ৰিমিয়াম এক্সেছৰ প্ৰয়োজন"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"বহুকেইটা ডিভাইচত শুনি আছে"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"সেই সমলটো অৱৰোধ কৰা আছে"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"সেই সমলটো ইয়াত পাব নোৱাৰি"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"সেই সমলটো ইতিমধ্যে প্লে’ হৈ আছে"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"আৰু ট্ৰেক এৰি যাব নোৱাৰি"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"সম্পূর্ণ কৰিব পৰা নগ’ল। আকৌ চেষ্টা কৰক।"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"শাৰীত অন্য একো নাই"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"মিডিয়াৰ সৈতে সংযোগ কৰি থকা হৈছে"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ধ্বনিৰ ছেটিংসমূহ"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"এপসমূহ সলনি কৰক"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index d27aa62..2d73a56 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Mahnı, ifaçı və s. axtarın"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"İndi oxudulur"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Xəta baş verdi. Sonra cəhd edin."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Hazırda onu etmək olmur"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Bu tətbiq onu edə bilmir"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Bu tətbiqi istifadə etmək üçün daxil olun"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium giriş tələb olunur"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Çox cihazda dinləmə aşkarlanıb"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Bu məzmun bloklanıb"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Bu məzmunu əldə etmək mümkün deyil"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Hazırda bu məzmun oxudulur"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Başqa treki keçmək mümkün deyil"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Bitirmək mümkün olmadı. Yenidən cəhd edin."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Növbədə başqa heç nə yoxdur"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Mediaya qoşulur"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Səs ayarları"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Tətbiqləri dəyişdirin"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 4ec1c1b..690453b 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Mediji"</string>
     <string name="search_hint" msgid="5401750426238148416">"Tražite pesme, izvođače i drugo..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Trenutno svira"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Nešto nije u redu. Probajte kasnije."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Trenutno ne može to da uradi"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ova aplikacija ne može to da uradi"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Prijavite se da biste koristili ovu aplikaciju"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Potreban je premijum pristup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Slušate na previše uređaja"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Taj sadržaj je blokiran"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Ne možete da dobijete taj sadržaj ovde"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Taj sadržaj se već reprodukuje"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Ne možete više da preskačete pesme"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nismo uspeli da dovršimo radnju. Probajte ponovo."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ništa drugo nije stavljeno u red"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Povezuje se sa medijima"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Podešavanja zvuka"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Pređi na drugu aplikaciju"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 42c7933..f52921a 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Мультымедыя"</string>
     <string name="search_hint" msgid="5401750426238148416">"Шукайце кампазіцыі…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Зараз іграе"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Узнікла памылка. Паўтарыце спробу пазней."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Не ўдаецца выканаць гэты запыт"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Праграме не ўдалося выканаць гэты запыт"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Увайдзіце, каб выкарыстоўваць гэту праграму"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Патрэбны платны доступ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Праслухоўваецца занадта шмат прылад"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Гэта змесціва заблакіравана"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Не ўдалося загрузіць змесціва ў гэтым рэгіёне"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Гэта змесціва ўжо прайграецца"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Не ўдалося прапусціць іншыя трэкі"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Не ўдалося завяршыць. Паўтарыце спробу."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"У чарзе пуста"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Ідзе падключэнне да мультымедыя"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Налады гуку"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Змяніць праграму"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 4e20fe8..c646700 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Мултимедия"</string>
     <string name="search_hint" msgid="5401750426238148416">"Търсете песни, изпълнители и др..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Сега слушате"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Нещо не е наред. Опитайте по-късно."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Понастоящем тази заявка не може да се изпълни"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Приложението не може да изпълни тази заявка"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Влезте в профила си, за да използвате това приложение"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"За достъп се изисква платен профил"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Слуша се на твърде много устройства"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Това съдържание е блокирано"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Това съдържание не е налице за региона ви"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Това съдържание вече се възпроизвежда"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Не могат да се пропускат повече записи"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Не можа да завърши. Опитайте отново."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Нищо друго не е поставено на опашка"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Установява се връзка с мултимедията"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Настройки за звука"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Превключване на приложенията"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 3e5cec7..9b02b93 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"মিডিয়া"</string>
     <string name="search_hint" msgid="5401750426238148416">"গান, শিল্পী ও অনেক কিছু খুঁজুন..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"এখন চলছে"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"কোনও সমস্যা হয়েছে। পরে চেষ্টা করুন।"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"এখন এটি করা যাবে না"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"এই অ্যাপটি এটি করতে পারবে না"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"এই অ্যাপ ব্যবহার করতে সাইন-ইন করুন"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium অ্যাক্সেস প্রয়োজন"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"একাধিক ডিভাইসে শুনছেন"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"এই কন্টেন্টটি ব্লক করা হয়েছে"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"এই কন্টেন্টটি এখানে পাওয়া যাবে না"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"কন্টেন্টটি আগে থেকেই চলছে"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"আর কোনও ট্র্যাক এড়িয়ে যেতে পারবেন না"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"সম্পূর্ণ করা যায়নি। আবার চেষ্টা করুন।"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"আর কিছুই অপেক্ষমাণ নয়"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"মিডিয়াতে কানেক্ট করা হচ্ছে"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"সাউন্ড সেটিংস"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"অ্যাপ সুইচ করুন"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 41e548c..fb4de24 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Mediji"</string>
     <string name="search_hint" msgid="5401750426238148416">"Pretražite pjesme, izvođače i još mnogo toga..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Trenutno se reproducira"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Nešto nije uredu. Pokušajte kasnije."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Taj zahtjev trenutno nije moguće izvršiti"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ova aplikacija ne može izvršiti taj zahtjev"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Prijavite se da koristite ovu aplikaciju"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Potreban je premijum pristup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Previše je uređaja na kojima se sluša"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Sadržaj je blokiran"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Nije moguće preuzeti taj sadržaj ovdje"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Reproduciranje tog sadržaja je već u toku"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Ne možete više preskakati numere"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Dovršavanje nije uspjelo. Pokušajte ponovo."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ništa više nije postavljeno u red čekanja"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Povezivanje s medijima"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Postavke zvuka"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Prebaci aplikacije"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 5e0ebbc..8ed94b7 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Multimèdia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Cerca cançons, artistes i més…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Està sonant"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"S\'ha produït un error. Prova-ho més tard."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Aquesta acció no es pot dur a terme ara mateix"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Aquesta aplicació no pot fer això"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Inicia la sessió per fer servir aquesta aplicació"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Es requereix accés Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"S\'està escoltant en massa dispositius"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"El contingut està bloquejat"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"El contingut no està disponible en aquesta regió"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ja s\'està reproduint aquest contingut"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"No es poden saltar més cançons"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"No s\'ha pogut acabar. Torna-ho a provar."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"No hi ha res més a la cua"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"S\'està connectant a la font multimèdia"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Configuració del so"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Canvia d\'aplicació"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 22cb6d3..3395351 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Média"</string>
     <string name="search_hint" msgid="5401750426238148416">"Vyhledávejte skladby, interprety apod..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Co to hraje"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Někde se stala chyba. Zkuste to později."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Tuto akci teď nelze provést"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Tuto akci aplikace nedokáže provést"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Chcete-li aplikaci použít, přihlaste se"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Je vyžadován prémiový přístup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Poslech je aktivován v příliš mnoha zařízeních"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Obsah je blokován"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Tento obsah tu nelze načíst"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Tento obsah se už přehrává"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Další skladby nelze přeskočit"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nelze dokončit. Zkuste to znovu."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ve frontě není nic dalšího"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Připojování k médiu"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Nastavení zvuku"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Přepnout aplikace"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 31636a9..d95fd56 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Medie"</string>
     <string name="search_hint" msgid="5401750426238148416">"Søg efter sange og kunstnere m.m..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Afspiller nu"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Der er noget galt. Prøv senere."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Det er ikke muligt lige nu"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Det kan denne app ikke gøre"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Log ind for at bruge denne app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Dette kræver en Premium-konto"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Du lytter på for mange enheder"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Indholdet er blokeret"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Der er ikke adgang til indholdet her"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Indholdet afspilles allerede"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Du kan ikke springe over flere numre"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Handlingen kunne ikke afsluttes. Prøv igen."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Der er ikke mere i køen"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Opretter forbindelse til medie"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Lydindstillinger"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Skift mellem apps"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index f05c6a4..1c385c3 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Medien"</string>
     <string name="search_hint" msgid="5401750426238148416">"Nach Songs, Künstlern und mehr suchen"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Aktuelle Wiedergabe"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Ein Fehler ist aufgetreten. Versuch es später noch mal."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Das ist gerade nicht möglich"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Diese App kann das nicht"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Damit du diese App verwenden kannst, musst du dich zuerst anmelden"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premiumzugriff erforderlich"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Es wird auf zu vielen Geräten gleichzeitig gestreamt"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Der Inhalt ist gesperrt"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Der Inhalt kann hier nicht abgerufen werden"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Der Inhalt wird bereits wiedergegeben"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Du kannst keine weiteren Titel überspringen"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Die Aktion konnte nicht abgeschlossen werden. Versuch es noch mal."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Es ist sonst nichts in der Warteschlange"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Verbindung zu Medien wird hergestellt"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Toneinstellungen"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Apps wechseln"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 970656e..b92faf8 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Πολυμέσα"</string>
     <string name="search_hint" msgid="5401750426238148416">"Αναζ. τραγ., καλλιτ…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Ακούγεται τώρα"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε αργότερα."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Δεν είναι δυνατή η εκτέλεση του αιτήματος αυτήν τη στιγμή."</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Δεν είναι δυνατή η εκτέλεση του αιτήματος από αυτήν την εφαρμογή."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Συνδεθείτε, για να χρησιμοποιήσετε αυτήν την εφαρμογή"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Απαιτείται premium πρόσβαση."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Ακρόαση πάρα πολλών συσκευών."</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Αυτό το περιεχόμενο είναι αποκλεισμένο."</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Δεν είναι δυνατή η λήψη αυτού του περιεχομένου εδώ."</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Γίνεται ήδη αναπαραγωγή αυτού του περιεχομένου."</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Δεν είναι δυνατή η παράβλεψη περισσότερων κομματιών."</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Δεν ήταν δυνατή η ολοκλήρωση. Δοκιμάστε ξανά."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Δεν υπάρχει κάτι άλλο στην ουρά."</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Σύνδεση σε πολυμέσα"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Ρυθμίσεις ήχου"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Να γίνει εναλλαγή μεταξύ εφαρμογών"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 5b2faed..7d6f5ee 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Search songs, artists and more…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Can’t do that right now"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nothing else is queued up"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Connecting to media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Sound settings"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Switch apps"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 5b2faed..7d6f5ee 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Search songs, artists and more…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Can’t do that right now"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nothing else is queued up"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Connecting to media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Sound settings"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Switch apps"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 5b2faed..7d6f5ee 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Search songs, artists and more…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Can’t do that right now"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nothing else is queued up"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Connecting to media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Sound settings"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Switch apps"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 5b2faed..7d6f5ee 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Search songs, artists and more…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Something’s wrong. Try later."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Can’t do that right now"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"This app can’t do that"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Sign in to use this app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium access required"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Listening on too many devices"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"That content is blocked"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Can’t get that content here"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Already playing that content"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Can’t skip any more tracks"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Couldn’t finish. Try again."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nothing else is queued up"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Connecting to media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Sound settings"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Switch apps"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 5537906..a76105f 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‎Media‎‏‎‎‏‎"</string>
     <string name="search_hint" msgid="5401750426238148416">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎Search songs, artists, and more...‎‏‎‎‏‎"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎Now Playing‎‏‎‎‏‎"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎Something’s wrong. Try later.‎‏‎‎‏‎"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎Can’t do that right now‎‏‎‎‏‎"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎This app can’t do that‎‏‎‎‏‎"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‎Sign in to use this app‎‏‎‎‏‎"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎Premium access required‎‏‎‎‏‎"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‎Listening on too many devices‎‏‎‎‏‎"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‏‎‎That content is blocked‎‏‎‎‏‎"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎Can’t get that content here‎‏‎‎‏‎"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎Already playing that content‎‏‎‎‏‎"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎Can’t skip any more tracks‎‏‎‎‏‎"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎Couldn’t finish. Try again.‎‏‎‎‏‎"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎Nothing else is queued up‎‏‎‎‏‎"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎Connecting to media‎‏‎‎‏‎"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‎‏‎Sound Settings‎‏‎‎‏‎"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎Switch apps‎‏‎‎‏‎"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 6b0b4f8..8c5beaf 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Multimedia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Busca artistas y más"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Está Sonando"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Se produjo un error. Vuelve a intentarlo más tarde."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"No se puede realizar esa acción en este momento"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Esta app no puede realizar esa acción"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Accede para usar esta app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Se requiere acceso Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Se está escuchando contenido en demasiados dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ese contenido está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"No se puede acceder a ese contenido en esta región"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ya se está reproduciendo ese contenido"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"No se pueden omitir más pistas"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"No se pudo completar la acción. Vuelve a intentarlo."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"No hay más contenido en la cola"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Estableciendo conexión con la fuente de contenido multimedia"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Configuración de sonido"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Cambiar de app"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 900e074..1816f7e 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Multimedia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Buscar canciones, artistas, etc."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Reproduciendo"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Se ha producido un error. Inténtalo más tarde."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"No se puede hacer en estos momentos"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"No se puede hacer con esta aplicación"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Inicia sesión para utilizar esta aplicación"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Se necesita acceso premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Se está escuchando en demasiados dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ese contenido está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Aquí no se puede reproducir ese contenido"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ya se está reproduciendo ese contenido"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"No se pueden saltar más pistas"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"No se ha podido finalizar. Inténtalo de nuevo."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"No hay nada más en la cola"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Conectando con la fuente de contenido multimedia"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Ajustes de sonido"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Cambiar de aplicación"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 63fbb6a..a690e6d 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Meedia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Lugude, esitajate ja muu otsimine …"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Hetkel mängimas"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Midagi on valesti. Proovige hiljem."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Seda ei saa praegu teha"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"See rakendus ei saa seda teha"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Rakenduse kasutamiseks logige sisse"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Vaja on Premium-tasemel juurdepääsu"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Kuulatakse liiga paljudes seadmetes"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"See sisu on blokeeritud"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Seda sisu ei saa siin esitada"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Seda sisu juba esitatakse"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Rohkem lugusid ei saa vahele jätta"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Ei saanud lõpetada. Proovige uuesti."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Midagi muud pole järjekorras"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Meediaga ühendamine"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Heliseaded"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Rakenduste vahetamine"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index cf7313a..aca4209 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Multimedia-edukia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Bilatu abestiak, artistak eta beste…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Orain erreproduzitzen"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Arazoren bat izan da. Saiatu geroago."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Ezin da egin halakorik une honetan"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Aplikazio honek ezin du egin halakorik"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Aplikazioa erabiltzeko, hasi saioa"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium sarbidea behar da"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Gailu gehiegitatik jasotzen ari da soinua"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Eduki hori blokeatuta dago"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Ezin da eskuratu eduki hori lurralde honetan"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Dagoeneko ari da erreproduzitzen eduki hori"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Ezin da saltatu pista gehiagorik"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Ezin izan da amaitu ekintza. Saiatu berriro."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ez dago beste ezer ilaran"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Multimedia-edukiaren iturburura konektatzen"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Soinuaren ezarpenak"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Aldatu aplikazioa"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index d9406d2..af2f072 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"رسانه"</string>
     <string name="search_hint" msgid="5401750426238148416">"جستجوی آهنگ‌ها، هنرمندان و موارد دیگر..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"درحال پخش"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"مشکلی رخ داد. بعداً امتحان کنید."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"درحال‌حاضر انجام نمی‌شود"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"این برنامه قادر به انجام آن نیست."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"برای استفاده از این به برنامه، به سیستم وارد شوید"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"دسترسی ممتاز لازم است"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"درحال پخش در تعداد زیادی دستگاه"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"این محتوا مسدود شده است"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"نمی‌توان این محتوا را در اینجا دریافت کرد"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"از قبل درحال پخش است"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"از هیچ آهنگ دیگری نمی‌توان رد شد"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"پایان نیافت. دوباره امتحان کنید."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"هیچ مورد دیگری در صف پخش نیست"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"درحال اتصال به رسانه"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"تنظیمات صدا"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"عوض کردن برنامه"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 0c1617f..2ce0f38 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Hae mm. kappaleita…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Musiikintunnistus"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Jotain meni pieleen.. Yritä myöhemmin."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Tämä ei juuri nyt onnistu"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Sovellus ei tue ominaisuutta"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Kirjaudu sisään käyttääksesi tätä sovellusta"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Edellyttää premium-tilausta"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Kuuntelu käynnissä liian monella laitteella"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Tämä sisältö on estetty"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Sisältö ei ole saatavilla tällä"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Se toistetaan jo"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Enimmäismäärä kappaleita ohitettu"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Toiminto keskeytyi. Yritä uudelleen."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ei muuta jonossa"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Yhdistetään mediaan"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Ääniasetukset"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Sovelluksen vaihtaminen"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index ec67c07..aea1742 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Média"</string>
     <string name="search_hint" msgid="5401750426238148416">"Rechercher chansons, artistes et plus…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"En cours de lecture"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Quelque chose ne va pas. Réessayez plus tard."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Impossible d\'effectuer cette action pour le moment"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Cette application ne peut pas effectuer cette action"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Connectez-vous pour utiliser cette application"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Un accès Premium est requis"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Écoute en cours sur trop d\'appareils"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ce contenu est bloqué"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Impossible d\'obtenir ce contenu ici"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ce contenu est déjà en cours de lecture"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Impossible de passer à d\'autres chansons"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Impossible de terminer. Réessayez."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Rien d\'autre n\'est dans la file d\'attente"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Connexion au contenu multimédia en cours…"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Paramètres sonores"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Changer d\'application"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 34263ab..aab6fc1 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Médias"</string>
     <string name="search_hint" msgid="5401750426238148416">"Titres, artistes…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"En écoute"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Il y a un problème. Réessayez plus tard."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Impossible d\'effectuer cette opération pour le moment"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Cette application ne peut pas effectuer cette opération"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Connectez-vous pour utiliser cette application"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Accès Premium requis"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Écoute en cours sur trop d\'appareils"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ce contenu est bloqué"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Impossible d\'accéder à ce contenu ici"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ce contenu est déjà en cours de lecture"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Impossible de passer d\'autres titres"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Impossible de terminer l\'action. Veuillez réessayer."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Aucun autre titre dans la file d\'attente"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Se connecter au contenu multimédia"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Paramètres audio"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Changer d\'application"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 7fba204..4efb241 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Contido multimedia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Busca cancións, artistas…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Está soando"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Produciuse un problema. Téntao máis tarde."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Nestes momentos non se pode facer iso"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Esta aplicación non pode facer iso"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Inicia sesión para utilizar esta aplicación"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Requírese acceso premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Estase escoitando contido en demasiados dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ese contido está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Aquí non se pode acceder a ese contido"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Xa se está reproducindo ese contido"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Non se poden saltar máis pistas"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Non se puido completar a acción. Téntao de novo."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Non hai nada máis na cola"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Conectando co dispositivo multimedia"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Configuración do son"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Cambiar de aplicación"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 3cefc06..d3b29da 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"મીડિયા"</string>
     <string name="search_hint" msgid="5401750426238148416">"ગીત, લેખકો અને વધુ શોધો..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"હમણાં વાગી રહ્યું છે"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"કંઈક ખોટું થયું. પછીથી પ્રયાસ કરો."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"તે અત્યારે કરી શકતા નથી"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"આ ઍપ તે કરી શકતી નથી"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"આ ઍપનો ઉપયોગ કરવા માટે સાઇન ઇન કરો"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"પ્રીમિયમ ઍક્સેસ જરૂરી છે"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"ઘણા બધા ડિવાઇસ પર સાંભળી રહ્યાં છે"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"તે કન્ટેન્ટ બ્લૉક કર્યું છે"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"તે કન્ટેન્ટ અહીં મેળવી શકતા નથી"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"તે કન્ટેન્ટ પહેલાંથી ચલાવી રહ્યાં છે"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"કોઈ વધુ ટ્રૅક છોડી શકતા નથી"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"સમાપ્ત કરી શક્યાં નથી. ફરી પ્રયાસ કરો."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"બીજું કંઈ કતારમાં નથી"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"મીડિયા સાથે કનેક્ટ કરી રહ્યાં છીએ"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"સાઉન્ડના સેટિંગ"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ઍપ સ્વિચ કરો"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index d04b28d..7ab9c79 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"मीडिया"</string>
     <string name="search_hint" msgid="5401750426238148416">"गाने, कलाकार वगैरह खोजें"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"अभी चल रहा है"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"कोई गड़बड़ी हुई. बाद में कोशिश करें."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"अभी नहीं किया जा सकता"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"इस ऐप्लिकेशन पर यह काम नहीं करेगा"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"इस ऐप्लिकेशन का इस्तेमाल करने के लिए साइन इन करें"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"इसके लिए Premium का ऐक्सेस ज़रूरी है"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"आप इसे बहुत सारे डिवाइस पर चला रहे/रही हैं"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"सामग्री पर रोक लगा दी गई है"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"वह सामग्री यहां नहीं चलाई जा सकती"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"वह सामग्री पहले से ही चल रही है"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"इससे ज़्यादा गाने नहीं छोड़े जा सकते"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"कार्रवाई पूरी नहीं हो सकी. फिर से कोशिश करें."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"कतार में और कुछ नहीं है"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"मीडिया स्रोत से कनेक्ट किया जा रहा है"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"आवाज़ की सेटिंग"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ऐप्लिकेशन स्विच करें"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 54b23a2..7b719ce 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Mediji"</string>
     <string name="search_hint" msgid="5401750426238148416">"Pretražite pjesme..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Upravo svira"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Nešto nije u redu. Pokušajte kasnije."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Trenutačno to ne možemo učiniti"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ova aplikacija nema tu mogućnost"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Prijavite se za upotrebu te aplikacije."</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Potreban je pristup uz dodatnu naplatu"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Slušate na previše uređaja"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Taj je sadržaj blokiran"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Taj sadržaj nije dostupan ovdje"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Taj se sadržaj već reproducira"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Ne možete više preskakati pjesme"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Završavanje nije uspjelo. Pokušajte ponovo."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nema više ničeg u redu čekanja"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Povezivanje s medijem"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Postavke zvuka"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Promijeni aplikaciju"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index d823bf0..279bd1d 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Média"</string>
     <string name="search_hint" msgid="5401750426238148416">"Dalok, előadók és egyebek keresése…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Hiba történt. Próbálja újra később."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Jelenleg nem lehetséges"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ez az alkalmazás nem képes erre"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Az alkalmazás használatához jelentkezzen be"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Prémium hozzáférés szükséges"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Túl sok eszköz van használatban"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"A tartalom le van tiltva"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Nem lehet betölteni a tartalmat"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"A tartalom lejátszása már folyamatban van"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Nem lehet több számot átugrani"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nem sikerült befejezni. Próbálja újra."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Semmi más nincs a sorban"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Csatlakozás a médiaforráshoz"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Hangbeállítások"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Alkalmazásváltás"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 1160e26..f6e4455 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Մուլտիմեդիա"</string>
     <string name="search_hint" msgid="5401750426238148416">"Որոնեք երգեր, կատարողներ և այլն…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Այժմ հնչում է"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Սխալ առաջացավ: Փորձեք ավելի ուշ։"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Այս պահին հնարավոր չէ անել դա"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Այս հավելվածը չի աջակցվում"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Մուտք գործեք՝ հավելվածն օգտագործելու համար"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Անհրաժեշտ է պրեմիում հաշիվ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Սարքերի քանակը գերազանցվել է"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Բովանդակությունն արգելափակված է"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Բովանդակությունն անհասանելի է այս տարածաշրջանում"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Բովանդակությունն արդեն նվագարկվում է"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Հնարավոր չէ այլ կատարումներ բաց թողնել"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Չհաջողվեց ավարտել: Նորից փորձեք։"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Հերթացանկի սկիզբ կամ վերջ"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Միանում է մեդիայի աղբյուրին"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Ձայնի կարգավորումներ"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Անցնել մյուս հավելված"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 7195f2d..b27cc2b 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Telusuri lagu, artis, dll..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Terjadi masalah. Coba nanti."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Tidak dapat melakukannya saat ini"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Aplikasi ini tidak dapat melakukannya"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Login untuk menggunakan aplikasi ini"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Perlu akses premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Terlalu banyak perangkat digunakan untuk mendengarkan"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Konten tersebut diblokir"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Tidak bisa mendapatkan konten tersebut di sini"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Sedang memutar konten tersebut"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Tidak dapat melewati lagu lagi"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Tidak dapat diselesaikan. Coba lagi."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Tidak ada lagi yang mengantre"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Menghubungkan ke media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Setelan Suara"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Beralih aplikasi"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 554bd44..9759532 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Efni"</string>
     <string name="search_hint" msgid="5401750426238148416">"Leita að lögum, flytjendum og fleira..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Í spilun"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Eitthvað er ekki í lagi. Reyna síðar."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Ekki er hægt að framkvæma þetta eins og er"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Forritið getur ekki framkvæmt þetta"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Skráðu þig inn til að nota þetta forrit"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium-aðgangur er nauðsynlegur"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Hlustað í of mörgum tækjum"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Þetta efni er á bannlista"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Efnið er ekki tiltækt hér"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Þegar að spila þetta efni"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Ekki er hægt að sleppa fleiri lögum"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Ekki tókst að ljúka aðgerð. Reyndu aftur."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ekkert annað er í röð"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Tengist við efni"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Hljóðstillingar"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Skipta um forrit"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index a66b2e2..5eec9a5 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Contenuti multimediali"</string>
     <string name="search_hint" msgid="5401750426238148416">"Cerca brani, artisti e non solo…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Si è verificato un problema. Riprova più tardi."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Al momento non è possibile svolgere l\'operazione"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Questa app non supporta l\'azione richiesta"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Accedi per usare questa app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"È necessario l\'accesso Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Ascolto attivo su troppi dispositivi"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Contenuti bloccati"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Qui non è possibile scaricare questi contenuti"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Contenuti già in riproduzione"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Impossibile saltare altre tracce"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Impossibile completare. Riprova."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nient\'altro in coda"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Connessione ai contenuti multimediali"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Impostazioni audio"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Cambia app"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index ab71498..122ff04 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"מדיה"</string>
     <string name="search_hint" msgid="5401750426238148416">"חיפוש שירים, אומנים…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"מושמע עכשיו"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"משהו השתבש. יש לנסות מאוחר יותר."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"לא ניתן לבצע את הפעולה הזו כרגע"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"אי אפשר לבצע פעולה זו באפליקציה הזו"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"יש להיכנס לחשבון כדי להשתמש באפליקציה הזו"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"נדרשת גישה ל-Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"בהאזנה ליותר מדי מכשירים"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"התוכן הזה חסום"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"לא ניתן לקבל את התוכן הזה כאן"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"התוכן הזה כבר פועל"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"לא ניתן לדלג יותר על טראקים"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"לא ניתן היה לסיים. יש לנסות שוב."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"אין עוד שירים ברשימת השירים"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"מתבצעת התחברות למדיה"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"הגדרות צליל"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"מעבר בין אפליקציות"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index fd7d81b..e852ad6 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"メディア"</string>
     <string name="search_hint" msgid="5401750426238148416">"曲、アーティストなどを検索..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"この曲なに?"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"エラーが発生しました。しばらくしてからお試しください。"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"現在、利用できません"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"このアプリではサポートされていません"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"このアプリを使用するにはログインしてください"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"プレミアム アカウントが必要です"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"再生しているデバイスが多すぎます"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"このコンテンツはブロックされています"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"このコンテンツはこの地域では再生できません"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"このコンテンツはすでに再生中です"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"これ以上トラックをスキップできません"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"完了できません。もう一度お試しください。"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"キューが一杯で追加できません"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"メディアに接続中"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"音声の設定"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"アプリの切り替え"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 90ad8e2..c870292 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"მედია"</string>
     <string name="search_hint" msgid="5401750426238148416">"სიმღ., მუსიკოს. და ა.შ. ძიება..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"რა უკრავს"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"რაღაც შეცდომაა. ცადეთ მოგვიანებით."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ამჟამად ამის გაკეთება შეუძლებელია"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ეს აპი ამას ვერ გააკეთებს"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ამ აპით სარგებლობისთვის შედით სისტემაში"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"საჭიროა პრემიუმ ტიპის წვდომა"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"მოსმენა მიმდინარეობს მეტისმეტად ბევრ მოწყობილობაზე"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ეს კონტენტი დაბლოკილია"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ამ კონტენტს აქ ვერ მიიღებთ"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ეს კონტენტი უკვე იკვრება"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"მეტ ჩანაწერს ვერ გამოტოვებთ"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"დასრულება ვერ მოხერხდა. ცადეთ ხელახლა."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"რიგში აღარაფერია"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"მიმდინარეობს მედიასთან დაკავშირება"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ხმის პარამეტრები"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"აპების გადართვა"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 3c98b57..aef87d7 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Meдиа"</string>
     <string name="search_hint" msgid="5401750426238148416">"Әнді, орындаушыны, т.б. іздеу..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Қазір ойнатылуда"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Бірдеңе дұрыс емес. Кейінірек қайталап көріңіз."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Мұны дәл қазір істеу мүмкін емес."</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Бұл қолданба мұны істей алмайды."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Осы қолданбаны пайдалану үшін есептік жазбаға кіріңіз."</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Премиум рұқсат қажет."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Бұл мазмұн тым көп құрылғыларда тыңдалып жатыр."</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Бұл мазмұнға тыйым салынған."</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Мазмұнды алу мүмкін емес."</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Бұл мазмұн әлдеқашан ойнатылып жатыр."</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Басқа тректерді өткізіп жіберу мүмкін емес."</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Аяқталмады. Қайталап көріңіз."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Кезекке басқа ештеңе қойылмаған."</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Медиамазмұн көзіне жалғау"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Дыбыс параметрлері"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Қолданбалар арасында ауысу"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 70daabc..7601110 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"មេឌៀ"</string>
     <string name="search_hint" msgid="5401750426238148416">"ស្វែងរក​ចម្រៀង សិល្បករ និងអ្វីៗជាច្រើនទៀត..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"ឥឡូវកំពុងចាក់"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"មានអ្វីមួយ​ខុស​ប្រក្រតី។ សូមព្យាយាម​នៅពេលក្រោយ។"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"មិនអាច​ធ្វើតាមសំណើនោះ​ឥឡូវនេះ​បានទេ"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"កម្មវិធីនេះ​មិនអាចធ្វើ​តាមសំណើនោះ​បានទេ"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ចូលគណនី ដើម្បីប្រើកម្មវិធីនេះ"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"តម្រូវឱ្យមាន​ការចូលប្រើ​លំដាប់ខ្ពស់"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"កំពុងស្ដាប់​នៅលើ​ឧបករណ៍​ច្រើនពេក"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ខ្លឹមសារនោះ​ត្រូវបានទប់ស្កាត់"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"មិនអាច​ទាញយក​ខ្លឹមសារនោះ​នៅទីនេះ​បានទេ"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"កំពុងចាក់​ខ្លឹមសារនោះ​ស្រាប់ហើយ"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"មិនអាច​រំលងចម្រៀង​បានទៀតទេ"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"មិនអាច​បញ្ចប់បានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"មិនមានអ្វី​ផ្សេងទៀត​នៅក្នុង​ជួរទេ"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"កំពុង​ភ្ជាប់​មេឌៀ"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ការកំណត់​សំឡេង"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ប្ដូរ​កម្មវិធី"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 97f5067..49a150f 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"ಮಾಧ್ಯಮ"</string>
     <string name="search_hint" msgid="5401750426238148416">"ಹಾಡು, ಕಲಾವಿದರು, ಇನ್ನಷ್ಟು ಹುಡುಕಿ..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"ಏನೋ ತಪ್ಪಾಗಿದೆ. ನಂತರ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ಸದ್ಯಕ್ಕೆ ಅದನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ಈ ಆ್ಯಪ್‌ನಿಂದ ಅದನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ಈ ಆ್ಯಪ್ ಬಳಸಲು ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ಪ್ರೀಮಿಯಂ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"ಹಲವಾರು ಸಾಧನಗಳಲ್ಲಿ ಆಲಿಸಲಾಗುತ್ತಿದೆ"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ವಿಷಯವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ಆ ವಿಷಯವನ್ನು ಇಲ್ಲಿ ಪಡೆದುಕೊಳ್ಳಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ಈಗಾಗಲೇ ಆ ವಿಷಯವನ್ನು ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ಇನ್ನು ಮುಂದೆ ಟ್ರ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ಕಿಪ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"ಪೂರ್ಣಗೊಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"ಸರದಿಯಲ್ಲಿ ಯಾವುದು ಬಾಕಿ ಉಳಿದಿಲ್ಲ"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"ಮೀಡಿಯಾಕ್ಕೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ಧ್ವನಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ಆ್ಯಪ್‌ಗಳನ್ನು ಬದಲಿಸಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 104f8cc..e5ed5a6 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"미디어"</string>
     <string name="search_hint" msgid="5401750426238148416">"노래, 아티스트 등을 검색하세요..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"지금 재생 중"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"문제가 발생했습니다. 나중에 다시 시도하세요."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"지금은 요청하신 작업을 할 수 없습니다."</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"이 앱에서는 요청하신 작업을 지원하지 않습니다."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"이 앱을 사용하려면 로그인하세요."</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"프리미엄 액세스 권한이 필요합니다."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"너무 많은 기기에서 스트리밍하고 있습니다."</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"차단된 콘텐츠입니다."</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"이 지역에서 재생할 수 없는 콘텐츠입니다."</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"요청하신 콘텐츠를 이미 재생 중입니다."</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"트랙을 더이상 건너뛸 수 없습니다."</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"완료할 수 없습니다. 다시 시도하세요."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"현재 재생목록이 비어있습니다."</string>
     <string name="service_notification_title" msgid="8085444675783592744">"미디어에 연결 중"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"소리 설정"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"앱 전환"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 493acdc..b9801ec 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Медиа"</string>
     <string name="search_hint" msgid="5401750426238148416">"Ырларды, аткаруучуларды издөө ж.б..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Эмне ойноп жатат?"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Бир жерден ката кетти. Бир аздан кийин кайталап көрүңүз."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Аны азыр аткаруу мүмкүн эмес"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Бул колдонмо аны аткара албайт"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Бул колдонмону пайдалануу үчүн аккаунтуңузга кириңиз"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Артыкчылыктуу кирүү мүмкүнчүлүгү талап кылынат"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Өтө көп түзмөк угулууда"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ал мазмун бөгөттөлгөн"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Ал мазмунду алуу мүмкүн эмес"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ал мазмун ойнотулууда"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Эми тректерди өткөрүп жиберүүгө болбойт"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Аягына чыккан жок. Кайталап көрүңүз."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Кезекте эч нерсе жок"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Медиа булагына туташууда"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Добуштун жөндөөлөрү"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Колдонмолорду которуштуруу"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 8abc6f9..1ad1ed4 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"ສື່"</string>
     <string name="search_hint" msgid="5401750426238148416">"ຊອກຫາເພງ, ສິນລະປິນ ແລະ ອື່ນໆອີກ..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"ມີບ່າງຢ່າງຜິດພາດ. ລອງໃໝ່ພາຍຫຼັງ."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ບໍ່ສາມາດເຮັດໄດ້ຕອນນີ້"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ແອັບນີ້ບໍ່ສາມາດເຮັດສິ່ງນັ້ນໄດ້"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ເຂົ້າສູ່ລະບົບເພື່ອໃຊ້ແອັບນີ້"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ຕ້ອງມີສິດເຂົ້າເຖິງລະດັບພຣີມຽມ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"ກຳລັງຟັງຢູ່ໃນຫຼາຍອຸປະກອນເກີນໄປ"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ເນື້ອຫານັ້ນຖືກບລັອກໄວ້"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ບໍ່ສາມາດຮັບເນື້ອຫານັ້ນຢູ່ບ່ອນນີ້"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ຫຼິ້ນເນື້ອຫານັ້ນແລ້ວ"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ຂ້າມເພງບໍ່ໄດ້ອີກແລ້ວ"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"ບໍ່ສາມາດສຳເລັດໄດ້. ລອງໃໝ່."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"ບໍ່ມີລາຍການອື່ນໃນຄິວ"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"ກຳລັງເຊື່ອມຕໍ່ກັບສື່"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ການຕັ້ງຄ່າສຽງ"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ສະຫຼັບແອັບ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 30c3aff..783d241 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Medija"</string>
     <string name="search_hint" msgid="5401750426238148416">"Ieškokite dainų, atlikėjų ir daugiau..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Dabar leidžiama"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Kažkas nepavyko. Bandykite vėliau."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Negalima atlikti to veiksmo dabar"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ši programa negali atlikti to veiksmo"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Prisijunkite, kad galėtumėte naudoti šią programą"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Būtina mokama prieiga"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Klausoma naudojant per daug įrenginių"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Tas turinys užblokuotas"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Negalima gauti to turinio čia"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Tas turinys jau leidžiamas"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Daugiau takelių praleisti nebegalima"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nepavyko užbaigti. Bandykite dar kartą."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Eilėje nieko nebėra"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Prisijungiama prie medijos"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Garso nustatymai"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Perjungti programas"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 7a25cd3..f542298 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Multivide"</string>
     <string name="search_hint" msgid="5401750426238148416">"Meklēt dziesmas u.c."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Tagad atskaņo"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Radās problēma. Mēģiniet vēlāk."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Pašlaik nevar veikt šo darbību."</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Šo darbību nevar veikt šajā lietotnē."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Pierakstieties, lai izmantotu šo lietotni."</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Nepieciešama maksas piekļuve"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Klausīšanās notiek pārāk daudz ierīcēs."</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Šis saturs ir bloķēts."</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Nevar šeit parādīt šo saturu."</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Šis saturs jau tiek atskaņots."</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Vairs nevar izlaist nevienu ierakstu."</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nevarēja pabeigt. Mēģiniet vēlreiz."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Rindā vairs nav nekā cita."</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Notiek savienojuma izveide ar multivides avotu"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Skaņas iestatījumi"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Pārslēgt lietotnes"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 2fd3aca..923dc72 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Аудиовизуелни содржини"</string>
     <string name="search_hint" msgid="5401750426238148416">"Пребарувај песни, изведувачи и друго…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Нешто не е во ред. Обидете се подоцна."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Не може да се направи тоа во моментов"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Апликацијава не може да го направи тоа"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Најавете се за да ја користите апликацијава"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Потребен е пристап со Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Се слуша на премногу уреди"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Таа содржина е блокирана"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Не може да се добие таа содржина тука"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Веќе е пуштена таа содржина"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Не може да прескокне повеќе песни"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Не може да заврши. Обидете се повторно."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Веќе ништо не чека на ред"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Се поврзува со аудиовизуелниот извор"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Поставки за звукот"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Променете ја апликацијата"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index b6337b1..84f293e 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"മീഡിയ"</string>
     <string name="search_hint" msgid="5401750426238148416">"പാട്ടും ആർട്ടിസ്റ്റും മറ്റും തിരയൂ..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"ഇപ്പോൾ കേൾക്കുന്നത്"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"എന്തോ കുഴപ്പം സംഭവിച്ചു. പിന്നീട് ശ്രമിക്കുക."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"അത് ഇപ്പോൾ ചെയ്യാനാവില്ല"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ഈ ആപ്പിന് അത് ചെയ്യാനാവില്ല"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ഈ ആപ്പ് ഉപയോഗിക്കാൻ സെെൻ ഇൻ ചെയ്യുക"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"പ്രീമിയം ആക്‌സസ് ആവശ്യമാണ്"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"നിരവധി ഉപകരണങ്ങളിൽ കേൾക്കുന്നു"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ആ ഉള്ളടക്കം ബ്ലോക്ക് ചെയ്‌തിരിക്കുന്നു"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ആ ഉള്ളടക്കം ഇവിടെ ലഭിക്കില്ല"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ആ ഉള്ളടക്കം നിലവിൽ പ്ലേ ചെയ്യുകയാണ്"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ഇനിയും ട്രാക്കുകൾ ഒഴിവാക്കാനാവില്ല"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"പൂർത്തിയാക്കാനായില്ല. വീണ്ടും ശ്രമിക്കൂ."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"ഒന്നും ക്യൂവിലില്ല"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"മീഡിയയിലേക്ക് കണക്‌റ്റ് ചെയ്യുന്നു"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ശബ്‌ദ ക്രമീകരണം"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ആപ്പുകൾ മാറുക"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 46fd785..31dce33 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Медиа"</string>
     <string name="search_hint" msgid="5401750426238148416">"Дуу, уран бүтээлчид болон бусад зүйлийг хайх..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Ямар нэг асуудал гарлаа. Дараа оролдоно уу."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Яг одоо үүнийг хийх боломжгүй"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Энэ аппаар үүнийг хийх боломжгүй"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Энэ аппыг ашиглахын тулд нэвтэрнэ үү"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium хандалт шаардлагатай"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Хэт олон төхөөрөмж сонсож байна"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ийм контентыг блоклодог"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Ийм контентыг энд авах боломжгүй"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ийм контентыг аль хэдийн тоглуулж байна"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Бичлэг дахин алгасах боломжгүй"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Дуусгаж чадсангүй. Дахин оролдоно уу."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Дууны жагсаалтад юу ч алга"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Медиад холбогдож байна"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Дууны тохиргоо"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Аппуудыг сэлгэх"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index ecf7592..2c497b1 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"मीडिया"</string>
     <string name="search_hint" msgid="5401750426238148416">"गाणी, कलाकार व बरेच शोधा…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"काहीतरी चूकले. नंतर प्रयत्न करा."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ते याक्षणी केले जाऊ शकत नाही"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"हे ॲप ते करू शकत नाही"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"हे अ‍ॅप वापरण्यासाठी साइन इन करा"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"प्रीमियम ॲक्सेस आवश्यक आहे"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"अनेक डिव्हाइसवर ऐकत आहे"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"तो आशय ब्लॉक केलेला आहे"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"तो आशय येथे आणू शकत नाही"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"तो आधीच आशय प्ले केला जात आहे"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"आणखी ट्रॅक वगळू शकत नाही"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"पूर्ण करता आले नाही. पुन्हा प्रयत्न करा."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"इतर काहीही क्यू केलेले नाही"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"मीडियाशी कनेक्ट करत आहे"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"आवाजाची सेटिंग्ज"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"अ‍ॅप्स स्विच करा"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 3dae631..16e2f2b 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Cari lagu, artis dll..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Ada yang tidak kena. Cuba nanti."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Tidak dapat berbuat demikian sekarang"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Apl ini tidak dapat berbuat demikian"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Log masuk untuk menggunakan apl ini"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Akses premium diperlukan"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Mendengar pada terlalu banyak peranti"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Kandungan itu disekat"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Tidak boleh mendapatkan kandungan itu di sini"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Sudah pun memainkan kandungan itu"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Tidak boleh melangkau sebarang lagu lagi"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Tidak dapat diselesaikan. Cuba lagi."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Tiada lagu lain dalam baris gilir"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Menyambung ke media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Tetapan Bunyi"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Tukar apl"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index fef3e1f..9b312d2 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"မီဒီယာ"</string>
     <string name="search_hint" msgid="5401750426238148416">"အရာများစွာ ရှာပါ..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"ယခု ဖွင့်နေသည်"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"တစ်ခုခု မှားနေသည်။ နောက်မှ စမ်းကြည့်ပါ။"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"၎င်းကို ယခု မပြုလုပ်နိုင်ပါ"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ဤအက်ပ်က ၎င်းကို မပြုလုပ်နိုင်ပါ"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ဤအက်ပ်အသုံးပြုရန် လက်မှတ်ထိုးဝင်ပါ"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ပရီမီယံ အသုံးပြုခွင့် လိုအပ်သည်"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"စက်ပစ္စည်းအများအပြားတွင် နားထောင်နေသည်"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ထိုအကြောင်းအရာကို ပိတ်ထားသည်"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ထိုအကြောင်းအရာကို ဤနေရာတွင် မရရှိနိုင်ပါ"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ထိုအကြောင်းအရာကို ဖွင့်နေပြီဖြစ်သည်"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"နောက်ထပ်သီချင်းပုဒ်များ ကျော်၍မရတော့ပါ"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"အပြီးသတ်၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"အခြားစီထားသည်များ မရှိပါ"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"မီဒီယာသို့ ချိတ်ဆက်ခြင်း"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"အသံဆက်တင်များ"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"အက်ပ်များပြောင်းခြင်း"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 78a470c..9af65d5 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Medier"</string>
     <string name="search_hint" msgid="5401750426238148416">"Søk etter sanger, artister med mer"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Spilles nå"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Noe gikk galt. Prøv senere."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Du kan ikke gjøre det akkurat nå"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Denne appen kan ikke gjøre det"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Logg på for å bruke denne appen"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premiumtilgang kreves"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Du lytter på for mange enheter"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Innholdet er blokkert"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Innholdet er ikke tilgjengelig her"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Du spiller allerede av innholdet"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Kan ikke hoppe over flere spor"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Kunne ikke fullføre. Prøv igjen."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ingenting annet står i køen"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Kobler til media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Lydinnstillinger"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Bytt app"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index aa135bb..9be29f5 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"मिडिया"</string>
     <string name="search_hint" msgid="5401750426238148416">"गीत, कलाकार र थप खोज्नु…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"अहिले प्ले भइरहेको"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"केही चिज गडबड छ। पछि प्रयास गर्नुहोस्।"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"त्यो कार्य अहिले नै गर्न सकिँदैन"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"यो एपले त्यो कार्य गर्न सक्दैन"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"यो एप प्रयोग गर्न साइन इन गर्नुहोस्"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"प्रिमियममाथिको पहुँच आवश्यक छ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"अत्यधिक यन्त्रहरूमा सुन्दै"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"त्यो सामग्रीमाथि रोक लगाइएको छ"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"त्यो सामग्री यहाँ प्राप्त गर्न सकिँदैन"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"त्यो सामग्री पहिलेदेखि नै प्ले भइरहेको छ"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"कुनै पनि थप ट्रयाकहरू छाड्न सकिँदैन"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"समाप्त गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"यसदेखि बाहेक केही पङ्क्तिबद्ध गरिएको छैन"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"मिडियामा जोड्दै"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ध्वनिसम्बन्धी सेटिङ"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"एउटा एपबाट अर्को एपमा जानुहोस्"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 3af6ffa..c282851 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Zoek nummers, artiesten en meer..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Er is iets misgegaan. Probeer het later opnieuw."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Kan dat nu niet doen"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Deze app kan dat niet doen"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Log in om deze app te gebruiken"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium-toegang vereist"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Er wordt op te veel apparaten geluisterd"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Die content is geblokkeerd"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Kan die content hier niet krijgen"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Die content wordt al afgespeeld"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Kan geen tracks meer overslaan"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Kan niet voltooien. Probeer het opnieuw."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Er staat niets anders in de wachtrij"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Verbinden met media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Geluidsinstellingen"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Schakelen tussen apps"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 664cc65..97b029d 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"ମିଡିଆ"</string>
     <string name="search_hint" msgid="5401750426238148416">"ଗୀତ, କଳାକାର, ଏବଂ ଅନେକ ସନ୍ଧାନ କରନ୍ତୁ..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"ଏବେ ଚାଲୁଅଛି"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"କିଛି ସମସ୍ୟା ଅଛି। ପରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ବର୍ତ୍ତମାନ ତାହା କରିପାରିବ ନାହିଁ"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ଏହି ଆପ୍ ତାହା କରିପାରିବ ନାହିଁ"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ଏହି ଆପ୍ ବ୍ୟବହାର କରିବାକୁ ସାଇନ୍ ଇନ୍ କରନ୍ତୁ"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ପ୍ରିମିୟମ୍ ଆକ୍ସେସ୍‌ର ଆବଶ୍ୟକ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"ଅନେକ ଡିଭାଇସ୍‌ରେ ଶୁଣାଯାଉଛି"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ସେହି ବିଷୟବସ୍ତୁ ବ୍ଲକ୍ କରାଯାଇଛି"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ଏଠାରେ ସେହି ବିଷୟବସ୍ତୁ ପାଇବେ ନାହିଁ"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ପୂର୍ବରୁ ସେହି ବିଷୟବସ୍ତୁ ଖେଳାଯାଉଛି"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ଅଧିକ ଟ୍ରାକ୍ ବାଦ୍ ଦେଇପାରିବ ନାହିଁ"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"ସମାପ୍ତ କରାଯାଇ ପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"ଅନୁକ୍ରମରେ ଆଉ କିଛି ନାହିଁ"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"ମିଡ଼ିଆ ସହ ସଂଯୋଗ ହେଉଛି"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ସାଉଣ୍ଡ ସେଟିଂସ୍"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ଆପଗୁଡ଼ିକୁ ବଦଳାନ୍ତୁ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 019ae5d..80105f6 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"ਮੀਡੀਆ"</string>
     <string name="search_hint" msgid="5401750426238148416">"ਗੀਤ, ਕਲਾਕਾਰ ਖੋਜੋ, ਹੋਰ"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"ਹੁਣੇ ਚੱਲ ਰਿਹਾ ਹੈ"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"ਕੋਈ ਗੜਬੜ ਹੈ। ਬਾਅਦ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ਫਿਲਹਾਲ ਇਹ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ਇਹ ਐਪ ਇਹ ਨਹੀਂ ਕਰ ਸਕਦੀ"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਲਈ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ਪ੍ਰੀਮੀਅਮ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਡੀਵਾਈਸਾਂ \'ਤੇ ਸੁਣਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ਇੱਥੇ ਇਹ ਸਮੱਗਰੀ ਨਹੀਂ ਮਿਲ ਸਕਦੀ"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ਇਹ ਸਮੱਗਰੀ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਹੀ ਹੈ"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ਕਿਸੇ ਹੋਰ ਟਰੈਕ ਨੂੰ ਛੱਡਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"ਪੂਰਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"ਹੋਰ ਕੁਝ ਵੀ ਕਤਾਰਬੱਧ ਨਹੀਂ ਹੈ"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"ਮੀਡੀਆ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ਧੁਨੀ ਸੈਟਿੰਗਾਂ"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 1b901ba..6a1d293 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Multimedia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Np. utwór lub wykonawca"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Teraz odtwarzane"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Coś poszło nie tak. Spróbuj później."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Teraz nie można tego zrobić"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Wybrana aplikacja nie ma takiej funkcji"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Zaloguj się, by używać tej aplikacji"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Wymagany jest dostęp na poziomie premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Słuchasz zbyt wielu urządzeń"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Te materiały są zablokowane"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Te materiały są niedostępne w tym regionie"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Te materiały są już odtwarzane"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Nie można pominąć większej liczby utworów"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nie udało się dokończyć. Spróbuj ponownie."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nie ma już nic w kolejce"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Łączenie z multimediami"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Ustawienia dźwięku"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Przełącz aplikacje"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 7a178a9..80e8898 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Multimédia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Pesquise músicas, artistas e mais…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"A tocar"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Ocorreu um problema. Tente mais tarde."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Não é possível responder a esse pedido neste momento."</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Esta aplicação não consegue responder a esse pedido."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Inicie sessão para utilizar esta aplicação."</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Acesso premium necessário."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"A ouvir em demasiados dispositivos."</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Esse conteúdo está bloqueado."</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Não é possível obter esse conteúdo aqui."</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Esse conteúdo já está em reprodução."</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Não é possível ignorar mais faixas."</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Não foi possível terminar. Tente novamente."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Não existem mais elementos em fila."</string>
     <string name="service_notification_title" msgid="8085444675783592744">"A ligar à fonte multimédia…"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Definições de som"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Mudar de app"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 6784ad9..06ce15d 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Mídia"</string>
     <string name="search_hint" msgid="5401750426238148416">"Pesq. músicas e mais"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Tocando agora"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Algo deu errado. Tente mais tarde."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Não é possível fazer isso no momento"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Não é possível fazer isso com este app"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Faça login para usar este app"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"É necessário ter acesso Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Ouvindo em muitos dispositivos"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Esse conteúdo está bloqueado"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Não é possível usar esse conteúdo aqui"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Esse conteúdo já está tocando"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Não é possível pular mais faixas"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Não foi possível concluir. Tente novamente."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Não há mais nada na fila"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Conectando à mídia"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Configurações de som"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Trocar de app"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index bbb8a83..320ca23 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Căutați cântece, artiști și altele…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Se redă acum"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"A apărut o problemă. Încercați mai târziu."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Acțiunea nu poate fi realizată momentan"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Aplicația nu poate realiza această acțiune"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Conectați-vă pentru a folosi aplicația"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Este necesar accesul premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Se ascultă prea multe dispozitive"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Conținutul este blocat"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Conținutul nu poate fi descărcat aici"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Conținutul se redă deja"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Nu mai pot fi omise melodii"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nu s-a putut finaliza. Încercați din nou."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Nu mai există elemente în coadă"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Se conectează la conținutul media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Setări pentru sunet"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Comutați între aplicații"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 3e8c860..22faade 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Мультимедиа"</string>
     <string name="search_hint" msgid="5401750426238148416">"Песня, исполнитель…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Сейчас играет"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Ошибка. Повторите попытку позже."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Невозможно выполнить действие в данный момент."</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Действие недоступно в этом приложении."</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Чтобы использовать это приложение, войдите в аккаунт."</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Требуется премиум-доступ."</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Слишком много устройств, на которых воспроизводится аудио."</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Контент заблокирован."</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Контент недоступен в вашем регионе."</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Этот контент уже воспроизводится."</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Пропускать треки больше нельзя."</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Произошла ошибка. Повторите попытку."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"В очереди воспроизведения нет других файлов."</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Подключение к источнику медиаконтента"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Настройки звука"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Переключение приложений"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index dad503c..3856a35 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"මාධ්‍ය"</string>
     <string name="search_hint" msgid="5401750426238148416">"ගීත, කලාකරුවන් සහ තවත් දේ සොයන්න..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"දැන් වාදනය වේ"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"යම් දෙයක් වැරදියි. පසුව උත්සාහ කරන්න."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"දැන් එය කළ නොහැක"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"මෙම යෙදුමට එය කළ නොහැක"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"මෙම යෙදුම භාවිත කිරීමට පුරන්න"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"පාරිතෝෂික ප්‍රවේශය අවශ්‍යයි"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"ඕනෑවට වඩා උපාංග මත සවන් දීම"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"එම අන්තර්ගතය අවහිර කර ඇත"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"එම අන්තර්ගතය මෙතැනින් ලබා ගත නොහැක"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"දැනටමත් එම අන්තර්ගතය වාදනය කරයි"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"තවත් ඛණ්ඩ මඟ හැරිය නොහැක"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"අවසන් කිරීමට නොහැකි විය. නැවත උත්සාහ කරන්න."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"වෙන කිසිවක් පෝලිමේ නැත"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"මාධ්‍ය වෙත සබැඳීම"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ශබ්ද සැකසීම්"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"යෙදුම් මාරු කරන්න"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 63fa1ca..e878ec4 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Médiá"</string>
     <string name="search_hint" msgid="5401750426238148416">"Hľadať skladby, interpretov a ďalší obsah…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Čo to hrá"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Vyskytol sa problém. Skúste to znova."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Teraz to nie je možné"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Táto aplikácia to nedokáže"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Ak chcete použiť túto aplikáciu, prihláste sa"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Vyžaduje sa prémiový prístup"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Počúva sa na príliš veľa zariadeniach"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Daný obsah je blokovaný"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Daný obsah tu nie je k dispozícii"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Tento obsah sa už prehráva"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Nie je možné preskočiť žiadne ďalšie stopy"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Akciu sa nepodarilo dokončiť. Skúste to znova."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Poradie je prázdne"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Pripája sa k médiu"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Nastavenia zvuku"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Prepnúť aplikácie"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 390c0b9..d9fc471 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Predstavnost"</string>
     <string name="search_hint" msgid="5401750426238148416">"Poiščite skladbe, izvajalce in drugo"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Zdaj se predvaja"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Prišlo je do težave. Poskusite pozneje."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Trenutno to ni izvedljivo"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ta aplikacija ne more izvesti tega"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Prijavite se, če želite uporabljati to aplikacijo"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Potrebujete plačljiv dostop"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Poslušanje v preveč napravah"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Ta vsebina je blokirana"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Te vsebine tukaj ni mogoče pridobiti"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ta vsebina se že predvaja"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Dosegli ste omejitev preskakovanja skladb"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Ni bilo mogoče dokončati. Poskusite znova."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Čakalna vrsta je prazna"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Povezovanje s predstavnostjo"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Nastavitve zvoka"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Preklop aplikacij"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index f2acebf..6fd862d 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Kërko për këngët, artistët etj..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Po luhet tani"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Ndodhi një gabim. Provo më vonë."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Këtë nuk mund ta bësh në këtë moment"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ky aplikacion nuk mund ta bëjë këtë"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Identifikohu për të përdorur këtë aplikacion"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Kërkohet qasje Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Po dëgjon në shumë pajisje"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Kjo përmbajtje është bllokuar"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Ajo përmbajtje nuk mund të merret këtu"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Ajo përmbajtje po luhet tashmë"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Nuk mund të kapërcejë këngë të tjera"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Nuk mundi të përfundojë. Provo sërish."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Asgjë tjetër nuk është në radhë"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Po lidhet me median"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Cilësimet e zërit"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Ndërro aplikaconet"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index ba42c4b..712eec5 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Медији"</string>
     <string name="search_hint" msgid="5401750426238148416">"Тражите песме, извођаче и друго..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Тренутно свира"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Нешто није у реду. Пробајте касније."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Тренутно не може то да уради"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ова апликација не може то да уради"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Пријавите се да бисте користили ову апликацију"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Потребан је премијум приступ"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Слушате на превише уређаја"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Тај садржај је блокиран"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Не можете да добијете тај садржај овде"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Тај садржај се већ репродукује"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Не можете више да прескачете песме"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Нисмо успели да довршимо радњу. Пробајте поново."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ништа друго није стављено у ред"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Повезује се са медијима"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Подешавања звука"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Пређи на другу апликацију"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 822c7a2..6a421f1 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Sök låt, artist m.m."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Nu spelas"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Något är fel. Försök igen senare."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Det går inte just nu"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Det går inte med den här appen"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Logga in om du vill använda appen"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium-konto krävs"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"För många enheter streamas"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Det innehållet har blockerats"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Det innehållet är inte tillgängligt här"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Det innehållet spelas redan"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Det går inte att hoppa över fler låtar"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Det gick inte att slutföra. Försök igen."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Inget annat har lagts i uppspelningskön"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Ansluter till mediakälla"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Ljudinställningar"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Byt app"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 4bde052..7161ca6 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Maudhui"</string>
     <string name="search_hint" msgid="5401750426238148416">"Tafuta nyimbo, wasanii na zaidi..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Inayocheza Sasa"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Hitilafu fulani imetokea. Jaribu baadaye."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Imeshindwa kufanya hivyo kwa sasa"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Programu hii imeshindwa kutekeleza ombi lako"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Ingia katika akaunti ili utumie programu hii"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Unahitaji kutumia akaunti ya Kulipia"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Unasikiliza kwenye vifaa vingi mno"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Maudhui haya yamezuiwa"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Imeshindwa kupata maudhui haya hapa"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Tayari inacheza maudhui hayo"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Imeshindwa kuruka nyimbo nyingine zaidi"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Imeshindwa kumaliza. Jaribu tena."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Hakuna maudhui mengine kwenye foleni"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Inaunganisha kwenye chanzo cha maudhui"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Mipangilio ya Sauti"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Badilisha programu"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index eb44d81..831b91f 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"மீடியா"</string>
     <string name="search_hint" msgid="5401750426238148416">"பாடல், கலைஞர் தேடல்"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"பாடல் விவரம்"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"ஏதோ தவறாகிவிட்டது. பிறகு முயலவும்."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"தற்சமயம் இதை செய்ய இயலாது"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"இந்த ஆப்ஸ் ஆதரிக்கவில்லை"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"இந்த ஆப்ஸை உபயோகிக்க உள்நுழைய வேண்டும்"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium அணுகல் தேவை"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"பல்வேறு சாதனங்களைக் கவனிக்கிறது"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"இது தடுக்கப்பட்டுள்ளது"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"அதை இங்குப் பெற முடியவில்லை"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ஏற்கெனவே அதைப் பிளே செய்து கொண்டிருக்கிறது"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"இதற்கு மேல் டிராக்குகளைத் தவிர்க்க முடியாது"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"நிறைவடையவில்லை. மீண்டும் முயலவும்."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"வேறு எதுவும் வரிசையில் இல்லை"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"மீடியாவுடன் இணைக்கிறது"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ஒலி அமைப்புகள்"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ஆப்ஸை மாற்றுவதற்கான பட்டன்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 5c5180a..14cd0f4 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"మీడియా"</string>
     <string name="search_hint" msgid="5401750426238148416">"పాటలు, కళాకారులు, మరిన్నింటిని వెతకండి..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"ప్రస్తుతం ప్లే అవుతున్నవి"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"ఏదో తప్పుగా ఉంది. తర్వాత ప్రయత్నించండి."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"దాన్ని ఇప్పుడే చేయడం సాధ్యపడదు"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"ఈ యాప్ దాన్ని చేయలేదు"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ఈ యాప్‌ను ఉపయోగించడానికి సైన్ ఇన్ చేయండి"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ప్రీమియం యాక్సెస్ అవసరం"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"చాలా ఎక్కువ పరికరాలలో వింటున్నారు"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"ఆ కంటెంట్ బ్లాక్ చేయబడింది"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"ఆ కంటెంట్‌ను ఇక్కడ పొందడం సాధ్యపడదు"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"ఇప్పటికే ఆ కంటెంట్ ప్లే అవుతోంది"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ఇక ఏ ట్రాక్‌లనూ దాటవేయడం సాధ్యపడదు"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"పూర్తి చేయడం సాధ్యపడలేదు. మళ్ళీ ప్రయత్నించండి."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"వరుసలో ఏమీ లేదు"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"మీడియాకు కనెక్ట్ చేస్తోంది"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"ధ్వని సెట్టింగ్‌లు"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"యాప్‌లను మార్చాలా?"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 928128b..dad42e0 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"สื่อ"</string>
     <string name="search_hint" msgid="5401750426238148416">"ค้นหาเพลง ศิลปิน และอื่นๆ..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"กำลังเล่น"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"มีข้อผิดพลาดเกิดขึ้น ลองอีกครั้งในภายหลัง"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ดำเนินการดังกล่าวไม่ได้ในขณะนี้"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"แอปนี้ดำเนินการดังกล่าวไม่ได้"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"ลงชื่อเข้าใช้เพื่อใช้แอปนี้"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"ต้องมีสิทธิ์เข้าถึงระดับพรีเมียม"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"กำลังเปิดฟังจากหลายอุปกรณ์เกินไป"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"เนื้อหาดังกล่าวถูกบล็อก"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"เปิดเนื้อหาดังกล่าวไม่ได้ที่นี่"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"กำลังเล่นเนื้อหาดังกล่าวอยู่แล้ว"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"ข้ามแทร็กอื่นอีกไม่ได้แล้ว"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"ดำเนินการไม่สำเร็จ ลองอีกครั้ง"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"ไม่มีรายการอื่นในคิว"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"กำลังเชื่อมต่อสื่อ"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"การตั้งค่าเสียง"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"เปลี่ยนแอป"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 5adf3ce..7be88a4 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Maghanap ng kanta, artist, atbp..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Nagpi-play Ngayon"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"May problema. Subukan sa ibang pagkakataon."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Hindi iyon magagawa ngayon"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Hindi iyon magagawa ng app na ito"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Mag-sign in para gamitin ang app na ito"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Kailangan ng premium na access"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Nakikinig sa masyadong maraming device"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Naka-block ang content na iyon"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Hindi makukuha ang content na iyon dito"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Pine-play na ang content na iyon"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Hindi na malalaktawan ang higit pang track"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Hindi matapos. Subukan ulit."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Wala nang naka-queue"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Kumokonekta sa media"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Mga Setting ng Tunog"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Lumipat ng app"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 97b0edf..77d821b 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Medya"</string>
     <string name="search_hint" msgid="5401750426238148416">"Şarkı vs. arayın..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Ne Çalıyor?"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Bir şeyler ters gitti. Daha sonra tekrar deneyin."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"İşlem şu anda gerçekleştirilemiyor"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Uygulama bu işlemi gerçekleştiremiyor"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Bu uygulamayı kullanmak için oturum açın"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Premium erişim gerekli"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Çok fazla cihazda dinleme yapılıyor"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Bu içerik engellendi"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"İçeriğe buradan erişilemiyor"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Bu içerik zaten oynatılıyor"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Daha fazla parça atlanamıyor"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Tamamlanamadı. Tekrar deneyin."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Sıraya eklenmiş başka bir şey yok"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Medyaya bağlanma"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Ses Ayarları"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Uygulama değiştir"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 48847cc..a732592 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Медіа"</string>
     <string name="search_hint" msgid="5401750426238148416">"Пошук пісень, виконавців тощо…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Зараз грає"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Сталася помилка. Повторіть спробу пізніше."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Зараз неможливо виконати запит"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Додаток не підтримує цю дію"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Увійдіть, щоб використовувати цей додаток"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Потрібна підписка Premium"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Для прослуховування використовується забагато пристроїв"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Цей вміст заблоковано"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Цей вміст недоступний у вашій країні"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Цей вміст уже відтворюється"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Неможливо пропустити більше композицій"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Не вдалося закінчити. Повторіть спробу."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Черга порожня"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Підключення до джерела медіавмісту"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Налаштування звуку"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Змінити додаток"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index af82518..073a76f 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"میڈیا"</string>
     <string name="search_hint" msgid="5401750426238148416">"گانے، فنکاران، اور مزید تلاش کریں..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Now Playing"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"کچھ غلط ہو گیا۔ بعد میں کوشش کریں۔"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"ابھی وہ ایسا نہیں کر سکتا"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"یہ ایپ ایسا نہیں کر سکتا"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"اس ایپ کا استعمال کرنے کے لیے سائن ان کریں"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"پریمیم رسائی درکار ہے"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"بہت سے آلات پر سننا"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"وہ مواد مسدود ہے"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"یہاں وہ مواد حاصل نہیں کر سکتے"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"وہ مواد پہلے سے ہی چلایا جارہا ہے"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"مزید کسی اور ٹریکس کو نظر انداز نہیں کر سکتے"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"پورا نہیں ہو سکا۔ پھر آزمائيں۔"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"مزید کچھ اور کی قطار نہیں ہے"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"میڈیا سے منسلک ہو رہا ہے"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"آواز کی ترتیبات"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"ایپس پر سوئچ کریں"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 02afdce..555efb3 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Media"</string>
     <string name="search_hint" msgid="5401750426238148416">"Musiqa qidiruvi..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Ijro qilinmoqda"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Nimadir xato ketdi Keyinroq qayta urining."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Buni hozir amalga oshira olmaydi"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Bu ilova bu amalni bajara olmaydi"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Bu ilovadan foydalanish uchun hisobingizga kiring"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Ishonchli ruxsat kerak"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Koʻplab qurilmalar tinglanmoqda"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Bu kontent bloklangan"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Bu kontentni bu yerga olish imkonsiz"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Bu kontent allaqachon ijro etilmoqda"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Boshqa treklarni qoldirib ketish imkonsiz"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Tugallanmadi. Qaytadan urining."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Ijro navbatida boshqa fayllar mavjud emas"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Media manbaga ulanish"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Tovush sozlamalari"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Ilovalarni almashtirish"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index beb9518..9727d99 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Nội dung nghe nhìn"</string>
     <string name="search_hint" msgid="5401750426238148416">"Tìm bài hát, nghệ sĩ, v.v."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Phát hiện nhạc"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Đã xảy ra lỗi. Hãy thử lại sau."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Không thể thực hiện yêu cầu đó ngay bây giờ"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Ứng dụng này không thể thực hiện yêu cầu đó"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Hãy đăng nhập để dùng ứng dụng này"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Yêu cầu quyền truy cập đặc biệt"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Đang nghe trên quá nhiều thiết bị"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Nội dung đó đã bị chặn"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Không thể xem nội dung đó tại đây"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Đang phát nội dung đó rồi"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Không thể bỏ qua bản nhạc nào nữa"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Không thể hoàn tất hành động. Hãy thử lại."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Không có nội dung nào khác trong hàng đợi"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Đang kết nối với nội dung nghe nhìn"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Cài đặt âm thanh"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Chuyển đổi ứng dụng"</string>
diff --git a/res/values-w1280dp/bools.xml b/res/values-w1280dp/bools.xml
new file mode 100644
index 0000000..a969b16
--- /dev/null
+++ b/res/values-w1280dp/bools.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <bool name="set_browse_list_focus_area_highlight_above_minimized_control_bar">false</bool>
+</resources>
diff --git a/res/values-w1280dp/dimens.xml b/res/values-w1280dp/dimens.xml
index 8bc2a0f..0ff8f11 100644
--- a/res/values-w1280dp/dimens.xml
+++ b/res/values-w1280dp/dimens.xml
@@ -19,7 +19,9 @@
     <!-- On wide screens, there is an additional margin below the minimized control bar.
       Since you can't sum dimensions in xml, this value is:
       @dimen/minimized_control_bar_height + @dimen/minimized_control_bar_margin_bottom -->
-    <dimen name="browse_fragment_bottom_padding">144dp</dimen>
+    <dimen name="browse_fragment_bottom_padding">152dp</dimen>
+
+    <dimen name="minimized_control_bar_margin_bottom">@dimen/car_ui_padding_3</dimen>
 
     <dimen name="media_browse_list_icons_item_art_margin_start">@dimen/car_ui_padding_4</dimen>
     <dimen name="queue_list_item_padding_x">@dimen/car_ui_padding_4</dimen>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index ee9b3aa..b928667 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"媒体"</string>
     <string name="search_hint" msgid="5401750426238148416">"搜索歌曲、音乐人等…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"正在播放"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"出了点问题。请稍后重试。"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"目前无法执行该操作"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"此应用无法执行该操作"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"登录才能使用此应用"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"需要有付费帐号才能访问"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"正在太多设备上同时聆听"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"该内容已遭到屏蔽"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"无法在此处获取这项内容"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"已经在播放这项内容"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"无法再跳过更多曲目"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"无法完成操作。请重试。"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"队列中没有任何其他内容"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"正在连接到媒体"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"声音设置"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"切换应用"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index a106414..15e6544 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"媒體"</string>
     <string name="search_hint" msgid="5401750426238148416">"搜尋歌曲、演出者和更多內容…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"正在播放"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"發生錯誤,請稍後再試。"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"目前無法執行有關操作"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"此應用程式無法執行有關操作"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"登入即可使用此應用程式"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"需要有付費帳戶方可存取"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"過多裝置正在同時收聽"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"有關內容已封鎖"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"無法在此取得有關內容"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"已正在播放有關內容"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"無法再跳播曲目"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"無法完成操作,請再試一次。"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"序列中沒有內容"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"正在連接媒體"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"音效設定"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"切換應用程式"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 5b588e3..a909a72 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"媒體"</string>
     <string name="search_hint" msgid="5401750426238148416">"搜尋歌曲、演出者和更多內容…"</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"正在播放"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"發生錯誤,請稍後再試。"</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"目前無法完成這項操作"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"這個應用程式不支援這項操作"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"如要使用這個應用程式,請登入帳戶"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"需要付費存取權"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"同時聆聽音樂的裝置過多"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"內容已遭到封鎖"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"該內容不適用於你所在地區"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"系統已開始播放該內容"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"無法再略過曲目"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"無法完成動作,請再試一次。"</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"待播清單中已無可播放的項目"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"正在連線到媒體"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"音效設定"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"切換應用程式"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 88ae0ab..e5807d4 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -26,18 +26,6 @@
     <string name="media_app_title" msgid="94717597743776797">"Imidiya"</string>
     <string name="search_hint" msgid="5401750426238148416">"Sesha izingoma, abaculi, nokuningi..."</string>
     <string name="fragment_playback_title" msgid="5014481549024607614">"Okudlala manje"</string>
-    <string name="default_error_message" msgid="6365377134388091079">"Kukhona okungalungile. Zama emuva kwesikhathi."</string>
-    <string name="error_code_app_error" msgid="1726372057192704809">"Ayikwazi ukwenza lokho khona manje"</string>
-    <string name="error_code_not_supported" msgid="1435878548411799387">"Lolu hlelo lokusebenza alukwazi ukwenza lokho"</string>
-    <string name="error_code_authentication_expired" msgid="905154133202017052">"Ngena ngemvume ukuze usebenzise lolu hlelo lokusebenza"</string>
-    <string name="error_code_premium_account_required" msgid="4736461331592855166">"Ukufinyelela kwe-premium kuyadingeka"</string>
-    <string name="error_code_concurrent_stream_limit" msgid="1279573243715957403">"Ilalele kumadivayisi amaningi kakhulu"</string>
-    <string name="error_code_parental_control_restricted" msgid="5222841294702530806">"Lokho okuqukethwe kuvinjelwe"</string>
-    <string name="error_code_not_available_in_region" msgid="4106605584926645567">"Ayikwazi ukuletha lokho okuqukethwe lapha"</string>
-    <string name="error_code_content_already_playing" msgid="8050972499898729459">"Isivele idlala lokho okuqukethwe"</string>
-    <string name="error_code_skip_limit_reached" msgid="8926507875025988831">"Ayikwazi ukweqa amanye amathrekhi amaningi"</string>
-    <string name="error_code_action_aborted" msgid="3889734248905737169">"Ayikwazanga ukuqeda. Zama futhi."</string>
-    <string name="error_code_end_of_queue" msgid="2842652212154074468">"Akukho okunye okufakwe kulayini"</string>
     <string name="service_notification_title" msgid="8085444675783592744">"Ixhumeka kumidiya"</string>
     <string name="menu_item_sound_settings_title" msgid="58887078120809669">"Izilungiselelo zomsindo"</string>
     <string name="menu_item_app_selector_title" msgid="4587248991114338595">"Shintsha izinhlelo zokusebenza"</string>
diff --git a/res/values/bools.xml b/res/values/bools.xml
index 16d7dfa..6d3c189 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -19,9 +19,22 @@
     <bool name="use_media_source_color_for_progress_bar">true</bool>
     <bool name="show_time_for_now_playing_queue_list_item">true</bool>
     <bool name="show_icon_for_now_playing_queue_list_item">false</bool>
+    <!-- Determines whether the mini playback controls should be shown or not. The mini playback
+         controls are used to show the user what is currently playing and give some means of
+         controlling the currently playing media (i.e play/pause, next/previous, etc). If similar
+         functionality is provided elsewhere (i.e. a persistent card in the sysui) this can be
+         disabled to minimize duplicate UI. -->
+    <bool name="show_mini_playback_controls">true</bool>
+    <!-- Determines whether clicking a playable item automatically shows the "Now Playing" screen.
+         Similar to `show_mini_playback_controls`, this can be set to false if there is some other
+         persistent means of seeing the currently playing media. -->
     <bool name="switch_to_playback_view_when_playable_item_is_clicked">true</bool>
     <bool name="show_thumbnail_for_queue_list_item">true</bool>
     <bool name="show_subtitle_for_queue_list_item">false</bool>
     <!-- Override this flag to show an icon that launches sound settings (equalizer) -->
     <bool name="show_sound_settings">false</bool>
+    <!-- The minimized control bar sits on top of the FocusArea that contains the browse list. This
+         flag sets whether to move the bottom highlight of the FocusArea upward so that the
+         highlight doesn't overlap with the minimized control bar. -->
+    <bool name="set_browse_list_focus_area_highlight_above_minimized_control_bar">true</bool>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index b667604..84d326e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -40,6 +40,10 @@
     <!-- Size of the thumb in the playback seekbar -->
     <dimen name="playback_seekbar_thumb_height">16dp</dimen>
     <dimen name="playback_seekbar_thumb_width">16dp</dimen>
+    <dimen name="playback_seekbar_thumb_inner_ring_inner_radius">8dp</dimen>
+    <dimen name="playback_seekbar_thumb_inner_ring_thickness">8dp</dimen>
+    <dimen name="playback_seekbar_thumb_outer_ring_inner_radius">16dp</dimen>
+    <dimen name="playback_seekbar_thumb_outer_ring_thickness">8dp</dimen>
     <dimen name="playback_seekbar_thumb_offset">0px</dimen>
     <!-- Paddings of playback seekbar -->
     <dimen name="playback_seekbar_padding_x">0dp</dimen>
@@ -102,7 +106,6 @@
     <dimen name="media_browse_grid_item_padding">0dp</dimen>
     <dimen name="media_browse_grid_item_margin_bottom">@dimen/car_ui_padding_4</dimen>
     <dimen name="media_browse_grid_item_text_margin_top">@dimen/car_ui_padding_3</dimen>
-    <dimen name="media_browse_grid_item_background_radius">4dp</dimen>
 
     <dimen name="media_browse_grid_icons_item_art_size">76dp</dimen>
 
diff --git a/res/values/id.xml b/res/values/id.xml
index 8f60cc7..c9d5250 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
   <item type="id" name="imageDownloadTask"/>
-  <item type="id" name="seek_bar_container"/>
+  <item type="id" name="playback_seek_bar_container"/>
 </resources>
diff --git a/res/values/integers.xml b/res/values/integers.xml
index 16247b9..2077b00 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -38,13 +38,13 @@
 
     <!-- Views to hide when opening the custom actions when the queue isn't visible. -->
     <integer-array name="playback_views_to_hide_when_showing_custom_actions">
-        <item>@id/seek_bar_container</item>
+        <item>@id/playback_seek_bar_container</item>
     </integer-array>
 
     <!-- Views to hide when the queue is visible (to show when the queue becomes invisible). -->
     <integer-array name="playback_views_to_hide_when_queue_is_visible">
         <item>@id/metadata_container</item>
-        <item>@id/seek_bar_container</item>
+        <item>@id/playback_seek_bar_container</item>
     </integer-array>
 
     <!-- Views to show when the queue is visible (to hide when the queue becomes invisible). -->
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
new file mode 100644
index 0000000..b7206d0
--- /dev/null
+++ b/res/values/overlayable.xml
@@ -0,0 +1,267 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.-->
+<!--
+THIS FILE WAS AUTO GENERATED, DO NOT EDIT MANUALLY.
+REGENERATE USING packages/apps/Car/tests/tools/rro/generate-overlayable.py
+-->
+<resources>
+  <overlayable name="CarMediaApp">
+    <policy type="system|product|signature">
+      <item type="anim" name="progress_indeterminate_material"/>
+      <item type="anim" name="progress_indeterminate_rotation_material"/>
+      <item type="array" name="playback_views_to_hide_immediately_when_queue_is_visible"/>
+      <item type="array" name="playback_views_to_hide_when_queue_is_visible"/>
+      <item type="array" name="playback_views_to_hide_when_showing_custom_actions"/>
+      <item type="array" name="playback_views_to_show_immediately_when_queue_is_visible"/>
+      <item type="array" name="playback_views_to_show_when_queue_is_visible"/>
+      <item type="bool" name="queue_fading_edge_length_enabled"/>
+      <item type="bool" name="set_browse_list_focus_area_highlight_above_minimized_control_bar"/>
+      <item type="bool" name="show_icon_for_now_playing_queue_list_item"/>
+      <item type="bool" name="show_mini_playback_controls"/>
+      <item type="bool" name="show_sound_settings"/>
+      <item type="bool" name="show_subtitle_for_queue_list_item"/>
+      <item type="bool" name="show_thumbnail_for_queue_list_item"/>
+      <item type="bool" name="show_time_for_now_playing_queue_list_item"/>
+      <item type="bool" name="switch_to_playback_view_when_playable_item_is_clicked"/>
+      <item type="bool" name="use_media_source_color_for_progress_bar"/>
+      <item type="color" name="album_art_background"/>
+      <item type="color" name="appbar_view_icon_tint"/>
+      <item type="color" name="appbar_view_settings_tint"/>
+      <item type="color" name="browse_playback_bg_color"/>
+      <item type="color" name="no_content_text_color"/>
+      <item type="color" name="progress_bar_background"/>
+      <item type="color" name="progress_bar_highlight"/>
+      <item type="color" name="progress_bar_thumb_color"/>
+      <item type="color" name="progress_bar_thumb_inner_ring_color"/>
+      <item type="color" name="progress_bar_thumb_outer_ring_color"/>
+      <item type="color" name="queue_playing_icon_color"/>
+      <item type="color" name="search_bar_underline_color"/>
+      <item type="color" name="search_hint_text_color"/>
+      <item type="dimen" name="appbar_view_control_buttons_margin_end"/>
+      <item type="dimen" name="appbar_view_control_buttons_spacing"/>
+      <item type="dimen" name="appbar_view_nav_button_width"/>
+      <item type="dimen" name="appbar_view_tabs_margin_end"/>
+      <item type="dimen" name="appbar_view_tabs_margin_start"/>
+      <item type="dimen" name="appbar_view_title_margin_start"/>
+      <item type="dimen" name="apps_max_content_width"/>
+      <item type="dimen" name="art_metadata_margin"/>
+      <item type="dimen" name="browse_fragment_bottom_padding"/>
+      <item type="dimen" name="browse_fragment_top_padding"/>
+      <item type="dimen" name="browse_fragment_top_padding_stacked"/>
+      <item type="dimen" name="browse_playback_controls_height"/>
+      <item type="dimen" name="browse_spacer_height"/>
+      <item type="dimen" name="browse_state_error_margin_top"/>
+      <item type="dimen" name="browse_tab_alpha_selected"/>
+      <item type="dimen" name="browse_tab_alpha_unselected"/>
+      <item type="dimen" name="browse_tab_padding"/>
+      <item type="dimen" name="browse_tab_width"/>
+      <item type="dimen" name="controls_margin"/>
+      <item type="dimen" name="controls_spacing_inner"/>
+      <item type="dimen" name="controls_spacing_outer"/>
+      <item type="dimen" name="controls_tap_target_height"/>
+      <item type="dimen" name="controls_tap_target_width"/>
+      <item type="dimen" name="fragment_error_button_margin_bottom"/>
+      <item type="dimen" name="fragment_error_button_margin_top"/>
+      <item type="dimen" name="fragment_error_message_margin_x"/>
+      <item type="dimen" name="fragment_metadata_margin_x"/>
+      <item type="dimen" name="fragment_playback_queue_overlap_bottom"/>
+      <item type="dimen" name="fragment_playback_queue_overlap_top"/>
+      <item type="dimen" name="grid_item_spacing"/>
+      <item type="dimen" name="media_activity_close_vector_x"/>
+      <item type="dimen" name="media_activity_close_vector_y"/>
+      <item type="dimen" name="media_activity_controls_container_padding"/>
+      <item type="dimen" name="media_activity_controls_margin_start"/>
+      <item type="dimen" name="media_background_alpha"/>
+      <item type="dimen" name="media_browse_grid_icons_item_art_size"/>
+      <item type="dimen" name="media_browse_grid_item_margin_bottom"/>
+      <item type="dimen" name="media_browse_grid_item_padding"/>
+      <item type="dimen" name="media_browse_grid_item_text_margin_top"/>
+      <item type="dimen" name="media_browse_header_item_height"/>
+      <item type="dimen" name="media_browse_header_item_margin_x"/>
+      <item type="dimen" name="media_browse_indicator_size"/>
+      <item type="dimen" name="media_browse_list_icons_item_art_margin_start"/>
+      <item type="dimen" name="media_browse_list_icons_item_art_size"/>
+      <item type="dimen" name="media_browse_list_icons_item_text_margin_x"/>
+      <item type="dimen" name="media_browse_list_item_arrow_size"/>
+      <item type="dimen" name="media_browse_list_item_height"/>
+      <item type="dimen" name="media_browse_list_item_icon_margin_start"/>
+      <item type="dimen" name="media_browse_list_item_text_margin_x"/>
+      <item type="dimen" name="media_browse_list_item_thumbnail_margin_bottom"/>
+      <item type="dimen" name="media_browse_list_item_thumbnail_size"/>
+      <item type="dimen" name="media_browse_subtitle_margin_top"/>
+      <item type="dimen" name="media_scrim_alpha"/>
+      <item type="dimen" name="media_scrim_darkened_alpha"/>
+      <item type="dimen" name="metadata_subtitles_margin"/>
+      <item type="dimen" name="metadata_title_subtitle_margin"/>
+      <item type="dimen" name="minimized_control_bar_margin_bottom"/>
+      <item type="dimen" name="missing_permission_icon_size"/>
+      <item type="dimen" name="music_action_icon_inset"/>
+      <item type="dimen" name="music_action_ripple_inset"/>
+      <item type="dimen" name="playback_album_art_size"/>
+      <item type="dimen" name="playback_background_blur_radius"/>
+      <item type="dimen" name="playback_background_blur_scale"/>
+      <item type="dimen" name="playback_background_raw_image_size"/>
+      <item type="dimen" name="playback_queue_background_alpha"/>
+      <item type="dimen" name="playback_queue_button_margin_end"/>
+      <item type="dimen" name="playback_queue_list_padding_top"/>
+      <item type="dimen" name="playback_seekbar_height"/>
+      <item type="dimen" name="playback_seekbar_margin_x"/>
+      <item type="dimen" name="playback_seekbar_padding_x"/>
+      <item type="dimen" name="playback_seekbar_thumb_height"/>
+      <item type="dimen" name="playback_seekbar_thumb_inner_ring_inner_radius"/>
+      <item type="dimen" name="playback_seekbar_thumb_inner_ring_thickness"/>
+      <item type="dimen" name="playback_seekbar_thumb_offset"/>
+      <item type="dimen" name="playback_seekbar_thumb_outer_ring_inner_radius"/>
+      <item type="dimen" name="playback_seekbar_thumb_outer_ring_thickness"/>
+      <item type="dimen" name="playback_seekbar_thumb_width"/>
+      <item type="dimen" name="playback_seekbar_track_height"/>
+      <item type="dimen" name="playback_title_margin_end"/>
+      <item type="dimen" name="queue_button_background_size"/>
+      <item type="dimen" name="queue_fading_edge_length"/>
+      <item type="dimen" name="queue_list_item_height"/>
+      <item type="dimen" name="queue_list_item_padding_x"/>
+      <item type="dimen" name="queue_list_item_spacer_width"/>
+      <item type="dimen" name="queue_list_item_thumbnail_container_width"/>
+      <item type="dimen" name="queue_list_item_thumbnail_size"/>
+      <item type="dimen" name="queue_list_item_title_time_margin"/>
+      <item type="dimen" name="tab_view_icon_margin_bottom"/>
+      <item type="dimen" name="tab_view_icon_size"/>
+      <item type="drawable" name="error_illustration"/>
+      <item type="drawable" name="ic_arrow_back"/>
+      <item type="drawable" name="ic_chevron_right"/>
+      <item type="drawable" name="ic_equalizer"/>
+      <item type="drawable" name="ic_expand_less"/>
+      <item type="drawable" name="ic_expand_more"/>
+      <item type="drawable" name="ic_explicit_black"/>
+      <item type="drawable" name="ic_file_download_done_black"/>
+      <item type="drawable" name="ic_queue_button"/>
+      <item type="drawable" name="ic_search"/>
+      <item type="drawable" name="ic_settings"/>
+      <item type="drawable" name="media_app_title_background"/>
+      <item type="drawable" name="music_overflow_action_background"/>
+      <item type="drawable" name="seekbar_foreground"/>
+      <item type="drawable" name="seekbar_progress"/>
+      <item type="drawable" name="seekbar_thumb"/>
+      <item type="id" name="album_art"/>
+      <item type="id" name="album_title"/>
+      <item type="id" name="artist"/>
+      <item type="id" name="background_scrim"/>
+      <item type="id" name="browse_content_area"/>
+      <item type="id" name="browse_list"/>
+      <item type="id" name="control_bar_first_row_guideline"/>
+      <item type="id" name="control_bar_scrim"/>
+      <item type="id" name="current_time"/>
+      <item type="id" name="download_icon_with_subtitle"/>
+      <item type="id" name="download_icon_with_title"/>
+      <item type="id" name="error_button"/>
+      <item type="id" name="error_container"/>
+      <item type="id" name="error_icon"/>
+      <item type="id" name="error_message"/>
+      <item type="id" name="explicit_icon_with_subtitle"/>
+      <item type="id" name="explicit_icon_with_title"/>
+      <item type="id" name="focus_area"/>
+      <item type="id" name="fpv"/>
+      <item type="id" name="fragment_container"/>
+      <item type="id" name="imageDownloadTask"/>
+      <item type="id" name="inner_separator"/>
+      <item type="id" name="item_container"/>
+      <item type="id" name="max_time"/>
+      <item type="id" name="media_activity_root"/>
+      <item type="id" name="metadata_container"/>
+      <item type="id" name="minimized_playback_controls"/>
+      <item type="id" name="now_playing_icon"/>
+      <item type="id" name="outer_separator"/>
+      <item type="id" name="playback_background"/>
+      <item type="id" name="playback_container"/>
+      <item type="id" name="playback_controls"/>
+      <item type="id" name="playback_seek_bar"/>
+      <item type="id" name="playback_seek_bar_container"/>
+      <item type="id" name="progress_text_container"/>
+      <item type="id" name="queue_container"/>
+      <item type="id" name="queue_list"/>
+      <item type="id" name="queue_list_bottom_constraint"/>
+      <item type="id" name="queue_list_item_subtitle"/>
+      <item type="id" name="queue_list_item_title"/>
+      <item type="id" name="queue_list_item_titles_container"/>
+      <item type="id" name="queue_list_top_constraint"/>
+      <item type="id" name="right_arrow"/>
+      <item type="id" name="separator"/>
+      <item type="id" name="spacer"/>
+      <item type="id" name="subtitle"/>
+      <item type="id" name="text_start_guideline"/>
+      <item type="id" name="thumbnail"/>
+      <item type="id" name="thumbnail_container"/>
+      <item type="id" name="title"/>
+      <item type="id" name="ui_content_bottom_guideline"/>
+      <item type="id" name="ui_content_end_guideline"/>
+      <item type="id" name="ui_content_start_guideline"/>
+      <item type="id" name="ui_content_top_guideline"/>
+      <item type="id" name="ui_content_top_guideline2"/>
+      <item type="integer" name="fragment_playback_queue_fade_duration_ms"/>
+      <item type="integer" name="max_tabs"/>
+      <item type="integer" name="media_artist_max_lines"/>
+      <item type="integer" name="media_title_max_lines"/>
+      <item type="integer" name="num_app_bar_view_rows"/>
+      <item type="integer" name="num_browse_columns"/>
+      <item type="integer" name="progress_indicator_delay"/>
+      <item type="interpolator" name="trim_end_interpolator"/>
+      <item type="interpolator" name="trim_start_interpolator"/>
+      <item type="layout" name="browse_node"/>
+      <item type="layout" name="fragment_browse"/>
+      <item type="layout" name="fragment_error"/>
+      <item type="layout" name="fragment_playback"/>
+      <item type="layout" name="media_activity"/>
+      <item type="layout" name="media_browse_grid_icons_item"/>
+      <item type="layout" name="media_browse_grid_item"/>
+      <item type="layout" name="media_browse_header_item"/>
+      <item type="layout" name="media_browse_list_icons_item"/>
+      <item type="layout" name="media_browse_list_item"/>
+      <item type="layout" name="media_browse_spacer"/>
+      <item type="layout" name="metadata_normal"/>
+      <item type="layout" name="queue_list_item"/>
+      <item type="layout" name="time_progress_text"/>
+      <item type="layout" name="ui_guides"/>
+      <item type="string" name="browser_loading"/>
+      <item type="string" name="cannot_connect_to_app"/>
+      <item type="string" name="dash_separator"/>
+      <item type="string" name="fragment_playback_title"/>
+      <item type="string" name="media_app_title"/>
+      <item type="string" name="media_browse_more"/>
+      <item type="string" name="menu_item_app_selector_title"/>
+      <item type="string" name="menu_item_sound_settings_title"/>
+      <item type="string" name="nothing_to_play"/>
+      <item type="string" name="search_hint"/>
+      <item type="string" name="service_notification_title"/>
+      <item type="string" name="slash_separator"/>
+      <item type="string" name="unknown_error"/>
+      <item type="string" name="unknown_media_provider_name"/>
+      <item type="style" name="BrowseGridSubtitleStyle"/>
+      <item type="style" name="BrowseGridTitleStyle"/>
+      <item type="style" name="BrowseListItemRightArrowStyle"/>
+      <item type="style" name="BrowseListSubtitleStyle"/>
+      <item type="style" name="BrowseListTitleStyle"/>
+      <item type="style" name="BrowseSubheaderStyle"/>
+      <item type="style" name="ErrorTextStyle"/>
+      <item type="style" name="MetadataContainerStyle"/>
+      <item type="style" name="MetadataPlaybackSubtitleStyle"/>
+      <item type="style" name="MetadataPlaybackTitleStyle"/>
+      <item type="style" name="QueueListItemSubtitleStyle"/>
+      <item type="style" name="QueueListItemTimeStyle"/>
+      <item type="style" name="QueueListItemTitleStyle"/>
+      <item type="style" name="QueueListItemTitlesContainerStyle"/>
+      <item type="style" name="SeekBarStyle"/>
+      <item type="style" name="TextAppearance.NoContent"/>
+      <item type="style" name="Theme.Media"/>
+      <item type="xml" name="uxr_config"/>
+    </policy>
+  </overlayable>
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 33d7f0d..258963f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -35,30 +35,7 @@
     <!-- Title to display when in playback view. [CHAR LIMIT=50] -->
     <string name="fragment_playback_title">Now Playing</string>
 
-    <!-- MediaActivity default error message [CHAR LIMIT=100] -->
-    <string name="default_error_message">Something’s wrong. Try later.</string>
-    <!-- Error message set when the application state is invalid to fulfill the request. [CHAR LIMIT=100] -->
-    <string name="error_code_app_error">Can’t do that right now</string>
-    <!-- Error message set when the request is not supported by the application. [CHAR LIMIT=100] -->
-    <string name="error_code_not_supported">This app can’t do that</string>
-    <!-- Error message set when the request cannot be performed because authentication has expired. [CHAR LIMIT=100] -->
-    <string name="error_code_authentication_expired">Sign in to use this app</string>
-    <!-- Error message set when a premium account is required for the request to succeed. [CHAR LIMIT=100] -->
-    <string name="error_code_premium_account_required">Premium access required</string>
-    <!-- Error message set when too many concurrent streams are detected. [CHAR LIMIT=100] -->
-    <string name="error_code_concurrent_stream_limit">Listening on too many devices</string>
-    <!-- Error message set when the content is blocked due to parental controls. [CHAR LIMIT=100] -->
-    <string name="error_code_parental_control_restricted">That content is blocked</string>
-    <!-- Error message set when the content is blocked due to being regionally unavailable. [CHAR LIMIT=100] -->
-    <string name="error_code_not_available_in_region">Can’t get that content here</string>
-    <!-- Error message set when the requested content is already playing. [CHAR LIMIT=100] -->
-    <string name="error_code_content_already_playing">Already playing that content</string>
-    <!-- Error message set when the application cannot skip any more songs because skip limit is reached. [CHAR LIMIT=100] -->
-    <string name="error_code_skip_limit_reached">Can’t skip any more tracks</string>
-    <!-- Error message set when the action is interrupted due to some external event. [CHAR LIMIT=100] -->
-    <string name="error_code_action_aborted">Couldn’t finish. Try again.</string>
-    <!-- Error message set when the playback navigation (previous, next) is not possible because the queue was exhausted. [CHAR LIMIT=100] -->
-    <string name="error_code_end_of_queue">Nothing else is queued up</string>
+
     <!-- Title string for the service used to bind to the current media source -->
     <string name="service_notification_title">Connecting to media</string>
     <!-- Title of the sound settings menu item. Will be displayed if the button is in the overflow menu. [CHAR_LIMIT=50] -->
diff --git a/res/xml/uxr_config.xml b/res/xml/uxr_config.xml
new file mode 100644
index 0000000..d00c842
--- /dev/null
+++ b/res/xml/uxr_config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<Mapping xmlns:app="http://schemas.android.com/apk/res-auto">
+    <!-- We use a default value of -1 to denote UNLIMITED -->
+    <!-- When maxLength is > 0, its value is rounded up to the nearest greater odd integer. -->
+    <ListConfig
+        app:id="@+id/playback_fragment_now_playing_list_uxr_config"
+        app:maxLength="-1"
+    />
+
+    <!-- We use a default value of -1 to denote UNLIMITED -->
+    <ListConfig
+        app:id="@+id/browse_list_uxr_config"
+        app:maxLength="-1"
+    />
+</Mapping>
diff --git a/src/com/android/car/media/BrowseViewController.java b/src/com/android/car/media/BrowseViewController.java
index dd6de4b..c1869e4 100644
--- a/src/com/android/car/media/BrowseViewController.java
+++ b/src/com/android/car/media/BrowseViewController.java
@@ -16,105 +16,93 @@
 
 package com.android.car.media;
 
-import static com.android.car.arch.common.LiveDataFunctions.ifThenElse;
+import static com.android.car.apps.common.util.ViewUtils.removeFromParent;
 
-import android.car.content.pm.CarPackageManager;
-import android.content.Context;
 import android.content.res.Resources;
 import android.os.Handler;
-import android.text.TextUtils;
 import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
 import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.ImageView;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.Observer;
 import androidx.lifecycle.ViewModelProviders;
+import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.car.apps.common.util.ViewUtils;
 import com.android.car.arch.common.FutureData;
 import com.android.car.media.browse.BrowseAdapter;
+import com.android.car.media.browse.LimitedBrowseAdapter;
 import com.android.car.media.common.GridSpacingItemDecoration;
 import com.android.car.media.common.MediaItemMetadata;
-import com.android.car.media.common.browse.MediaBrowserViewModel;
+import com.android.car.media.common.browse.MediaBrowserViewModelImpl;
+import com.android.car.media.common.browse.MediaItemsRepository.MediaItemsLiveData;
 import com.android.car.media.common.source.MediaSource;
-import com.android.car.media.widgets.AppBarView;
-import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.FocusArea;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.uxr.LifeCycleObserverUxrContentLimiter;
+import com.android.car.uxr.UxrContentLimiterImpl;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
-import java.util.Objects;
-import java.util.Stack;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 /**
- * A view controller that implements the content forward browsing experience.
- *
- * This can be used to display either search or browse results at the root level. Deeper levels will
- * be handled the same way between search and browse, using a back stack to return to the root.
+ * A view controller that displays the media item children of a {@link MediaItemMetadata}.
+ * The controller manages a recycler view where the items can be displayed as a list or a grid, as
+ * well as an error icon and a message used to indicate loading and errors.
+ * The content view is initialized with 0 alpha and needs to be animated or set to to full opacity
+ * to become visible.
  */
-public class BrowseViewController extends ViewControllerBase {
+public class BrowseViewController {
     private static final String TAG = "BrowseViewController";
 
-    private static final String REGULAR_BROWSER_VIEW_MODEL_KEY
-            = "com.android.car.media.regular_browser_view_model";
-    private static final String SEARCH_BROWSER_VIEW_MODEL_KEY
-            = "com.android.car.media.search_browser_view_model";
-
     private final Callbacks mCallbacks;
-
+    private final FocusArea mFocusArea;
+    private final MediaItemMetadata mParentItem;
+    private final MediaItemsLiveData mMediaItems;
+    private final boolean mDisplayMediaItems;
+    private final LifeCycleObserverUxrContentLimiter mUxrContentLimiter;
+    private final View mContent;
     private final RecyclerView mBrowseList;
     private final ImageView mErrorIcon;
     private final TextView mMessage;
-    private final BrowseAdapter mBrowseAdapter;
-    private String mSearchQuery;
+    private final LimitedBrowseAdapter mLimitedBrowseAdapter;
+
     private final int mFadeDuration;
     private final int mLoadingIndicatorDelay;
-    private final boolean mIsSearchController;
-    private final MutableLiveData<Boolean> mShowSearchResults = new MutableLiveData<>();
+
+    private final boolean mSetFocusAreaHighlightBottom;
+
     private final Handler mHandler = new Handler();
-    /**
-     * Stores the reference to {@link MediaActivity.ViewModel#getSearchStack} or to
-     * {@link MediaActivity.ViewModel#getBrowseStack}. Updated in {@link #onMediaSourceChanged}.
-     */
-    private Stack<MediaItemMetadata> mBrowseStack = new Stack<>();
+
     private final MediaActivity.ViewModel mViewModel;
-    private final MediaBrowserViewModel mRootMediaBrowserViewModel;
-    private final MediaBrowserViewModel.WithMutableBrowseId mMediaBrowserViewModel;
+
     private final BrowseAdapter.Observer mBrowseAdapterObserver = new BrowseAdapter.Observer() {
 
         @Override
-        protected void onPlayableItemClicked(MediaItemMetadata item) {
-            hideKeyboard();
-            getParent().onPlayableItemClicked(item);
+        protected void onPlayableItemClicked(@NonNull MediaItemMetadata item) {
+            mCallbacks.onPlayableItemClicked(item);
         }
 
         @Override
-        protected void onBrowsableItemClicked(MediaItemMetadata item) {
-            hideKeyboard();
-            navigateInto(item);
+        protected void onBrowsableItemClicked(@NonNull MediaItemMetadata item) {
+            mCallbacks.onBrowsableItemClicked(item);
         }
     };
 
-    private boolean mBrowseTreeHasChildren;
-    private boolean mAcceptTabSelection = true;
-
     /**
-     * Media items to display as tabs. If null, it means we haven't finished loading them yet. If
-     * empty, it means there are no tabs to show
+     * The bottom padding of the FocusArea highlight.
      */
-    @Nullable
-    private List<MediaItemMetadata> mTopItems;
+    private int mFocusAreaHighlightBottomPadding;
 
     /**
-     * Callbacks (implemented by the hosting Activity)
+     * Callbacks (implemented by the host)
      */
     public interface Callbacks {
         /**
@@ -122,134 +110,70 @@
          *
          * @param item item to be played.
          */
-        void onPlayableItemClicked(MediaItemMetadata item);
+        void onPlayableItemClicked(@NonNull MediaItemMetadata item);
 
-        /** Called once the list of the root node's children has been loaded. */
-        void onRootLoaded();
+        /** Invoked when the user clicks on a browsable item. */
+        void onBrowsableItemClicked(@NonNull MediaItemMetadata item);
 
-        /** Change to a new UI mode. */
-        void changeMode(MediaActivity.Mode mode);
+        /** Invoked when child nodes have been removed from this controller. */
+        void onChildrenNodesRemoved(@NonNull BrowseViewController controller,
+                @NonNull Collection<MediaItemMetadata> removedNodes);
 
         FragmentActivity getActivity();
     }
 
-    /**
-     * Moves the user one level up in the browse tree. Returns whether that was possible.
-     */
-    private boolean navigateBack() {
-        boolean result = false;
-        if (!isAtTopStack()) {
-            mBrowseStack.pop();
-            mMediaBrowserViewModel.search(mSearchQuery);
-            mMediaBrowserViewModel.setCurrentBrowseId(getCurrentMediaItemId());
-            updateAppBar();
-            result = true;
-        }
-        if (isAtTopStack()) {
-            mShowSearchResults.setValue(mIsSearchController);
-        }
-        return result;
-    }
-
-    private void reopenSearch() {
-        if (mIsSearchController) {
-            mBrowseStack.clear();
-            updateAppBar();
-            mShowSearchResults.setValue(true);
-        } else {
-            Log.e(TAG, "reopenSearch called on browse controller");
-        }
-    }
-
-    @NonNull
-    private Callbacks getParent() {
-        return mCallbacks;
-    }
-
     private FragmentActivity getActivity() {
         return mCallbacks.getActivity();
     }
 
     /**
-     * @return whether the user is at the top of the browsing stack.
+     * Creates a controller to display the children of the given parent {@link MediaItemMetadata}.
+     * This parent node can have been obtained from the browse tree, or from browsing the search
+     * results.
      */
-    private boolean isAtTopStack() {
-        if (mIsSearchController) {
-            return mBrowseStack.isEmpty();
-        } else {
-            // The mBrowseStack stack includes the tab...
-            return mBrowseStack.size() <= 1;
-        }
+    static BrowseViewController newBrowseController(Callbacks callbacks, ViewGroup container,
+            @NonNull MediaItemMetadata parentItem, MediaItemsLiveData mediaItems,
+            int rootBrowsableHint, int rootPlayableHint) {
+        return new BrowseViewController(callbacks, container, parentItem, mediaItems,
+                rootBrowsableHint, rootPlayableHint, true);
+    }
+
+    /** Creates a controller to display the top results of a search query (in a list). */
+    static BrowseViewController newSearchResultsController(Callbacks callbacks, ViewGroup container,
+            MediaItemsLiveData mediaItems) {
+        return new BrowseViewController(callbacks, container, null, mediaItems, 0, 0, true);
     }
 
     /**
-     * Creates a new instance of this controller meant to browse the root node.
-     * @return a fully initialized {@link BrowseViewController}
+     * Creates a controller to "display" the children of the root: the children are actually hidden
+     * since they are shown as tabs, and the controller is only used to display loading and error
+     * messages.
      */
-    public static BrowseViewController newInstance(Callbacks callbacks,
-            CarPackageManager carPackageManager, ViewGroup container) {
-        boolean isSearchController = false;
-        return new BrowseViewController(callbacks, carPackageManager, container, isSearchController);
+    static BrowseViewController newRootController(Callbacks callbacks, ViewGroup container,
+            MediaItemsLiveData mediaItems) {
+        return new BrowseViewController(callbacks, container, null, mediaItems, 0, 0, false);
     }
 
-    /**
-     * Creates a new instance of this controller meant to display search results. The root browse
-     * screen will be the search results for the provided query.
-     *
-     * @return a fully initialized {@link BrowseViewController}
-     */
-    static BrowseViewController newSearchInstance(Callbacks callbacks,
-            CarPackageManager carPackageManager, ViewGroup container) {
-        boolean isSearchController = true;
-        return new BrowseViewController(callbacks, carPackageManager, container, isSearchController);
-    }
 
-    private void updateSearchQuery(@Nullable String query) {
-        mSearchQuery = query;
-        mMediaBrowserViewModel.search(query);
-    }
-
-    /**
-     * Clears search state, removes any UI elements from previous results.
-     */
-    @Override
-    void onMediaSourceChanged(@Nullable MediaSource mediaSource) {
-        super.onMediaSourceChanged(mediaSource);
-
-        mBrowseTreeHasChildren = false;
-
-        if (mIsSearchController) {
-            updateSearchQuery(mViewModel.getSearchQuery());
-            mAppBarView.setSearchQuery(mSearchQuery);
-            mBrowseStack = mViewModel.getSearchStack();
-            mShowSearchResults.setValue(isAtTopStack());
-        } else {
-            mBrowseStack = mViewModel.getBrowseStack();
-            mShowSearchResults.setValue(false);
-            updateTabs((mediaSource != null) ? null : new ArrayList<>());
-        }
-
-        mBrowseAdapter.submitItems(null, null);
-        stopLoadingIndicator();
-        ViewUtils.hideViewAnimated(mErrorIcon, mFadeDuration);
-        ViewUtils.hideViewAnimated(mMessage, mFadeDuration);
-
-        mMediaBrowserViewModel.setCurrentBrowseId(getCurrentMediaItemId());
-
-        updateAppBar();
-    }
-
-    private BrowseViewController(Callbacks callbacks, CarPackageManager carPackageManager,
-            ViewGroup container, boolean isSearchController) {
-        super(callbacks.getActivity(), carPackageManager, container, R.layout.fragment_browse);
-
+    private BrowseViewController(Callbacks callbacks, ViewGroup container,
+            @Nullable MediaItemMetadata parentItem, MediaItemsLiveData mediaItems,
+            int rootBrowsableHint, int rootPlayableHint, boolean displayMediaItems) {
         mCallbacks = callbacks;
-        mIsSearchController = isSearchController;
+        mParentItem = parentItem;
+        mMediaItems = mediaItems;
+        mDisplayMediaItems = displayMediaItems;
+
+        LayoutInflater inflater = LayoutInflater.from(container.getContext());
+        mContent = inflater.inflate(R.layout.browse_node, container, false);
+        mContent.setAlpha(0f);
+        container.addView(mContent);
 
         mLoadingIndicatorDelay = mContent.getContext().getResources()
                 .getInteger(R.integer.progress_indicator_delay);
+        mSetFocusAreaHighlightBottom = mContent.getContext().getResources().getBoolean(
+                R.bool.set_browse_list_focus_area_highlight_above_minimized_control_bar);
 
-        mAppBarView.setListener(mAppBarListener);
+        mFocusArea = mContent.findViewById(R.id.focus_area);
         mBrowseList = mContent.findViewById(R.id.browse_list);
         mErrorIcon = mContent.findViewById(R.id.error_icon);
         mMessage = mContent.findViewById(R.id.error_message);
@@ -258,82 +182,81 @@
 
 
         FragmentActivity activity = callbacks.getActivity();
-
         mViewModel = ViewModelProviders.of(activity).get(MediaActivity.ViewModel.class);
 
-        // Browse logic for the root node
-        mRootMediaBrowserViewModel = MediaBrowserViewModel.Factory.getInstanceForBrowseRoot(
-                mMediaSourceVM, ViewModelProviders.of(activity));
-        mRootMediaBrowserViewModel.getBrowsedMediaItems()
-                .observe(activity, futureData -> onItemsUpdate(/* forRoot */ true, futureData));
-
-        mRootMediaBrowserViewModel.supportsSearch().observe(activity,
-                mAppBarView::setSearchSupported);
-
-
-        // Browse logic for current node
-        mMediaBrowserViewModel = MediaBrowserViewModel.Factory.getInstanceWithMediaBrowser(
-                mIsSearchController ? SEARCH_BROWSER_VIEW_MODEL_KEY : REGULAR_BROWSER_VIEW_MODEL_KEY,
-                ViewModelProviders.of(activity),
-                mMediaSourceVM.getConnectedMediaBrowser());
-
         mBrowseList.addItemDecoration(new GridSpacingItemDecoration(
                 activity.getResources().getDimensionPixelSize(R.dimen.grid_item_spacing)));
 
-        mBrowseAdapter = new BrowseAdapter(mBrowseList.getContext());
-        mBrowseList.setAdapter(mBrowseAdapter);
-        mBrowseAdapter.registerObserver(mBrowseAdapterObserver);
+        GridLayoutManager manager = (GridLayoutManager) mBrowseList.getLayoutManager();
+        BrowseAdapter browseAdapter = new BrowseAdapter(mBrowseList.getContext());
+        mLimitedBrowseAdapter = new LimitedBrowseAdapter(browseAdapter, manager,
+                mBrowseAdapterObserver);
+        mBrowseList.setAdapter(mLimitedBrowseAdapter);
 
-        mMediaBrowserViewModel.rootBrowsableHint().observe(activity,
-                mBrowseAdapter::setRootBrowsableViewType);
-        mMediaBrowserViewModel.rootPlayableHint().observe(activity,
-                mBrowseAdapter::setRootPlayableViewType);
-        LiveData<FutureData<List<MediaItemMetadata>>> mediaItems = ifThenElse(mShowSearchResults,
-                mMediaBrowserViewModel.getSearchedMediaItems(),
-                mMediaBrowserViewModel.getBrowsedMediaItems());
+        mUxrContentLimiter = new LifeCycleObserverUxrContentLimiter(
+                new UxrContentLimiterImpl(activity, R.xml.uxr_config));
+        mUxrContentLimiter.setAdapter(mLimitedBrowseAdapter);
+        activity.getLifecycle().addObserver(mUxrContentLimiter);
 
-        mediaItems.observe(activity, futureData -> onItemsUpdate(/* forRoot */ false, futureData));
+        browseAdapter.setRootBrowsableViewType(rootBrowsableHint);
+        browseAdapter.setRootPlayableViewType(rootPlayableHint);
 
-        updateAppBar();
+        mMediaItems.observe(activity, mItemsObserver);
     }
 
-    private AppBarView.AppBarListener mAppBarListener = new BasicAppBarListener() {
-        @Override
-        public void onTabSelected(MediaItemMetadata item) {
-            if (mAcceptTabSelection) {
-                showTopItem(item);
+    public MediaItemMetadata getParentItem() {
+        return mParentItem;
+    }
+
+    /** Shares the browse adapter with the given view... #local-hack. */
+    public void shareBrowseAdapterWith(RecyclerView view) {
+        view.setAdapter(mLimitedBrowseAdapter);
+    }
+
+    private final Observer<FutureData<List<MediaItemMetadata>>> mItemsObserver =
+            this::onItemsUpdate;
+
+    View getContent() {
+        return mContent;
+    }
+
+    String getDebugInfo() {
+        StringBuilder log = new StringBuilder();
+        log.append("[");
+        log.append((mParentItem != null) ? mParentItem.getTitle() : "Root");
+        log.append("]");
+        FutureData<List<MediaItemMetadata>> children = mMediaItems.getValue();
+        if (children == null) {
+            log.append(" null future data");
+        } else if (children.isLoading()) {
+            log.append(" loading");
+        } else if (children.getData() == null) {
+            log.append(" null list");
+        } else {
+            List<MediaItemMetadata> nodes = children.getData();
+            log.append(" ");
+            log.append(nodes.size());
+            log.append(" {");
+            if (nodes.size() > 0) {
+                log.append(nodes.get(0).getTitle().toString());
             }
-        }
-
-        @Override
-        public void onBack() {
-            onBackPressed();
-        }
-
-        @Override
-        public void onSearchSelection() {
-            if (mIsSearchController) {
-                reopenSearch();
-            } else {
-                mCallbacks.changeMode(MediaActivity.Mode.SEARCHING);
+            if (nodes.size() > 1) {
+                log.append(", ");
+                log.append(nodes.get(1).getTitle().toString());
             }
-        }
-
-        @Override
-        public void onHeightChanged(int height) {
-            onAppBarHeightChanged(height);
-        }
-
-        @Override
-        public void onSearch(String query) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "onSearch: " + query);
+            if (nodes.size() > 2) {
+                log.append(", ...");
             }
-            mViewModel.setSearchQuery(query);
-            updateSearchQuery(query);
+            log.append(" }");
         }
-    };
+        return log.toString();
+    }
 
+    void destroy() {
+        mCallbacks.getActivity().getLifecycle().removeObserver(mUxrContentLimiter);
+        mMediaItems.removeObserver(mItemsObserver);
+        removeFromParent(mContent);
+    }
 
     private Runnable mLoadingIndicatorRunnable = new Runnable() {
         @Override
@@ -343,19 +266,6 @@
         }
     };
 
-    boolean onBackPressed() {
-        boolean success = navigateBack();
-        if (!success && (mIsSearchController)) {
-            mCallbacks.changeMode(MediaActivity.Mode.BROWSING);
-            return true;
-        }
-        return success;
-    }
-
-    boolean browseTreeHasChildren() {
-        return mBrowseTreeHasChildren;
-    }
-
     private void startLoadingIndicator() {
         // Display the indicator after a certain time, to avoid flashing the indicator constantly,
         // even when performance is acceptable.
@@ -367,52 +277,36 @@
         ViewUtils.hideViewAnimated(mMessage, mFadeDuration);
     }
 
-    private void navigateInto(@Nullable MediaItemMetadata item) {
-        if (item != null) {
-            mBrowseStack.push(item);
-            mMediaBrowserViewModel.setCurrentBrowseId(item.getId());
-        } else {
-            mMediaBrowserViewModel.setCurrentBrowseId(null);
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        int leftPadding = mBrowseList.getPaddingLeft();
+        int rightPadding = mBrowseList.getPaddingRight();
+        int bottomPadding = mBrowseList.getPaddingBottom();
+        mBrowseList.setPadding(leftPadding, insets.getTop(), rightPadding, bottomPadding);
+        if (bottomPadding > mFocusAreaHighlightBottomPadding) {
+            mFocusAreaHighlightBottomPadding = bottomPadding;
         }
-
-        mShowSearchResults.setValue(false);
-        updateAppBar();
-    }
-
-    /**
-     * @return the current item being displayed
-     */
-    @Nullable
-    private MediaItemMetadata getCurrentMediaItem() {
-        return mBrowseStack.isEmpty() ? null : mBrowseStack.lastElement();
-    }
-
-    @Nullable
-    private String getCurrentMediaItemId() {
-        MediaItemMetadata currentItem = getCurrentMediaItem();
-        return currentItem != null ? currentItem.getId() : null;
-    }
-
-    private void onAppBarHeightChanged(int height) {
-        if (mBrowseList == null) {
-            return;
-        }
-
-        mBrowseList.setPadding(mBrowseList.getPaddingLeft(), height,
-                mBrowseList.getPaddingRight(), mBrowseList.getPaddingBottom());
+        mFocusArea.setHighlightPadding(
+                leftPadding, insets.getTop(), rightPadding, mFocusAreaHighlightBottomPadding);
+        mFocusArea.setBoundsOffset(leftPadding, insets.getTop(), rightPadding, bottomPadding);
     }
 
     void onPlaybackControlsChanged(boolean visible) {
-        if (mBrowseList == null) {
-            return;
-        }
-
+        int leftPadding = mBrowseList.getPaddingLeft();
+        int topPadding = mBrowseList.getPaddingTop();
+        int rightPadding = mBrowseList.getPaddingRight();
         Resources res = getActivity().getResources();
         int bottomPadding = visible
-                ? res.getDimensionPixelOffset(R.dimen.browse_fragment_bottom_padding)
-                : 0;
-        mBrowseList.setPadding(mBrowseList.getPaddingLeft(), mBrowseList.getPaddingTop(),
-                mBrowseList.getPaddingRight(), bottomPadding);
+                ? res.getDimensionPixelOffset(R.dimen.browse_fragment_bottom_padding) : 0;
+        mBrowseList.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
+        int highlightBottomPadding = mSetFocusAreaHighlightBottom ? bottomPadding : 0;
+        if (highlightBottomPadding > mFocusAreaHighlightBottomPadding) {
+            mFocusAreaHighlightBottomPadding = highlightBottomPadding;
+        }
+        mFocusArea.setHighlightPadding(
+                leftPadding, topPadding, rightPadding, mFocusAreaHighlightBottomPadding);
+        // Set the bottom offset to bottomPadding regardless of mSetFocusAreaHighlightBottom so that
+        // RotaryService can find the correct target when the user nudges the rotary controller.
+        mFocusArea.setBoundsOffset(leftPadding, topPadding, rightPadding, bottomPadding);
 
         ViewGroup.MarginLayoutParams messageLayout =
                 (ViewGroup.MarginLayoutParams) mMessage.getLayoutParams();
@@ -420,102 +314,9 @@
         mMessage.setLayoutParams(messageLayout);
     }
 
-    private void hideKeyboard() {
-        InputMethodManager in =
-                (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
-        in.hideSoftInputFromWindow(mContent.getWindowToken(), 0);
-    }
-
-    private void showTopItem(@Nullable MediaItemMetadata item) {
-        mViewModel.getBrowseStack().clear();
-        navigateInto(item);
-    }
-
-    /**
-     * Updates the tabs displayed on the app bar, based on the top level items on the browse tree.
-     * If there is at least one browsable item, we show the browse content of that node. If there
-     * are only playable items, then we show those items. If there are not items at all, we show the
-     * empty message. If we receive null, we show the error message.
-     *
-     * @param items top level items, null if the items are still being loaded, or empty list if
-     *              items couldn't be loaded.
-     */
-    private void updateTabs(@Nullable List<MediaItemMetadata> items) {
-        if (Objects.equals(mTopItems, items)) {
-            // When coming back to the app, the live data sends an update even if the list hasn't
-            // changed. Updating the tabs then recreates the browse view, which produces jank
-            // (b/131830876), and also resets the navigation to the top of the first tab...
-            return;
-        }
-        mTopItems = items;
-
-        if (mTopItems == null || mTopItems.isEmpty()) {
-            mAppBarView.setItems(null);
-            mAppBarView.setActiveItem(null);
-            if (items != null) {
-                // Only do this when not loading the tabs or we loose the saved one.
-                showTopItem(null);
-            }
-            updateAppBar();
-            return;
-        }
-
-        MediaItemMetadata oldTab = mViewModel.getSelectedTab();
-        try {
-            mAcceptTabSelection = false;
-            mAppBarView.setItems(mTopItems.size() == 1 ? null : mTopItems);
-            updateAppBar();
-
-            if (items.contains(oldTab)) {
-                mAppBarView.setActiveItem(oldTab);
-            } else {
-                showTopItem(items.get(0));
-            }
-        }  finally {
-            mAcceptTabSelection = true;
-        }
-    }
-
-    private void updateAppBarTitle() {
-        boolean isStacked = !isAtTopStack();
-
-        final CharSequence title;
-        if (isStacked) {
-            // If not at top level, show the current item as title
-            title = getCurrentMediaItem().getTitle();
-        } else if (mTopItems == null) {
-            // If still loading the tabs, force to show an empty bar.
-            title = "";
-        } else if (mTopItems.size() == 1) {
-            // If we finished loading tabs and there is only one, use that as title.
-            title = mTopItems.get(0).getTitle();
-        } else {
-            // Otherwise (no tabs or more than 1 tabs), show the current media source title.
-            MediaSource mediaSource = mMediaSourceVM.getPrimaryMediaSource().getValue();
-            title = getAppBarDefaultTitle(mediaSource);
-        }
-
-        mAppBarView.setTitle(title);
-    }
-
-    /**
-     * Update elements of the appbar that change depending on where we are in the browse.
-     */
-    private void updateAppBar() {
-        boolean isStacked = !isAtTopStack();
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "App bar is in stacked state: " + isStacked);
-        }
-        Toolbar.State unstackedState =
-                mIsSearchController ? Toolbar.State.SEARCH : Toolbar.State.HOME;
-        updateAppBarTitle();
-        mAppBarView.setState(isStacked ? Toolbar.State.SUBPAGE : unstackedState);
-        mAppBarView.showSearchIfSupported(!mIsSearchController || isStacked);
-    }
-
-    private String getErrorMessage(boolean forRoot) {
-        if (forRoot) {
-            MediaSource mediaSource = mMediaSourceVM.getPrimaryMediaSource().getValue();
+    private String getErrorMessage() {
+        if (/*root*/ !mDisplayMediaItems) {
+            MediaSource mediaSource = mViewModel.getMediaSourceValue();
             return getActivity().getString(
                     R.string.cannot_connect_to_app,
                     mediaSource != null
@@ -527,68 +328,40 @@
         }
     }
 
-    /**
-     * Filters the items that are valid for the root (tabs) or the current node. Returns null when
-     * the given list is null to preserve its error signal.
-     */
-    @Nullable
-    private List<MediaItemMetadata> filterItems(boolean forRoot,
-            @Nullable List<MediaItemMetadata> items) {
-        if (items == null) return null;
-        Predicate<MediaItemMetadata> predicate = forRoot ? MediaItemMetadata::isBrowsable
-                : item -> (item.isPlayable() || item.isBrowsable());
-        return items.stream().filter(predicate).collect(Collectors.toList());
-    }
-
-    private void onItemsUpdate(boolean forRoot, FutureData<List<MediaItemMetadata>> futureData) {
-
-        // Prevent showing loading spinner or any error messages if search is uninitialized
-        if (mIsSearchController && TextUtils.isEmpty(mSearchQuery)) {
-            return;
-        }
-
-        if (!forRoot && !mBrowseTreeHasChildren && !mIsSearchController) {
-            // Ignore live data ghost values
-            return;
-        }
-
-        if (futureData.isLoading()) {
-            startLoadingIndicator();
+    private void onItemsUpdate(@Nullable FutureData<List<MediaItemMetadata>> futureData) {
+        if (futureData == null || futureData.isLoading()) {
             ViewUtils.hideViewAnimated(mErrorIcon, 0);
             ViewUtils.hideViewAnimated(mMessage, 0);
+
             // TODO(b/139759881) build a jank-free animation of the transition.
             mBrowseList.setAlpha(0f);
-            mBrowseAdapter.submitItems(null, null);
+            mLimitedBrowseAdapter.submitItems(null, null);
 
-            if (forRoot) {
-                if (Log.isLoggable(TAG, Log.INFO)) {
-                    Log.i(TAG, "Loading browse tree...");
-                }
-                mBrowseTreeHasChildren = false;
-                updateTabs(null);
+            if (futureData != null) {
+                startLoadingIndicator();
             }
             return;
         }
 
         stopLoadingIndicator();
 
-        List<MediaItemMetadata> items = filterItems(forRoot, futureData.getData());
-        if (forRoot) {
-            boolean browseTreeHasChildren = items != null && !items.isEmpty();
-            if (Log.isLoggable(TAG, Log.INFO)) {
-                Log.i(TAG, "Browse tree loaded, status (has children or not) changed: "
-                        + mBrowseTreeHasChildren + " -> " + browseTreeHasChildren);
+        List<MediaItemMetadata> items = MediaBrowserViewModelImpl.filterItems(
+                /*root*/ !mDisplayMediaItems, futureData.getData());
+        if (mDisplayMediaItems) {
+            mLimitedBrowseAdapter.submitItems(mParentItem, items);
+
+            List<MediaItemMetadata> lastNodes =
+                    MediaBrowserViewModelImpl.selectBrowseableItems(futureData.getPastData());
+            Collection<MediaItemMetadata> removedNodes =
+                    MediaBrowserViewModelImpl.computeRemovedItems(lastNodes, items);
+            if (!removedNodes.isEmpty()) {
+                mCallbacks.onChildrenNodesRemoved(this, removedNodes);
             }
-            mBrowseTreeHasChildren = browseTreeHasChildren;
-            mCallbacks.onRootLoaded();
-            updateTabs(items != null ? items : new ArrayList<>());
-        } else {
-            mBrowseAdapter.submitItems(getCurrentMediaItem(), items);
         }
 
-        int duration = forRoot ? 0 : mFadeDuration;
+        int duration = mFadeDuration;
         if (items == null) {
-            mMessage.setText(getErrorMessage(forRoot));
+            mMessage.setText(getErrorMessage());
             ViewUtils.hideViewAnimated(mBrowseList, duration);
             ViewUtils.showViewAnimated(mMessage, duration);
             ViewUtils.showViewAnimated(mErrorIcon, duration);
@@ -597,10 +370,14 @@
             ViewUtils.hideViewAnimated(mBrowseList, duration);
             ViewUtils.hideViewAnimated(mErrorIcon, duration);
             ViewUtils.showViewAnimated(mMessage, duration);
-        } else if (!forRoot) {
+        } else {
             ViewUtils.showViewAnimated(mBrowseList, duration);
             ViewUtils.hideViewAnimated(mErrorIcon, duration);
             ViewUtils.hideViewAnimated(mMessage, duration);
         }
+
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "onItemsUpdate " + getDebugInfo());
+        }
     }
 }
diff --git a/src/com/android/car/media/ErrorScreenController.java b/src/com/android/car/media/ErrorScreenController.java
new file mode 100644
index 0000000..bd62f81
--- /dev/null
+++ b/src/com/android/car/media/ErrorScreenController.java
@@ -0,0 +1,41 @@
+package com.android.car.media;
+
+import android.app.PendingIntent;
+import android.car.content.pm.CarPackageManager;
+import android.view.ViewGroup;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.car.media.common.PlaybackErrorViewController;
+import com.android.car.media.common.source.MediaSource;
+
+/**
+ * A view controller that displays the playback state error iif there is no browse tree.
+ */
+public class ErrorScreenController extends ViewControllerBase {
+
+    private final PlaybackErrorViewController mPlaybackErrorViewController;
+
+    ErrorScreenController(FragmentActivity activity,
+            CarPackageManager carPackageManager, ViewGroup container) {
+        super(activity, carPackageManager, container, R.layout.fragment_error);
+
+        mPlaybackErrorViewController = new PlaybackErrorViewController(mContent);
+    }
+
+    @Override
+    void onMediaSourceChanged(@Nullable MediaSource mediaSource) {
+        super.onMediaSourceChanged(mediaSource);
+
+        mAppBarController.setListener(new BasicAppBarListener());
+        mAppBarController.setTitle(getAppBarDefaultTitle(mediaSource));
+
+        mPlaybackErrorViewController.hideErrorNoAnim();
+    }
+
+    public void setError(String message, String label, PendingIntent pendingIntent,
+            boolean distractionOptimized) {
+        mPlaybackErrorViewController.setError(message, label, pendingIntent, distractionOptimized);
+    }
+}
diff --git a/src/com/android/car/media/ErrorViewController.java b/src/com/android/car/media/ErrorViewController.java
deleted file mode 100644
index e455092..0000000
--- a/src/com/android/car/media/ErrorViewController.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.android.car.media;
-
-import android.app.PendingIntent;
-import android.car.content.pm.CarPackageManager;
-import android.car.drivingstate.CarUxRestrictions;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.car.apps.common.UxrButton;
-import com.android.car.apps.common.UxrTextView;
-import com.android.car.apps.common.util.ViewUtils;
-import com.android.car.media.common.source.MediaSource;
-
-/**
- * A view controller that displays the playback state error iif there is no browse tree.
- */
-public class ErrorViewController extends ViewControllerBase {
-    private final String TAG = "ErrorViewController";
-
-    // mErrorMessageView is defined explicitly as a UxrTextView instead of a TextView to
-    // provide clarity as it may be misleading to assume that mErrorMessageView extends all TextView
-    // methods. In addition, it increases discoverability of runtime issues that may occur.
-    private final UxrTextView mErrorMessageView;
-    private final UxrButton mErrorButton;
-
-
-    ErrorViewController(FragmentActivity activity,
-            CarPackageManager carPackageManager, ViewGroup container) {
-        super(activity, carPackageManager, container, R.layout.fragment_error);
-
-        mErrorMessageView = mContent.findViewById(R.id.error_message);
-        mErrorButton = mContent.findViewById(R.id.error_button);
-    }
-
-    @Override
-    void onMediaSourceChanged(@Nullable MediaSource mediaSource) {
-        super.onMediaSourceChanged(mediaSource);
-
-        mAppBarView.setListener(new BasicAppBarListener());
-        mAppBarView.setTitle(getAppBarDefaultTitle(mediaSource));
-
-        ViewUtils.hideViewAnimated(mErrorMessageView, 0);
-        ViewUtils.hideViewAnimated(mErrorButton, 0);
-    }
-
-    public void setError(String message, String label, PendingIntent pendingIntent,
-            boolean isDistractionOptimized) {
-        mErrorMessageView.setText(message);
-
-        // Only show the error button if the error is actionable.
-        if (label != null && pendingIntent != null) {
-            mErrorButton.setText(label);
-
-            mErrorButton.setUxRestrictions(isDistractionOptimized
-                    ? CarUxRestrictions.UX_RESTRICTIONS_BASELINE
-                    : CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP);
-
-            mErrorButton.setOnClickListener(v -> {
-                try {
-                    pendingIntent.send();
-                } catch (PendingIntent.CanceledException e) {
-                    if (Log.isLoggable(TAG, Log.ERROR)) {
-                        Log.e(TAG, "Pending intent canceled");
-                    }
-                }
-            });
-            mErrorButton.setVisibility(View.VISIBLE);
-        } else {
-            mErrorButton.setVisibility(View.GONE);
-        }
-
-        ViewUtils.showViewAnimated(mErrorMessageView, mFadeDuration);
-        ViewUtils.showViewAnimated(mErrorButton, mFadeDuration);
-    }
-}
diff --git a/src/com/android/car/media/GuidelinesUpdater.java b/src/com/android/car/media/GuidelinesUpdater.java
new file mode 100644
index 0000000..e12ba84
--- /dev/null
+++ b/src/com/android/car/media/GuidelinesUpdater.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.media;
+
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Applies the insets computed by the car-ui-lib to the spacer views in ui_guides.xml. This allows
+ * the Media app to have different instances of the application bar.
+ */
+class GuidelinesUpdater implements InsetsChangedListener {
+
+    private final View mGuidedView;
+    private final Set<InsetsChangedListener> mListeners = new HashSet<>();
+
+    public GuidelinesUpdater(View guidedView) {
+        mGuidedView = guidedView;
+    }
+
+    public void addListener(InsetsChangedListener listener) {
+        mListeners.add(listener);
+    }
+
+    // Read the results of the base layout measurements and adjust the guidelines to match
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        View startPad = mGuidedView.findViewById(R.id.ui_content_start_guideline);
+        ConstraintLayout.LayoutParams start =
+                (ConstraintLayout.LayoutParams)startPad.getLayoutParams();
+        start.setMargins(insets.getLeft(), 0,0, 0);
+        startPad.setLayoutParams(start);
+
+        View endPad = mGuidedView.findViewById(R.id.ui_content_end_guideline);
+        ConstraintLayout.LayoutParams end = (ConstraintLayout.LayoutParams)endPad.getLayoutParams();
+        end.setMargins(0, 0, insets.getRight(), 0);
+        endPad.setLayoutParams(end);
+
+        View topPad = mGuidedView.findViewById(R.id.ui_content_top_guideline);
+        ConstraintLayout.LayoutParams top = (ConstraintLayout.LayoutParams)topPad.getLayoutParams();
+        top.setMargins(0, insets.getTop(), 0, 0);
+        topPad.setLayoutParams(top);
+
+        View bottomPad = mGuidedView.findViewById(R.id.ui_content_bottom_guideline);
+        ConstraintLayout.LayoutParams bottom =
+                (ConstraintLayout.LayoutParams)bottomPad.getLayoutParams();
+        bottom.setMargins(0, 0, 0, insets.getBottom());
+        bottomPad.setLayoutParams(bottom);
+
+        for (InsetsChangedListener listener : mListeners) {
+            listener.onCarUiInsetsChanged(insets);
+        }
+    }
+}
diff --git a/src/com/android/car/media/MediaActivity.java b/src/com/android/car/media/MediaActivity.java
index 36586d2..21f6d46 100644
--- a/src/com/android/car/media/MediaActivity.java
+++ b/src/com/android/car/media/MediaActivity.java
@@ -18,6 +18,7 @@
 import static android.car.media.CarMediaManager.MEDIA_SOURCE_MODE_BROWSE;
 
 import static com.android.car.apps.common.util.VectorMath.EPSILON;
+import static com.android.car.arch.common.LiveDataFunctions.dataOf;
 
 import android.annotation.SuppressLint;
 import android.app.AlertDialog;
@@ -26,12 +27,10 @@
 import android.car.Car;
 import android.car.content.pm.CarPackageManager;
 import android.car.drivingstate.CarUxRestrictions;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Bundle;
-import android.support.v4.media.session.PlaybackStateCompat;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Size;
@@ -51,28 +50,29 @@
 import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.ViewModelProviders;
 
-import com.android.car.apps.common.util.VectorMath;
 import com.android.car.apps.common.util.CarPackageManagerUtils;
+import com.android.car.apps.common.util.VectorMath;
 import com.android.car.apps.common.util.ViewUtils;
-import com.android.car.media.common.MediaConstants;
+import com.android.car.arch.common.FutureData;
 import com.android.car.media.common.MediaItemMetadata;
 import com.android.car.media.common.MinimizedPlaybackControlBar;
+import com.android.car.media.common.PlaybackErrorsHelper;
+import com.android.car.media.common.browse.MediaItemsRepository;
 import com.android.car.media.common.playback.PlaybackViewModel;
 import com.android.car.media.common.source.MediaSource;
-import com.android.car.media.common.source.MediaSourceViewModel;
 import com.android.car.ui.AlertDialogBuilder;
 import com.android.car.ui.utils.CarUxRestrictionsUtil;
 
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Stack;
 
 /**
  * This activity controls the UI of media. It also updates the connection status for the media app
  * by broadcast.
  */
-public class MediaActivity extends FragmentActivity implements BrowseViewController.Callbacks {
+public class MediaActivity extends FragmentActivity implements MediaActivityController.Callbacks {
     private static final String TAG = "MediaActivity";
 
     /** Configuration (controlled from resources) */
@@ -82,16 +82,13 @@
     private PlaybackViewModel.PlaybackController mPlaybackController;
 
     /** Layout views */
-    private View mRootView;
     private PlaybackFragment mPlaybackFragment;
-    private BrowseViewController mSearchController;
-    private BrowseViewController mBrowseController;
+    private MediaActivityController mMediaActivityController;
     private MinimizedPlaybackControlBar mMiniPlaybackControls;
     private ViewGroup mBrowseContainer;
     private ViewGroup mPlaybackContainer;
     private ViewGroup mErrorContainer;
-    private ErrorViewController mErrorController;
-    private ViewGroup mSearchContainer;
+    private ErrorScreenController mErrorController;
 
     private Toast mToast;
     private AlertDialog mDialog;
@@ -121,42 +118,18 @@
 
     /**
      * Possible modes of the application UI
+     * Todo: refactor into non exclusive flags to allow concurrent modes (eg: play details & browse)
+     * (b/179292793).
      */
     enum Mode {
-        /** The user is browsing a media source */
+        /** The user is browsing or searching a media source */
         BROWSING,
         /** The user is interacting with the full screen playback UI */
         PLAYBACK,
-        /** The user is searching within a media source */
-        SEARCHING,
         /** There's no browse tree and playback doesn't work. */
         FATAL_ERROR
     }
 
-    private static final Map<Integer, Integer> ERROR_CODE_MESSAGES_MAP;
-
-    static {
-        Map<Integer, Integer> map = new HashMap<>();
-        map.put(PlaybackStateCompat.ERROR_CODE_APP_ERROR, R.string.error_code_app_error);
-        map.put(PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED, R.string.error_code_not_supported);
-        map.put(PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
-                R.string.error_code_authentication_expired);
-        map.put(PlaybackStateCompat.ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED,
-                R.string.error_code_premium_account_required);
-        map.put(PlaybackStateCompat.ERROR_CODE_CONCURRENT_STREAM_LIMIT,
-                R.string.error_code_concurrent_stream_limit);
-        map.put(PlaybackStateCompat.ERROR_CODE_PARENTAL_CONTROL_RESTRICTED,
-                R.string.error_code_parental_control_restricted);
-        map.put(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION,
-                R.string.error_code_not_available_in_region);
-        map.put(PlaybackStateCompat.ERROR_CODE_CONTENT_ALREADY_PLAYING,
-                R.string.error_code_content_already_playing);
-        map.put(PlaybackStateCompat.ERROR_CODE_SKIP_LIMIT_REACHED,
-                R.string.error_code_skip_limit_reached);
-        map.put(PlaybackStateCompat.ERROR_CODE_ACTION_ABORTED, R.string.error_code_action_aborted);
-        map.put(PlaybackStateCompat.ERROR_CODE_END_OF_QUEUE, R.string.error_code_end_of_queue);
-        ERROR_CODE_MESSAGES_MAP = Collections.unmodifiableMap(map);
-    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -168,8 +141,6 @@
         mCloseVectorY = res.getFloat(R.dimen.media_activity_close_vector_y);
         mCloseVectorNorm = VectorMath.norm2(mCloseVectorX, mCloseVectorY);
 
-
-        MediaSourceViewModel mediaSourceViewModel = getMediaSourceViewModel();
         // TODO(b/151174811): Use appropriate modes, instead of just MEDIA_SOURCE_MODE_BROWSE
         PlaybackViewModel playbackViewModel = getPlaybackViewModel();
         ViewModel localViewModel = getInnerViewModel();
@@ -182,10 +153,7 @@
         }
         mMode = localViewModel.getSavedMode();
 
-        mRootView = findViewById(R.id.media_activity_root);
-
-        mediaSourceViewModel.getPrimaryMediaSource().observe(this,
-                this::onMediaSourceChanged);
+        localViewModel.getBrowsedMediaSource().observe(this, this::onMediaSourceChanged);
 
         mPlaybackFragment = new PlaybackFragment();
         mPlaybackFragment.setListener(mPlaybackFragmentListener);
@@ -200,15 +168,12 @@
         mBrowseContainer = findViewById(R.id.fragment_container);
         mErrorContainer = findViewById(R.id.error_container);
         mPlaybackContainer = findViewById(R.id.playback_container);
-        mSearchContainer = findViewById(R.id.search_container);
         getSupportFragmentManager().beginTransaction()
                 .replace(R.id.playback_container, mPlaybackFragment)
                 .commit();
 
-        mBrowseController = BrowseViewController.newInstance(this,
+        mMediaActivityController = new MediaActivityController(this, getMediaItemsRepository(),
                 mCarPackageManager, mBrowseContainer);
-        mSearchController = BrowseViewController.newSearchInstance(this,
-                mCarPackageManager, mSearchContainer);
 
         playbackViewModel.getPlaybackController().observe(this,
                 playbackController -> {
@@ -227,17 +192,13 @@
         mCarUxRestrictionsUtil.register(mListener);
 
         mPlaybackContainer.setOnTouchListener(new ClosePlaybackDetector(this));
-
-        localViewModel.getMiniControlsVisible().observe(this, visible -> {
-            mBrowseController.onPlaybackControlsChanged(visible);
-            mSearchController.onPlaybackControlsChanged(visible);
-        });
     }
 
     @Override
     protected void onDestroy() {
         mCarUxRestrictionsUtil.unregister(mListener);
         mCar.disconnect();
+        mMediaActivityController.onDestroy();
         super.onDestroy();
     }
 
@@ -247,97 +208,62 @@
 
     private void handlePlaybackState(PlaybackViewModel.PlaybackStateWrapper state,
             boolean ignoreSameState) {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG,
-                    "handlePlaybackState(); state change: " + (mCurrentPlaybackStateWrapper != null
-                            ? mCurrentPlaybackStateWrapper.getState() : null) + " -> " + (
-                            state != null ? state.getState() : null));
-
-        }
-
-        // TODO(arnaudberry) rethink interactions between customized layouts and dynamic visibility.
-        mCanShowMiniPlaybackControls = (state != null) && state.shouldDisplay();
-        updateMiniPlaybackControls(true);
-
-        if (state == null) {
-            mCurrentPlaybackStateWrapper = null;
-            return;
-        }
-
-        String displayedMessage = getDisplayedMessage(state);
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Displayed error message: [" + displayedMessage + "]");
-        }
-        if (ignoreSameState && mCurrentPlaybackStateWrapper != null
-                && mCurrentPlaybackStateWrapper.getState() == state.getState()
-                && TextUtils.equals(displayedMessage,
-                getDisplayedMessage(mCurrentPlaybackStateWrapper))) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Ignore same playback state.");
-            }
-            return;
-        }
-
-        mCurrentPlaybackStateWrapper = state;
-
-        maybeCancelToast();
-        maybeCancelDialog();
-
-        Bundle extras = state.getExtras();
-        PendingIntent intent = extras == null ? null : extras.getParcelable(
-                MediaConstants.ERROR_RESOLUTION_ACTION_INTENT);
-        String label = extras == null ? null : extras.getString(
-                MediaConstants.ERROR_RESOLUTION_ACTION_LABEL);
-
-        boolean isFatalError = false;
-        if (!TextUtils.isEmpty(displayedMessage)) {
-            if (mBrowseController.browseTreeHasChildren()) {
-                if (intent != null && !isUxRestricted()) {
-                    showDialog(intent, displayedMessage, label, getString(android.R.string.cancel));
-                } else {
-                    showToast(displayedMessage);
-                }
-            } else {
-                getErrorController().setError(displayedMessage, label, intent,
-                        CarPackageManagerUtils.isDistractionOptimized(mCarPackageManager, intent));
-                isFatalError = true;
-            }
-        }
-        if (isFatalError) {
-            changeMode(Mode.FATAL_ERROR);
-        } else if (mMode == Mode.FATAL_ERROR) {
-            changeMode(Mode.BROWSING);
-        }
+        mErrorsHelper.handlePlaybackState(TAG, state, ignoreSameState);
     }
 
-    private ErrorViewController getErrorController() {
+    private final PlaybackErrorsHelper mErrorsHelper = new PlaybackErrorsHelper(this) {
+
+        @Override
+        public void handlePlaybackState(@NonNull String tag,
+                PlaybackViewModel.PlaybackStateWrapper state, boolean ignoreSameState) {
+
+            // TODO rethink interactions between customized layouts and dynamic visibility.
+            mCanShowMiniPlaybackControls = (state != null) && state.shouldDisplay();
+            updateMiniPlaybackControls(true);
+            super.handlePlaybackState(tag, state, ignoreSameState);
+        }
+
+        @Override
+        public void handleNewPlaybackState(String displayedMessage, PendingIntent intent,
+                String label) {
+            maybeCancelToast();
+            maybeCancelDialog();
+
+            boolean isFatalError = false;
+            if (!TextUtils.isEmpty(displayedMessage)) {
+                if (mMediaActivityController.browseTreeHasChildren()) {
+                    if (intent != null && !isUxRestricted()) {
+                        showDialog(intent, displayedMessage, label,
+                                getString(android.R.string.cancel));
+                    } else {
+                        showToast(displayedMessage);
+                    }
+                } else {
+                    boolean isDistractionOptimized =
+                            intent != null && CarPackageManagerUtils.isDistractionOptimized(
+                                    mCarPackageManager, intent);
+                    getErrorController().setError(displayedMessage, label, intent,
+                            isDistractionOptimized);
+                    isFatalError = true;
+                }
+            }
+            if (isFatalError) {
+                changeMode(MediaActivity.Mode.FATAL_ERROR);
+            } else if (mMode == MediaActivity.Mode.FATAL_ERROR) {
+                changeMode(MediaActivity.Mode.BROWSING);
+            }
+        }
+    };
+
+    private ErrorScreenController getErrorController() {
         if (mErrorController == null) {
-            mErrorController = new ErrorViewController(this, mCarPackageManager, mErrorContainer);
-            MediaSource mediaSource = getMediaSourceViewModel().getPrimaryMediaSource().getValue();
+            mErrorController = new ErrorScreenController(this, mCarPackageManager, mErrorContainer);
+            MediaSource mediaSource = getInnerViewModel().getMediaSourceValue();
             mErrorController.onMediaSourceChanged(mediaSource);
         }
         return mErrorController;
     }
 
-    private String getDisplayedMessage(@Nullable PlaybackViewModel.PlaybackStateWrapper state) {
-        if (state == null) {
-            return null;
-        }
-        if (!TextUtils.isEmpty(state.getErrorMessage())) {
-            return state.getErrorMessage().toString();
-        }
-        // ERROR_CODE_UNKNOWN_ERROR means there is no error in PlaybackState.
-        if (state.getErrorCode() != PlaybackStateCompat.ERROR_CODE_UNKNOWN_ERROR) {
-            Integer messageId = ERROR_CODE_MESSAGES_MAP.get(state.getErrorCode());
-            return messageId != null ? getString(messageId) : getString(
-                    R.string.default_error_message);
-        }
-        if (state.getState() == PlaybackStateCompat.STATE_ERROR) {
-            return getString(R.string.default_error_message);
-        }
-        return null;
-    }
-
     private void showDialog(PendingIntent intent, String message, String positiveBtnText,
             String negativeButtonText) {
         AlertDialogBuilder dialog = new AlertDialogBuilder(this);
@@ -380,11 +306,8 @@
             case PLAYBACK:
                 changeMode(Mode.BROWSING);
                 break;
-            case SEARCHING:
-                mSearchController.onBackPressed();
-                break;
             case BROWSING:
-                boolean handled = mBrowseController.onBackPressed();
+                boolean handled = mMediaActivityController.onBackPressed();
                 if (handled) return;
                 // Fall through.
             case FATAL_ERROR:
@@ -396,41 +319,46 @@
     /**
      * Sets the media source being browsed.
      *
-     * @param mediaSource the new media source we are going to try to browse
+     * @param futureSource contains the new media source we are going to try to browse, as well as
+     *                     the old one (either could be null).
      */
-    private void onMediaSourceChanged(@Nullable MediaSource mediaSource) {
-        ComponentName savedMediaSource = getInnerViewModel().getSavedMediaSource();
-        if (Log.isLoggable(TAG, Log.INFO)) {
-            Log.i(TAG, "MediaSource changed from " + savedMediaSource + " to " + mediaSource);
-        }
+    private void onMediaSourceChanged(FutureData<MediaSource> futureSource) {
 
-        savedMediaSource = mediaSource != null ? mediaSource.getBrowseServiceComponentName() : null;
-        getInnerViewModel().saveMediaSource(savedMediaSource);
+        MediaSource newMediaSource = FutureData.getData(futureSource);
+        MediaSource oldMediaSource = FutureData.getPastData(futureSource);
 
-        mBrowseController.onMediaSourceChanged(mediaSource);
-        mSearchController.onMediaSourceChanged(mediaSource);
         if (mErrorController != null) {
-            mErrorController.onMediaSourceChanged(mediaSource);
+            mErrorController.onMediaSourceChanged(newMediaSource);
         }
 
         mCurrentPlaybackStateWrapper = null;
         maybeCancelToast();
         maybeCancelDialog();
-        if (mediaSource != null) {
+        if (newMediaSource != null) {
             if (Log.isLoggable(TAG, Log.INFO)) {
-                Log.i(TAG, "Browsing: " + mediaSource.getDisplayName());
+                Log.i(TAG, "Browsing: " + newMediaSource.getDisplayName());
             }
-            Mode mediaSourceMode = getInnerViewModel().getSavedMode();
-            // Changes the mode regardless of its previous value so that the views can be updated.
-            changeModeInternal(mediaSourceMode, false);
 
-            // Always go through the trampoline activity to keep all the dispatching logic there.
+            if (Objects.equals(oldMediaSource, newMediaSource)) {
+                // The UI is being restored (eg: after a config change) => restore the mode.
+                Mode mediaSourceMode = getInnerViewModel().getSavedMode();
+                changeModeInternal(mediaSourceMode, false);
+            } else {
+                // Change the mode regardless of its previous value to update the views.
+                // The saved mode is ignored as the media apps don't always recreate a playback
+                // state that can be displayed (and some send a displayable state after sending a
+                // non displayable one...).
+                changeModeInternal(Mode.BROWSING, false);
+
+                // Always go through the trampoline activity to keep the dispatching logic there.
+                startActivity(new Intent(Car.CAR_INTENT_ACTION_MEDIA_TEMPLATE));
+            }
+        } else {
             startActivity(new Intent(Car.CAR_INTENT_ACTION_MEDIA_TEMPLATE));
         }
     }
 
-    @Override
-    public void changeMode(Mode mode) {
+    private void changeMode(Mode mode) {
         if (mMode == mode) {
             if (Log.isLoggable(TAG, Log.INFO)) {
                 Log.i(TAG, "Mode " + mMode + " change is ignored");
@@ -458,7 +386,6 @@
                 ViewUtils.showViewAnimated(mErrorContainer, mFadeDuration);
                 ViewUtils.hideViewAnimated(mPlaybackContainer, fadeOutDuration);
                 ViewUtils.hideViewAnimated(mBrowseContainer, fadeOutDuration);
-                ViewUtils.hideViewAnimated(mSearchContainer, fadeOutDuration);
                 break;
             case PLAYBACK:
                 mPlaybackContainer.setX(0);
@@ -467,27 +394,22 @@
                 ViewUtils.hideViewAnimated(mErrorContainer, fadeOutDuration);
                 ViewUtils.showViewAnimated(mPlaybackContainer, mFadeDuration);
                 ViewUtils.hideViewAnimated(mBrowseContainer, fadeOutDuration);
-                ViewUtils.hideViewAnimated(mSearchContainer, fadeOutDuration);
                 break;
             case BROWSING:
                 if (oldMode == Mode.PLAYBACK) {
+                    // When switching from PLAYBACK mode to BROWSING mode, if a CarUiRecyclerView
+                    // shows up and it's in rotary mode, restore focus in the CarUiRecyclerView.
+                    mMediaActivityController.restoreFocusInCurrentNode();
+
                     ViewUtils.hideViewAnimated(mErrorContainer, 0);
                     ViewUtils.showViewAnimated(mBrowseContainer, 0);
-                    ViewUtils.hideViewAnimated(mSearchContainer, 0);
                     animateOutPlaybackContainer(fadeOutDuration);
                 } else {
                     ViewUtils.hideViewAnimated(mErrorContainer, fadeOutDuration);
                     ViewUtils.hideViewAnimated(mPlaybackContainer, fadeOutDuration);
                     ViewUtils.showViewAnimated(mBrowseContainer, mFadeDuration);
-                    ViewUtils.hideViewAnimated(mSearchContainer, fadeOutDuration);
                 }
                 break;
-            case SEARCHING:
-                ViewUtils.hideViewAnimated(mErrorContainer, fadeOutDuration);
-                ViewUtils.hideViewAnimated(mPlaybackContainer, fadeOutDuration);
-                ViewUtils.hideViewAnimated(mBrowseContainer, fadeOutDuration);
-                ViewUtils.showViewAnimated(mSearchContainer, mFadeDuration);
-                break;
         }
     }
 
@@ -535,9 +457,14 @@
         int fadeOutDuration = hideViewAnimated ? mFadeDuration : 0;
         // Minimized control bar should be hidden in playback view.
         final boolean shouldShowMiniPlaybackControls =
-                mCanShowMiniPlaybackControls && mMode != Mode.PLAYBACK;
+                getResources().getBoolean(R.bool.show_mini_playback_controls)
+                        && mCanShowMiniPlaybackControls
+                        && mMode != Mode.PLAYBACK;
         if (shouldShowMiniPlaybackControls) {
-            ViewUtils.showViewAnimated(mMiniPlaybackControls, mFadeDuration);
+            Boolean visible = getInnerViewModel().getMiniControlsVisible().getValue();
+            if (visible != Boolean.TRUE) {
+                ViewUtils.showViewAnimated(mMiniPlaybackControls, mFadeDuration);
+            }
         } else {
             ViewUtils.hideViewAnimated(mMiniPlaybackControls, fadeOutDuration);
         }
@@ -545,14 +472,12 @@
     }
 
     @Override
-    public void onPlayableItemClicked(MediaItemMetadata item) {
+    public void onPlayableItemClicked(@NonNull MediaItemMetadata item) {
         mPlaybackController.playItem(item);
         boolean switchToPlayback = getResources().getBoolean(
                 R.bool.switch_to_playback_view_when_playable_item_is_clicked);
         if (switchToPlayback) {
             changeMode(Mode.PLAYBACK);
-        } else if (mMode == Mode.SEARCHING) {
-            changeMode(Mode.BROWSING);
         }
         setIntent(null);
     }
@@ -568,8 +493,8 @@
         return this;
     }
 
-    private MediaSourceViewModel getMediaSourceViewModel() {
-        return MediaSourceViewModel.get(getApplication(), MEDIA_SOURCE_MODE_BROWSE);
+    private MediaItemsRepository getMediaItemsRepository() {
+        return MediaItemsRepository.get(getApplication(), MEDIA_SOURCE_MODE_BROWSE);
     }
 
     private PlaybackViewModel getPlaybackViewModel() {
@@ -586,14 +511,19 @@
             Mode mMode = Mode.BROWSING;
             Stack<MediaItemMetadata> mBrowseStack = new Stack<>();
             Stack<MediaItemMetadata> mSearchStack = new Stack<>();
+            /** True when the search bar has been opened or when the search results are browsed. */
+            boolean mSearching;
+            /** True iif the list of search results is being shown (implies mIsSearching). */
+            boolean mShowingSearchResults;
             String mSearchQuery;
             boolean mQueueVisible = false;
         }
 
         private boolean mNeedsInitialization = true;
         private PlaybackViewModel mPlaybackViewModel;
-        private ComponentName mMediaSource;
-        private final Map<ComponentName, MediaServiceState> mStates = new HashMap<>();
+        private final MutableLiveData<FutureData<MediaSource>> mBrowsedMediaSource =
+                dataOf(FutureData.newLoadingData());
+        private final Map<MediaSource, MediaServiceState> mStates = new HashMap<>();
         private MutableLiveData<Boolean> mIsMiniControlsVisible = new MutableLiveData<>();
 
         public ViewModel(@NonNull Application application) {
@@ -620,11 +550,17 @@
             return mIsMiniControlsVisible;
         }
 
+        @Nullable
+        MediaSource getMediaSourceValue() {
+            return FutureData.getData(mBrowsedMediaSource.getValue());
+        }
+
         MediaServiceState getSavedState() {
-            MediaServiceState state = mStates.get(mMediaSource);
+            MediaSource source = getMediaSourceValue();
+            MediaServiceState state = mStates.get(source);
             if (state == null) {
                 state = new MediaServiceState();
-                mStates.put(mMediaSource, state);
+                mStates.put(source, state);
             }
             return state;
         }
@@ -651,26 +587,47 @@
             return getSavedState().mQueueVisible;
         }
 
-        void saveMediaSource(ComponentName mediaSource) {
-            mMediaSource = mediaSource;
+        void saveBrowsedMediaSource(MediaSource mediaSource) {
+            MediaSource oldSource = getMediaSourceValue();
+            if (Log.isLoggable(TAG, Log.INFO)) {
+                Log.i(TAG, "MediaSource changed from " + oldSource + " to " + mediaSource);
+            }
+            mBrowsedMediaSource.setValue(FutureData.newLoadedData(oldSource, mediaSource));
         }
 
-        ComponentName getSavedMediaSource() {
-            return mMediaSource;
+        LiveData<FutureData<MediaSource>> getBrowsedMediaSource() {
+            return mBrowsedMediaSource;
         }
 
-        Stack<MediaItemMetadata> getBrowseStack() {
+        @NonNull Stack<MediaItemMetadata> getBrowseStack() {
             return getSavedState().mBrowseStack;
         }
 
-        Stack<MediaItemMetadata> getSearchStack() {
+        @NonNull Stack<MediaItemMetadata> getSearchStack() {
             return getSavedState().mSearchStack;
         }
 
+        /** Returns whether search mode is on (showing search results or browsing them). */
+        boolean isSearching() {
+            return getSavedState().mSearching;
+        }
+
+        boolean isShowingSearchResults() {
+            return getSavedState().mShowingSearchResults;
+        }
+
         String getSearchQuery() {
             return getSavedState().mSearchQuery;
         }
 
+        void setSearching(boolean isSearching) {
+            getSavedState().mSearching = isSearching;
+        }
+
+        void setShowingSearchResults(boolean isShowing) {
+            getSavedState().mShowingSearchResults = isShowing;
+        }
+
         void setSearchQuery(String searchQuery) {
             getSavedState().mSearchQuery = searchQuery;
         }
diff --git a/src/com/android/car/media/MediaActivityController.java b/src/com/android/car/media/MediaActivityController.java
new file mode 100644
index 0000000..9a7d39b
--- /dev/null
+++ b/src/com/android/car/media/MediaActivityController.java
@@ -0,0 +1,679 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.media;
+
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
+
+import static com.android.car.apps.common.util.ViewUtils.showHideViewAnimated;
+import static com.android.car.ui.utils.ViewUtils.LazyLayoutView;
+
+import android.car.content.pm.CarPackageManager;
+import android.content.Context;
+import android.support.v4.media.MediaBrowserCompat;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProviders;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.apps.common.util.ViewUtils;
+import com.android.car.apps.common.util.ViewUtils.ViewAnimEndListener;
+import com.android.car.arch.common.FutureData;
+import com.android.car.media.common.MediaItemMetadata;
+import com.android.car.media.common.browse.MediaBrowserViewModelImpl;
+import com.android.car.media.common.browse.MediaItemsRepository;
+import com.android.car.media.common.browse.MediaItemsRepository.MediaItemsLiveData;
+import com.android.car.media.common.source.MediaBrowserConnector.BrowsingState;
+import com.android.car.media.common.source.MediaSource;
+import com.android.car.media.widgets.AppBarController;
+import com.android.car.ui.FocusParkingView;
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.recyclerview.CarUiRecyclerView;
+import com.android.car.ui.toolbar.Toolbar;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Stack;
+
+/**
+ * Controls the views of the {@link MediaActivity}.
+ * TODO: finish moving control code out of MediaActivity (b/179292809).
+ */
+public class MediaActivityController extends ViewControllerBase {
+
+    private static final String TAG = "MediaActivityCtr";
+
+    private final MediaItemsRepository mMediaItemsRepository;
+    private final Callbacks mCallbacks;
+    private final ViewGroup mBrowseArea;
+    private final FocusParkingView mFpv;
+    private Insets mCarUiInsets;
+    private boolean mPlaybackControlsVisible;
+
+    private final Map<MediaItemMetadata, BrowseViewController> mBrowseViewControllersByNode =
+            new HashMap<>();
+
+    // Controllers that should be destroyed once their view is hidden.
+    private final Map<View, BrowseViewController> mBrowseViewControllersToDestroy = new HashMap<>();
+
+    private final BrowseViewController mRootLoadingController;
+    private final BrowseViewController mSearchResultsController;
+
+    /**
+     * Stores the reference to {@link MediaActivity.ViewModel#getBrowseStack}.
+     * Updated in {@link #onMediaSourceChanged}.
+     */
+    private Stack<MediaItemMetadata> mBrowseStack;
+    /**
+     * Stores the reference to {@link MediaActivity.ViewModel#getSearchStack}.
+     * Updated in {@link #onMediaSourceChanged}.
+     */
+    private Stack<MediaItemMetadata> mSearchStack;
+    private final MediaActivity.ViewModel mViewModel;
+
+    private int mRootBrowsableHint;
+    private int mRootPlayableHint;
+    private boolean mBrowseTreeHasChildren;
+    private boolean mAcceptTabSelection = true;
+
+    /**
+     * Media items to display as tabs. If null, it means we haven't finished loading them yet. If
+     * empty, it means there are no tabs to show
+     */
+    @Nullable
+    private List<MediaItemMetadata> mTopItems;
+
+    private final Observer<BrowsingState> mMediaBrowsingObserver =
+            this::onMediaBrowsingStateChanged;
+
+    /**
+     * Callbacks (implemented by the hosting Activity)
+     */
+    public interface Callbacks {
+
+        /** Invoked when the user clicks on a browsable item. */
+        void onPlayableItemClicked(@NonNull MediaItemMetadata item);
+
+        /** Called once the list of the root node's children has been loaded. */
+        void onRootLoaded();
+
+        /** Returns the activity. */
+        FragmentActivity getActivity();
+    }
+
+    /**
+     * Moves the user one level up in the browse/search tree. Returns whether that was possible.
+     */
+    private boolean navigateBack() {
+        boolean result = false;
+        if (!isAtTopStack()) {
+            hideAndDestroyControllerForItem(getStack().pop());
+
+            // Show the parent (if any)
+            showCurrentNode(true);
+
+            if (isAtTopStack() && mViewModel.isSearching()) {
+                showSearchResults(true);
+            }
+
+            updateAppBar();
+            result = true;
+        }
+        return result;
+    }
+
+    private void reopenSearch() {
+        clearStack(mSearchStack);
+        showSearchResults(true);
+        updateAppBar();
+    }
+
+    private FragmentActivity getActivity() {
+        return mCallbacks.getActivity();
+    }
+
+    /** Returns the browse or search stack. */
+    private Stack<MediaItemMetadata> getStack() {
+        return mViewModel.isSearching() ? mSearchStack : mBrowseStack;
+    }
+
+    /**
+     * @return whether the user is at the top of the browsing stack.
+     */
+    private boolean isAtTopStack() {
+        if (mViewModel.isSearching()) {
+            return mSearchStack.isEmpty();
+        } else {
+            // The mBrowseStack stack includes the tab...
+            return mBrowseStack.size() <= 1;
+        }
+    }
+
+    private void clearMediaSource() {
+        showSearchMode(false);
+        for (BrowseViewController controller : mBrowseViewControllersByNode.values()) {
+            controller.destroy();
+        }
+        mBrowseViewControllersByNode.clear();
+        mBrowseTreeHasChildren = false;
+    }
+
+    private void updateSearchQuery(@Nullable String query) {
+        mMediaItemsRepository.setSearchQuery(query);
+    }
+
+    /**
+     * Clears search state, removes any UI elements from previous results.
+     */
+    @Override
+    void onMediaSourceChanged(@Nullable MediaSource mediaSource) {
+        super.onMediaSourceChanged(mediaSource);
+
+        updateTabs((mediaSource != null) ? null : new ArrayList<>());
+
+        mSearchStack = mViewModel.getSearchStack();
+        mBrowseStack = mViewModel.getBrowseStack();
+
+        updateAppBar();
+    }
+
+    private void onMediaBrowsingStateChanged(BrowsingState newBrowsingState) {
+        switch (newBrowsingState.mConnectionStatus) {
+            case CONNECTING:
+                break;
+            case CONNECTED:
+                MediaBrowserCompat browser = newBrowsingState.mBrowser;
+                mRootBrowsableHint = MediaBrowserViewModelImpl.getRootBrowsableHint(browser);
+                mRootPlayableHint = MediaBrowserViewModelImpl.getRootPlayableHint(browser);
+
+                boolean canSearch = MediaBrowserViewModelImpl.getSupportsSearch(browser);
+                mAppBarController.setSearchSupported(canSearch);
+                break;
+
+            case DISCONNECTING:
+            case REJECTED:
+            case SUSPENDED:
+                clearMediaSource();
+                break;
+        }
+
+        mViewModel.saveBrowsedMediaSource(newBrowsingState.mMediaSource);
+    }
+
+
+    MediaActivityController(Callbacks callbacks, MediaItemsRepository mediaItemsRepo,
+            CarPackageManager carPackageManager, ViewGroup container) {
+        super(callbacks.getActivity(), carPackageManager, container, R.layout.fragment_browse);
+
+        FragmentActivity activity = callbacks.getActivity();
+        mCallbacks = callbacks;
+        mMediaItemsRepository = mediaItemsRepo;
+        mViewModel = ViewModelProviders.of(activity).get(MediaActivity.ViewModel.class);
+        mSearchStack = mViewModel.getSearchStack();
+        mBrowseStack = mViewModel.getBrowseStack();
+        mBrowseArea = mContent.requireViewById(R.id.browse_content_area);
+        mFpv = activity.requireViewById(R.id.fpv);
+
+        MediaItemsLiveData rootMediaItems = mediaItemsRepo.getRootMediaItems();
+        mRootLoadingController = BrowseViewController.newRootController(
+                mBrowseCallbacks, mBrowseArea, rootMediaItems);
+        mRootLoadingController.getContent().setAlpha(1f);
+
+        mSearchResultsController = BrowseViewController.newSearchResultsController(
+                mBrowseCallbacks, mBrowseArea, mMediaItemsRepository.getSearchMediaItems());
+
+        boolean showingSearch = mViewModel.isShowingSearchResults();
+        ViewUtils.setVisible(mSearchResultsController.getContent(), showingSearch);
+        if (showingSearch) {
+            mSearchResultsController.getContent().setAlpha(1f);
+        }
+
+        mAppBarController.setListener(mAppBarListener);
+        mAppBarController.setSearchQuery(mViewModel.getSearchQuery());
+        if (mAppBarController.canShowSearchResultsView()) {
+            // TODO(b/180441965) eliminate the need to create a different view and use
+            //     mSearchResultsController.getContent() instead.
+            RecyclerView toolbarSearchResultsView = new RecyclerView(activity);
+            mSearchResultsController.shareBrowseAdapterWith(toolbarSearchResultsView);
+
+            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+            toolbarSearchResultsView.setLayoutParams(params);
+            toolbarSearchResultsView.setLayoutManager(new LinearLayoutManager(activity));
+            toolbarSearchResultsView.setBackground(
+                    activity.getDrawable(R.drawable.car_ui_ime_wide_screen_background));
+
+            mAppBarController.setSearchResultsView(toolbarSearchResultsView);
+        }
+
+        updateAppBar();
+
+        // Observe forever ensures the caches are destroyed even while the activity isn't resumed.
+        mediaItemsRepo.getBrowsingState().observeForever(mMediaBrowsingObserver);
+
+        mViewModel.getBrowsedMediaSource().observeForever(future -> {
+            onMediaSourceChanged(future.isLoading() ? null : future.getData());
+        });
+
+        rootMediaItems.observe(activity, this::onRootMediaItemsUpdate);
+        mViewModel.getMiniControlsVisible().observe(activity, this::onPlaybackControlsChanged);
+    }
+
+    void onDestroy() {
+        mMediaItemsRepository.getBrowsingState().removeObserver(mMediaBrowsingObserver);
+    }
+
+    private AppBarController.AppBarListener mAppBarListener = new BasicAppBarListener() {
+        @Override
+        public void onTabSelected(MediaItemMetadata item) {
+            if (mAcceptTabSelection && (item != null) && (item != mViewModel.getSelectedTab())) {
+                clearStack(mBrowseStack);
+                mBrowseStack.push(item);
+                showCurrentNode(true);
+            }
+        }
+
+        @Override
+        public void onSearchSelection() {
+            if (mViewModel.isSearching()) {
+                reopenSearch();
+            } else {
+                showSearchMode(true);
+                updateAppBar();
+            }
+        }
+
+        @Override
+        public void onSearch(String query) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "onSearch: " + query);
+            }
+            mViewModel.setSearchQuery(query);
+            updateSearchQuery(query);
+        }
+    };
+
+    private final BrowseViewController.Callbacks mBrowseCallbacks =
+            new BrowseViewController.Callbacks() {
+        @Override
+        public void onPlayableItemClicked(@NonNull MediaItemMetadata item) {
+            hideKeyboard();
+            mCallbacks.onPlayableItemClicked(item);
+        }
+
+        @Override
+        public void onBrowsableItemClicked(@NonNull MediaItemMetadata item) {
+            hideKeyboard();
+            navigateInto(item);
+        }
+
+        @Override
+            public void onChildrenNodesRemoved(@NonNull BrowseViewController controller,
+                    @NonNull Collection<MediaItemMetadata> removedNodes) {
+
+            if (mBrowseStack.contains(controller.getParentItem())) {
+                for (MediaItemMetadata node : removedNodes) {
+                    int indexOfNode = mBrowseStack.indexOf(node);
+                    if (indexOfNode >= 0) {
+                        clearStack(mBrowseStack.subList(indexOfNode, mBrowseStack.size()));
+                        if (!mViewModel.isShowingSearchResults()) {
+                            showCurrentNode(true);
+                            updateAppBar();
+                        }
+                        break; // The stack contains at most one of the removed nodes.
+                    }
+                }
+            }
+        }
+
+        @Override
+        public FragmentActivity getActivity() {
+            return mCallbacks.getActivity();
+        }
+    };
+
+    private final ViewAnimEndListener mViewAnimEndListener = view -> {
+        BrowseViewController toDestroy = mBrowseViewControllersToDestroy.remove(view);
+        if (toDestroy != null) {
+            toDestroy.destroy();
+        }
+    };
+
+    boolean onBackPressed() {
+        boolean success = navigateBack();
+        if (!success && mViewModel.isSearching()) {
+            showSearchMode(false);
+            updateAppBar();
+            success = true;
+        }
+        if (success) {
+            // When the back button is pressed, if a CarUiRecyclerView shows up and it's in rotary
+            // mode, restore focus in the CarUiRecyclerView.
+            restoreFocusInCurrentNode();
+        }
+        return success;
+    }
+
+    boolean browseTreeHasChildren() {
+        return mBrowseTreeHasChildren;
+    }
+
+    private void navigateInto(@NonNull MediaItemMetadata item) {
+        showSearchResults(false);
+
+        // Hide the current node (parent)
+        showCurrentNode(false);
+
+        // Make item the current node
+        getStack().push(item);
+
+        // Show the current node (item)
+        showCurrentNode(true);
+
+        updateAppBar();
+    }
+
+    private BrowseViewController getControllerForItem(@NonNull MediaItemMetadata item) {
+        BrowseViewController controller = mBrowseViewControllersByNode.get(item);
+        if (controller == null) {
+            controller = BrowseViewController.newBrowseController(mBrowseCallbacks, mBrowseArea,
+                    item, mMediaItemsRepository.getMediaChildren(item.getId()), mRootBrowsableHint,
+                    mRootPlayableHint);
+
+            if (mCarUiInsets != null) {
+                controller.onCarUiInsetsChanged(mCarUiInsets);
+            }
+            controller.onPlaybackControlsChanged(mPlaybackControlsVisible);
+
+            mBrowseViewControllersByNode.put(item, controller);
+        }
+        return controller;
+    }
+
+    private void showCurrentNode(boolean show) {
+        MediaItemMetadata currentNode = getCurrentMediaItem();
+        if (currentNode == null) {
+            return;
+        }
+        // Only create a controller to show it.
+        BrowseViewController controller = show ? getControllerForItem(currentNode) :
+                mBrowseViewControllersByNode.get(currentNode);
+
+        if (controller != null) {
+            showHideContentAnimated(show, controller.getContent(), mViewAnimEndListener);
+        }
+    }
+
+    // If the current node has a CarUiRecyclerView and it's in rotary mode, restore focus in it.
+    void restoreFocusInCurrentNode() {
+        MediaItemMetadata currentNode = getCurrentMediaItem();
+        if (currentNode == null) {
+            return;
+        }
+        BrowseViewController controller = getControllerForItem(currentNode);
+        if (controller == null) {
+            return;
+        }
+        CarUiRecyclerView carUiRecyclerView =
+                controller.getContent().findViewById(R.id.browse_list);
+        if (carUiRecyclerView != null && carUiRecyclerView instanceof LazyLayoutView
+                && !carUiRecyclerView.hasFocus() && !carUiRecyclerView.isInTouchMode()) {
+            LazyLayoutView lazyLayoutView = (LazyLayoutView) carUiRecyclerView;
+            com.android.car.ui.utils.ViewUtils.initFocus(lazyLayoutView);
+        }
+    }
+
+    private void showHideContentAnimated(boolean show, @NonNull View content,
+            @Nullable ViewAnimEndListener listener) {
+        CarUiRecyclerView carUiRecyclerView = content.findViewById(R.id.browse_list);
+        if (carUiRecyclerView != null && carUiRecyclerView instanceof LazyLayoutView
+                && !carUiRecyclerView.isInTouchMode()) {
+            // If a CarUiRecyclerView is about to hide and it has focus, park the focus on the
+            // FocusParkingView before hiding the CarUiRecyclerView. Otherwise hiding the focused
+            // view will cause the Android framework to move focus to another view, causing visual
+            // jank.
+            if (!show && carUiRecyclerView.hasFocus()) {
+                mFpv.performAccessibilityAction(ACTION_FOCUS, null);
+            }
+            // If a new CarUiRecyclerView is about to show and there is no view focused or the
+            // FocusParkingView is focused, restore focus in the new CarUiRecyclerView.
+            if (show) {
+                View focusedView = carUiRecyclerView.getRootView().findFocus();
+                if (focusedView == null || focusedView instanceof FocusParkingView) {
+                    LazyLayoutView lazyLayoutView = (LazyLayoutView) carUiRecyclerView;
+                    com.android.car.ui.utils.ViewUtils.initFocus(lazyLayoutView);
+                }
+            }
+        }
+
+        showHideViewAnimated(show, content, mFadeDuration, listener);
+    }
+
+
+
+    private void showSearchResults(boolean show) {
+        if (mViewModel.isShowingSearchResults() != show) {
+            mViewModel.setShowingSearchResults(show);
+            showHideContentAnimated(show, mSearchResultsController.getContent(), null);
+        }
+    }
+
+    private void showSearchMode(boolean show) {
+        if (mViewModel.isSearching() != show) {
+            if (show) {
+                showCurrentNode(false);
+            }
+
+            mViewModel.setSearching(show);
+            showSearchResults(show);
+
+            if (!show) {
+                showCurrentNode(true);
+            }
+        }
+    }
+
+    /**
+     * @return the current item being displayed
+     */
+    @Nullable
+    private MediaItemMetadata getCurrentMediaItem() {
+        Stack<MediaItemMetadata> stack = getStack();
+        return stack.isEmpty() ? null : stack.lastElement();
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        mCarUiInsets = insets;
+        for (BrowseViewController controller : mBrowseViewControllersByNode.values()) {
+            controller.onCarUiInsetsChanged(mCarUiInsets);
+        }
+        mRootLoadingController.onCarUiInsetsChanged(mCarUiInsets);
+        mSearchResultsController.onCarUiInsetsChanged(mCarUiInsets);
+    }
+
+    void onPlaybackControlsChanged(boolean visible) {
+        mPlaybackControlsVisible = visible;
+        for (BrowseViewController controller : mBrowseViewControllersByNode.values()) {
+            controller.onPlaybackControlsChanged(mPlaybackControlsVisible);
+        }
+        mRootLoadingController.onPlaybackControlsChanged(mPlaybackControlsVisible);
+        mSearchResultsController.onPlaybackControlsChanged(mPlaybackControlsVisible);
+    }
+
+    private void hideKeyboard() {
+        InputMethodManager in =
+                (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+        in.hideSoftInputFromWindow(mContent.getWindowToken(), 0);
+    }
+
+    private void hideAndDestroyControllerForItem(@Nullable MediaItemMetadata item) {
+        if (item == null) {
+            return;
+        }
+        BrowseViewController controller = mBrowseViewControllersByNode.get(item);
+        if (controller == null) {
+            return;
+        }
+
+        if (controller.getContent().getVisibility() == View.VISIBLE) {
+            View view = controller.getContent();
+            mBrowseViewControllersToDestroy.put(view, controller);
+            showHideContentAnimated(false, view, mViewAnimEndListener);
+        } else {
+            controller.destroy();
+        }
+        mBrowseViewControllersByNode.remove(item);
+    }
+
+    /**
+     * Clears the given stack (or a portion of a stack) and destroys the old controllers (after
+     * their view is hidden).
+     */
+    private void clearStack(List<MediaItemMetadata> stack) {
+        for (MediaItemMetadata item : stack) {
+            hideAndDestroyControllerForItem(item);
+        }
+        stack.clear();
+    }
+
+    /**
+     * Updates the tabs displayed on the app bar, based on the top level items on the browse tree.
+     * If there is at least one browsable item, we show the browse content of that node. If there
+     * are only playable items, then we show those items. If there are not items at all, we show the
+     * empty message. If we receive null, we show the error message.
+     *
+     * @param items top level items, null if the items are still being loaded, or empty list if
+     *              items couldn't be loaded.
+     */
+    private void updateTabs(@Nullable List<MediaItemMetadata> items) {
+        if (Objects.equals(mTopItems, items)) {
+            // When coming back to the app, the live data sends an update even if the list hasn't
+            // changed. Updating the tabs then recreates the browse view, which produces jank
+            // (b/131830876), and also resets the navigation to the top of the first tab...
+            return;
+        }
+        mTopItems = items;
+
+        if (mTopItems == null || mTopItems.isEmpty()) {
+            mAppBarController.setItems(null);
+            mAppBarController.setActiveItem(null);
+            if (items != null) {
+                // Only do this when not loading the tabs or we loose the saved one.
+                clearStack(mBrowseStack);
+            }
+            updateAppBar();
+            return;
+        }
+
+        MediaItemMetadata oldTab = mViewModel.getSelectedTab();
+        MediaItemMetadata newTab = items.contains(oldTab) ? oldTab : items.get(0);
+
+        try {
+            mAcceptTabSelection = false;
+            mAppBarController.setItems(mTopItems.size() == 1 ? null : mTopItems);
+            mAppBarController.setActiveItem(newTab);
+
+            if (oldTab != newTab) {
+                // Tabs belong to the browse stack.
+                clearStack(mBrowseStack);
+                mBrowseStack.push(newTab);
+            }
+
+            if (!mViewModel.isShowingSearchResults()) {
+                // Needed when coming back to an app after a config change or from another app,
+                // or when the tab actually changes.
+                showCurrentNode(true);
+            }
+        }  finally {
+            mAcceptTabSelection = true;
+        }
+        updateAppBar();
+    }
+
+    private void updateAppBarTitle() {
+        boolean isStacked = !isAtTopStack();
+
+        final CharSequence title;
+        if (isStacked) {
+            // If not at top level, show the current item as title
+            title = getCurrentMediaItem().getTitle();
+        } else if (mTopItems == null) {
+            // If still loading the tabs, force to show an empty bar.
+            title = "";
+        } else if (mTopItems.size() == 1) {
+            // If we finished loading tabs and there is only one, use that as title.
+            title = mTopItems.get(0).getTitle();
+        } else {
+            // Otherwise (no tabs or more than 1 tabs), show the current media source title.
+            MediaSource mediaSource = mMediaSourceVM.getPrimaryMediaSource().getValue();
+            title = getAppBarDefaultTitle(mediaSource);
+        }
+
+        mAppBarController.setTitle(title);
+    }
+
+    /**
+     * Update elements of the appbar that change depending on where we are in the browse.
+     */
+    private void updateAppBar() {
+        boolean isSearching = mViewModel.isSearching();
+        boolean isStacked = !isAtTopStack();
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "App bar is in stacked state: " + isStacked);
+        }
+        Toolbar.State unstackedState = isSearching ? Toolbar.State.SEARCH : Toolbar.State.HOME;
+        updateAppBarTitle();
+        mAppBarController.setState(isStacked ? Toolbar.State.SUBPAGE : unstackedState);
+        mAppBarController.showSearchIfSupported(!isSearching || isStacked);
+    }
+
+    private void onRootMediaItemsUpdate(FutureData<List<MediaItemMetadata>> data) {
+        if (data.isLoading()) {
+            if (Log.isLoggable(TAG, Log.INFO)) {
+                Log.i(TAG, "Loading browse tree...");
+            }
+            mBrowseTreeHasChildren = false;
+            updateTabs(null);
+            return;
+        }
+
+        List<MediaItemMetadata> items =
+                MediaBrowserViewModelImpl.filterItems(/*forRoot*/ true, data.getData());
+
+        boolean browseTreeHasChildren = items != null && !items.isEmpty();
+        if (Log.isLoggable(TAG, Log.INFO)) {
+            Log.i(TAG, "Browse tree loaded, status (has children or not) changed: "
+                    + mBrowseTreeHasChildren + " -> " + browseTreeHasChildren);
+        }
+        mBrowseTreeHasChildren = browseTreeHasChildren;
+        mCallbacks.onRootLoaded();
+        updateTabs(items != null ? items : new ArrayList<>());
+    }
+
+}
diff --git a/src/com/android/car/media/MediaDispatcherActivity.java b/src/com/android/car/media/MediaDispatcherActivity.java
index b44feb9..973937b 100644
--- a/src/com/android/car/media/MediaDispatcherActivity.java
+++ b/src/com/android/car/media/MediaDispatcherActivity.java
@@ -67,6 +67,8 @@
             // Launch custom app (e.g. Radio)
             String srcPackage = mediaSrc.getPackageName();
             newIntent = getPackageManager().getLaunchIntentForPackage(srcPackage);
+            newIntent.putExtra(Car.CAR_EXTRA_MEDIA_COMPONENT,
+                    mediaSrc.getBrowseServiceComponentName().flattenToString());
             if (Log.isLoggable(TAG, Log.DEBUG)) {
                 Log.d(TAG, "Getting launch intent for package : " + srcPackage + (newIntent != null
                         ? " succeeded" : " failed"));
diff --git a/src/com/android/car/media/PlaybackFragment.java b/src/com/android/car/media/PlaybackFragment.java
index dcaf7dc..cbf1ade 100644
--- a/src/com/android/car/media/PlaybackFragment.java
+++ b/src/com/android/car/media/PlaybackFragment.java
@@ -21,9 +21,11 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
 import android.os.Bundle;
 import android.util.Log;
 import android.util.Size;
@@ -51,8 +53,16 @@
 import com.android.car.media.common.PlaybackControlsActionBar;
 import com.android.car.media.common.playback.PlaybackViewModel;
 import com.android.car.media.common.source.MediaSourceViewModel;
+import com.android.car.media.widgets.AppBarController;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.recyclerview.ContentLimiting;
+import com.android.car.ui.recyclerview.ScrollingLimitedViewHolder;
 import com.android.car.ui.toolbar.MenuItem;
 import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
+import com.android.car.ui.utils.DirectManipulationHelper;
+import com.android.car.uxr.LifeCycleObserverUxrContentLimiter;
+import com.android.car.uxr.UxrContentLimiterImpl;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -68,7 +78,9 @@
 public class PlaybackFragment extends Fragment {
     private static final String TAG = "PlaybackFragment";
 
+    private LifeCycleObserverUxrContentLimiter mUxrContentLimiter;
     private ImageBinder<MediaItemMetadata.ArtworkRef> mAlbumArtBinder;
+    private AppBarController mAppBarController;
     private BackgroundImageView mAlbumBackground;
     private View mBackgroundScrim;
     private View mControlBarScrim;
@@ -77,7 +89,6 @@
     private RecyclerView mQueue;
     private ViewGroup mSeekBarContainer;
     private SeekBar mSeekBar;
-    private Toolbar mToolbar;
     private List<View> mViewsToHideForCustomActions;
     private List<View> mViewsToHideWhenQueueIsVisible;
     private List<View> mViewsToShowWhenQueueIsVisible;
@@ -106,6 +117,8 @@
 
     private MediaActivity.ViewModel mViewModel;
 
+    private MenuItem mQueueMenuItem;
+
     /**
      * PlaybackFragment listener
      */
@@ -199,13 +212,47 @@
     }
 
 
-    private class QueueItemsAdapter extends RecyclerView.Adapter<QueueViewHolder> {
+    private class QueueItemsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+            implements ContentLimiting {
 
+        private static final int CLAMPED_MESSAGE_VIEW_TYPE = -1;
+        private static final int QUEUE_ITEM_VIEW_TYPE = 0;
+
+        private UxrPivotFilter mUxrPivotFilter;
         private List<MediaItemMetadata> mQueueItems = Collections.emptyList();
         private String mCurrentTimeText = "";
         private String mMaxTimeText = "";
-        private Integer mActiveItemPos;
+        /** Index in {@link #mQueueItems}. */
+        private Integer mActiveItemIndex;
         private boolean mTimeVisible;
+        private Integer mScrollingLimitedMessageResId;
+
+        QueueItemsAdapter() {
+            mUxrPivotFilter = UxrPivotFilter.PASS_THROUGH;
+        }
+
+        @Override
+        public void setMaxItems(int maxItems) {
+            if (maxItems >= 0) {
+                mUxrPivotFilter = new UxrPivotFilterImpl(this, maxItems);
+            } else {
+                mUxrPivotFilter = UxrPivotFilter.PASS_THROUGH;
+            }
+            applyFilterToQueue();
+        }
+
+        @Override
+        public void setScrollingLimitedMessageResId(int resId) {
+            if (mScrollingLimitedMessageResId == null || mScrollingLimitedMessageResId != resId) {
+                mScrollingLimitedMessageResId = resId;
+                mUxrPivotFilter.invalidateMessagePositions();
+            }
+        }
+
+        @Override
+        public int getConfigurationId() {
+            return R.id.playback_fragment_now_playing_list_uxr_config;
+        }
 
         void setItems(@Nullable List<MediaItemMetadata> items) {
             List<MediaItemMetadata> newQueueItems =
@@ -214,62 +261,97 @@
                 return;
             }
             mQueueItems = newQueueItems;
-            updateActiveItem();
+            updateActiveItem(/* listIsNew */ true);
+        }
+
+        private int getActiveItemIndex() {
+            return mActiveItemIndex != null ? mActiveItemIndex : 0;
+        }
+
+        private int getQueueSize() {
+            return (mQueueItems != null) ? mQueueItems.size() : 0;
+        }
+
+
+        /**
+         * Returns the position of the active item if there is one, otherwise returns
+         * @link UxrPivotFilter#INVALID_POSITION}.
+         */
+        private int getActiveItemPosition() {
+            if (mActiveItemIndex == null) {
+                return UxrPivotFilter.INVALID_POSITION;
+            }
+            return mUxrPivotFilter.indexToPosition(mActiveItemIndex);
+        }
+
+        private void invalidateActiveItemPosition() {
+            int position = getActiveItemPosition();
+            if (position != UxrPivotFilterImpl.INVALID_POSITION) {
+                notifyItemChanged(position);
+            }
+        }
+
+        private void scrollToActiveItemPosition() {
+            int position = getActiveItemPosition();
+            if (position != UxrPivotFilterImpl.INVALID_POSITION) {
+                mQueue.scrollToPosition(position);
+            }
+        }
+
+        private void applyFilterToQueue() {
+            mUxrPivotFilter.recompute(getQueueSize(), getActiveItemIndex());
             notifyDataSetChanged();
         }
 
         // Updates mActiveItemPos, then scrolls the queue to mActiveItemPos.
         // It should be called when the active item (mActiveQueueItemId) changed or
         // the queue items (mQueueItems) changed.
-        void updateActiveItem() {
+        void updateActiveItem(boolean listIsNew) {
             if (mQueueItems == null || mActiveQueueItemId == null) {
-                mActiveItemPos = null;
+                mActiveItemIndex = null;
+                applyFilterToQueue();
                 return;
             }
             Integer activeItemPos = null;
             for (int i = 0; i < mQueueItems.size(); i++) {
-                if (mQueueItems.get(i).getQueueId() == mActiveQueueItemId) {
+                if (Objects.equals(mQueueItems.get(i).getQueueId(), mActiveQueueItemId)) {
                     activeItemPos = i;
                     break;
                 }
             }
 
-            if (mActiveItemPos != activeItemPos) {
-                if (mActiveItemPos != null) {
-                    notifyItemChanged(mActiveItemPos.intValue());
-                }
-                mActiveItemPos = activeItemPos;
-                if (mActiveItemPos != null) {
-                    mQueue.scrollToPosition(mActiveItemPos.intValue());
-                    notifyItemChanged(mActiveItemPos.intValue());
-                }
+            // Invalidate the previous active item so it gets redrawn as a normal one.
+            invalidateActiveItemPosition();
+
+            mActiveItemIndex = activeItemPos;
+            if (listIsNew) {
+                applyFilterToQueue();
+            } else {
+                mUxrPivotFilter.updatePivotIndex(getActiveItemIndex());
             }
+
+            scrollToActiveItemPosition();
+            invalidateActiveItemPosition();
         }
 
         void setCurrentTime(String currentTime) {
             if (!mCurrentTimeText.equals(currentTime)) {
                 mCurrentTimeText = currentTime;
-                if (mActiveItemPos != null) {
-                    notifyItemChanged(mActiveItemPos.intValue());
-                }
+                invalidateActiveItemPosition();
             }
         }
 
         void setMaxTime(String maxTime) {
             if (!mMaxTimeText.equals(maxTime)) {
                 mMaxTimeText = maxTime;
-                if (mActiveItemPos != null) {
-                    notifyItemChanged(mActiveItemPos.intValue());
-                }
+                invalidateActiveItemPosition();
             }
         }
 
         void setTimeVisible(boolean visible) {
             if (mTimeVisible != visible) {
                 mTimeVisible = visible;
-                if (mActiveItemPos != null) {
-                    notifyItemChanged(mActiveItemPos.intValue());
-                }
+                invalidateActiveItemPosition();
             }
         }
 
@@ -286,51 +368,83 @@
         }
 
         @Override
-        public QueueViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        public final int getItemViewType(int position) {
+            if (mUxrPivotFilter.positionToIndex(position) == UxrPivotFilterImpl.INVALID_INDEX) {
+                return CLAMPED_MESSAGE_VIEW_TYPE;
+            } else {
+                return QUEUE_ITEM_VIEW_TYPE;
+            }
+        }
+
+        @Override
+        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+            if (viewType == CLAMPED_MESSAGE_VIEW_TYPE) {
+                return ScrollingLimitedViewHolder.create(parent);
+            }
             LayoutInflater inflater = LayoutInflater.from(parent.getContext());
             return new QueueViewHolder(inflater.inflate(R.layout.queue_list_item, parent, false));
         }
 
         @Override
-        public void onBindViewHolder(QueueViewHolder holder, int position) {
-            int size = mQueueItems.size();
-            if (0 <= position && position < size) {
-                holder.bind(mQueueItems.get(position));
+        public void onBindViewHolder(RecyclerView.ViewHolder vh, int position) {
+            if (vh instanceof QueueViewHolder) {
+                int index = mUxrPivotFilter.positionToIndex(position);
+                if (index != UxrPivotFilterImpl.INVALID_INDEX) {
+                    int size = mQueueItems.size();
+                    if (0 <= index && index < size) {
+                        QueueViewHolder holder = (QueueViewHolder) vh;
+                        holder.bind(mQueueItems.get(index));
+                    } else {
+                        Log.e(TAG, "onBindViewHolder pos: " + position + " gave index: " + index +
+                                " out of bounds size: " + size + " " + mUxrPivotFilter.toString());
+                    }
+                } else {
+                    Log.e(TAG, "onBindViewHolder invalid position " + position + " " +
+                            mUxrPivotFilter.toString());
+                }
+            } else if (vh instanceof ScrollingLimitedViewHolder) {
+                ScrollingLimitedViewHolder holder = (ScrollingLimitedViewHolder) vh;
+                holder.bind(mScrollingLimitedMessageResId);
             } else {
-                Log.e(TAG, "onBindViewHolder invalid position " + position + " of " + size);
+                throw new IllegalArgumentException("unknown holder class " + vh.getClass());
             }
         }
 
         @Override
-        public void onViewAttachedToWindow(@NonNull QueueViewHolder holder) {
-            super.onViewAttachedToWindow(holder);
-            holder.onViewAttachedToWindow();
+        public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder vh) {
+            super.onViewAttachedToWindow(vh);
+            if (vh instanceof QueueViewHolder) {
+                QueueViewHolder holder = (QueueViewHolder) vh;
+                holder.onViewAttachedToWindow();
+            }
         }
 
         @Override
-        public void onViewDetachedFromWindow(@NonNull QueueViewHolder holder) {
-            super.onViewDetachedFromWindow(holder);
-            holder.onViewDetachedFromWindow();
+        public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder vh) {
+            super.onViewDetachedFromWindow(vh);
+            if (vh instanceof QueueViewHolder) {
+                QueueViewHolder holder = (QueueViewHolder) vh;
+                holder.onViewDetachedFromWindow();
+            }
         }
 
         @Override
         public int getItemCount() {
-            return mQueueItems.size();
-        }
-
-        void refresh() {
-            // TODO: Perform a diff between current and new content and trigger the proper
-            // RecyclerView updates.
-            this.notifyDataSetChanged();
+            return mUxrPivotFilter.getFilteredCount();
         }
 
         @Override
         public long getItemId(int position) {
-            return mQueueItems.get(position).getQueueId();
+            int index = mUxrPivotFilter.positionToIndex(position);
+            if (index != UxrPivotFilterImpl.INVALID_INDEX) {
+                return mQueueItems.get(position).getQueueId();
+            } else {
+                return RecyclerView.NO_ID;
+            }
         }
     }
 
-    private class QueueTopItemDecoration extends RecyclerView.ItemDecoration {
+    private static class QueueTopItemDecoration extends RecyclerView.ItemDecoration {
         int mHeight;
         int mDecorationPosition;
 
@@ -352,31 +466,33 @@
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, final ViewGroup container,
             Bundle savedInstanceState) {
-        View view = inflater.inflate(R.layout.fragment_playback, container, false);
+        return inflater.inflate(R.layout.fragment_playback, container, false);
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         mAlbumBackground = view.findViewById(R.id.playback_background);
         mQueue = view.findViewById(R.id.queue_list);
-        mSeekBarContainer = view.findViewById(R.id.seek_bar_container);
-        mSeekBar = view.findViewById(R.id.seek_bar);
-        mToolbar = view.findViewById(R.id.toolbar);
-        if (mToolbar != null) {
-            mToolbar.setBackgroundShown(false);
-            mToolbar.setNavButtonMode(Toolbar.NavButtonMode.DOWN);
+        mSeekBarContainer = view.findViewById(R.id.playback_seek_bar_container);
+        mSeekBar = view.findViewById(R.id.playback_seek_bar);
+        DirectManipulationHelper.setSupportsRotateDirectly(mSeekBar, true);
 
-            // Notify listeners when toolbar's down button is pressed.
-            mToolbar.registerOnBackListener(() -> {
-                if (mListener != null) {
-                    mListener.onCollapse();
-                }
-                return true;
-            });
+        GuidelinesUpdater updater = new GuidelinesUpdater(view);
+        ToolbarController toolbarController = CarUi.installBaseLayoutAround(view, updater, true);
+        mAppBarController = new AppBarController(view.getContext(), toolbarController);
 
-            // Update toolbar's logo
-            MediaSourceViewModel mediaSourceViewModel = getMediaSourceViewModel();
-            mediaSourceViewModel.getPrimaryMediaSource().observe(this, mediaSource ->
-                mToolbar.setLogo(mediaSource != null
-                        ? new BitmapDrawable(getResources(), mediaSource.getCroppedPackageIcon())
-                        : null));
-        }
+        mAppBarController.setTitle(R.string.fragment_playback_title);
+        mAppBarController.setBackgroundShown(false);
+        mAppBarController.setNavButtonMode(Toolbar.NavButtonMode.DOWN);
+        mAppBarController.setState(Toolbar.State.SUBPAGE);
+
+        // Update toolbar's logo
+        MediaSourceViewModel mediaSourceViewModel = getMediaSourceViewModel();
+        mediaSourceViewModel.getPrimaryMediaSource().observe(this, mediaSource ->
+                mAppBarController.setLogo(mediaSource != null
+                    ? new BitmapDrawable(getResources(), mediaSource.getCroppedPackageIcon())
+                    : null));
+
         mBackgroundScrim = view.findViewById(R.id.background_scrim);
         ViewUtils.setVisible(mBackgroundScrim, false);
         mControlBarScrim = view.findViewById(R.id.control_bar_scrim);
@@ -406,15 +522,13 @@
                 if (useMediaSourceColor) {
                     getPlaybackViewModel().getMediaSourceColors().observe(getViewLifecycleOwner(),
                             sourceColors -> {
-                                int color = sourceColors != null ? sourceColors.getAccentColor(
-                                        defaultColor)
+                                int color = sourceColors != null
+                                        ? sourceColors.getAccentColor(defaultColor)
                                         : defaultColor;
-                                mSeekBar.setThumbTintList(ColorStateList.valueOf(color));
-                                mSeekBar.setProgressTintList(ColorStateList.valueOf(color));
+                                setSeekBarColor(color);
                             });
                 } else {
-                    mSeekBar.setThumbTintList(ColorStateList.valueOf(defaultColor));
-                    mSeekBar.setProgressTintList(ColorStateList.valueOf(defaultColor));
+                    setSeekBarColor(defaultColor);
                 }
             } else {
                 mSeekBar.setVisibility(View.GONE);
@@ -453,7 +567,10 @@
                 item -> mAlbumArtBinder.setImage(PlaybackFragment.this.getContext(),
                         item != null ? item.getArtworkKey() : null));
 
-        return view;
+        mUxrContentLimiter = new LifeCycleObserverUxrContentLimiter(
+                new UxrContentLimiterImpl(getContext(), R.xml.uxr_config));
+        mUxrContentLimiter.setAdapter(mQueueAdapter);
+        getLifecycle().addObserver(mUxrContentLimiter);
     }
 
     @Override
@@ -519,7 +636,7 @@
                     Long itemId = (state != null) ? state.getActiveQueueItemId() : null;
                     if (!Objects.equals(mActiveQueueItemId, itemId)) {
                         mActiveQueueItemId = itemId;
-                        mQueueAdapter.updateActiveItem();
+                        mQueueAdapter.updateActiveItem(/* listIsNew */ false);
                     }
                 });
         mQueue.setAdapter(mQueueAdapter);
@@ -529,12 +646,19 @@
         mItemAnimator.setSupportsChangeAnimations(false);
         mQueue.setItemAnimator(mItemAnimator);
 
+        // Make sure the AppBar menu reflects the initial state of playback fragment.
+        updateAppBarMenu(mHasQueue);
+        if (mQueueMenuItem != null) {
+            mQueueMenuItem.setActivated(mQueueIsVisible);
+        }
+
         getPlaybackViewModel().getQueue().observe(this, this::setQueue);
 
         getPlaybackViewModel().hasQueue().observe(getViewLifecycleOwner(), hasQueue -> {
             boolean enableQueue = (hasQueue != null) && hasQueue;
-            mQueueIsVisible = mViewModel.getQueueVisible();
-            setHasQueue(enableQueue);
+            boolean isQueueVisible = enableQueue && mViewModel.getQueueVisible();
+
+            setQueueState(enableQueue, isQueueVisible);
         });
         getPlaybackViewModel().getProgress().observe(getViewLifecycleOwner(),
                 playbackProgress ->
@@ -571,7 +695,7 @@
      */
     private void toggleQueueVisibility() {
         boolean updatedQueueVisibility = !mQueueIsVisible;
-        setQueueVisible(updatedQueueVisibility);
+        setQueueState(mHasQueue, updatedQueueVisibility);
 
         // When the visibility of queue is changed by the user, save the visibility into ViewModel
         // so that we can restore PlaybackFragment properly when needed. If it's changed by media
@@ -580,39 +704,39 @@
         mViewModel.setQueueVisible(updatedQueueVisibility);
     }
 
-    private void setQueueVisible(boolean visible) {
-        mQueueIsVisible = visible;
-
-        if (mToolbar != null) {
-            if (mHasQueue) {
-                MenuItem queueMenuItem = MenuItem.builder(getContext())
-                        .setIcon(R.drawable.ic_queue_button)
-                        .setActivated(mQueueIsVisible)
-                        .setOnClickListener(button -> toggleQueueVisibility())
-                        .build();
-                mToolbar.setMenuItems(Collections.singletonList(queueMenuItem));
-            } else {
-                mToolbar.setMenuItems(Collections.emptyList());
-            }
+    private void updateAppBarMenu(boolean hasQueue) {
+        if (hasQueue && mQueueMenuItem == null) {
+            mQueueMenuItem = MenuItem.builder(getContext())
+                    .setIcon(R.drawable.ic_queue_button)
+                    .setActivatable()
+                    .setOnClickListener(button -> toggleQueueVisibility())
+                    .build();
         }
-
-        if (mQueueIsVisible) {
-            ViewUtils.showViewsAnimated(mViewsToShowWhenQueueIsVisible, mFadeDuration);
-            ViewUtils.hideViewsAnimated(mViewsToHideWhenQueueIsVisible, mFadeDuration);
-            ViewUtils.setVisible(mViewsToShowImmediatelyWhenQueueIsVisible, true);
-            ViewUtils.setVisible(mViewsToHideImmediatelyWhenQueueIsVisible, false);
-        } else {
-            ViewUtils.hideViewsAnimated(mViewsToShowWhenQueueIsVisible, mFadeDuration);
-            ViewUtils.showViewsAnimated(mViewsToHideWhenQueueIsVisible, mFadeDuration);
-            ViewUtils.setVisible(mViewsToShowImmediatelyWhenQueueIsVisible, false);
-            ViewUtils.setVisible(mViewsToHideImmediatelyWhenQueueIsVisible, true);
-        }
+        mAppBarController.setMenuItems(
+                hasQueue ? Collections.singletonList(mQueueMenuItem) : Collections.emptyList());
     }
 
-    /** Sets whether the source has a queue. */
-    private void setHasQueue(boolean hasQueue) {
-        mHasQueue = hasQueue;
-        setQueueVisible(hasQueue && mQueueIsVisible);
+    private void setQueueState(boolean hasQueue, boolean visible) {
+        if (mHasQueue != hasQueue) {
+            mHasQueue = hasQueue;
+            updateAppBarMenu(hasQueue);
+        }
+        if (mQueueMenuItem != null) {
+            mQueueMenuItem.setActivated(visible);
+        }
+
+        if (mQueueIsVisible != visible) {
+            mQueueIsVisible = visible;
+            if (mQueueIsVisible) {
+                ViewUtils.showViewsAnimated(mViewsToShowWhenQueueIsVisible, mFadeDuration);
+                ViewUtils.hideViewsAnimated(mViewsToHideWhenQueueIsVisible, mFadeDuration);
+            } else {
+                ViewUtils.hideViewsAnimated(mViewsToShowWhenQueueIsVisible, mFadeDuration);
+                ViewUtils.showViewsAnimated(mViewsToHideWhenQueueIsVisible, mFadeDuration);
+            }
+            ViewUtils.setVisible(mViewsToShowImmediatelyWhenQueueIsVisible, mQueueIsVisible);
+            ViewUtils.setVisible(mViewsToHideImmediatelyWhenQueueIsVisible, !mQueueIsVisible);
+        }
     }
 
     private void onQueueItemClicked(MediaItemMetadata item) {
@@ -642,6 +766,24 @@
         return MediaSourceViewModel.get(getActivity().getApplication(), MEDIA_SOURCE_MODE_BROWSE);
     }
 
+    private void setSeekBarColor(int color) {
+        mSeekBar.setProgressTintList(ColorStateList.valueOf(color));
+
+        // If the thumb drawable consists of a center drawable, only change the color of the center
+        // drawable. Otherwise change the color of the entire thumb drawable.
+        Drawable thumb = mSeekBar.getThumb();
+        if (thumb instanceof LayerDrawable) {
+            LayerDrawable thumbDrawable = (LayerDrawable) thumb;
+            Drawable thumbCenter = thumbDrawable.findDrawableByLayerId(R.id.thumb_center);
+            if (thumbCenter != null) {
+                thumbCenter.setColorFilter(color, PorterDuff.Mode.SRC);
+                thumbDrawable.setDrawableByLayerId(R.id.thumb_center, thumbCenter);
+                return;
+            }
+        }
+        mSeekBar.setThumbTintList(ColorStateList.valueOf(color));
+    }
+
     /**
      * Sets a listener of this PlaybackFragment events. In order to avoid memory leaks, consumers
      * must reset this reference by setting the listener to null.
diff --git a/src/com/android/car/media/UxrPivotFilter.java b/src/com/android/car/media/UxrPivotFilter.java
new file mode 100644
index 0000000..57b1e52
--- /dev/null
+++ b/src/com/android/car/media/UxrPivotFilter.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.media;
+
+
+/**
+ * Interface for helper objects that hide elements from lists that are too long. The limiting
+ * happens around a pivot element that can be anywhere in the list. Elements near that pivot will
+ * be visible, while elements at the head and / or tail of the list will be replaced by a message
+ * telling the user about the truncation.
+ * When no restrictions are in effect, the {@link #PASS_THROUGH} instance should be used.
+ */
+public interface UxrPivotFilter {
+
+    int INVALID_INDEX = -1;
+    int INVALID_POSITION = -1;
+
+    /**
+     * Computes new restrictions when the list (and optionally) the pivot have changed.
+     * The implementation doesn't send any notification.
+     */
+    void recompute(int newCount, int pivotIndex);
+
+    /**
+     * Computes new restrictions when only the pivot has changed.
+     * The implementation must send notification changes (ideally incremental ones).
+     */
+    void updatePivotIndex(int pivotIndex);
+
+    /** Returns the number of elements in the resulting list, including the message(s). */
+    int getFilteredCount();
+
+    /**
+     * Converts an index in the unfiltered data set to a RV position in the filtered UI in the
+     * 0 .. {@link #getFilteredCount} range which includes the limits message(s).
+     * Returns INVALID_POSITION if that element has been filtered out.
+     */
+    int indexToPosition(int index);
+
+    /**
+     * Converts a RV position in the filtered UI to an index in the unfiltered data set.
+     * Returns INVALID_INDEX if a message is shown at that position.
+     */
+    int positionToIndex(int position);
+
+    /** Send notification changes for the restriction message(s) if there are any. */
+    void invalidateMessagePositions();
+
+
+    /**
+     * A trivial implementation that doesn't do any filtering (simplifies the filter's code).
+     */
+    UxrPivotFilter PASS_THROUGH = new UxrPivotFilter() {
+        private int mCount;
+
+        @Override
+        public void recompute(int newCount, int pivotIndex) {
+            mCount = newCount;
+        }
+
+        @Override
+        public void updatePivotIndex(int pivotIndex) {
+        }
+
+        @Override
+        public int getFilteredCount() {
+            return mCount;
+        }
+
+        @Override
+        public int indexToPosition(int index) {
+            return index;
+        }
+
+        @Override
+        public int positionToIndex(int position) {
+            return position;
+        }
+
+        @Override
+        public void invalidateMessagePositions() {
+        }
+    };
+}
diff --git a/src/com/android/car/media/UxrPivotFilterImpl.java b/src/com/android/car/media/UxrPivotFilterImpl.java
new file mode 100644
index 0000000..29be569
--- /dev/null
+++ b/src/com/android/car/media/UxrPivotFilterImpl.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.car.media;
+
+import android.util.Log;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+
+public class UxrPivotFilterImpl implements UxrPivotFilter {
+
+    private static final String TAG = "UxrPivotFilterImpl";
+
+    private final RecyclerView.Adapter<?> mAdapter;
+    private final int mMaxItems;
+    private final int mMaxItemsDiv2;
+
+    private int mUnlimitedCount;
+    private int mPivotIndex;
+    private final ListRange mRange = new ListRange();
+    private final ListRange mSavedRange = new ListRange();
+
+
+    /**
+     * Constructor
+     * @param adapter the adapter to notify of changes in {@link #updatePivotIndex}.
+     * @param maxItems the maximum number of items to show. When > 0, its value is rounded up to
+     *                 the nearest greater odd integer in order to show the active element plus or
+     *                 minus maxItems / 2.
+     */
+    public UxrPivotFilterImpl(RecyclerView.Adapter<?> adapter, int maxItems) {
+        mAdapter = adapter;
+        if (maxItems <= 0) {
+            mMaxItemsDiv2 = 0;
+            mMaxItems = 0;
+        } else {
+            mMaxItemsDiv2 = maxItems / 2;
+            mMaxItems = 1 + (mMaxItemsDiv2 * 2);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "UxrPivotFilterImpl{" +
+                "mMaxItemsDiv2=" + mMaxItemsDiv2 +
+                ", mUnlimitedCount=" + mUnlimitedCount +
+                ", mPivotIndex=" + mPivotIndex +
+                ", mRange=" + mRange.toString() +
+                '}';
+    }
+
+    @Override
+    public int getFilteredCount() {
+        return mRange.mLimitedCount;
+    }
+
+    @Override
+    public void invalidateMessagePositions() {
+        if (mRange.mClampedHead > 0) {
+            mAdapter.notifyItemChanged(0);
+        }
+        if (mRange.mClampedTail > 0) {
+            mAdapter.notifyItemChanged(getFilteredCount() - 1);
+        }
+    }
+
+    @Override
+    public void recompute(int newCount, int pivotIndex) {
+        if (pivotIndex < 0 || newCount <= pivotIndex) {
+            Log.e(TAG, "Invalid pivotIndex: " + pivotIndex + " newCount: " + newCount);
+            pivotIndex = 0;
+        }
+        mUnlimitedCount = newCount;
+        mPivotIndex = pivotIndex;
+        mRange.mClampedHead = 0;
+        mRange.mClampedTail = 0;
+
+        if (newCount <= mMaxItems) {
+            // Under the cap case.
+            mRange.mStartIndex = 0;
+            mRange.mEndIndex = mUnlimitedCount;
+            mRange.mLimitedCount = mUnlimitedCount;
+        } else if (mMaxItems <= 0) {
+            // Zero cap case.
+            mRange.mStartIndex = 0;
+            mRange.mEndIndex = 0;
+            mRange.mLimitedCount = 1; // One limit message
+            mRange.mClampedTail = 1;
+        } else if (mPivotIndex <= mMaxItemsDiv2) {
+            // No need to clamp the head case
+            // For example: P = 2, M/2 = 2 => exactly two items before the pivot.
+            // Tail has to be clamped or we'd be in the "under the cap" case.
+            mRange.mStartIndex = 0;
+            mRange.mEndIndex = mMaxItems;
+            mRange.mLimitedCount = mMaxItems + 1; // One limit message at the end
+            mRange.mClampedTail = 1;
+        } else if ((mUnlimitedCount - 1 - mPivotIndex) <= mMaxItemsDiv2) {
+            // No need to clamp the tail case
+            // For example: C = 5, P = 2 => exactly 2 items after the pivot (count is exclusive).
+            // Head has to be clamped or we'd be in the "under the cap" case.
+            mRange.mEndIndex = mUnlimitedCount;
+            mRange.mStartIndex = mRange.mEndIndex - mMaxItems;
+            mRange.mLimitedCount = mMaxItems + 1; // One limit message at the start
+            mRange.mClampedHead = 1;
+        } else {
+            // Both head and tail need clamping
+            mRange.mStartIndex = mPivotIndex - mMaxItemsDiv2;
+            mRange.mEndIndex = mPivotIndex + mMaxItemsDiv2 + 1;
+            mRange.mLimitedCount = mMaxItems + 2; // One limit message at each end.
+            mRange.mClampedHead = 1;
+            mRange.mClampedTail = 1;
+        }
+    }
+
+    /**
+     * Computes the new restrictions when the pivot changes but the list remains the same.
+     * Notifications are done from the end to the beginning of the list so we don't have to mess
+     * with the indices as we go. Beyond the addition or removal of head and tail messages, the
+     * method boils down to intersecting two segments and determining which elements to remove and
+     * which to add to go from the old one to the new one.<p/>
+     * The diagram below illustrates all the cases with [S1, E1[ the old range and [S2, E2[ the
+     * new one. The =, + and - signs identify identical, inserted and removed elements.<p/>
+     * <pre>
+     *                             S1                      E1
+     *                            |........................|
+     *                            |                        |
+     *             S2             |      E2                |
+     *             +++++++++++++++|======------------------|
+     *                            |                        |
+     *                            |             S2         |           E2
+     *                            |             ===========|+++++++++++
+     *                            |                        |
+     *                            |     S2         E2      |
+     *                            |-----===========--------|
+     *                            |                        |
+     *                  S2        |                        |                E2
+     *                  ++++++++++|========================|++++++++++++++++
+     * <pre/>
+     */
+    @Override
+    public void updatePivotIndex(int pivotIndex) {
+        if (mPivotIndex == pivotIndex) return;
+
+        mSavedRange.copyFrom(mRange);
+
+        recompute(mUnlimitedCount, pivotIndex);
+
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "updatePivotIndex pivot: " + pivotIndex + " saved: " + mSavedRange
+                    + " new: " + mRange);
+        }
+
+        if (mSavedRange.intersects(mRange)) {
+            if (mSavedRange.mClampedTail < mRange.mClampedTail) {
+                // Add a tail message, inserting it after the last element of the restricted list.
+                mAdapter.notifyItemInserted(mSavedRange.mLimitedCount);
+            }
+            if (mSavedRange.mClampedTail > mRange.mClampedTail) {
+                // Remove a tail message which was shown as the last element of the restricted list.
+                mAdapter.notifyItemRemoved(mSavedRange.mLimitedCount - 1);
+            }
+
+            // Add or remove items at the end
+            if (mSavedRange.mEndIndex < mRange.mEndIndex) {
+                int insertPos = mSavedRange.indexToPosition(mSavedRange.mEndIndex);
+                int insertCount = mRange.mEndIndex - mSavedRange.mEndIndex;
+                mAdapter.notifyItemRangeInserted(insertPos, insertCount);
+            }
+            if (mSavedRange.mEndIndex > mRange.mEndIndex) {
+                int delPos = mSavedRange.indexToPosition(mRange.mEndIndex);
+                int delCount = mSavedRange.mEndIndex - mRange.mEndIndex;
+                mAdapter.notifyItemRangeRemoved(delPos, delCount);
+            }
+
+            // Add or remove items at the start
+            if (mSavedRange.mStartIndex > mRange.mStartIndex) {
+                int insertPos = mSavedRange.indexToPosition(mSavedRange.mStartIndex);
+                int insertCount = mSavedRange.mStartIndex - mRange.mStartIndex;
+                mAdapter.notifyItemRangeInserted(insertPos, insertCount);
+            }
+            if (mSavedRange.mStartIndex < mRange.mStartIndex) {
+                int delPos = mSavedRange.indexToPosition(mSavedRange.mStartIndex);
+                int delCount = mRange.mStartIndex - mSavedRange.mStartIndex;
+                mAdapter.notifyItemRangeRemoved(delPos, delCount);
+            }
+
+            // Add or remove the head message
+            if (mSavedRange.mClampedHead < mRange.mClampedHead) {
+                mAdapter.notifyItemInserted(0);
+            }
+            if (mSavedRange.mClampedHead > mRange.mClampedHead) {
+                mAdapter.notifyItemRemoved(0);
+            }
+        } else {
+            // No element is the same, invalidate all.
+            mAdapter.notifyDataSetChanged();
+        }
+    }
+
+    @Override
+    public int indexToPosition(int index) {
+        if ((mRange.mStartIndex <= index) && (index < mRange.mEndIndex)) {
+            return mRange.indexToPosition(index);
+        } else {
+            return INVALID_POSITION;
+        }
+    }
+
+    @Override
+    public int positionToIndex(int position) {
+        return mRange.positionToIndex(position);
+    }
+
+
+    /** A portion of the unfiltered list. */
+    private static class ListRange {
+
+        /** In original data, inclusive. */
+        private int mStartIndex;
+        /** In original data, exclusive. */
+        private int mEndIndex;
+
+        /** 1 when clamped, otherwise 0. */
+        private int mClampedHead;
+        /** 1 when clamped, otherwise 0. */
+        private int mClampedTail;
+
+        /** The count of the resulting elements, including the truncation message(s). */
+        private int mLimitedCount;
+
+        public void copyFrom(ListRange range) {
+            mStartIndex = range.mStartIndex;
+            mEndIndex = range.mEndIndex;
+            mClampedHead = range.mClampedHead;
+            mClampedTail = range.mClampedTail;
+            mLimitedCount = range.mLimitedCount;
+        }
+
+        @Override
+        public String toString() {
+            return "ListRange{" +
+                    "mStartIndex=" + mStartIndex +
+                    ", mEndIndex=" + mEndIndex +
+                    ", mClampedHead=" + mClampedHead +
+                    ", mClampedTail=" + mClampedTail +
+                    ", mLimitedCount=" + mLimitedCount +
+                    '}';
+        }
+
+        public boolean intersects(ListRange range) {
+            return ((range.mEndIndex > mStartIndex) && (mEndIndex > range.mStartIndex));
+        }
+
+        /** Unchecked index needed by {@link #updatePivotIndex}. */
+        public int indexToPosition(int index) {
+            return index - mStartIndex + mClampedHead;
+        }
+
+        public int positionToIndex(int position) {
+            int index = position - mClampedHead + mStartIndex;
+            if ((index < mStartIndex) || (mEndIndex <= index)) {
+                return INVALID_INDEX;
+            } else {
+                return index;
+            }
+        }
+    }
+}
diff --git a/src/com/android/car/media/ViewControllerBase.java b/src/com/android/car/media/ViewControllerBase.java
index a4c413d..b27e4bf 100644
--- a/src/com/android/car/media/ViewControllerBase.java
+++ b/src/com/android/car/media/ViewControllerBase.java
@@ -34,19 +34,25 @@
 
 import androidx.annotation.CallSuper;
 import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
 
 import com.android.car.apps.common.util.CarPackageManagerUtils;
 import com.android.car.media.common.source.MediaSource;
 import com.android.car.media.common.source.MediaSourceViewModel;
-import com.android.car.media.widgets.AppBarView;
+import com.android.car.media.widgets.AppBarController;
+
+import com.android.car.ui.baselayout.Insets;
+import com.android.car.ui.baselayout.InsetsChangedListener;
+import com.android.car.ui.core.CarUi;
+import com.android.car.ui.toolbar.ToolbarController;
 
 /**
  * Functionality common to content view controllers. It mainly handles the AppBar view,
- * which is common to all them.
+ * which is common to all of them.
  */
-abstract class ViewControllerBase {
+abstract class ViewControllerBase implements InsetsChangedListener {
     private static final String TAG = "ViewControllerBase";
 
     private final boolean mShouldShowSoundSettings;
@@ -55,7 +61,7 @@
     final FragmentActivity mActivity;
     final int mFadeDuration;
     final View mContent;
-    final AppBarView mAppBarView;
+    final AppBarController mAppBarController;
     final MediaSourceViewModel mMediaSourceVM;
 
     private Intent mCurrentSourcePreferences;
@@ -69,17 +75,26 @@
 
         LayoutInflater inflater = LayoutInflater.from(container.getContext());
         mContent = inflater.inflate(resource, container, false);
-
-        mAppBarView = mContent.findViewById(R.id.app_bar);
-        mAppBarView.setSearchSupported(false);
-        mAppBarView.setHasEqualizer(false);
-
         container.addView(mContent);
 
+        GuidelinesUpdater updater = new GuidelinesUpdater(mContent);
+        updater.addListener(this);
+        ToolbarController toolbar = CarUi.installBaseLayoutAround(mContent, updater, true);
+
+        mAppBarController = new AppBarController(activity, toolbar);
+        mAppBarController.setSearchSupported(false);
+        mAppBarController.setHasEqualizer(false);
+
         mCarPackageManager = carPackageManager;
 
         mMediaSourceVM = MediaSourceViewModel.get(activity.getApplication(),
                 MEDIA_SOURCE_MODE_BROWSE);
+
+    }
+
+    @Override
+    public void onCarUiInsetsChanged(@NonNull Insets insets) {
+        // Overridden in subclasses
     }
 
     CharSequence getAppBarDefaultTitle(@Nullable MediaSource mediaSource) {
@@ -87,7 +102,7 @@
                 : mActivity.getResources().getString(R.string.media_app_title);
     }
 
-    class BasicAppBarListener extends AppBarView.AppBarListener {
+    class BasicAppBarListener extends AppBarController.AppBarListener {
         @Override
         protected void onSettingsSelection() {
             if (Log.isLoggable(TAG, Log.DEBUG)) {
@@ -127,8 +142,8 @@
             packageName = mediaSource.getPackageName();
         }
 
-        mAppBarView.setLogo(icon);
-        mAppBarView.setSearchIcon(searchIcon);
+        mAppBarController.setLogo(icon);
+        mAppBarController.setSearchIcon(searchIcon);
         updateSourcePreferences(packageName);
     }
 
@@ -142,13 +157,13 @@
             if (info != null && info.activityInfo != null && info.activityInfo.exported) {
                 mCurrentSourcePreferences = new Intent(prefsIntent.getAction())
                         .setClassName(info.activityInfo.packageName, info.activityInfo.name);
-                mAppBarView.setSettingsDistractionOptimized(
+                mAppBarController.setSettingsDistractionOptimized(
                         CarPackageManagerUtils.isDistractionOptimized(
                                 mCarPackageManager, info.activityInfo));
             }
         }
-        mAppBarView.setHasSettings(mCurrentSourcePreferences != null);
-        mAppBarView.setHasEqualizer(mShouldShowSoundSettings);
+        mAppBarController.setHasSettings(mCurrentSourcePreferences != null);
+        mAppBarController.setHasEqualizer(mShouldShowSoundSettings);
     }
 
 
diff --git a/src/com/android/car/media/browse/BrowseAdapter.java b/src/com/android/car/media/browse/BrowseAdapter.java
index 9ba3cd1..847d270 100644
--- a/src/com/android/car/media/browse/BrowseAdapter.java
+++ b/src/com/android/car/media/browse/BrowseAdapter.java
@@ -33,7 +33,6 @@
 import com.android.car.media.common.MediaItemMetadata;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -51,6 +50,17 @@
  */
 public class BrowseAdapter extends ListAdapter<BrowseViewData, BrowseViewHolder> {
     private static final String TAG = "BrowseAdapter";
+
+    /**
+     * Listens to the list data changes.
+     */
+    public interface OnListChangedListener {
+        /**
+         * Called when {@link #onCurrentListChanged(List, List)} is called.
+         */
+        void onListChanged(List<BrowseViewData> previousList, List<BrowseViewData> currentList);
+    }
+
     @NonNull
     private final Context mContext;
     @NonNull
@@ -59,11 +69,12 @@
     private CharSequence mTitle;
     @Nullable
     private MediaItemMetadata mParentMediaItem;
-    private int mMaxSpanSize = 1;
 
     private BrowseItemViewType mRootBrowsableViewType = BrowseItemViewType.LIST_ITEM;
     private BrowseItemViewType mRootPlayableViewType = BrowseItemViewType.LIST_ITEM;
 
+    private OnListChangedListener mOnListChangedListener;
+
     private static final DiffUtil.ItemCallback<BrowseViewData> DIFF_CALLBACK =
             new DiffUtil.ItemCallback<BrowseViewData>() {
                 @Override
@@ -88,13 +99,13 @@
         /**
          * Callback invoked when a user clicks on a playable item.
          */
-        protected void onPlayableItemClicked(MediaItemMetadata item) {
+        protected void onPlayableItemClicked(@NonNull MediaItemMetadata item) {
         }
 
         /**
          * Callback invoked when a user clicks on a browsable item.
          */
-        protected void onBrowsableItemClicked(MediaItemMetadata item) {
+        protected void onBrowsableItemClicked(@NonNull MediaItemMetadata item) {
         }
 
         /**
@@ -133,16 +144,6 @@
         mObservers.remove(observer);
     }
 
-    /**
-     * Sets the number of columns that items can take. This method only needs to be used if the
-     * attached {@link RecyclerView} is NOT using a {@link GridLayoutManager}. This class will
-     * automatically determine this value on {@link #onAttachedToRecyclerView(RecyclerView)}
-     * otherwise.
-     */
-    public void setMaxSpanSize(int maxSpanSize) {
-        mMaxSpanSize = maxSpanSize;
-    }
-
     public void setRootBrowsableViewType(int hintValue) {
         mRootBrowsableViewType = fromMediaHint(hintValue);
     }
@@ -151,20 +152,16 @@
         mRootPlayableViewType = fromMediaHint(hintValue);
     }
 
+    public int getSpanSize(int position, int maxSpanSize) {
+        BrowseItemViewType viewType = getItem(position).mViewType;
+        return viewType.getSpanSize(maxSpanSize);
+    }
+
     /**
-     * @return a {@link GridLayoutManager.SpanSizeLookup} that can be used to obtain the span size
-     * of each item in this adapter. This method is only needed if the {@link RecyclerView} is NOT
-     * using a {@link GridLayoutManager}. This class will automatically use it on\ {@link
-     * #onAttachedToRecyclerView(RecyclerView)} otherwise.
+     * Sets a listener to listen for the list data changes.
      */
-    private GridLayoutManager.SpanSizeLookup getSpanSizeLookup() {
-        return new GridLayoutManager.SpanSizeLookup() {
-            @Override
-            public int getSpanSize(int position) {
-                BrowseItemViewType viewType = getItem(position).mViewType;
-                return viewType.getSpanSize(mMaxSpanSize);
-            }
-        };
+    public void setOnListChangedListener(OnListChangedListener onListChangedListener) {
+        mOnListChangedListener = onListChangedListener;
     }
 
     @NonNull
@@ -198,6 +195,15 @@
         return getItem(position).mViewType.ordinal();
     }
 
+    @Override
+    public void onCurrentListChanged(@NonNull List<BrowseViewData> previousList,
+            @NonNull List<BrowseViewData> currentList) {
+        super.onCurrentListChanged(previousList, currentList);
+        if (mOnListChangedListener != null) {
+            mOnListChangedListener.onListChanged(previousList, currentList);
+        }
+    }
+
     public void submitItems(@Nullable MediaItemMetadata parentItem,
             @Nullable List<MediaItemMetadata> children) {
         mParentMediaItem = parentItem;
@@ -214,15 +220,6 @@
         }
     }
 
-    @Override
-    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
-        if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
-            GridLayoutManager manager = (GridLayoutManager) recyclerView.getLayoutManager();
-            mMaxSpanSize = manager.getSpanCount();
-            manager.setSpanSizeLookup(getSpanSizeLookup());
-        }
-    }
-
     private class ItemsBuilder {
         private List<BrowseViewData> result = new ArrayList<>();
 
diff --git a/src/com/android/car/media/browse/BrowseViewHolder.java b/src/com/android/car/media/browse/BrowseViewHolder.java
index aa4449f..b885a9c 100644
--- a/src/com/android/car/media/browse/BrowseViewHolder.java
+++ b/src/com/android/car/media/browse/BrowseViewHolder.java
@@ -34,7 +34,7 @@
 /**
  * Generic {@link RecyclerView.ViewHolder} to use for all views in the {@link BrowseAdapter}
  */
-class BrowseViewHolder extends RecyclerView.ViewHolder {
+public class BrowseViewHolder extends RecyclerView.ViewHolder {
     private final TextView mTitle;
     private final TextView mSubtitle;
     private final ImageView mAlbumArt;
@@ -55,7 +55,7 @@
         mTitle = itemView.findViewById(com.android.car.media.R.id.title);
         mSubtitle = itemView.findViewById(com.android.car.media.R.id.subtitle);
         mAlbumArt = itemView.findViewById(com.android.car.media.R.id.thumbnail);
-        mContainer = itemView.findViewById(com.android.car.media.R.id.container);
+        mContainer = itemView.findViewById(com.android.car.media.R.id.item_container);
         mRightArrow = itemView.findViewById(com.android.car.media.R.id.right_arrow);
         mTitleDownloadIcon = itemView.findViewById(
                 com.android.car.media.R.id.download_icon_with_title);
diff --git a/src/com/android/car/media/browse/LimitedBrowseAdapter.java b/src/com/android/car/media/browse/LimitedBrowseAdapter.java
new file mode 100644
index 0000000..6d3c6a7
--- /dev/null
+++ b/src/com/android/car/media/browse/LimitedBrowseAdapter.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.media.browse;
+
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.media.R;
+import com.android.car.media.common.MediaItemMetadata;
+import com.android.car.ui.recyclerview.DelegatingContentLimitingAdapter;
+
+import java.util.List;
+
+/**
+ * Provides list limiting functionality to {@link BrowseAdapter}.
+ */
+public class LimitedBrowseAdapter extends DelegatingContentLimitingAdapter<BrowseViewHolder> {
+
+    private final BrowseAdapter mBrowseAdapter;
+    private final GridLayoutManager mLayoutManager;
+    private final int mMaxSpanSize;
+
+    @Nullable private String mAnchorId;
+
+    public LimitedBrowseAdapter(BrowseAdapter browseAdapter, GridLayoutManager manager,
+            BrowseAdapter.Observer browseAdapterObserver) {
+        super(browseAdapter, R.id.browse_list_uxr_config);
+
+        mBrowseAdapter = browseAdapter;
+        mLayoutManager = manager;
+        mMaxSpanSize = manager.getSpanCount();
+
+        mLayoutManager.setSpanSizeLookup(mSpanSizeLookup);
+        mBrowseAdapter.registerObserver(browseAdapterObserver);
+        mBrowseAdapter.setOnListChangedListener(((previousList, currentList) -> {
+            updateUnderlyingDataChanged(currentList.size(), validateAnchor());
+        }));
+    }
+
+    private final GridLayoutManager.SpanSizeLookup mSpanSizeLookup =
+            new GridLayoutManager.SpanSizeLookup() {
+                @Override
+                public int getSpanSize(int position) {
+                    if (getItemViewType(position) == getScrollingLimitedMessageViewType()) {
+                        return mMaxSpanSize;
+                    }
+
+                    int itemIndex = positionToIndex(position);
+                    return mBrowseAdapter.getSpanSize(itemIndex, mMaxSpanSize);
+                }
+            };
+
+    /**
+     * @see BrowseAdapter#submitItems(MediaItemMetadata, List)
+     */
+    public void submitItems(@Nullable MediaItemMetadata parentItem,
+            @Nullable List<MediaItemMetadata> items) {
+        mBrowseAdapter.submitItems(parentItem, items);
+
+        if (items == null) {
+            updateUnderlyingDataChanged(0, 0);
+            return;
+        }
+        // We can't take any action with the new items as they must first go through the
+        // AsyncListDiffer of ListAdapter. This is handled in the OnListChangedListener.
+    }
+
+    private int validateAnchor() {
+        if (mAnchorId == null) {
+            return 0;
+        }
+
+        List<BrowseViewData> items = mBrowseAdapter.getCurrentList();
+        for (int i = 0; i < items.size(); i++) {
+            MediaItemMetadata mediaItem = items.get(i).mMediaItem;
+            if (mediaItem != null && mAnchorId.equals(mediaItem.getId())) {
+                return i;
+            }
+        }
+
+        // The anchor isn't present in the new list, reset it.
+        mAnchorId = null;
+        return 0;
+    }
+
+
+    @Override
+    public int computeAnchorIndexWhenRestricting() {
+        List<BrowseViewData> items = mBrowseAdapter.getCurrentList();
+        if (items.size() <= 0) {
+            mAnchorId = null;
+            return 0;
+        }
+
+        int anchorIndex = (getFirstVisibleItemPosition() + getLastVisibleItemPosition()) / 2;
+        if (0 <= anchorIndex && anchorIndex < items.size()) {
+            MediaItemMetadata mediaItem = items.get(anchorIndex).mMediaItem;
+            mAnchorId = mediaItem != null ? mediaItem.getId() : null;
+            return anchorIndex;
+        } else {
+            mAnchorId = null;
+            return 0;
+        }
+    }
+
+    private int getFirstVisibleItemPosition() {
+        int firstItem = mLayoutManager.findFirstCompletelyVisibleItemPosition();
+        if (firstItem == RecyclerView.NO_POSITION) {
+            firstItem = mLayoutManager.findFirstVisibleItemPosition();
+        }
+        return firstItem;
+    }
+
+    private int getLastVisibleItemPosition() {
+        int lastItem = mLayoutManager.findLastCompletelyVisibleItemPosition();
+        if (lastItem == RecyclerView.NO_POSITION) {
+            lastItem = mLayoutManager.findLastVisibleItemPosition();
+        }
+        return lastItem;
+    }
+}
diff --git a/src/com/android/car/media/widgets/AppBarView.java b/src/com/android/car/media/widgets/AppBarController.java
similarity index 62%
rename from src/com/android/car/media/widgets/AppBarView.java
rename to src/com/android/car/media/widgets/AppBarController.java
index b17a773..962f2ac 100644
--- a/src/com/android/car/media/widgets/AppBarView.java
+++ b/src/com/android/car/media/widgets/AppBarController.java
@@ -3,7 +3,8 @@
 import android.car.drivingstate.CarUxRestrictions;
 import android.content.Context;
 import android.content.Intent;
-import android.util.AttributeSet;
+import android.graphics.drawable.Drawable;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -13,6 +14,7 @@
 import com.android.car.media.common.source.MediaSource;
 import com.android.car.ui.toolbar.MenuItem;
 import com.android.car.ui.toolbar.Toolbar;
+import com.android.car.ui.toolbar.ToolbarController;
 
 import java.util.Arrays;
 import java.util.List;
@@ -24,13 +26,16 @@
  * views via {@link #setState}. A detailed explanation of all possible states of this application
  * bar can be seen at {@link Toolbar.State}.
  */
-public class AppBarView extends Toolbar {
+public class AppBarController {
 
     private static final int MEDIA_UX_RESTRICTION_DEFAULT =
             CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP;
     private static final int MEDIA_UX_RESTRICTION_NONE = CarUxRestrictions.UX_RESTRICTIONS_BASELINE;
 
     private int mMaxTabs;
+    private final ToolbarController mToolbarController;
+
+    private final boolean mUseSourceLogoForAppSelector;
 
     @NonNull
     private AppBarListener mListener = new AppBarListener();
@@ -41,6 +46,7 @@
 
     private boolean mSearchSupported;
     private boolean mShowSearchIfSupported;
+    private String mSearchQuery;
 
     private Intent mAppSelectorIntent;
 
@@ -54,11 +60,6 @@
         protected void onTabSelected(MediaItemMetadata item) {}
 
         /**
-         * Invoked when the user clicks on the back button
-         */
-        protected void onBack() {}
-
-        /**
          * Invoked when the user clicks on the settings button.
          */
         protected void onSettingsSelection() {}
@@ -77,56 +78,48 @@
          * Invoked when the user clicks on the search button
          */
         protected void onSearchSelection() {}
-
-        /**
-         * Invoked when the height of the toolbar changes
-         */
-        protected void onHeightChanged(int height) {}
     }
 
-    public AppBarView(Context context) {
-        this(context, null);
-    }
-
-    public AppBarView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public AppBarView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(context);
-    }
-
-    private void init(Context context) {
+    public AppBarController(Context context, ToolbarController controller) {
+        mToolbarController = controller;
         mMaxTabs = context.getResources().getInteger(R.integer.max_tabs);
 
+        mUseSourceLogoForAppSelector =
+                context.getResources().getBoolean(R.bool.use_media_source_logo_for_app_selector);
+
         mAppSelectorIntent = MediaSource.getSourceSelectorIntent(context, false);
 
-        registerOnTabSelectedListener(tab ->
+        mToolbarController.registerOnTabSelectedListener(tab ->
                 mListener.onTabSelected(((MediaItemTab) tab).getItem()));
-        registerOnBackListener(() -> {
-            mListener.onBack();
-            return true;
+        mToolbarController.registerOnSearchListener(query -> {
+            mSearchQuery = query;
+            mListener.onSearch(query);
         });
-        registerOnSearchListener(query -> mListener.onSearch(query));
-        registerToolbarHeightChangeListener(height -> mListener.onHeightChanged(height));
-        mSearch = MenuItem.Builder.createSearch(context, v -> mListener.onSearchSelection());
-        mSettings = new MenuItem.Builder(context)
+        mToolbarController.registerOnSearchCompletedListener(
+                () -> mListener.onSearch(mSearchQuery));
+        mSearch = MenuItem.builder(context)
+                .setToSearch()
+                .setOnClickListener(v -> mListener.onSearchSelection())
+                .build();
+        mSettings = MenuItem.builder(context)
                 .setToSettings()
                 .setUxRestrictions(MEDIA_UX_RESTRICTION_DEFAULT)
                 .setOnClickListener(v -> mListener.onSettingsSelection())
                 .build();
-        mEqualizer = new MenuItem.Builder(context)
+        mEqualizer = MenuItem.builder(context)
                 .setTitle(R.string.menu_item_sound_settings_title)
                 .setIcon(R.drawable.ic_equalizer)
                 .setOnClickListener(v -> mListener.onEqualizerSelection())
                 .build();
-        mAppSelector = new MenuItem.Builder(context)
+        mAppSelector = MenuItem.builder(context)
                 .setTitle(R.string.menu_item_app_selector_title)
-                .setIcon(R.drawable.ic_app_switch)
-                .setOnClickListener(m -> getContext().startActivity(mAppSelectorIntent))
+                .setTinted(!mUseSourceLogoForAppSelector)
+                .setIcon(mUseSourceLogoForAppSelector
+                        ? null : context.getDrawable(R.drawable.ic_app_switch))
+                .setOnClickListener(m -> context.startActivity(mAppSelectorIntent))
                 .build();
-        setMenuItems(Arrays.asList(mSearch, mEqualizer, mSettings, mAppSelector));
+        mToolbarController.setMenuItems(
+                Arrays.asList(mSearch, mEqualizer, mSettings, mAppSelector));
 
         setAppLauncherSupported(mAppSelectorIntent != null);
     }
@@ -145,12 +138,12 @@
      * @param items list of tabs to show, or null if no tabs should be shown.
      */
     public void setItems(@Nullable List<MediaItemMetadata> items) {
-        clearAllTabs();
+        mToolbarController.clearAllTabs();
 
         if (items != null && !items.isEmpty()) {
             int count = 0;
             for (MediaItemMetadata item : items) {
-                addTab(new MediaItemTab(item));
+                mToolbarController.addTab(new MediaItemTab(item));
 
                 count++;
                 if (count >= mMaxTabs) {
@@ -206,15 +199,65 @@
      * Updates the currently active item
      */
     public void setActiveItem(MediaItemMetadata item) {
-        for (int i = 0; i < getTabLayout().getTabCount(); i++) {
-            MediaItemTab mediaItemTab = (MediaItemTab) getTabLayout().get(i);
+        for (int i = 0; i < mToolbarController.getTabCount(); i++) {
+            MediaItemTab mediaItemTab = (MediaItemTab) mToolbarController.getTab(i);
             boolean match = item != null && Objects.equals(
                     item.getId(),
                     mediaItemTab.getItem().getId());
             if (match) {
-                getTabLayout().selectTab(i);
+                mToolbarController.selectTab(i);
                 return;
             }
         }
     }
+
+    public void setSearchQuery(String query) {
+        mToolbarController.setSearchQuery(query);
+    }
+
+    public void setLogo(Drawable drawable) {
+        if (mUseSourceLogoForAppSelector) {
+            mAppSelector.setIcon(drawable);
+        } else {
+            mToolbarController.setLogo(drawable);
+        }
+    }
+
+    public void setSearchIcon(Drawable drawable) {
+        mToolbarController.setSearchIcon(drawable);
+    }
+
+    public void setTitle(CharSequence title) {
+        mToolbarController.setTitle(title);
+    }
+
+    public void setTitle(int title) {
+        mToolbarController.setTitle(title);
+    }
+
+    public void setState(Toolbar.State state) {
+        mToolbarController.setState(state);
+    }
+
+    public void setMenuItems(List<MenuItem> items) {
+        mToolbarController.setMenuItems(items);
+    }
+
+    public void setBackgroundShown(boolean shown) {
+        mToolbarController.setBackgroundShown(shown);
+    }
+
+    public void setNavButtonMode(Toolbar.NavButtonMode mode) {
+        mToolbarController.setNavButtonMode(mode);
+    }
+
+    /** See {@link ToolbarController#canShowSearchResultItems}. */
+    public boolean canShowSearchResultsView() {
+        return mToolbarController.canShowSearchResultsView();
+    }
+
+    /** See {@link ToolbarController#setSearchResultsView}. */
+    public void setSearchResultsView(View view) {
+        mToolbarController.setSearchResultsView(view);
+    }
 }
diff --git a/tools/generate-overlayable.sh b/tools/generate-overlayable.sh
new file mode 100755
index 0000000..833d9f5
--- /dev/null
+++ b/tools/generate-overlayable.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#  Copyright (C) 2021 The Android Open Source Project
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+# Run this script to regenerate the overlayable.xml file.
+
+if [[ -z "$ANDROID_BUILD_TOP" ]]; then
+  echo 'ANDROID_BUILD_TOP environment variable is empty; did you forget to run `lunch`?'
+  exit 1
+fi
+
+PROJECT_TOP=$ANDROID_BUILD_TOP/packages/apps/Car/Media
+
+python $ANDROID_BUILD_TOP/packages/apps/Car/tests/tools/rro/generate-overlayable.py \
+    -n CarMediaApp \
+    -r $PROJECT_TOP/res \
+    -e $PROJECT_TOP/res/values/overlayable.xml $PROJECT_TOP/res/xml/automotive_app_desc.xml \
+    -o $PROJECT_TOP/res/values/overlayable.xml
\ No newline at end of file