Update CarLauncher Owners am: 4d9257df23

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Car/Launcher/+/2278186

Change-Id: I972869c7b9fbf5e67de038535e81e068ceadee18
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1d3fc7b..8c990c2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -125,6 +125,8 @@
             Dialer application.-->
             <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="false"/>
             <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI" android:value="false"/>
+            <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+                android:value="true" />
             <intent-filter>
                 <action android:name="android.telecom.InCallService"/>
             </intent-filter>
diff --git a/res/drawable-night/ic_launcher_home.png b/res/drawable-night/ic_launcher_home.png
deleted file mode 100644
index 2cc02a6..0000000
--- a/res/drawable-night/ic_launcher_home.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-night/ic_launcher_home.xml b/res/drawable-night/ic_launcher_home.xml
new file mode 100644
index 0000000..72e70be
--- /dev/null
+++ b/res/drawable-night/ic_launcher_home.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="48"
+        android:viewportHeight="48">
+
+    <path
+        android:fillColor="@color/launcher_home_icon_color"
+        android:fillType="evenOdd"
+        android:pathData="M24 48C37.2548 48 48 37.2548 48 24C48 10.7452 37.2548 0 24 0C10.7452 0 0 10.7452 0 24C0 37.2548 10.7452 48 24 48ZM13.4395 20.16V35.52H17.3995V22.72H30.5995V35.52H34.5595V20.16L23.9995 12.48L13.4395 20.16ZM27.9595 30.4V32.96H20.0395V30.4H27.9595ZM27.9595 25.28V27.84H20.0395V25.28H27.9595Z" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_launcher_home.png b/res/drawable/ic_launcher_home.png
deleted file mode 100644
index da4fe58..0000000
--- a/res/drawable/ic_launcher_home.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_launcher_home.xml b/res/drawable/ic_launcher_home.xml
new file mode 100644
index 0000000..72e70be
--- /dev/null
+++ b/res/drawable/ic_launcher_home.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="48"
+        android:viewportHeight="48">
+
+    <path
+        android:fillColor="@color/launcher_home_icon_color"
+        android:fillType="evenOdd"
+        android:pathData="M24 48C37.2548 48 48 37.2548 48 24C48 10.7452 37.2548 0 24 0C10.7452 0 0 10.7452 0 24C0 37.2548 10.7452 48 24 48ZM13.4395 20.16V35.52H17.3995V22.72H30.5995V35.52H34.5595V20.16L23.9995 12.48L13.4395 20.16ZM27.9595 30.4V32.96H20.0395V30.4H27.9595ZM27.9595 25.28V27.84H20.0395V25.28H27.9595Z" />
+</vector>
\ No newline at end of file
diff --git a/res/layout/app_item.xml b/res/layout/app_item.xml
index cecbc65..cae5797 100644
--- a/res/layout/app_item.xml
+++ b/res/layout/app_item.xml
@@ -23,6 +23,7 @@
               android:layout_marginBottom="@dimen/app_grid_row_margin"
               android:layout_marginEnd="@dimen/app_touch_target_margin"
               android:layout_marginStart="@dimen/app_touch_target_margin"
+              android:background="?android:attr/selectableItemBackground"
               android:gravity="center"
               android:orientation="vertical"
               android:padding="@dimen/app_touch_target_padding">
diff --git a/res/layout/descriptive_text.xml b/res/layout/descriptive_text.xml
index 317bd4f..f1aa5b0 100644
--- a/res/layout/descriptive_text.xml
+++ b/res/layout/descriptive_text.xml
@@ -34,7 +34,7 @@
         android:id="@+id/primary_text"
         android:layout_height="wrap_content"
         android:layout_width="0dp"
-        android:singleLine="true"
+        android:maxLines="2"
         android:textAppearance="?android:attr/textAppearanceLarge"
         android:layout_marginStart="@dimen/card_content_image_margin"
         app:layout_goneMarginStart="0dp"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 212c1a7..c300dc9 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Bel tans …"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Begin Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Kan nie Android Auto begin nie. Geen aktiwiteit gevind nie."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# toestel}other{# toestelle}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weer"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° meestal sonnig"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Bergaansig • H: --° L: --°"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 24484e2..8e602e7 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"በመደወል ላይ…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Autoን አስጀምር"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Autoን ማስጀመር አልተቻለም። ምንም እንቅስቃሴ አልተገኘም።"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# መሣሪያ}one{# መሣሪያዎች}other{# መሣሪያዎች}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"የአየር ሁኔታ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° በአብዛኛው ጸሐያማ"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"የተራራ እይታ • ከ፦ --° ዝ፦ --°"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 7c43663..968f3ad 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"جارٍ طلب الرقم…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"تشغيل Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"يتعذّر تشغيل Android Auto. لم يتم العثور على أي أنشطة."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{جهاز واحد (#)}zero{# جهاز}two{جهازان (#)}few{# أجهزة}many{# جهازًا}other{# جهاز}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"الطقس"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° مشمس في أغلب الأوقات"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"مدينة القاهرة • درجة الحرارة الأعلى: --° الأدنى: --°"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 7412d08..00c1f3e 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ডায়েল কৰি থকা হৈছে…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto লঞ্চ কৰক"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto লঞ্চ কৰিব পৰা নগ’ল। কোনো কাৰ্যকলাপ পোৱা নগ’ল।"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# টা ডিভাইচ}one{# টা ডিভাইচ}other{# টা ডিভাইচ}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"বতৰ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° অধিক সময় ৰৌদ্ৰোজ্জ্বল"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"মাউণ্টেইন ভিউ • H: --° L: --°"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 83a2333..fc13524 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Nömrə yığılır…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto\'nu başladın"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto\'nu başlatmaq mümkün deyil. Fəaliyyət tapılmadı."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# cihaz}other{# cihaz}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Hava"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Əksərən günəşli"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Dağ Görünüşü • Y: --° U: --°"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index f25b7ed..bc39d61 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Poziva se…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Pokreni Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Pokretanje usluge Android Auto nije uspelo. Nije pronađena nijedna aktivnost."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Vreme"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° uglavnom sunčano"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Novi Sad • Najviša: --° Najniža: --°"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 2d7f0b9..ec0f7f8 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Ідзе набор нумара…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Запусціць Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Не ўдалося запусціць Android Auto. Дзеянні не знойдзены."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# прылада}one{# прылада}few{# прылады}many{# прылад}other{# прылады}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Надвор\'е"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--°, пераважна сонечна"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Маўтын-В\'ю • макс.: --°, мін.: --°"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 4c3cef9..dc0a5f2 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Набиране…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Стартиране на Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto не може да се стартира. Няма намерена активност."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# устройство}other{# устройства}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Времето"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Предимно слънчево"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Макс: --° Мин: --°"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index d685aba..dad3d42 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ডায়াল করা হচ্ছে…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto লঞ্চ করুন"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto লঞ্চ করা যায়নি। কোনও অ্যাক্টিভিটি পাওয়া যায়নি।"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{#টি ডিভাইস}one{#টি ডিভাইস}other{#টি ডিভাইস}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° সাধারণত রৌদ্রোজ্জ্বল"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"পাহাড়ের দৃশ্য • H: --° L: --°"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 20d014f..1860247 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Biranje…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Pokreni Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Nije moguće pokrenuti Android Auto. Nije pronađena nijedna aktivnost."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Vrijeme"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Pretežno sunčano"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • V: --° N: --°"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 4fb7682..86d8ca8 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"S\'està marcant…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Inicia Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"No es pot iniciar Android Auto. No s\'ha trobat cap activitat."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispositiu}other{# dispositius}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Temps"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Principalment assolellat"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Màx.: --° Mín.: --°"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index a9a2e88..079f968 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Vytáčení…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Spustit Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto se nepodařilo spustit. Nebyla nalezena žádná aktivita."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# zařízení}few{# zařízení}many{# zařízení}other{# zařízení}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Počasí"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Většinou slunečno"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Nejvyšší: --° Nejnižší: --°"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 428e190..a1656a2 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Ringer op…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Start Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto kunne ikke startes. Der blev ikke fundet nogen aktivitet."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# enhed}one{# enhed}other{# enheder}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Vejret"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"-- ° Overvejende solskin"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: -- ° L: -- °"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index d67ff3f..df2bda5 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Rufaufbau…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto starten"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto kann nicht gestartet werden. Keine Aktivität gefunden."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# Gerät}other{# Geräte}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Wetter"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Größtenteils sonnig"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° T: --°"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index f51198b..de0bffb 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Κλήση…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Εκκίνηση του Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Δεν είναι δυνατή η εκκίνηση τη εφαρμογής Android Auto. Δεν βρέθηκαν δραστηριότητες."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# συσκευή}other{# συσκευές}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Καιρός"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Κυρίως ηλιοφάνεια"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Μ: --° Ε: --°"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index aea87d3..154182d 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Dialling…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Launch Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Unable to launch Android Auto. No activity found."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# device}other{# devices}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"–° Mostly sunny"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: –° L: –°"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index aea87d3..154182d 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Dialling…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Launch Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Unable to launch Android Auto. No activity found."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# device}other{# devices}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"–° Mostly sunny"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: –° L: –°"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index aea87d3..154182d 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Dialling…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Launch Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Unable to launch Android Auto. No activity found."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# device}other{# devices}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"–° Mostly sunny"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: –° L: –°"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index aea87d3..154182d 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Dialling…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Launch Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Unable to launch Android Auto. No activity found."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# device}other{# devices}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"–° Mostly sunny"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: –° L: –°"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index e7041c3..1833004 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎Dialing…‎‏‎‎‏‎"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎Launch Android Auto‎‏‎‎‏‎"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎Unable to launch Android Auto. No activity found.‎‏‎‎‏‎"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎# device‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎# devices‎‏‎‎‏‎}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎Weather‎‏‎‎‏‎"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎--° Mostly sunny‎‏‎‎‏‎"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎Mountain View • H: --° L: --°‎‏‎‎‏‎"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 3695fff..5086144 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Marcando…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Iniciar Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"No se puede iniciar Android Auto. No se encontró ninguna actividad."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Tiempo"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Mayormente soleado"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • M: --° M: --°"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 4bacf9f..f5730ac 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Marcando…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Iniciar Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"No se ha podido iniciar Android Auto. No se ha encontrado ninguna actividad."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Tiempo"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--°, mayormente soleado"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Máx.: --° Mín.: --°"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 2d3b569..5401812 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Valimine …"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto käivitamine"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Autot ei õnnestu käivitada. Ühtegi tegevust ei leitud."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# seade}other{# seadet}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Ilm"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° – enamasti päikeseline"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • K: --° M: --°"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 71694ca..3200fa5 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Markatzen…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Abiarazi Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Ezin da abiarazi Android Auto. Ez da jarduerarik aurkitu."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# gailu}other{# gailu}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Eguraldia"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"-- ° Gehienbat eguzkitsua"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: -- ° L: -- °"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 758c667..057fbe4 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"درحال شماره‌گیری…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"راه‌اندازی Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto راه‌اندازی نشد. فعالیتی پیدا نشد."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# دستگاه}one{# دستگاه}other{# دستگاه}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"آب‌وهوا"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° بیشتر آفتابی"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"مانتین ویو • بیشینه: --° کمینه: --°"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index ff51fff..2cef252 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Soitetaan…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Käynnistä Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Autoa ei voi käynnistää. Tapahtumia ei löytynyt."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# laite}other{# laitetta}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Sää"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Enimmäkseen aurinkoista"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Maks.: --° Min.: --°"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index afc69b8..88d6141 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Composition en cours…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Lancez Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Impossible de lancer Android Auto. Aucune activité trouvée."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# appareil}one{# appareil}other{# appareils}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Météo"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° et principalement ensoleillé"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Montréal • Max. : --° Min. : --°"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index b229688..64c5ead 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Appel…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Lancer Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Impossible de lancer Android Auto. Aucune activité trouvée."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# appareil}one{# appareil}other{# appareils}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Météo"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"-- ° Ensoleillé dans l\'ensemble"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Max. : -- ° - Min. : -- °"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 976a67d..c2d830e 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Marcando…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Iniciar Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Non se puido iniciar Android Auto. Non se atopou ningunha actividade."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Información meteorolóxica"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--°, principalmente solleiro"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Máxima: --°; mínima: --°"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 34422f3..eb1f3ad 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ડાયલ કરી રહ્યાં છીએ…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto લૉન્ચ કરો"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto લૉન્ચ કરી શકાતું નથી. કોઈ પ્રવૃત્તિ મળી નથી."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# ડિવાઇસ}one{# ડિવાઇસ}other{# ડિવાઇસ}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° મોટેભાગે તડકો"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"માઉન્ટેન વ્યૂ • H: --° L: --°"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index ac31389..8f2bc10 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"डायल किया जा रहा है…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto लॉन्च करें"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto लॉन्च नहीं किया जा सका. कोई गतिविधि नहीं मिली."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# डिवाइस}one{# डिवाइस}other{# डिवाइस}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° ज़्यादातर समय धूप रहेगी"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"माउंट आबू • H: --° L: --°"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index ed37d64..7e1fe23 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Biranje broja…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Pokrenite Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Pokretanje Android Auta nije uspjelo. Nije pronađena nijedna aktivnost."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Vrijeme"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° uglavnom sunčano"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • V: --° N: --°"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 76d3089..bfa3664 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Tárcsázás…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto indítása"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Az Android Auto indítása nem sikerült. Nem található tevékenység."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# eszköz}other{# eszköz}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Időjárás"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Túlnyomóan napos"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Max.: --° Min.: --°"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 7a3b3db..cdd44d5 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Համարհավաքում…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Գործարկել Android Auto-ն"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Չհաջողվեց գործարկել Android Auto-ն։ Ոչ մի գործողություն չի գտնվել։"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# սարք}one{# սարք}other{# սարք}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Եղանակ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Հիմնականում արևոտ"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Մաունթին Վյու • Առավ.՝ --° Նվազ.՝ --°"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 86212ac..1a2ee89 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Memanggil…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Luncurkan Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Tidak dapat meluncurkan Android Auto. Tidak ditemukan aktivitas."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# perangkat}other{# perangkat}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Cuaca"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Sebagian besar cerah"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 5d0d782..5395bac 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Hringir…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Ræsa Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Ekki er hægt að ræsa Android Auto. Engin virkni fannst."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# tæki}one{# tæki}other{# tæki}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Veður"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Sólskin að mestu"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Fjallasýn • H: --° L: --°"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index c818555..8b6381e 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Chiamata in corso…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Avvia Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Impossibile avviare Android Auto. Non è stata trovata alcuna attività."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispositivo}other{# dispositivi}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Meteo"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--°, prevalentemente soleggiato"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Max: --° Min: --°"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 0bc2471..d7543d6 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"החיוג מתבצע…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"הפעלה של Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"לא ניתן להפעיל את Android Auto. לא נמצאה פעילות."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{מכשיר אחד}two{# מכשירים}many{# מכשירים}other{# מכשירים}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"מזג אוויר"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° שמשי"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°‎"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 18d30c0..a1d5493 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"発信中…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto の起動"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto を起動できません。アクティビティが見つかりません。"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# 台のデバイス}other{# 台のデバイス}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"天気情報"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° 晴れ"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index a24b9cf..21b6c0d 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"მიმდინარეობს აკრეფა…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"გაუშვით Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto-ს გაშვება შეუძლებელია. აქტივობა ვერ მოიძებნა."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# მოწყობილობა}other{# მოწყობილობა}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"ამინდი"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° უმეტესად მზიანი"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"მთების ხედი • მაქს.: --° მინ.: --°"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index f4fe182..1ee7800 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Терілуде…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto қолданбасын іске қосу"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto қолданбасы іске қосылмады. Ешқандай әрекет табылмады."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# құрылғы}other{# құрылғы}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Ауа райы"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° көбінесе күн ашық"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 67fe569..bbec4ce 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"កំពុងហៅ…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"ចាប់ផ្ដើម Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"មិនអាចចាប់ផ្ដើម Android Auto បានទេ។ រកមិនឃើញសកម្មភាពទេ។"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{ឧបករណ៍ #}other{ឧបករណ៍ #}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"អាកាសធាតុ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° ភាគច្រើន​បើកថ្ងៃ"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 9e4f319..aa1e4e9 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ಡಯಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ಯಾವುದೇ ಚಟುವಟಿಕೆ ಕಂಡುಬಂದಿಲ್ಲ."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# ಸಾಧನ}one{# ಸಾಧನಗಳು}other{# ಸಾಧನಗಳು}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"ಹವಾಮಾನ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° ಬಹುತೇಕ ಬಿಸಿಲಿನ ವಾತಾವರಣ"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"ಮೌಂಟೇನ್ ವ್ಯೂ • H: --° L: --°"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 820c414..72f9dfc 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"전화 거는 중…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto 시작"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto를 시작할 수 없습니다. 활동이 없습니다."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{기기 1개}other{기기 #개}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"날씨"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° 대체로 맑음"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"마운틴 뷰 • 최고: --° 최저: --°"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index b4db2a2..f2bdaf1 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Терилүүдө…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto\'ну ишке киргизүү"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto иштетилген жок. Аракеттер табылган жок."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# түзмөк}other{# түзмөк}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Аба ырайы"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Көбүнесе күн чайыттай ачык болот"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Маунтин-Вью • Ж: --° Т: --°"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 691a05b..52e584f 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ກຳລັງໂທ…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"ເປີດໃຊ້ Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"ບໍ່ສາມາດເປີດໃຊ້ Android Auto ໄດ້. ບໍ່ພົບການເຄື່ອນໄຫວໃດໆ."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{ອຸປະກອນ # ເຄື່ອງ}other{ອຸປະກອນ # ເຄື່ອງ}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"ສະພາບອາກາດ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° ແດດອອກເປັນສ່ວນໃຫຍ່"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"ວິວພູເຂົາ • ສູງສຸດ: --° ຕໍ່າສຸດ: --°"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 636dd58..130316b 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Renkamas numeris…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Paleisti „Android Auto“"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Nepavyko paleisti „Android Auto“. Nerasta jokios veiklos."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# įrenginys}one{# įrenginys}few{# įrenginiai}many{# įrenginio}other{# įrenginių}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Orai"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Daugiausia saulėta"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mauntin Vju • H: --° L: --°"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index a7cd62e..9fa0456 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Notiek numura sastādīšana…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Palaist Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Nevar palaist Android Auto. Netika atrasta neviena darbība."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# ierīce}zero{# ierīču}one{# ierīce}other{# ierīces}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Laikapstākļi"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--°; galvenokārt saulains laiks"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mauntinvjū • Augstākā: --°; zemākā: --°"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 482348f..c6a3a4e 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Бирање…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Стартувајте ја Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Не може да се стартува Android Auto. Не е најдена активност."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# уред}one{# уред}other{# уреди}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Временска прогноза"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"-- ° Претежно сончево"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Маунтин Вју • В: -- ° Н: -- °"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 7fc810a..c7ced4a 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ഡയൽ ചെയ്യുന്നു…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto ലോഞ്ച് ചെയ്യുക"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto ലോഞ്ച് ചെയ്യാനാകുന്നില്ല. ആക്റ്റിവിറ്റിയൊന്നും കണ്ടെത്തിയില്ല."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# ഉപകരണം}other{# ഉപകരണങ്ങൾ}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"കാലാവസ്ഥ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° കൂടുതലും തെളിഞ്ഞ ആകാശം"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • കൂടിയത്: --° കുറഞ്ഞത്: --°"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 2b07935..ade4d7c 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Залгаж байна…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Аuto-г эхлүүлэх"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto-г эхлүүлэх боломжгүй. Үйл ажиллагаа олдсонгүй."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# Төхөөрөмж}other{# Төхөөрөмжүүд}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Цаг агаар"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Ихэвчлэн нартай"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Дээд: --° Доод: --°"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index dc2b0cb..2813aba 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"डायल करत आहे…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto लाँच करा"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto लाँच करता आले नाही. कोणतीही अ‍ॅक्टिव्हिटी आढळली नाही."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# डिव्हाइस}other{# डिव्हाइस}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"हवामान"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° बहुतांशी सुर्यप्रकाशित"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"महाबळेश्वर • कमाल: --° किमान: --°"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 22b2c9b..4e52f4b 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Mendail…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Lancarkan Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Tidak dapat melancarkan Android Auto. Tiada aktiviti ditemukan."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# peranti}other{# peranti}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Cuaca"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Kebanyakannya cerah"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Pemandangan Gunung • H: --° L: --°"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 3a72e41..ebeb56e 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ခေါ်ဆိုနေသည်…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto ဖွင့်ပါ"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto ဖွင့်၍မရပါ။ လုပ်ဆောင်ချက် မရှိပါ။"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{စက် # ခု}other{စက် # ခု}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"မိုးလေဝသ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° အများအားဖြင့် နေသာသည်"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • မြင့်- --° နိမ့်- --°"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index fea699e..11f0381 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Slår nummeret …"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Start Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Kan ikke starte Android Auto. Fant ingen aktiviteter."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# enhet}other{# enheter}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Været"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° For det meste sol"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Høyeste temp.: --° Laveste temp.: --°"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 6189f08..33a96e5 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"डायल गरिँदै छ"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto लन्च गर्नुहोस्"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto लन्च गर्न सकिएन। कुनै गतिविधि भेट्टिएन।"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# डिभाइस}other{# वटा डिभाइस}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"मौसम"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° अधिकांश घमाइलो"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"माउन्टेन भ्यू • H: --° L: --°"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 569950a..93291d2 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Kiezen…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto starten"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Kan Android Auto niet starten. Geen activiteit gevonden."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# apparaat}other{# apparaten}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weer"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"-- ° Grotendeels zonnig"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Max: -- ° Min: -- °"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index f738f69..60717e3 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ଡାଏଲ କରାଯାଉଛି…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Autoକୁ ଲଞ୍ଚ କରନ୍ତୁ"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Autoକୁ ଲଞ୍ଚ କରିବା ପାଇଁ ଅସମର୍ଥ। କୌଣସି କାର୍ଯ୍ୟକଳାପ ମିଳୁ ନାହିଁ।"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{#ଟି ଡିଭାଇସ}other{#ଟି ଡିଭାଇସ}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"ପାଣିପାଗ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° ପ୍ରାୟତଃ ଖରା"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"ମାଉଣ୍ଟେନ୍ ଭ୍ୟୁ • H: --° L: --°"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 2660ff7..ba08803 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ਡਾਇਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto ਲਾਂਚ ਕਰੋ"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto ਲਾਂਚ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕੋਈ ਸਰਗਰਮੀ ਨਹੀਂ ਮਿਲੀ।"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# ਡੀਵਾਈਸ}one{# ਡੀਵਾਈਸ}other{# ਡੀਵਾਈਸ}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"ਮੌਸਮ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° ਜ਼ਿਆਦਾਤਰ ਧੁੱਪ"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"ਅੰਮ੍ਰਿਤਸਰ • ਉੱਚ: --° ਨਿਮਨ: --°"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index e4b2293..3c8b96c 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Wybieram numer…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Uruchom Androida Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Nie można uruchomić Androida Auto. Nie znaleziono żadnych działań."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# urządzenie}few{# urządzenia}many{# urządzeń}other{# urządzenia}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Pogoda"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--°, liczne przejaśnienia"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • maks.: --° min.: --°"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 02ecb5d..0e34870 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"A marcar…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Iniciar o Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Não é possível iniciar o Android Auto. Não foram encontradas atividades."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Meteorologia"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Céu maioritariamente limpo"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Máx.: --° Mín.: --°"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index d18cc93..f7b60d3 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Chamando…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Iniciar o Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Não foi possível iniciar o Android Auto. Nenhuma atividade foi encontrada."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispositivo}one{# dispositivo}other{# dispositivos}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Clima"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Predominantemente ensolarado"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Mínima: --° Máxima: --°"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index d25222b..276e817 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -20,18 +20,19 @@
     <string name="app_title" msgid="1995858460392177468">"Lansator de aplicații pentru mașină"</string>
     <string name="app_launcher_title_all_apps" msgid="3215107396036838217">"Toate aplicațiile"</string>
     <string name="app_launcher_title_media_only" msgid="4400886555907422816">"Aplicații media"</string>
-    <string name="driving_toast_text" msgid="149483091947120092">"Nu poți folosi <xliff:g id="APP_NAME">%1$s</xliff:g> în timp ce conduci."</string>
-    <string name="tap_for_more_info_text" msgid="2043549383814415585">"Pentru mai multe informații, atinge cardul"</string>
-    <string name="tap_to_launch_text" msgid="6910695705119260847">"Pentru a lansa, atinge cardul"</string>
+    <string name="driving_toast_text" msgid="149483091947120092">"Nu puteți folosi <xliff:g id="APP_NAME">%1$s</xliff:g> în timp ce conduceți."</string>
+    <string name="tap_for_more_info_text" msgid="2043549383814415585">"Pentru mai multe informații, atingeți cardul"</string>
+    <string name="tap_to_launch_text" msgid="6910695705119260847">"Pentru a lansa, atingeți cardul"</string>
     <string name="ongoing_call_duration_text_separator" msgid="6019453854809413561">" • "</string>
     <string name="ongoing_call_text" msgid="2394626676478708070">"Apel în desfășurare"</string>
     <string name="dialing_call_text" msgid="415326503409745490">"Se apelează…"</string>
-    <string name="projected_launch_text" msgid="5809132353957907500">"Lansează Android Auto"</string>
+    <string name="projected_launch_text" msgid="5809132353957907500">"Lansați Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Nu se poate lansa Android Auto. Nu a fost găsită nicio activitate."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# dispozitiv}few{# dispozitive}other{# de dispozitive}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Meteo"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° În mare parte însorit"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Max: --° Min: --°"</string>
-    <string name="hide_debug_apps" msgid="6128313544379622475">"Ascunde aplicațiile de remediere a erorilor"</string>
-    <string name="show_debug_apps" msgid="4521073121286325786">"Afișează aplicațiile de remediere a erorilor"</string>
+    <string name="hide_debug_apps" msgid="6128313544379622475">"Ascundeți aplicațiile de remediere a erorilor"</string>
+    <string name="show_debug_apps" msgid="4521073121286325786">"Afișați aplicațiile de remediere a erorilor"</string>
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 9a92fcf..90a5808 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Набор номера…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Запустить Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Не удается запустить Android Auto. Ничего не найдено."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# устройство}one{# устройство}few{# устройства}many{# устройств}other{# устройства}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Погода"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Преим. солнечно"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Маунтин-Вью • Макс. --°, мин. --°"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 5696d29..36bfede 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"අමතමින්…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto දියත් කරන්න"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto දියත් කිරීමට නොහැකිය. ක්‍රියාකාරකම් නොමැත."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{උපාංග #ක්}one{උපාංග #ක්}other{උපාංග #ක්}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"කාලගුණය"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° බොහෝ විට අව්ව"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"කඳුකර දර්ශනය • H: --° L: --°"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 1add2ba..083520b 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Vytáča sa…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Spustiť Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto sa nepodarilo spustiť. Nebola nájdená sa žiadna aktivita."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# zariadenie}few{# zariadenia}many{# devices}other{# zariadení}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Počasie"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Väčšinou slnečno"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 5e17c9a..31a983f 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Klicanje …"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Zaženite storitev Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Ni mogoče zagnati Androida Auto. Najdena ni bila nobena dejavnost."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# naprava}one{# naprava}two{# napravi}few{# naprave}other{# naprav}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Vreme"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° pretežno sončno"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • V: --° N: --°"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 4416119..2bc0b4a 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Po formon numrin…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Hap Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto nuk mund të niset. Nuk u gjet asnjë aktivitet."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# pajisje}other{# pajisje}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Moti"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Kryesisht me diell"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • L: --° U: --°"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 634d94a..c81bfda 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Позива се…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Покрени Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Покретање услуге Android Auto није успело. Није пронађена ниједна активност."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# уређај}one{# уређај}few{# уређаја}other{# уређаја}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Време"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° углавном сунчано"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Нови Сад • Највиша: --° Најнижа: --°"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index f9f9247..dbffb81 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Ringer upp …"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Starta Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Det gick inte att starta Android Auto. Ingen aktivitet hittades."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# enhet}other{# enheter}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Väder"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Mestadels soligt"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • max: --° min: --°"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index df698de..24c7959 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Inapiga…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Fungua Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Imeshindwa kufungua Android Auto. Hamna shughuli iliyopatikana."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{Kifaa #}other{Vifaa #}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Hali ya Hewa"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Jua mara nyingi"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mwonekano wa Mlima • H: --° L: --°"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index b979d2a..c464b25 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"டயல் செய்கிறது…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Autoவைத் தொடங்கு"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Autoவைத் தொடங்க முடியவில்லை. செயல்பாடு எதுவுமில்லை."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# சாதனம்}other{# சாதனங்கள்}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Weather"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° உடன் பெரும்பாலும் வெயிலடிக்கும்"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"மவுண்டன் வியூ • H: --° L: --°"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 91954aa..f12f4c1 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"డయల్ చేస్తోంది…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Autoను లాంచ్ చేయండి"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Autoను లాంచ్ చేయడం సాధ్యం కాలేదు. ఏ యాక్టివిటీ కనుగొనబడలేదు."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# పరికరం}other{# పరికరాలు}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"వాతావరణం"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"చాలావరకు --° ఎండగా ఉంటుంది"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"మౌంటెయిన్ వ్యూ • H: --° L: --°"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 6c4ee1c..20506ad 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"กำลังโทรออก…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"เปิด Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"เปิด Android Auto ไม่ได้ ไม่พบกิจกรรม"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{อุปกรณ์ # เครื่อง}other{อุปกรณ์ # เครื่อง}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"สภาพอากาศ"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° แดดจัดเป็นส่วนใหญ่"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"เมาน์เทนวิว • สูงสุด: --° ต่ำสุด: --°"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 717db2c..8653b8e 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Dina-dial…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Ilunsad ang Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Hindi mailunsad ang Android Auto. Walang nakitang aktibidad."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# device}one{# device}other{# na device}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Lagay ng Panahon"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Maaraw sa pangkalahatan"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 564df99..6359c16 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Aranıyor…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto\'yu başlatın"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto başlatılamadı. Hiçbir etkinlik bulunamadı."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# cihaz}other{# cihaz}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Hava durumu"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Çoğunlukla güneşli"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • E.Y.: --° E.D.: --°"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 71cf26e..16af560 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Набір номера…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Запустити Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Не вдається запустити Android Auto. Не знайдено жодних дій."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# пристрій}one{# пристрій}few{# пристрої}many{# пристроїв}other{# пристрою}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Погода"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--°, в основному сонячно"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Маунтін-В\'ю • Макс. --°, мін. --°"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index fd629ee..5733061 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"ڈائل ہو رہی ہے…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto شروع کریں"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto شروع کرنے سے قاصر۔ کوئی سرگرمی نہیں ملی۔"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# آلہ}other{# آلات}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"موسم"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° زیادہ تر دھوپ"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°‎"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 46eec29..9b1c0c2 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Raqam terilmoqda…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Android Auto xizmatini ishga tushirish"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Android Auto ishga tushmadi. Hech qanday harakat topilmadi."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# ta qurilma}other{# ta qurilma}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Ob-havo"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Asosan quyoshli"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • Maks: --° Min: --°"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 5a006ba..7ad0bea 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Đang gọi…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Chạy Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Không thể chạy Android Auto. Không tìm thấy hoạt động nào."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# thiết bị}other{# thiết bị}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Thời tiết"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Nhiều nắng"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Mountain View • H: --° L: --°"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 1556192..b424cb2 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"正在拨号…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"启动 Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"无法启动 Android Auto。未找到任何活动。"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# 个设备}other{# 个设备}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"天气"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° 以晴为主"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"山景城 • 高:--° 低:--°"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 725f273..ee4b0de 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"正在撥號…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"啟動 Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"無法啟動 Android Auto。找不到活動。"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# 部裝置}other{# 部裝置}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"天氣"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° 大致晴朗"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"山景城 • H: --° L: --°"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 49fe232..6df32bc 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"撥號中…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"啟動 Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"無法啟動 Android Auto。找不到任何活動。"</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{# 部裝置}other{# 部裝置}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"天氣"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° 晴時多雲"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"山景城 • 高:--° 低:--°"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 60052e7..bc66686 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -28,7 +28,8 @@
     <string name="dialing_call_text" msgid="415326503409745490">"Iyadayela…"</string>
     <string name="projected_launch_text" msgid="5809132353957907500">"Qalisa i-Android Auto"</string>
     <string name="projected_onclick_launch_error_toast_text" msgid="7462478007773137082">"Ayikwazi ukuqalisa i-Android Auto. Awukho umsebenzi otholakalayo."</string>
-    <string name="projection_devices" msgid="916314090031116598">"{count,plural, =1{idivayisi #}one{amadivayisi #}other{amadivayisi #}}"</string>
+    <!-- no translation found for projection_devices (916314090031116598) -->
+    <skip />
     <string name="weather_app_name" msgid="8048146303519139993">"Isimo sezulu"</string>
     <string name="fake_weather_main_text" msgid="8117240999340284429">"--° Kuzoshisa isikhathi esiningi"</string>
     <string name="fake_weather_footer_text" msgid="4570172025869749926">"Ukubuka Kwentaba • H: --° L: --°"</string>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index fe15153..9367957 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -23,4 +23,5 @@
     <color name="dialer_button_icon_color">#FFFFFF</color>
     <color name="dialer_end_call_button_color">#EE675C</color>
     <color name="minimized_progress_bar_background">#5CFFFFFF</color>
+    <color name="launcher_home_icon_color">#66B5FF</color>
 </resources>
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
index b1ab52f..e4af574 100644
--- a/res/values/overlayable.xml
+++ b/res/values/overlayable.xml
@@ -25,6 +25,7 @@
       <item type="color" name="dialer_button_icon_color"/>
       <item type="color" name="dialer_end_call_button_color"/>
       <item type="color" name="icon_tint"/>
+      <item type="color" name="launcher_home_icon_color"/>
       <item type="color" name="media_button_tint"/>
       <item type="color" name="minimized_progress_bar_background"/>
       <item type="color" name="recent_apps_line_divider_color"/>
@@ -84,6 +85,7 @@
       <item type="drawable" name="ic_call_end_button"/>
       <item type="drawable" name="ic_clear_black"/>
       <item type="drawable" name="ic_dialpad"/>
+      <item type="drawable" name="ic_launcher_home"/>
       <item type="drawable" name="ic_mic_off"/>
       <item type="drawable" name="ic_mic_on"/>
       <item type="drawable" name="ic_mute_activatable"/>
@@ -151,6 +153,7 @@
       <item type="string" name="app_launcher_title_media_only"/>
       <item type="string" name="app_title"/>
       <item type="string" name="config_smallCanvasOptimizedMapIntent"/>
+      <item type="string" name="default_media_song_title"/>
       <item type="string" name="dialing_call_text"/>
       <item type="string" name="driving_toast_text"/>
       <item type="string" name="fake_weather_footer_text"/>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 949794b..71b8017 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -20,6 +20,8 @@
     <string name="app_launcher_title_all_apps">All apps</string>
     <string name="app_launcher_title_media_only">Media apps</string>
 
+    <string name="default_media_song_title"></string>
+
     <string name="driving_toast_text">
         <xliff:g id="app_name" example="Settings">%1$s</xliff:g> can\'t be used while driving.
     </string>
diff --git a/src/com/android/car/carlauncher/AppLauncherUtils.java b/src/com/android/car/carlauncher/AppLauncherUtils.java
index 3b4eda0..0d637bf 100644
--- a/src/com/android/car/carlauncher/AppLauncherUtils.java
+++ b/src/com/android/car/carlauncher/AppLauncherUtils.java
@@ -261,15 +261,7 @@
                                         carMediaManager);
                             }
                         },
-                        contextArg -> {
-                            // getLaunchIntentForPackage looks for a main activity in the category
-                            // Intent.CATEGORY_INFO, then Intent.CATEGORY_LAUNCHER, and returns null
-                            // if neither are found
-                            Intent packageLaunchIntent =
-                                    packageManager.getLaunchIntentForPackage(packageName);
-                            AppLauncherUtils.launchApp(contextArg,
-                                    packageLaunchIntent != null ? packageLaunchIntent : intent);
-                        });
+                        /* alternateLaunchCallback */ null);
                     launchablesMap.put(componentName, appMetaData);
                 }
             }
@@ -298,7 +290,7 @@
                         info.getBadgedIcon(0),
                         isDistractionOptimized,
                         contextArg -> AppLauncherUtils.launchApp(contextArg, intent),
-                        null);
+                        /* alternateLaunchCallback */ null);
                     launchablesMap.put(componentName, appMetaData);
                 }
             }
@@ -342,7 +334,7 @@
                             Log.i(TAG, "Successfully enabled package [" + packageName + "]");
                             AppLauncherUtils.launchApp(contextArg, intent);
                         },
-                        null);
+                        /* alternateLaunchCallback */ null);
                 launchablesMap.put(componentName, appMetaData);
             }
         }
diff --git a/src/com/android/car/carlauncher/CarFullscreenTaskMonitorListener.java b/src/com/android/car/carlauncher/CarFullscreenTaskMonitorListener.java
index 90c6224..5dbcd44 100644
--- a/src/com/android/car/carlauncher/CarFullscreenTaskMonitorListener.java
+++ b/src/com/android/car/carlauncher/CarFullscreenTaskMonitorListener.java
@@ -23,7 +23,6 @@
 
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
-import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
 
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
@@ -37,9 +36,8 @@
 
     public CarFullscreenTaskMonitorListener(
             AtomicReference<CarActivityManager> carActivityManagerRef,
-            SyncTransactionQueue syncQueue,
-            Optional<FullscreenUnfoldController> unfoldController) {
-        super(syncQueue, unfoldController);
+            SyncTransactionQueue syncQueue) {
+        super(syncQueue);
         mCarActivityManagerRef = carActivityManagerRef;
     }
     @Override
diff --git a/src/com/android/car/carlauncher/CarLauncher.java b/src/com/android/car/carlauncher/CarLauncher.java
index 7a62dc3..e045a4e 100644
--- a/src/com/android/car/carlauncher/CarLauncher.java
+++ b/src/com/android/car/carlauncher/CarLauncher.java
@@ -17,49 +17,32 @@
 package com.android.car.carlauncher;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING;
-import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 
 import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.app.PendingIntent;
 import android.app.TaskStackListener;
-import android.car.Car;
-import android.car.app.CarActivityManager;
 import android.car.user.CarUserManager;
-import android.car.user.CarUserManager.UserLifecycleListener;
-import android.car.user.UserLifecycleEventFilter;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.res.Configuration;
-import android.graphics.Rect;
 import android.os.Bundle;
-import android.os.UserManager;
 import android.util.Log;
-import android.view.Display;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 
 import androidx.collection.ArraySet;
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentTransaction;
-import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.ViewModelProvider;
 
 import com.android.car.carlauncher.homescreen.HomeCardModule;
 import com.android.car.carlauncher.taskstack.TaskStackChangeListeners;
 import com.android.car.internal.common.UserHelperLite;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.wm.shell.TaskView;
 import com.android.wm.shell.common.HandlerExecutor;
 
+import com.google.common.annotations.VisibleForTesting;
+
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Basic Launcher for Android Automotive which demonstrates the use of {@link TaskView} to host
@@ -76,82 +59,22 @@
  */
 public class CarLauncher extends FragmentActivity {
     public static final String TAG = "CarLauncher";
-    private static final boolean DEBUG = false;
-    private static final String SCHEME_PACKAGE = "package";
-
-    private final AtomicReference<CarActivityManager> mCarActivityManagerRef =
-            new AtomicReference<>();
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private ActivityManager mActivityManager;
-    private UserManager mUserManager;
-    private CarUserManager mCarUserManager;
     private TaskViewManager mTaskViewManager;
 
-    private TaskView mTaskView;
-    private boolean mTaskViewReady;
-    // Tracking this to check if the task in TaskView has crashed in the background.
-    private int mTaskViewTaskId = INVALID_TASK_ID;
+    private CarTaskView mTaskView;
     private int mCarLauncherTaskId = INVALID_TASK_ID;
     private Set<HomeCardModule> mHomeCardModules;
 
     /** Set to {@code true} once we've logged that the Activity is fully drawn. */
     private boolean mIsReadyLogged;
-
     private boolean mUseSmallCanvasOptimizedMap;
 
-    // The callback methods in {@code mTaskViewListener} are running under MainThread.
-    private final TaskView.Listener mTaskViewListener = new TaskView.Listener() {
-        @Override
-        public void onInitialized() {
-            if (DEBUG) Log.d(TAG, "onInitialized(" + getUserId() + ")");
-            mTaskViewReady = true;
-            startMapsInTaskView();
-            maybeLogReady();
-        }
-
-        @Override
-        public void onReleased() {
-            if (DEBUG) Log.d(TAG, "onReleased(" + getUserId() + ")");
-            mTaskViewReady = false;
-        }
-
-        @Override
-        public void onTaskCreated(int taskId, ComponentName name) {
-            if (DEBUG) Log.d(TAG, "onTaskCreated: taskId=" + taskId);
-            mTaskViewTaskId = taskId;
-            if (isResumed()) {
-                maybeBringEmbeddedTaskToForeground();
-            }
-        }
-
-        @Override
-        public void onTaskRemovalStarted(int taskId) {
-            if (DEBUG) Log.d(TAG, "onTaskRemovalStarted: taskId=" + taskId);
-            mTaskViewTaskId = INVALID_TASK_ID;
-            // Don't restart the crashed Maps automatically, because it hinders lots of MultiXXX
-            // CTS tests which cleans up all tasks but Home, then monitor Activity state
-            // changes. If it restarts Maps, which causes unexpected Activity state changes.
-        }
-    };
-
     private final TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
-        public void onTaskFocusChanged(int taskId, boolean focused) {
-            boolean launcherFocused = taskId == mCarLauncherTaskId && focused;
-            if (DEBUG) {
-                Log.d(TAG, "onTaskFocusChanged: taskId=" + taskId
-                        + ", launcherFocused=" + launcherFocused
-                        + ", mTaskViewTaskId=" + mTaskViewTaskId);
-            }
-            if (!launcherFocused) {
-                return;
-            }
-            if (mTaskViewTaskId == INVALID_TASK_ID) {
-                // If the task in TaskView is crashed during CarLauncher is background,
-                // We'd like to restart it when CarLauncher becomes foreground and focused.
-                startMapsInTaskView();
-            }
-        }
+        public void onTaskFocusChanged(int taskId, boolean focused) {}
 
         @Override
         public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
@@ -162,61 +85,23 @@
             }
             if (!mUseSmallCanvasOptimizedMap
                     && !homeTaskVisible
-                    && mTaskViewTaskId == task.taskId) {
+                    && mTaskView != null
+                    && mTaskView.getTaskId() == task.taskId) {
                 // The embedded map component received an intent, therefore forcibly bringing the
                 // launcher to the foreground.
                 bringToForeground();
                 return;
             }
-            if (homeTaskVisible && mCarLauncherTaskId == task.taskId
-                    && mTaskViewTaskId == INVALID_TASK_ID) {
-                // Interprets Home Intent while CarLauncher is foreground and Maps is crashed
-                // as restarting Maps.
-                startMapsInTaskView();
-            }
-        }
-    };
-
-    private final UserLifecycleListener mUserLifecycleListener = event -> {
-        if (DEBUG) {
-            Log.d(TAG, "UserLifecycleListener.onEvent: For User " + getUserId()
-                    + ", received an event " + event);
-        }
-        // When user-unlocked, if Maps isn't launched yet, then try to start it.
-        if (event.getEventType() == USER_LIFECYCLE_EVENT_TYPE_UNLOCKED
-                && getUserId() == event.getUserId()
-                && mTaskViewTaskId == INVALID_TASK_ID) {
-            startMapsInTaskView();
-            return;
-        }
-
-        // When user-switching, onDestroy in the previous user's CarLauncher isn't called.
-        // So tries to release the resource explicitly.
-        if (event.getEventType() == USER_LIFECYCLE_EVENT_TYPE_SWITCHING
-                && getUserId() == event.getPreviousUserId()) {
-            release();
-            return;
-        }
-    };
-
-    private Set<String> mTaskViewPackages;
-    private final BroadcastReceiver mPackageBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DEBUG) Log.d(TAG, "onReceive: intent=" + intent);
-            String packageName = intent.getData().getSchemeSpecificPart();
-            boolean started = getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED);
-            if (started  // Don't start Maps in STOPPED, because it'll be started onRestart.
-                    && mTaskViewTaskId == INVALID_TASK_ID
-                    && mTaskViewPackages.contains(packageName)) {
-                startMapsInTaskView();
-            }
         }
     };
 
     @VisibleForTesting
     void setCarUserManager(CarUserManager carUserManager) {
-        mCarUserManager = carUserManager;
+        if (mTaskViewManager == null) {
+            Log.w(TAG, "Task view manager is null, cannot set CarUserManager");
+            return;
+        }
+        mTaskViewManager.setCarUserManager(carUserManager);
     }
 
     @Override
@@ -237,27 +122,7 @@
         mUseSmallCanvasOptimizedMap =
                 CarLauncherUtils.isSmallCanvasOptimizedMapIntentConfigured(this);
 
-        Car.createCar(/* context= */ this, /* handler= */ null,
-                Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER,
-                (car, ready) -> {
-                    if (!ready) {
-                        Log.w(TAG, "CarService looks crashed");
-                        mCarActivityManagerRef.set(null);
-                        return;
-                    }
-                    setCarUserManager((CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE));
-                    UserLifecycleEventFilter filter = new UserLifecycleEventFilter.Builder()
-                            .addEventType(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED)
-                            .addEventType(USER_LIFECYCLE_EVENT_TYPE_SWITCHING).build();
-                    mCarUserManager.addListener(getMainExecutor(), filter, mUserLifecycleListener);
-                    CarActivityManager carAM = (CarActivityManager) car.getCarManager(
-                            Car.CAR_ACTIVITY_SERVICE);
-                    mCarActivityManagerRef.set(carAM);
-                    carAM.registerTaskMonitor();
-                });
-
         mActivityManager = getSystemService(ActivityManager.class);
-        mUserManager = getSystemService(UserManager.class);
         mCarLauncherTaskId = getTaskId();
         TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
 
@@ -283,30 +148,44 @@
         }
         initializeCards();
 
-        mTaskViewPackages = new ArraySet<>(getResources().getStringArray(
-                R.array.config_taskViewPackages));
-        IntentFilter packageIntentFilter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
-        packageIntentFilter.addDataScheme(SCHEME_PACKAGE);
-        registerReceiver(mPackageBroadcastReceiver, packageIntentFilter);
     }
 
     private void setUpTaskView(ViewGroup parent) {
+        Set<String> taskViewPackages = new ArraySet<>(getResources().getStringArray(
+                R.array.config_taskViewPackages));
         mTaskViewManager = new TaskViewManager(this,
-                new HandlerExecutor(getMainThreadHandler()), mCarActivityManagerRef);
-        mTaskViewManager.createTaskView(taskView -> {
-            taskView.setListener(getMainExecutor(), mTaskViewListener);
-            parent.addView(taskView);
-            mTaskView = taskView;
-        });
+                new HandlerExecutor(getMainThreadHandler()));
+
+        Intent mapIntent = mUseSmallCanvasOptimizedMap
+                ? CarLauncherUtils.getSmallCanvasOptimizedMapIntent(this)
+                : CarLauncherUtils.getMapsIntent(this);
+        mTaskViewManager.createControlledCarTaskView(
+                getMainExecutor(),
+                mapIntent,
+                /* autoRestartOnCrash = */ false,
+                new ControlledCarTaskViewCallbacks() {
+                    @Override
+                    public void onTaskViewCreated(CarTaskView taskView) {
+                        parent.addView(taskView);
+                        mTaskView = taskView;
+                    }
+
+                    @Override
+                    public void onTaskViewReady() {
+                        maybeLogReady();
+                    }
+
+                    @Override
+                    public Set<String> getDependingPackageNames() {
+                        return taskViewPackages;
+                    }
+                });
     }
 
     @Override
     protected void onResume() {
         super.onResume();
         maybeLogReady();
-        if (DEBUG) {
-            Log.d(TAG, "onResume(" + getUserId() + "): mTaskViewTaskId=" + mTaskViewTaskId);
-        }
     }
 
     @Override
@@ -315,68 +194,12 @@
         if (CarLauncherUtils.isCustomDisplayPolicyDefined(this)) {
             return;
         }
-        if (DEBUG) {
-            Log.d(TAG, "onDestroy(" + getUserId() + "): mTaskViewTaskId=" + mTaskViewTaskId);
-        }
-        unregisterReceiver(mPackageBroadcastReceiver);
         TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
-        if (mCarUserManager != null) {
-            mCarUserManager.removeListener(mUserLifecycleListener);
-        }
         release();
     }
 
     private void release() {
-        if (mTaskView != null && mTaskViewReady) {
-            mTaskView.release();
-            mTaskView = null;
-        }
-        if (mTaskViewManager != null) {
-            mTaskViewManager.release();
-        }
-        CarActivityManager carAM = mCarActivityManagerRef.get();
-        if (carAM != null) {
-            carAM.unregisterTaskMonitor();
-            mCarActivityManagerRef.set(null);
-        }
-    }
-
-    private void startMapsInTaskView() {
-        if (mTaskView == null || !mTaskViewReady) {
-            if (DEBUG) Log.d(TAG, "Can't start Maps due to TaskView isn't ready.");
-            return;
-        }
-        if (!mUserManager.isUserUnlocked()) {
-            if (DEBUG) Log.d(TAG, "Can't start Maps due to the user isn't unlocked.");
-            return;
-        }
-        // If we happen to be be resurfaced into a multi display mode we skip launching content
-        // in the activity view as we will get recreated anyway.
-        if (isInMultiWindowMode() || isInPictureInPictureMode()) {
-            if (DEBUG) Log.d(TAG, "Can't start Maps due to CarLauncher isn't in a correct mode");
-            return;
-        }
-        // Don't start Maps when the display is off for ActivityVisibilityTests.
-        if (getDisplay().getState() != Display.STATE_ON) {
-            if (DEBUG) Log.d(TAG, "Can't start Maps due to the display is off");
-            return;
-        }
-        try {
-            ActivityOptions options = ActivityOptions.makeCustomAnimation(this,
-                    /* enterResId= */ 0, /* exitResId= */ 0);
-            Intent mapIntent = mUseSmallCanvasOptimizedMap
-                    ? CarLauncherUtils.getSmallCanvasOptimizedMapIntent(this)
-                    : CarLauncherUtils.getMapsIntent(this);
-            Rect launchBounds = new Rect();
-            mTaskView.getBoundsOnScreen(launchBounds);
-            mTaskView.startActivity(
-                    PendingIntent.getActivity(this, /* requestCode= */ 0,
-                            mapIntent,
-                            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT),
-                    /* fillInIntent= */ null, options, launchBounds);
-        } catch (ActivityNotFoundException e) {
-            Log.w(TAG, "Maps activity not found", e);
-        }
+        mTaskView = null;
     }
 
     @Override
@@ -420,11 +243,13 @@
     /** Logs that the Activity is ready. Used for startup time diagnostics. */
     private void maybeLogReady() {
         boolean isResumed = isResumed();
+        boolean taskViewInitialized = mTaskView != null && mTaskView.isInitialized();
         if (DEBUG) {
-            Log.d(TAG, "maybeLogReady(" + getUserId() + "): activityReady=" + mTaskViewReady
-                    + ", started=" + isResumed + ", alreadyLogged: " + mIsReadyLogged);
+            Log.d(TAG, "maybeLogReady(" + getUserId() + "): mapsReady="
+                    + taskViewInitialized + ", started=" + isResumed + ", alreadyLogged: "
+                    + mIsReadyLogged);
         }
-        if (mTaskViewReady && isResumed) {
+        if (taskViewInitialized && isResumed) {
             // We should report every time - the Android framework will take care of logging just
             // when it's effectively drawn for the first time, but....
             reportFullyDrawn();
@@ -438,16 +263,6 @@
         }
     }
 
-    /** Brings embedded task to front, if the task view is created and the task is launched. */
-    private void maybeBringEmbeddedTaskToForeground() {
-        if (mTaskViewTaskId != INVALID_TASK_ID) {
-            // The task in TaskView should be in top to make it visible.
-            // NOTE: Tried setTaskAlwaysOnTop before, the flag has some side effect to hinder
-            // AccessibilityService from finding the correct window geometry: b/197247311
-            mActivityManager.moveTaskToFront(mTaskViewTaskId, /* flags= */ 0);
-        }
-    }
-
     /** Brings the Car Launcher to the foreground. */
     private void bringToForeground() {
         if (mCarLauncherTaskId != INVALID_TASK_ID) {
diff --git a/src/com/android/car/carlauncher/CarLauncherUtils.java b/src/com/android/car/carlauncher/CarLauncherUtils.java
index 6083a83..fabec7e 100644
--- a/src/com/android/car/carlauncher/CarLauncherUtils.java
+++ b/src/com/android/car/carlauncher/CarLauncherUtils.java
@@ -31,10 +31,15 @@
 public class CarLauncherUtils {
 
     private static final String TAG = "CarLauncherUtils";
+    private static final String ACTION_APP_GRID = "com.android.car.carlauncher.ACTION_APP_GRID";
 
     private CarLauncherUtils() {
     }
 
+    public static Intent getAppsGridIntent() {
+        return new Intent(ACTION_APP_GRID);
+    }
+
     /** Intent used to find/launch the maps activity to run in the relevant DisplayArea. */
     public static Intent getMapsIntent(Context context) {
         Intent defaultIntent =
diff --git a/src/com/android/car/carlauncher/CarTaskView.java b/src/com/android/car/carlauncher/CarTaskView.java
index da50f82..6d616d6 100644
--- a/src/com/android/car/carlauncher/CarTaskView.java
+++ b/src/com/android/car/carlauncher/CarTaskView.java
@@ -16,10 +16,17 @@
 
 package com.android.car.carlauncher;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+
+import static com.android.car.carlauncher.TaskViewManager.DBG;
+
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Context;
+import android.graphics.Rect;
+import android.util.Log;
+import android.util.SparseArray;
 import android.view.SurfaceControl;
-import android.view.View;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -28,11 +35,19 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 
 /**
- * CarLauncher version of {@link TaskView} which solves some CarLauncehr specific issues.
+ * CarLauncher version of {@link TaskView} which solves some CarLauncher specific issues:
+ * <ul>
+ * <li>b/228092608: Clears the hidden flag to make it TopFocusedRootTask.</li>
+ * <li>b/225388469: Moves the embedded task to the top to make it resumed.</li>
+ * </ul>
  */
 public class CarTaskView extends TaskView {
+    private static final String TAG = CarTaskView.class.getSimpleName();
+    @Nullable
     private WindowContainerToken mTaskToken;
     private final SyncTransactionQueue mSyncQueue;
+    private final SparseArray<Rect> mInsets = new SparseArray<>();
+    private boolean mTaskViewReadySent;
 
     public CarTaskView(Context context, ShellTaskOrganizer organizer,
             SyncTransactionQueue syncQueue) {
@@ -44,22 +59,76 @@
     public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
         mTaskToken = taskInfo.token;
         super.onTaskAppeared(taskInfo, leash);
+
+        applyInsets();
+    }
+
+    @Override
+    protected void notifyInitialized() {
+        super.notifyInitialized();
+        if (mTaskViewReadySent) {
+            if (DBG) Log.i(TAG, "car task view ready already sent");
+            return;
+        }
+        onCarTaskViewInitialized();
+        mTaskViewReadySent = true;
     }
 
     /**
-     * Called when the visibility of the window containing the view has changed.
-     * @param visibility The new visibility of the window.
+     * Called only once when the {@link CarTaskView} is ready.
      */
-    @Override
-    protected void onWindowVisibilityChanged(int visibility) {
-        super.onWindowVisibilityChanged(visibility);
-        if (visibility == View.VISIBLE && mTaskToken != null) {
-            WindowContainerTransaction wct = new WindowContainerTransaction();
-            // Clears the hidden flag to make it TopFocusedRootTask: b/228092608
-            wct.setHidden(mTaskToken, /* hidden= */false);
-            // Moves the embedded task to the top to make it resumed: b/225388469
-            wct.reorder(mTaskToken, /* onTop= */ true);
-            mSyncQueue.queue(wct);
+    protected void onCarTaskViewInitialized() {}
+
+    /**
+     * Moves the embedded task over the embedding task to make it shown.
+     */
+    public void showEmbeddedTask() {
+        if (mTaskToken == null) {
+            return;
         }
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        // Clears the hidden flag to make it TopFocusedRootTask: b/228092608
+        wct.setHidden(mTaskToken, /* hidden= */ false);
+        // Moves the embedded task to the top to make it resumed: b/225388469
+        wct.reorder(mTaskToken, /* onTop= */ true);
+        mSyncQueue.queue(wct);
+    }
+
+    // TODO(b/238473897): Consider taking insets one by one instead of taking all insets.
+    /**
+     * Set & apply the given {@code insets} on the Task.
+     */
+    public void setInsets(SparseArray<Rect> insets) {
+        mInsets.clear();
+        for (int i = insets.size() - 1; i >= 0; i--) {
+            mInsets.append(insets.keyAt(i), insets.valueAt(i));
+        }
+        applyInsets();
+    }
+
+    private void applyInsets() {
+        if (mInsets == null || mInsets.size() == 0) {
+            Log.w(TAG, "Cannot apply null or empty insets");
+            return;
+        }
+        if (mTaskToken == null) {
+            Log.w(TAG, "Cannot apply insets as the task token is not present.");
+            return;
+        }
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        for (int i = 0; i < mInsets.size(); i++) {
+            wct.addRectInsetsProvider(mTaskToken, mInsets.valueAt(i), new int[]{mInsets.keyAt(i)});
+        }
+        mSyncQueue.queue(wct);
+    }
+
+    /**
+     * @return the taskId of the currently running task.
+     */
+    public int getTaskId() {
+        if (mTaskInfo == null) {
+            return INVALID_TASK_ID;
+        }
+        return mTaskInfo.taskId;
     }
 }
diff --git a/src/com/android/car/carlauncher/CarTaskViewCallbacks.java b/src/com/android/car/carlauncher/CarTaskViewCallbacks.java
new file mode 100644
index 0000000..03edce5
--- /dev/null
+++ b/src/com/android/car/carlauncher/CarTaskViewCallbacks.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+/**
+ * A callback interface for the host activity that uses {@link CarTaskView} and its derivatives.
+ */
+interface CarTaskViewCallbacks {
+    /**
+     * Called when the underlying {@link CarTaskView} instance is created.
+     *
+     * @param taskView the new newly created {@link CarTaskView} instance.
+     */
+    void onTaskViewCreated(CarTaskView taskView);
+
+    /**
+     * Called when the underlying {@link CarTaskView} is ready. A {@link CarTaskView} can be
+     * considered ready when it has completed all the set up that is required.
+     * This callback is only triggered once.
+     *
+     * For {@link LaunchRootCarTaskView}, this is called once the launch root task has been
+     * fully set up.
+     * For {@link SemiControlledCarTaskView} & {@link ControlledCarTaskView} this is called when
+     * the surface is created.
+     */
+    void onTaskViewReady();
+}
+
+
diff --git a/src/com/android/car/carlauncher/ControlledCarTaskView.java b/src/com/android/car/carlauncher/ControlledCarTaskView.java
new file mode 100644
index 0000000..1d92267
--- /dev/null
+++ b/src/com/android/car/carlauncher/ControlledCarTaskView.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+import static com.android.car.carlauncher.TaskViewManager.DBG;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.UserManager;
+import android.util.Log;
+import android.view.Display;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+/**
+ * A controlled {@link CarTaskView} is fully managed by the {@link TaskViewManager}.
+ * The underlying task will be restarted if it is crashed.
+ *
+ * It should be used when:
+ * <ul>
+ *     <li>The underlying task is meant to be started by the host and be there forever.</li>
+ * </ul>
+ */
+final class ControlledCarTaskView extends CarTaskView {
+    private static final String TAG = ControlledCarTaskView.class.getSimpleName();
+
+    private final Executor mCallbackExecutor;
+    private final Intent mActivityIntent;
+    private final boolean mAutoRestartOnCrash;
+    // TODO(b/242861717): When mAutoRestartOnCrash is enabled, mPackagesThatCanRestart doesn't make
+    // a lot of sense. Consider removing it when there is more confidence with mAutoRestartOnCrash.
+    private final ControlledCarTaskViewCallbacks mCallbacks;
+    private final UserManager mUserManager;
+
+    public ControlledCarTaskView(Activity context,
+            ShellTaskOrganizer organizer,
+            SyncTransactionQueue syncQueue,
+            Executor callbackExecutor,
+            Intent activityIntent,
+            Boolean autoRestartOnCrash,
+            ControlledCarTaskViewCallbacks callbacks,
+            UserManager userManager) {
+        super(context, organizer, syncQueue);
+        mCallbackExecutor = callbackExecutor;
+        mActivityIntent = activityIntent;
+        mAutoRestartOnCrash = autoRestartOnCrash;
+        mCallbacks = callbacks;
+        mUserManager = userManager;
+
+        mCallbackExecutor.execute(() -> mCallbacks.onTaskViewCreated(this));
+    }
+
+    @Override
+    protected void onCarTaskViewInitialized() {
+        super.onCarTaskViewInitialized();
+        startActivity();
+        mCallbackExecutor.execute(() -> mCallbacks.onTaskViewReady());
+    }
+
+    /**
+     * Starts the underlying activity.
+     */
+    public void startActivity() {
+        if (!mUserManager.isUserUnlocked()) {
+            if (DBG) Log.d(TAG, "Can't start activity due to user is isn't unlocked");
+            return;
+        }
+
+        // Don't start activity when the display is off. This can happen when the taskview is not
+        // attached to a window.
+        if (getDisplay() == null) {
+            Log.w(TAG, "Can't start activity because display is not available in "
+                    + "taskview yet.");
+            return;
+        }
+        // Don't start activity when the display is off for ActivityVisibilityTests.
+        if (getDisplay().getState() != Display.STATE_ON) {
+            Log.w(TAG, "Can't start activity due to the display is off");
+            return;
+        }
+
+        ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext,
+                /* enterResId= */ 0, /* exitResId= */ 0);
+        Rect launchBounds = new Rect();
+        getBoundsOnScreen(launchBounds);
+        if (DBG) {
+            Log.d(TAG, "Starting (" + mActivityIntent.getComponent() + ") on " + launchBounds);
+        }
+        startActivity(
+                PendingIntent.getActivity(mContext, /* requestCode= */ 0,
+                        mActivityIntent,
+                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT),
+                /* fillInIntent= */ null, options, launchBounds);
+    }
+
+    /**
+     * See {@link ControlledCarTaskViewCallbacks#getDependingPackageNames()}.
+     */
+    Set<String> getDependingPackageNames() {
+        return mCallbacks.getDependingPackageNames();
+    }
+
+    @Override
+    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+        super.onTaskVanished(taskInfo);
+        if (mAutoRestartOnCrash) {
+            Log.i(TAG, "Restarting task " + taskInfo.baseActivity
+                    + " in ControlledCarTaskView");
+            startActivity();
+        }
+    }
+}
diff --git a/src/com/android/car/carlauncher/ControlledCarTaskViewCallbacks.java b/src/com/android/car/carlauncher/ControlledCarTaskViewCallbacks.java
new file mode 100644
index 0000000..56ef8ea
--- /dev/null
+++ b/src/com/android/car/carlauncher/ControlledCarTaskViewCallbacks.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * A callback interface for {@link ControlledCarTaskView}.
+ */
+public interface ControlledCarTaskViewCallbacks extends
+        CarTaskViewCallbacks {
+    /**
+     * @return a set of package names which the task in the ControlledCarTaskView depends upon.
+     * When any of these packages are changed, it will lead to restart of the task.
+     */
+    default Set<String> getDependingPackageNames() {
+        return Collections.emptySet();
+    }
+}
diff --git a/src/com/android/car/carlauncher/LaunchRootCarTaskView.java b/src/com/android/car/carlauncher/LaunchRootCarTaskView.java
new file mode 100644
index 0000000..c0a4049
--- /dev/null
+++ b/src/com/android/car/carlauncher/LaunchRootCarTaskView.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.car.carlauncher.TaskViewManager.DBG;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.util.Log;
+import android.view.SurfaceControl;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A {@link CarTaskView} that can act as a default app container. A default app container is the
+ * container where all apps open by default.
+ */
+final class LaunchRootCarTaskView extends CarTaskView {
+    private static final String TAG = LaunchRootCarTaskView.class.getSimpleName();
+
+    private final Executor mCallbackExecutor;
+    private final LaunchRootCarTaskViewCallbacks mCallbacks;
+    private final ShellTaskOrganizer mShellTaskOrganizer;
+    private final SyncTransactionQueue mSyncQueue;
+    private final ShellTaskOrganizer.TaskListener mRootTaskListener;
+
+    private ActivityManager.RunningTaskInfo mLaunchRootTask;
+
+    private final ShellTaskOrganizer.TaskListener mRootTaskListenerWrapper =
+            new ShellTaskOrganizer.TaskListener() {
+                @Override
+                public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo,
+                        SurfaceControl leash) {
+                    // The first call to onTaskAppeared() is always for the root-task.
+                    if (mLaunchRootTask == null && !taskInfo.hasParentTask()) {
+                        setRootTaskAsLaunchRoot(taskInfo);
+                        LaunchRootCarTaskView.this.onTaskAppeared(taskInfo, leash);
+                        mCallbackExecutor.execute(() -> mCallbacks.onTaskViewReady());
+                        return;
+                    }
+
+                    if (DBG) {
+                        Log.d(TAG, "onTaskAppeared " + taskInfo.taskId + " - "
+                                + taskInfo.baseActivity);
+                    }
+
+
+                    mRootTaskListener.onTaskAppeared(taskInfo, leash);
+                }
+
+                @Override
+                public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+                    if (mLaunchRootTask != null
+                            && mLaunchRootTask.taskId == taskInfo.taskId) {
+                        LaunchRootCarTaskView.this.onTaskInfoChanged(taskInfo);
+                        if (DBG) {
+                            Log.d(TAG, "got onTaskInfoChanged for the launch root task. Not "
+                                    + "forwarding this to root task listener");
+                        }
+                        return;
+                    }
+                    if (DBG) {
+                        Log.d(TAG, "onTaskInfoChanged " + taskInfo.taskId + " - "
+                                + taskInfo.baseActivity);
+                    }
+
+                    mRootTaskListener.onTaskInfoChanged(taskInfo);
+                }
+
+                @Override
+                public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+                    if (DBG) {
+                        Log.d(TAG, "onTaskVanished " + taskInfo.taskId + " - "
+                                + taskInfo.baseActivity);
+                    }
+                    if (mLaunchRootTask != null
+                            && mLaunchRootTask.taskId == taskInfo.taskId) {
+                        LaunchRootCarTaskView.this.onTaskVanished(taskInfo);
+                        if (DBG) {
+                            Log.d(TAG, "got onTaskVanished for the launch root task. Not "
+                                    + "forwarding this to root task listener");
+                        }
+                        return;
+                    }
+
+                    mRootTaskListener.onTaskVanished(taskInfo);
+                }
+            };
+
+    public LaunchRootCarTaskView(Activity context,
+            ShellTaskOrganizer organizer,
+            SyncTransactionQueue syncQueue,
+            Executor callbackExecutor,
+            LaunchRootCarTaskViewCallbacks callbacks,
+            ShellTaskOrganizer.TaskListener rootTaskListener) {
+        super(context, organizer, syncQueue);
+        mCallbacks = callbacks;
+        mCallbackExecutor = callbackExecutor;
+        mShellTaskOrganizer = organizer;
+        mSyncQueue = syncQueue;
+        mRootTaskListener = rootTaskListener;
+
+        mCallbackExecutor.execute(() -> mCallbacks.onTaskViewCreated(this));
+    }
+
+    @Override
+    protected void onCarTaskViewInitialized() {
+        super.onCarTaskViewInitialized();
+        mShellTaskOrganizer.getExecutor().execute(() -> {
+            // Should run on shell's executor
+            mShellTaskOrganizer.createRootTask(DEFAULT_DISPLAY,
+                    WINDOWING_MODE_MULTI_WINDOW,
+                    mRootTaskListenerWrapper);
+        });
+    }
+
+    @Override
+    protected void notifyReleased() {
+        super.notifyReleased();
+        clearLaunchRootTask();
+    }
+
+    private void clearLaunchRootTask() {
+        if (mLaunchRootTask == null) {
+            Log.w(TAG, "Unable to clear launch root task because it is not created.");
+            return;
+        }
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.setLaunchRoot(mLaunchRootTask.token, null, null);
+        mSyncQueue.queue(wct);
+        // Should run on shell's executor
+        mShellTaskOrganizer.deleteRootTask(mLaunchRootTask.token);
+        mLaunchRootTask = null;
+    }
+
+    private void setRootTaskAsLaunchRoot(ActivityManager.RunningTaskInfo taskInfo) {
+        mLaunchRootTask = taskInfo;
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.setLaunchRoot(taskInfo.token,
+                        new int[]{WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED},
+                        new int[]{ACTIVITY_TYPE_STANDARD})
+                .reorder(taskInfo.token, true);
+        mSyncQueue.queue(wct);
+    }
+}
diff --git a/src/com/android/car/carlauncher/LaunchRootCarTaskViewCallbacks.java b/src/com/android/car/carlauncher/LaunchRootCarTaskViewCallbacks.java
new file mode 100644
index 0000000..e30ffe5
--- /dev/null
+++ b/src/com/android/car/carlauncher/LaunchRootCarTaskViewCallbacks.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+/**
+ * A callbacks interface for {@link LaunchRootCarTaskView}.
+ */
+public interface LaunchRootCarTaskViewCallbacks extends
+        CarTaskViewCallbacks {}
diff --git a/src/com/android/car/carlauncher/SemiControlledCarTaskView.java b/src/com/android/car/carlauncher/SemiControlledCarTaskView.java
new file mode 100644
index 0000000..5b5ed85
--- /dev/null
+++ b/src/com/android/car/carlauncher/SemiControlledCarTaskView.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+import android.app.Activity;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A Semi-controlled {@link CarTaskView} is where the apps are meant to stay temporarily. It always
+ * works when a {@link LaunchRootCarTaskView} has been set up.
+ *
+ * It serves these use-cases:
+ * <ul>
+ *     <li>Should be used when the apps that are meant to be in it can be started from anywhere
+ *     in the system. i.e. when the host app has no control over their launching.</li>
+ *     <li>Suitable for apps like Assistant or Setup-Wizard.</li>
+ * </ul>
+ */
+final class SemiControlledCarTaskView extends CarTaskView {
+    private final Executor mCallbackExecutor;
+    private final SemiControlledCarTaskViewCallbacks mCallbacks;
+
+    public SemiControlledCarTaskView(Activity context,
+            ShellTaskOrganizer organizer,
+            SyncTransactionQueue syncQueue,
+            Executor callbackExecutor,
+            SemiControlledCarTaskViewCallbacks callbacks) {
+        super(context, organizer, syncQueue);
+        mCallbacks = callbacks;
+        mCallbackExecutor = callbackExecutor;
+        mCallbackExecutor.execute(() -> mCallbacks.onTaskViewCreated(this));
+    }
+
+    @Override
+    protected void onCarTaskViewInitialized() {
+        super.onCarTaskViewInitialized();
+        mCallbackExecutor.execute(() -> mCallbacks.onTaskViewReady());
+    }
+
+    /**
+     * @return the underlying {@link SemiControlledCarTaskViewCallbacks}.
+     */
+    SemiControlledCarTaskViewCallbacks getCallbacks() {
+        return mCallbacks;
+    }
+}
diff --git a/src/com/android/car/carlauncher/SemiControlledCarTaskViewCallbacks.java b/src/com/android/car/carlauncher/SemiControlledCarTaskViewCallbacks.java
new file mode 100644
index 0000000..9576772
--- /dev/null
+++ b/src/com/android/car/carlauncher/SemiControlledCarTaskViewCallbacks.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+import android.app.TaskInfo;
+
+/**
+ * A callbacks interface for {@link SemiControlledCarTaskView}.
+ */
+public interface SemiControlledCarTaskViewCallbacks extends
+        CarTaskViewCallbacks {
+    /**
+     * Specifies whether or not the given {@code taskInfo} should start in this
+     * {@link SemiControlledCarTaskView}.
+     * @return true if the task should be started on this {@link SemiControlledCarTaskView}, false
+     * otherwise.
+     */
+    boolean shouldStartInTaskView(TaskInfo taskInfo);
+}
diff --git a/src/com/android/car/carlauncher/TaskViewManager.java b/src/com/android/car/carlauncher/TaskViewManager.java
index f7c403f..df1434f 100644
--- a/src/com/android/car/carlauncher/TaskViewManager.java
+++ b/src/com/android/car/carlauncher/TaskViewManager.java
@@ -16,79 +16,481 @@
 
 package com.android.car.carlauncher;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING;
+import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED;
 
 import static com.android.car.carlauncher.CarLauncher.TAG;
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
 
-import android.annotation.UiContext;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
+import android.app.Application.ActivityLifecycleCallbacks;
 import android.app.TaskInfo;
+import android.app.TaskStackListener;
+import android.car.Car;
 import android.car.app.CarActivityManager;
+import android.car.user.CarUserManager;
+import android.car.user.UserLifecycleEventFilter;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
 import android.util.Slog;
+import android.view.SurfaceControl;
 import android.window.TaskAppearedInfo;
 
+import com.android.car.carlauncher.taskstack.TaskStackChangeListeners;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.TaskView;
 import com.android.wm.shell.common.HandlerExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
 import com.android.wm.shell.startingsurface.StartingWindowController;
 import com.android.wm.shell.startingsurface.phone.PhoneStartingWindowTypeAlgorithm;
+import com.android.wm.shell.sysui.ShellInit;
 
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Optional;
+import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
 
+
+/**
+ * A manager for creating {@link ControlledCarTaskView}, {@link LaunchRootCarTaskView} &
+ * {@link SemiControlledCarTaskView}.
+ */
 public final class TaskViewManager {
-    private static final boolean DBG = false;
+    static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final String SCHEME_PACKAGE = "package";
 
-    private final Context mContext;
-    private final HandlerExecutor mExecutor;
+    private final AtomicReference<CarActivityManager> mCarActivityManagerRef =
+            new AtomicReference<>();
+    @ShellMainThread
+    private final HandlerExecutor mShellExecutor;
     private final SyncTransactionQueue mSyncQueue;
     private final ShellTaskOrganizer mTaskOrganizer;
+    private final int mHostTaskId;
 
-    public TaskViewManager(@UiContext Context context, HandlerExecutor handlerExecutor,
-            AtomicReference<CarActivityManager> carActivityManagerRef) {
-        mContext = context;
-        mExecutor = handlerExecutor;
-        mTaskOrganizer = new ShellTaskOrganizer(mExecutor, mContext);
-        TransactionPool transactionPool = new TransactionPool();
-        mSyncQueue = new SyncTransactionQueue(transactionPool, mExecutor);
-        initTaskOrganizer(carActivityManagerRef, transactionPool);
-        if (DBG) Slog.d(TAG, "TaskViewManager.create");
+    // All TaskView are bound to the Host Activity if it exists.
+    @ShellMainThread
+    private final List<ControlledCarTaskView> mControlledTaskViews = new ArrayList<>();
+    @ShellMainThread
+    private final List<SemiControlledCarTaskView> mSemiControlledTaskViews = new ArrayList<>();
+    @ShellMainThread
+    private LaunchRootCarTaskView mLaunchRootCarTaskView = null;
+
+    private CarUserManager mCarUserManager;
+    private Activity mContext;
+
+    private final ShellTaskOrganizer.TaskListener mRootTaskListener =
+            new ShellTaskOrganizer.TaskListener() {
+                @Override
+                public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo,
+                        SurfaceControl leash) {
+                    // Called for a task appearing the launch root. Route it to the appropriate
+                    // semi-controlled taskview;
+                    for (SemiControlledCarTaskView taskView : mSemiControlledTaskViews) {
+                        if (taskView.getCallbacks().shouldStartInTaskView(taskInfo)) {
+                            if (taskView.isInitialized()) {
+                                taskView.onTaskAppeared(taskInfo, leash);
+                            }
+                            return;
+                        }
+                    }
+
+                    // TODO(b/228077499): Fix for the case when a task is started in the
+                    // launch-root-task right after the initialization of launch-root-task, it
+                    // remains blank.
+                    mSyncQueue.runInSync(t -> t.show(leash));
+
+                    CarActivityManager carAm = mCarActivityManagerRef.get();
+                    if (carAm != null) {
+                        carAm.onTaskAppeared(taskInfo);
+                    } else {
+                        Log.w(TAG, "CarActivityManager is null, skip onTaskAppeared: TaskInfo"
+                                + " = " + taskInfo);
+                    }
+                }
+
+                @Override
+                public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+                    for (SemiControlledCarTaskView taskView : mSemiControlledTaskViews) {
+                        if (taskView.getCallbacks().shouldStartInTaskView(taskInfo)) {
+                            if (taskView.isInitialized()) {
+                                // onLocationChanged() is crucial. If this is not called, the
+                                // further activities opened by the current activity do not open in
+                                // the correct size.
+                                // TODO(b/234879199): Explore more for a better solution.
+                                taskView.onLocationChanged();
+                                taskView.onTaskInfoChanged(taskInfo);
+                            }
+                            // Semi-controlled apps are assumed to be Distraction optimised and
+                            // hence not reported to CarActivityManager.
+                            return;
+                        }
+                    }
+
+                    // Uncontrolled apps by default launch in the launch root so nothing needs to
+                    // be done here for them.
+                    CarActivityManager carAm = mCarActivityManagerRef.get();
+                    if (carAm != null) {
+                        carAm.onTaskInfoChanged(taskInfo);
+                    } else {
+                        Log.w(TAG, "CarActivityManager is null, skip onTaskAppeared: TaskInfo"
+                                + " = " + taskInfo);
+                    }
+                }
+
+                @Override
+                public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+                    for (SemiControlledCarTaskView taskView : mSemiControlledTaskViews) {
+                        if (taskView.getCallbacks().shouldStartInTaskView(taskInfo)) {
+                            if (taskView.isInitialized()) {
+                                taskView.onTaskVanished(taskInfo);
+                            }
+                            return;
+                        }
+                    }
+
+                    CarActivityManager carAm = mCarActivityManagerRef.get();
+                    if (carAm != null) {
+                        carAm.onTaskVanished(taskInfo);
+                    } else {
+                        Log.w(TAG, "CarActivityManager is null, skip onTaskAppeared: TaskInfo"
+                                + " = " + taskInfo);
+                    }
+                }
+            };
+
+    private final TaskStackListener mTaskStackListener = new TaskStackListener() {
+        @Override
+        public void onTaskFocusChanged(int taskId, boolean focused) {
+            boolean hostFocused = taskId == mHostTaskId && focused;
+            if (DBG) {
+                Log.d(TAG, "onTaskFocusChanged: taskId=" + taskId
+                        + ", hostFocused=" + hostFocused);
+            }
+            if (!hostFocused) {
+                return;
+            }
+
+            for (int i = mControlledTaskViews.size() - 1; i >= 0; --i) {
+                ControlledCarTaskView taskView = mControlledTaskViews.get(i);
+                if (taskView.getTaskId() == INVALID_TASK_ID) {
+                    // If the task in TaskView is crashed when host is in background,
+                    // We'd like to restart it when host becomes foreground and focused.
+                    taskView.startActivity();
+                }
+            }
+        }
+
+        @Override
+        public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+                boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+            if (DBG) {
+                Log.d(TAG, "onActivityRestartAttempt: taskId=" + task.taskId
+                        + ", homeTaskVisible=" + homeTaskVisible + ", wasVisible=" + wasVisible);
+            }
+            if (homeTaskVisible && mHostTaskId == task.taskId) {
+                for (int i = mControlledTaskViews.size() - 1; i >= 0; --i) {
+                    ControlledCarTaskView taskView = mControlledTaskViews.get(i);
+                    // In the case of CarLauncher, this code handles the case where Home Intent is
+                    // sent when CarLauncher is foreground and the task in a ControlledTaskView is
+                    // crashed.
+                    if (taskView.getTaskId() == INVALID_TASK_ID) {
+                        taskView.startActivity();
+                    }
+                }
+            }
+        }
+    };
+
+    private final CarUserManager.UserLifecycleListener mUserLifecycleListener = event -> {
+        if (DBG) {
+            Log.d(TAG, "UserLifecycleListener.onEvent: For User "
+                    + mContext.getUserId()
+                    + ", received an event " + event);
+        }
+
+        // When user-unlocked, if task isn't launched yet, then try to start it.
+        if (event.getEventType() == USER_LIFECYCLE_EVENT_TYPE_UNLOCKED
+                && mContext.getUserId() == event.getUserId()) {
+            for (int i = mControlledTaskViews.size() - 1; i >= 0; --i) {
+                ControlledCarTaskView taskView = mControlledTaskViews.get(i);
+                if (taskView.getTaskId() == INVALID_TASK_ID) {
+                    taskView.startActivity();
+                }
+            }
+        }
+
+        // When user-switching, onDestroy in the previous user's Host app isn't called.
+        // So try to release the resource explicitly.
+        if (event.getEventType() == USER_LIFECYCLE_EVENT_TYPE_SWITCHING
+                && mContext.getUserId() == event.getPreviousUserId()) {
+            release();
+        }
+    };
+
+    private final BroadcastReceiver mPackageBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DBG) Log.d(TAG, "onReceive: intent=" + intent);
+
+            if (isActivityStopped(mContext)) {
+                return;
+            }
+
+            String packageName = intent.getData().getSchemeSpecificPart();
+            for (int i = mControlledTaskViews.size() - 1; i >= 0; --i) {
+                ControlledCarTaskView taskView = mControlledTaskViews.get(i);
+                if (taskView.getTaskId() == INVALID_TASK_ID
+                        && taskView.getDependingPackageNames().contains(packageName)) {
+                    taskView.startActivity();
+                }
+            }
+        }
+    };
+
+    public TaskViewManager(Activity context, HandlerExecutor handlerExecutor) {
+        this(context, handlerExecutor, new ShellTaskOrganizer(handlerExecutor),
+                new SyncTransactionQueue(new TransactionPool(), handlerExecutor));
     }
 
-    private void initTaskOrganizer(AtomicReference<CarActivityManager> carActivityManagerRef,
-            TransactionPool transactionPool) {
+    @VisibleForTesting
+    TaskViewManager(Activity context, HandlerExecutor handlerExecutor,
+            ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue) {
+        if (DBG) Slog.d(TAG, "TaskViewManager(): " + context);
+        mContext = context;
+        mShellExecutor = handlerExecutor;
+        mTaskOrganizer = shellTaskOrganizer;
+        mHostTaskId = mContext.getTaskId();
+        mSyncQueue = syncQueue;
+
+        initCar();
+        initTaskOrganizer(mCarActivityManagerRef);
+        mContext.registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
+    }
+
+    private void initCar() {
+        Car.createCar(/* context= */ mContext, /* handler= */ null,
+                Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER,
+                (car, ready) -> {
+                    if (!ready) {
+                        Log.w(TAG, "CarService looks crashed");
+                        mCarActivityManagerRef.set(null);
+                        return;
+                    }
+                    setCarUserManager((CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE));
+                    UserLifecycleEventFilter filter = new UserLifecycleEventFilter.Builder()
+                            .addEventType(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED)
+                            .addEventType(USER_LIFECYCLE_EVENT_TYPE_SWITCHING).build();
+                    mCarUserManager.addListener(mContext.getMainExecutor(), filter,
+                            mUserLifecycleListener);
+                    CarActivityManager carAM = (CarActivityManager) car.getCarManager(
+                            Car.CAR_ACTIVITY_SERVICE);
+                    mCarActivityManagerRef.set(carAM);
+
+                    carAM.registerTaskMonitor();
+                });
+
+        TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
+
+        IntentFilter packageIntentFilter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
+        packageIntentFilter.addDataScheme(SCHEME_PACKAGE);
+        mContext.registerReceiver(mPackageBroadcastReceiver, packageIntentFilter);
+    }
+
+    // TODO(b/239958124A): Remove this method when unit tests for TaskViewManager have been added.
+    /**
+     * This method only exists for the container activity to set mock car user manager in tests.
+     */
+    void setCarUserManager(CarUserManager carUserManager) {
+        mCarUserManager = carUserManager;
+    }
+
+    private void initTaskOrganizer(AtomicReference<CarActivityManager> carActivityManagerRef) {
         FullscreenTaskListener fullscreenTaskListener = new CarFullscreenTaskMonitorListener(
-                carActivityManagerRef, mSyncQueue, Optional.empty());
+                carActivityManagerRef, mSyncQueue);
         mTaskOrganizer.addListenerForType(fullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN);
-        StartingWindowController startingController =
-                new StartingWindowController(mContext, mExecutor,
-                        new PhoneStartingWindowTypeAlgorithm(), new IconProvider(mContext),
-                        transactionPool);
-        mTaskOrganizer.initStartingWindow(startingController);
+        ShellInit shellInit = new ShellInit(mShellExecutor);
+        // StartingWindowController needs to be initialized so that splash screen is displayed.
+        new StartingWindowController(mContext, shellInit, mTaskOrganizer, mShellExecutor,
+                new PhoneStartingWindowTypeAlgorithm(), new IconProvider(mContext),
+                new TransactionPool());
+        shellInit.init();
         List<TaskAppearedInfo> taskAppearedInfos = mTaskOrganizer.registerOrganizer();
         cleanUpExistingTaskViewTasks(taskAppearedInfos);
     }
 
-    void release() {
-        if (DBG) Slog.d(TAG, "TaskViewManager.release");
-        mTaskOrganizer.unregisterOrganizer();
-    }
-
-    void createTaskView(Consumer<TaskView> onCreate) {
-        CarTaskView taskView = new CarTaskView(mContext, mTaskOrganizer, mSyncQueue);
-        mExecutor.execute(() -> {
-            onCreate.accept(taskView);
+    /**
+     * Creates a {@link ControlledCarTaskView}.
+     *
+     * @param callbackExecutor the executor which the {@link ControlledCarTaskViewCallbacks} will
+     *                         be executed on.
+     * @param activityIntent the intent of the activity that is meant to be started in this
+     *                       {@link ControlledCarTaskView}.
+     * @param taskViewCallbacks the callbacks for the underlying TaskView.
+     */
+    public void createControlledCarTaskView(
+            Executor callbackExecutor,
+            Intent activityIntent,
+            boolean autoRestartOnCrash,
+            ControlledCarTaskViewCallbacks taskViewCallbacks) {
+        mShellExecutor.execute(() -> {
+            ControlledCarTaskView taskView = new ControlledCarTaskView(mContext, mTaskOrganizer,
+                    mSyncQueue, callbackExecutor, activityIntent, autoRestartOnCrash,
+                    taskViewCallbacks, mContext.getSystemService(UserManager.class));
+            mControlledTaskViews.add(taskView);
         });
     }
 
+    /**
+     * Creates a {@link LaunchRootCarTaskView}.
+     *
+     * @param callbackExecutor the executor which the {@link LaunchRootCarTaskViewCallbacks} will be
+     *                         executed on.
+     * @param taskViewCallbacks the callbacks for the underlying TaskView.
+     */
+    public void createLaunchRootTaskView(Executor callbackExecutor,
+            LaunchRootCarTaskViewCallbacks taskViewCallbacks) {
+        mShellExecutor.execute(() -> {
+            if (mLaunchRootCarTaskView != null) {
+                throw new IllegalStateException("Cannot create more than one launch root task");
+            }
+            mLaunchRootCarTaskView = new LaunchRootCarTaskView(mContext, mTaskOrganizer,
+                    mSyncQueue, callbackExecutor, taskViewCallbacks, mRootTaskListener);
+        });
+    }
+
+    /**
+     * Creates a {@link SemiControlledCarTaskView}.
+     *
+     * @param callbackExecutor the executor which the {@link SemiControlledCarTaskViewCallbacks}
+     *                         will be executed on.
+     * @param taskViewCallbacks the callbacks for the underlying TaskView.
+     */
+    public void createSemiControlledTaskView(Executor callbackExecutor,
+            SemiControlledCarTaskViewCallbacks taskViewCallbacks) {
+        mShellExecutor.execute(() -> {
+            if (mLaunchRootCarTaskView == null) {
+                throw new IllegalStateException("Cannot create a semi controlled taskview without a"
+                        + " launch root taskview");
+            }
+            SemiControlledCarTaskView taskView = new SemiControlledCarTaskView(mContext,
+                    mTaskOrganizer, mSyncQueue, callbackExecutor, taskViewCallbacks);
+            mSemiControlledTaskViews.add(taskView);
+        });
+    }
+
+    /**
+     * Releases {@link TaskViewManager} and unregisters the underlying {@link ShellTaskOrganizer}.
+     * It also removes all TaskViews which are created by this {@link TaskViewManager}.
+     */
+    private void release() {
+        mShellExecutor.execute(() -> {
+            if (DBG) Slog.d(TAG, "TaskViewManager.release");
+
+            if (mCarUserManager != null) {
+                mCarUserManager.removeListener(mUserLifecycleListener);
+            }
+            TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
+            mContext.unregisterReceiver(mPackageBroadcastReceiver);
+
+            CarActivityManager carAM = mCarActivityManagerRef.get();
+            if (carAM != null) {
+                carAM.unregisterTaskMonitor();
+                mCarActivityManagerRef.set(null);
+            }
+
+            for (int i = mControlledTaskViews.size() - 1; i >= 0; --i) {
+                mControlledTaskViews.get(i).release();
+            }
+            mControlledTaskViews.clear();
+
+            for (int i = mSemiControlledTaskViews.size() - 1; i >= 0; --i) {
+                mSemiControlledTaskViews.get(i).release();
+            }
+            mSemiControlledTaskViews.clear();
+
+            if (mLaunchRootCarTaskView != null) {
+                mLaunchRootCarTaskView.release();
+                mLaunchRootCarTaskView = null;
+            }
+
+            mContext.unregisterActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
+            mTaskOrganizer.unregisterOrganizer();
+        });
+    }
+
+    private static boolean isActivityStopped(Activity activity) {
+        // This code relies on Activity#isVisibleForAutofill() instead of maintaining a custom
+        // activity state.
+        return !activity.isVisibleForAutofill();
+    }
+
+    private final ActivityLifecycleCallbacks mActivityLifecycleCallbacks =
+            new ActivityLifecycleCallbacks() {
+                @Override
+                public void onActivityCreated(@NonNull Activity activity,
+                        @Nullable Bundle savedInstanceState) {
+                    if (DBG) {
+                        Log.d(TAG, "Host activity created");
+                    }
+                }
+
+                @Override
+                public void onActivityStarted(@NonNull Activity activity) {
+                    if (DBG) {
+                        Log.d(TAG, "Host activity started");
+                    }
+                }
+
+                @Override
+                public void onActivityResumed(@NonNull Activity activity) {
+                    Log.d(TAG, "Host activity resumed");
+                    if (activity != mContext) {
+                        return;
+                    }
+                    mShellExecutor.execute(() -> {
+                        for (int i = mControlledTaskViews.size() - 1; i >= 0; --i) {
+                            mControlledTaskViews.get(i).showEmbeddedTask();
+                        }
+                        if (mLaunchRootCarTaskView != null) {
+                            mLaunchRootCarTaskView.showEmbeddedTask();
+                        }
+                        for (int i = mSemiControlledTaskViews.size() - 1; i >= 0; --i) {
+                            mSemiControlledTaskViews.get(i).showEmbeddedTask();
+                        }
+                    });
+                }
+
+                @Override
+                public void onActivityPaused(@NonNull Activity activity) {}
+
+                @Override
+                public void onActivityStopped(@NonNull Activity activity) {}
+
+                @Override
+                public void onActivitySaveInstanceState(@NonNull Activity activity,
+                        @NonNull Bundle outState) {}
+
+                @Override
+                public void onActivityDestroyed(@NonNull Activity activity) {
+                    release();
+                }
+            };
+
     private static void cleanUpExistingTaskViewTasks(List<TaskAppearedInfo> taskAppearedInfos) {
         ActivityTaskManager atm = ActivityTaskManager.getInstance();
         for (TaskAppearedInfo taskAppearedInfo : taskAppearedInfos) {
@@ -100,4 +502,24 @@
             }
         }
     }
+
+    @VisibleForTesting
+    List<ControlledCarTaskView> getControlledTaskViews() {
+        return mControlledTaskViews;
+    }
+
+    @VisibleForTesting
+    LaunchRootCarTaskView getLaunchRootCarTaskView() {
+        return mLaunchRootCarTaskView;
+    }
+
+    @VisibleForTesting
+    List<SemiControlledCarTaskView> getSemiControlledTaskViews() {
+        return mSemiControlledTaskViews;
+    }
+
+    @VisibleForTesting
+    BroadcastReceiver getPackageBroadcastReceiver() {
+        return mPackageBroadcastReceiver;
+    }
 }
diff --git a/src/com/android/car/carlauncher/homescreen/audio/AudioFragment.java b/src/com/android/car/carlauncher/homescreen/audio/AudioFragment.java
index 5dd7813..977ccc0 100644
--- a/src/com/android/car/carlauncher/homescreen/audio/AudioFragment.java
+++ b/src/com/android/car/carlauncher/homescreen/audio/AudioFragment.java
@@ -19,6 +19,7 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.util.Size;
 import android.view.View;
 import android.view.ViewStub;
@@ -137,6 +138,7 @@
         getMediaLayoutView().setVisibility(View.VISIBLE);
         mMediaTitle.setText(title);
         mMediaSubtitle.setText(subtitle);
+        mMediaSubtitle.setVisibility(TextUtils.isEmpty(subtitle) ? View.GONE : View.VISIBLE);
     }
 
     private void updateAudioDuration(DescriptiveTextWithControlsView content) {
diff --git a/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenter.java b/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenter.java
index 3398389..5c14aaa 100644
--- a/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenter.java
+++ b/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenter.java
@@ -101,6 +101,10 @@
                 // empty content since that would hide the card.
                 return;
             }
+        } else if (mCurrentModel != null && mCurrentModel.getClass() == InCallModel.class) {
+            // If the Model has content, check if currentModel on display is an ongoing phone call.
+            // If there is any ongoing phone call do not update the View.
+            return;
         }
         mCurrentModel = model;
         super.onModelUpdated(model);
diff --git a/src/com/android/car/carlauncher/homescreen/audio/InCallModel.java b/src/com/android/car/carlauncher/homescreen/audio/InCallModel.java
index 5d0d664..48981ba 100644
--- a/src/com/android/car/carlauncher/homescreen/audio/InCallModel.java
+++ b/src/com/android/car/carlauncher/homescreen/audio/InCallModel.java
@@ -22,17 +22,22 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.telecom.Call;
 import android.telecom.CallAudioState;
+import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.Display;
 import android.view.View;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.core.content.ContextCompat;
 
 import com.android.car.carlauncher.R;
@@ -43,6 +48,7 @@
 import com.android.car.carlauncher.homescreen.ui.DescriptiveTextWithControlsView;
 import com.android.car.telephony.common.CallDetail;
 import com.android.car.telephony.common.TelecomUtils;
+import com.android.car.ui.utils.CarUxRestrictionsUtil;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
@@ -61,13 +67,18 @@
 
     private Context mContext;
     private TelecomManager mTelecomManager;
+    private CarUxRestrictionsUtil mCarUxRestrictionsUtil;
+
+    private PackageManager mPackageManager;
     private final Clock mElapsedTimeClock;
+
     private Call mCurrentCall;
     private CompletableFuture<Void> mPhoneNumberInfoFuture;
 
     private InCallServiceImpl mInCallService;
     private HomeCardInterface.Presenter mPresenter;
 
+    private CardHeader mDefaultDialerCardHeader;
     private CardHeader mCardHeader;
     private CardContent mCardContent;
     private CharSequence mOngoingCallSubtitle;
@@ -107,19 +118,15 @@
     public void onCreate(Context context) {
         mContext = context;
         mTelecomManager = context.getSystemService(TelecomManager.class);
+        mCarUxRestrictionsUtil = CarUxRestrictionsUtil.getInstance(context);
+
         mOngoingCallSubtitle = context.getResources().getString(R.string.ongoing_call_text);
         mDialingCallSubtitle = context.getResources().getString(R.string.dialing_call_text);
         initializeAudioControls();
-        try {
-            PackageManager pm = context.getPackageManager();
-            Drawable appIcon = pm.getApplicationIcon(mTelecomManager.getDefaultDialerPackage());
-            CharSequence appName = pm.getApplicationLabel(
-                    pm.getApplicationInfo(mTelecomManager.getDefaultDialerPackage(), /* flags = */
-                            0));
-            mCardHeader = new CardHeader(appName, appIcon);
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(TAG, "No default dialer package found", e);
-        }
+
+        mPackageManager = context.getPackageManager();
+        mDefaultDialerCardHeader = createCardHeader(mTelecomManager.getDefaultDialerPackage());
+        mCardHeader = mDefaultDialerCardHeader;
 
         Intent intent = new Intent(context, InCallServiceImpl.class);
         intent.setAction(InCallServiceImpl.ACTION_LOCAL_BIND);
@@ -160,8 +167,25 @@
      */
     @Override
     public void onClick(View view) {
-        PackageManager pm = mContext.getPackageManager();
-        Intent intent = pm.getLaunchIntentForPackage(mTelecomManager.getDefaultDialerPackage());
+        Intent intent = null;
+        if (isSelfManagedCall() && !isRequiresDistractionOptimization()) {
+            Bundle extras = mCurrentCall.getDetails().getExtras();
+            ComponentName componentName = extras == null ? null : extras.getParcelable(
+                    Intent.EXTRA_COMPONENT_NAME, ComponentName.class);
+            if (componentName != null) {
+                intent = new Intent();
+                intent.setComponent(componentName);
+            } else {
+                String callingAppPackageName = getCallingAppPackageName();
+                if (!TextUtils.isEmpty(callingAppPackageName)) {
+                    intent = mPackageManager.getLaunchIntentForPackage(callingAppPackageName);
+                }
+            }
+        } else {
+            intent = mPackageManager.getLaunchIntentForPackage(
+                    mTelecomManager.getDefaultDialerPackage());
+        }
+
         if (intent != null) {
             // Launch activity in the default app task container: the display area where
             // applications are launched by default.
@@ -171,8 +195,7 @@
             mContext.startActivity(intent, options.toBundle());
         } else {
             if (DEBUG) {
-                Log.d(TAG, "No launch intent found for dialer package: "
-                        + mTelecomManager.getDefaultDialerPackage());
+                Log.d(TAG, "No launch intent found to show in call ui for call : " + mCurrentCall);
             }
         }
     }
@@ -196,6 +219,7 @@
     @Override
     public void onCallRemoved(Call call) {
         mCurrentCall = null;
+        mCardHeader = null;
         mCardContent = null;
         mPresenter.onModelUpdated(this);
         if (call != null) {
@@ -262,7 +286,23 @@
     @VisibleForTesting
     void updateModelWithContact(TelecomUtils.PhoneNumberInfo phoneNumberInfo,
             @Call.CallState int callState) {
-        String contactName = phoneNumberInfo.getDisplayName();
+        // If call has been removed, return.
+        if (mCurrentCall == null) {
+            return;
+        }
+
+        // Use the caller display name or contact display name from call details first.
+        String contactName = mCurrentCall.getDetails().getCallerDisplayName();
+        if (TextUtils.isEmpty(contactName)) {
+            contactName = mCurrentCall.getDetails().getContactDisplayName();
+        }
+        String initials = null;
+        if (TextUtils.isEmpty(contactName)) {
+            contactName = phoneNumberInfo.getDisplayName();
+            initials = phoneNumberInfo.getInitials();
+        } else {
+            initials = TelecomUtils.getInitials(contactName);
+        }
         Drawable contactImage = null;
         if (phoneNumberInfo.getAvatarUri() != null) {
             try {
@@ -280,8 +320,7 @@
             }
         }
         if (contactImage == null) {
-            contactImage = TelecomUtils.createLetterTile(mContext,
-                    phoneNumberInfo.getInitials(), phoneNumberInfo.getDisplayName());
+            contactImage = TelecomUtils.createLetterTile(mContext, initials, contactName);
         }
 
         mCardContent = createPhoneCardContent(contactImage, contactName, callState);
@@ -289,12 +328,22 @@
     }
 
     private void handleActiveCall(@NonNull Call call) {
-        @Call.CallState int callState = call.getState();
+        @Call.CallState int callState = call.getDetails().getState();
         if (callState != Call.STATE_ACTIVE && callState != Call.STATE_DIALING) {
             return;
         }
         mCurrentCall = call;
+
         CallDetail callDetails = CallDetail.fromTelecomCallDetail(call.getDetails());
+        if (callDetails.isSelfManaged()) {
+            String packageName = getCallingAppPackageName();
+            mCardHeader = createCardHeader(packageName);
+        }
+        if (mCardHeader == null) {
+            // Default to show the default dialer app info
+            mCardHeader = mDefaultDialerCardHeader;
+        }
+
         // If the home app does not have permission to read contacts, just display the
         // phone number
         if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CONTACTS)
@@ -302,6 +351,7 @@
             updateModelWithPhoneNumber(callDetails.getNumber(), callState);
             return;
         }
+
         if (mPhoneNumberInfoFuture != null) {
             mPhoneNumberInfoFuture.cancel(/* mayInterruptIfRunning= */ true);
         }
@@ -353,4 +403,37 @@
     int[] getMuteButtonDrawableState() {
         return mMuteButton.getIcon().getState();
     }
+
+    @Nullable
+    private String getCallingAppPackageName() {
+        Call.Details callDetails = mCurrentCall == null ? null : mCurrentCall.getDetails();
+        PhoneAccountHandle phoneAccountHandle =
+                callDetails == null ? null : callDetails.getAccountHandle();
+        return phoneAccountHandle == null ? null
+                : phoneAccountHandle.getComponentName().getPackageName();
+    }
+
+    private boolean isRequiresDistractionOptimization() {
+        return mCarUxRestrictionsUtil.getCurrentRestrictions().isRequiresDistractionOptimization();
+    }
+
+    private boolean isSelfManagedCall() {
+        return mCurrentCall != null
+                && mCurrentCall.getDetails().hasProperty(Call.Details.PROPERTY_SELF_MANAGED);
+    }
+
+    private CardHeader createCardHeader(String packageName) {
+        if (!TextUtils.isEmpty(packageName)) {
+            try {
+                ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(
+                        packageName, PackageManager.ApplicationInfoFlags.of(0));
+                Drawable appIcon = mPackageManager.getApplicationIcon(applicationInfo);
+                CharSequence appName = mPackageManager.getApplicationLabel(applicationInfo);
+                return new CardHeader(appName, appIcon);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "No such package found " + packageName, e);
+            }
+        }
+        return null;
+    }
 }
diff --git a/src/com/android/car/carlauncher/homescreen/audio/MediaViewModel.java b/src/com/android/car/carlauncher/homescreen/audio/MediaViewModel.java
index fc848b8..5900fef 100644
--- a/src/com/android/car/carlauncher/homescreen/audio/MediaViewModel.java
+++ b/src/com/android/car/carlauncher/homescreen/audio/MediaViewModel.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
+import android.util.Log;
 import android.util.Size;
 import android.view.Display;
 import android.view.View;
@@ -53,6 +54,8 @@
  */
 public class MediaViewModel extends AndroidViewModel implements HomeCardInterface.Model {
 
+    private static final String TAG = "MediaViewModel";
+
     private HomeCardInterface.Presenter mAudioPresenter;
     // MediaSourceViewModel is for the current or last played media app
     private MediaSourceViewModel mSourceViewModel;
@@ -169,16 +172,19 @@
             // will switch to showing "no media playing" case.
             if (mediaSource != null
                     && !AppLauncherUtils.isVideoApp(mContext.getPackageManager(),
-                        mediaSource.getPackageName())) {
+                          mediaSource.getPackageName())) {
+                if (Log.isLoggable(TAG, Log.INFO)) {
+                    Log.i(TAG, "Setting Media view to source " + mediaSource.getDisplayName());
+                }
                 mAppName = mediaSource.getDisplayName();
                 mAppIcon = mediaSource.getIcon();
                 mCardHeader = new CardHeader(mAppName, mAppIcon);
                 updateMetadata();
             } else {
-                mAppName = null;
-                mAppIcon = null;
-                mCardHeader = null;
-                clearMetadata();
+                if (Log.isLoggable(TAG, Log.INFO)) {
+                    Log.i(TAG, "Not resetting media widget for video apps or apps "
+                            + "that do not support media browse");
+                }
             }
             mAudioPresenter.onModelUpdated(this);
         }
@@ -208,7 +214,7 @@
     }
 
     private void clearMetadata() {
-        mSongTitle = null;
+        mSongTitle = mContext.getString(R.string.default_media_song_title);
         mArtistName = null;
         mAlbumArtBinder.setImage(mContext, /* newArtRef = */ null);
     }
@@ -234,10 +240,16 @@
     private boolean mediaSourceChanged() {
         MediaSource mediaSource = mSourceViewModel.getPrimaryMediaSource().getValue();
         if (mediaSource == null && (mAppName != null || mAppIcon != null)) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "new media source is null...");
+            }
             return true;
         }
         if (mediaSource != null && (mAppName != mediaSource.getDisplayName()
                 || mAppIcon != mediaSource.getIcon())) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "new media source is " + mediaSource.toString());
+            }
             return true;
         }
         return false;
diff --git a/tests/Android.bp b/tests/Android.bp
index 1c79540..569f469 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -26,11 +26,17 @@
   resource_dirs: ["res"],
 
   libs: [
+      "android.car",
       "android.test.base",
       "android.car-system-stubs",
   ],
 
+  optimize: {
+      enabled: false,
+  },
+
   static_libs: [
+      "android.car.testapi",
       "android.car.test.utils",
       "androidx.test.core",
       "androidx.test.runner",
@@ -39,6 +45,7 @@
       "androidx.test.ext.junit",
       "hamcrest-library",
       "mockito-target-extended",
+      "truth-prebuilt",
       "testables",
       "CarLauncher-core"
   ],
@@ -47,6 +54,8 @@
 
   certificate: "platform",
 
+  privileged: true,
+
   manifest: "AndroidManifest.xml",
 
   instrumentation_for: "CarLauncher",
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index b27745a..7238180 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -24,6 +24,8 @@
         <!-- This is used in AppLauncherUtilTests -->
         <meta-data android:name="com.android.automotive"
             android:resource="@xml/automotive_app_desc"/>
+
+        <activity android:name="com.android.car.carlauncher.TaskViewManagerTest$TestActivity" />
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/src/com/android/car/carlauncher/TaskViewManagerTest.java b/tests/src/com/android/car/carlauncher/TaskViewManagerTest.java
new file mode 100644
index 0000000..8dc1602
--- /dev/null
+++ b/tests/src/com/android/car/carlauncher/TaskViewManagerTest.java
@@ -0,0 +1,806 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.carlauncher;
+
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
+
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_SWITCHING;
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.TaskStackListener;
+import android.car.Car;
+import android.car.app.CarActivityManager;
+import android.car.test.mocks.AbstractExtendedMockitoTestCase;
+import android.car.user.CarUserManager;
+import android.content.Intent;
+import android.net.Uri;
+import android.view.SurfaceControl;
+import android.view.SurfaceHolder;
+import android.window.TaskAppearedInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Lifecycle;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.carlauncher.taskstack.TaskStackChangeListeners;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.TaskView;
+import com.android.wm.shell.common.HandlerExecutor;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+@RunWith(AndroidJUnit4.class)
+public class TaskViewManagerTest extends AbstractExtendedMockitoTestCase {
+    @Rule
+    public ActivityScenarioRule mActivityRule = new ActivityScenarioRule<>(TestActivity.class);
+
+    @Mock
+    private ShellTaskOrganizer mOrganizer;
+    @Mock
+    private SyncTransactionQueue mSyncQueue;
+    @Mock
+    private HandlerExecutor mShellExecutor;
+    @Mock
+    private CarActivityManager mCarActivityManager;
+    @Mock
+    private Car mCar;
+    @Mock
+    private TaskStackChangeListeners mTaskStackChangeListeners;
+    @Mock
+    private CarUserManager mCarUserManager;
+    @Mock
+    private WindowContainerToken mToken;
+
+    @Captor
+    private ArgumentCaptor<TaskStackListener> mTaskStackListenerArgumentCaptor;
+    @Captor
+    private ArgumentCaptor<CarUserManager.UserLifecycleListener>
+            mUserLifecycleListenerArgumentCaptor;
+
+    private TestActivity mActivity;
+    private Car.CarServiceLifecycleListener mCarServiceLifecycleListener;
+    private ActivityTaskManager mSpyActivityTaskManager;
+    private CountDownLatch mIdleHandlerLatch = new CountDownLatch(1);
+    private SurfaceControl mLeash;
+
+    @Override
+    protected void onSessionBuilder(@NonNull CustomMockitoSessionBuilder builder) {
+        builder.spyStatic(ActivityTaskManager.class);
+        builder.spyStatic(Car.class);
+        builder.spyStatic(TaskStackChangeListeners.class);
+    }
+
+    @Before
+    public void setUp() {
+        ExtendedMockito.doAnswer(invocation -> {
+            mCarServiceLifecycleListener = invocation.getArgument(3);
+            return mCar;
+        }).when(() -> Car.createCar(any(), any(), anyLong(), any()));
+        when(mCar.getCarManager(eq(Car.CAR_ACTIVITY_SERVICE))).thenReturn(mCarActivityManager);
+        when(mCar.getCarManager(eq(Car.CAR_USER_SERVICE))).thenReturn(mCarUserManager);
+
+        ExtendedMockito.doReturn(mTaskStackChangeListeners).when(() ->
+                TaskStackChangeListeners.getInstance());
+        doNothing().when(mTaskStackChangeListeners).registerTaskStackListener(
+                mTaskStackListenerArgumentCaptor.capture());
+
+        doNothing().when(mCarUserManager).addListener(any(), any(),
+                mUserLifecycleListenerArgumentCaptor.capture());
+
+        mLeash = new SurfaceControl.Builder(null)
+                .setName("test")
+                .build();
+
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            SyncTransactionQueue.TransactionRunnable r =
+                    invocationOnMock.getArgument(0);
+            r.runWithTransaction(new SurfaceControl.Transaction());
+            return null;
+        }).when(mSyncQueue).runInSync(any());
+
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            Runnable r = invocationOnMock.getArgument(0);
+            r.run();
+            return null;
+        }).when(mShellExecutor).execute(any());
+        doReturn(mShellExecutor).when(mOrganizer).getExecutor();
+
+        mSpyActivityTaskManager = spy(ActivityTaskManager.getInstance());
+        ExtendedMockito.doReturn(mSpyActivityTaskManager).when(() ->
+                ActivityTaskManager.getInstance());
+
+        ActivityScenario<TestActivity> scenario = mActivityRule.getScenario();
+        scenario.onActivity(activity -> mActivity = activity);
+    }
+
+    private TaskAppearedInfo createMultiWindowTask(int taskId) {
+        ActivityManager.RunningTaskInfo taskInfo =
+                new ActivityManager.RunningTaskInfo();
+        taskInfo.taskId = taskId;
+        taskInfo.configuration.windowConfiguration.setWindowingMode(
+                WINDOWING_MODE_MULTI_WINDOW);
+        taskInfo.parentTaskId = INVALID_TASK_ID;
+        taskInfo.token = mToken;
+        return new TaskAppearedInfo(taskInfo, new SurfaceControl());
+    }
+
+    @Test
+    public void init_cleansUpExistingMultiWindowTasks() {
+        TaskAppearedInfo existingTask1 = createMultiWindowTask(/* taskId= */ 1);
+        TaskAppearedInfo existingTask2 = createMultiWindowTask(/* taskId= */ 2);
+        doReturn(ImmutableList.of(existingTask1, existingTask2))
+                .when(mOrganizer).registerOrganizer();
+        ExtendedMockito.doReturn(false).when(mSpyActivityTaskManager).removeTask(anyInt());
+
+        new TaskViewManager(mActivity, mShellExecutor, mOrganizer, mSyncQueue);
+
+        verify(mSpyActivityTaskManager).removeTask(eq(1));
+        verify(mSpyActivityTaskManager).removeTask(eq(2));
+    }
+
+    @Test
+    public void testCreateControlledTaskView() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        Intent activityIntent = new Intent();
+        Set<String> packagesThatCanRestart = ImmutableSet.of("com.random.package");
+        ControlledCarTaskViewCallbacks controlledCarTaskViewCallbacks = mock(
+                ControlledCarTaskViewCallbacks.class);
+        when(controlledCarTaskViewCallbacks.getDependingPackageNames())
+                .thenReturn(packagesThatCanRestart);
+
+        taskViewManager.createControlledCarTaskView(
+                mActivity.getMainExecutor(),
+                activityIntent,
+                /* autoRestartOnCrash= */ false,
+                controlledCarTaskViewCallbacks
+        );
+
+        runOnMainAndWait(() -> {});
+        verify(controlledCarTaskViewCallbacks).onTaskViewCreated(any());
+    }
+
+    @Test
+    public void testCreateControlledTaskView_callsOnReadyWhenVisible() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor, mOrganizer,
+                mSyncQueue);
+        Intent activityIntent = new Intent("ACTION_VIEW");
+        Set<String> packagesThatCanRestart = ImmutableSet.of("com.random.package");
+        ControlledCarTaskViewCallbacks controlledCarTaskViewCallbacks = mock(
+                ControlledCarTaskViewCallbacks.class);
+        when(controlledCarTaskViewCallbacks.getDependingPackageNames())
+                .thenReturn(packagesThatCanRestart);
+        taskViewManager.createControlledCarTaskView(
+                mActivity.getMainExecutor(),
+                activityIntent,
+                /* autoRestartOnCrash= */ false,
+                controlledCarTaskViewCallbacks
+        );
+        ControlledCarTaskView taskView = spy(taskViewManager.getControlledTaskViews().get(0));
+        doNothing().when(taskView).startActivity();
+
+        taskView.surfaceCreated(mock(SurfaceHolder.class));
+
+        runOnMainAndWait(() -> {});
+        verify(controlledCarTaskViewCallbacks).onTaskViewCreated(any());
+        verify(controlledCarTaskViewCallbacks).onTaskViewReady();
+    }
+
+    @Test
+    public void testCreateLaunchRootTaskView() throws Exception {
+        LaunchRootCarTaskViewCallbacks taskViewCallbacks =
+                mock(LaunchRootCarTaskViewCallbacks.class);
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+
+        taskViewManager.createLaunchRootTaskView(
+                mActivity.getMainExecutor(),
+                taskViewCallbacks
+        );
+        runOnMainAndWait(() -> {});
+        TaskView taskView = taskViewManager.getLaunchRootCarTaskView();
+        taskView.surfaceCreated(mock(SurfaceHolder.class));
+
+        runOnMainAndWait(() -> {});
+        verify(taskViewCallbacks).onTaskViewCreated(any());
+        verify(mOrganizer).createRootTask(eq(DEFAULT_DISPLAY),
+                eq(WINDOWING_MODE_MULTI_WINDOW),
+                any(ShellTaskOrganizer.TaskListener.class));
+    }
+
+    @Test
+    public void testCreateLaunchRootTaskView_callsOnReadyWhenVisible() throws Exception {
+        TaskAppearedInfo fakeLaunchRootTaskInfo  = createMultiWindowTask(1);
+        LaunchRootCarTaskViewCallbacks taskViewCallbacks =
+                mock(LaunchRootCarTaskViewCallbacks.class);
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        doAnswer(invocation -> {
+            ShellTaskOrganizer.TaskListener listener = invocation.getArgument(2);
+            listener.onTaskAppeared(fakeLaunchRootTaskInfo.getTaskInfo(), mLeash);
+            return null;
+        }).when(mOrganizer).createRootTask(eq(DEFAULT_DISPLAY),
+                eq(WINDOWING_MODE_MULTI_WINDOW),
+                any(ShellTaskOrganizer.TaskListener.class));
+
+        taskViewManager.createLaunchRootTaskView(
+                mActivity.getMainExecutor(),
+                taskViewCallbacks
+        );
+        runOnMainAndWait(() -> {});
+        TaskView taskView = taskViewManager.getLaunchRootCarTaskView();
+        taskView.surfaceCreated(mock(SurfaceHolder.class));
+
+        runOnMainAndWait(() -> {});
+        verify(taskViewCallbacks).onTaskViewCreated(any());
+        verify(taskViewCallbacks).onTaskViewReady();
+        ArgumentCaptor<WindowContainerTransaction> wctCaptor = ArgumentCaptor.forClass(
+                WindowContainerTransaction.class);
+        verify(mSyncQueue, atLeastOnce()).queue(wctCaptor.capture());
+        List<WindowContainerTransaction> wcts = wctCaptor.getAllValues();
+        assertWithMessage("There must be a WindowContainerTransaction to set the"
+                + " root task as the launch root.")
+                .that(wcts.stream()
+                        .flatMap(wct -> wct.getHierarchyOps().stream())
+                        .map(WindowContainerTransaction.HierarchyOp::getType)
+                        .anyMatch(type -> type == HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT))
+                .isTrue();
+    }
+
+    @Test
+    public void testCreateSemiControlledTaskView_launchRootTaskViewAbsent_throwsError()
+            throws Exception {
+        SemiControlledCarTaskViewCallbacks taskViewCallbacks =
+                mock(SemiControlledCarTaskViewCallbacks.class);
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+
+        // The exception happens in the current stack because mShellExecutor simply calls .run()
+        assertThrows(IllegalStateException.class, () -> {
+            taskViewManager.createSemiControlledTaskView(
+                    mActivity.getMainExecutor(),
+                    taskViewCallbacks
+            );
+        });
+
+        runOnMainAndWait(() -> {});
+        verifyZeroInteractions(taskViewCallbacks);
+    }
+
+    @Test
+    public void testCreateSemiControlledTaskView() throws Exception {
+        SemiControlledCarTaskViewCallbacks taskViewCallbacks =
+                mock(SemiControlledCarTaskViewCallbacks.class);
+        when(taskViewCallbacks.shouldStartInTaskView(any())).thenReturn(true);
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+        AtomicReference<ShellTaskOrganizer.TaskListener> listener = new AtomicReference<>();
+        setUpLaunchRootTaskView(taskViewManager, listener, /* rootTaskId = */ 1);
+
+        taskViewManager.createSemiControlledTaskView(
+                mActivity.getMainExecutor(),
+                taskViewCallbacks
+        );
+        runOnMainAndWait(() -> {});
+        // Trigger surfaceCreated on SemiControlledTaskView so that taskView can get into the
+        // initialized state.
+        SemiControlledCarTaskView semiControlledCarTaskView =
+                taskViewManager.getSemiControlledTaskViews().get(0);
+        semiControlledCarTaskView.surfaceCreated(mock(SurfaceHolder.class));
+        runOnMainAndWait(() -> {});
+
+        verify(taskViewCallbacks).onTaskViewCreated(any());
+        verify(taskViewCallbacks).onTaskViewReady();
+    }
+
+    @Test
+    public void testSemiControlledTaskAppeared_reparentedCorrectly() throws Exception {
+        SemiControlledCarTaskViewCallbacks taskViewCallbacks =
+                mock(SemiControlledCarTaskViewCallbacks.class);
+        when(taskViewCallbacks.shouldStartInTaskView(any())).thenReturn(true);
+
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+        // Set up a LaunchRootTaskView
+        AtomicReference<ShellTaskOrganizer.TaskListener> rootTaskListener = new AtomicReference<>();
+        setUpLaunchRootTaskView(taskViewManager, rootTaskListener, /* rootTaskId = */ 1);
+        // Set up a SemiControlledTaskView
+        taskViewManager.createSemiControlledTaskView(
+                mActivity.getMainExecutor(),
+                taskViewCallbacks
+        );
+        runOnMainAndWait(() -> {});
+        SemiControlledCarTaskView semiControlledCarTaskView =
+                taskViewManager.getSemiControlledTaskViews().get(0);
+        semiControlledCarTaskView.surfaceCreated(mock(SurfaceHolder.class));
+        runOnMainAndWait(() -> {});
+        TaskView.Listener mockListener = mock(TaskView.Listener.class);
+        semiControlledCarTaskView.setListener(mActivity.getMainExecutor(), mockListener);
+
+        // Act
+        // Trigger a taskAppeared on the launch root task to mimic the task appearance.
+        rootTaskListener.get().onTaskAppeared(createMultiWindowTask(2).getTaskInfo(), mLeash);
+        runOnMainAndWait(() -> {});
+
+        // Assert
+        // Verify if the task was reparented in the SemiControlledTaskView
+        verify(mockListener).onTaskCreated(eq(2), any());
+    }
+
+    @Test
+    public void testSemiControlledTaskVanished_reparentedCorrectly() throws Exception {
+        SemiControlledCarTaskViewCallbacks taskViewCallbacks =
+                mock(SemiControlledCarTaskViewCallbacks.class);
+        when(taskViewCallbacks.shouldStartInTaskView(any())).thenReturn(true);
+
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+        // Set up a LaunchRootTaskView
+        AtomicReference<ShellTaskOrganizer.TaskListener> rootTaskListener = new AtomicReference<>();
+        setUpLaunchRootTaskView(taskViewManager, rootTaskListener, /* rootTaskId = */ 1);
+        // Set up a SemiControlledTaskView
+        taskViewManager.createSemiControlledTaskView(
+                mActivity.getMainExecutor(),
+                taskViewCallbacks
+        );
+        runOnMainAndWait(() -> {});
+        SemiControlledCarTaskView semiControlledCarTaskView =
+                taskViewManager.getSemiControlledTaskViews().get(0);
+        semiControlledCarTaskView.surfaceCreated(mock(SurfaceHolder.class));
+        runOnMainAndWait(() -> {});
+        TaskView.Listener mockListener = mock(TaskView.Listener.class);
+        semiControlledCarTaskView.setListener(mActivity.getMainExecutor(), mockListener);
+
+        ActivityManager.RunningTaskInfo semiControlledTaskInfo = createMultiWindowTask(2)
+                .getTaskInfo();
+        rootTaskListener.get().onTaskAppeared(semiControlledTaskInfo, mLeash);
+        runOnMainAndWait(() -> {});
+
+        // Act
+        // Trigger a taskVanished on the launch root task
+        rootTaskListener.get().onTaskVanished(semiControlledTaskInfo);
+        runOnMainAndWait(() -> {});
+
+        // Assert
+        // Verify if the task was removed from the SemiControlledTaskView
+        verify(mockListener).onTaskRemovalStarted(/* taskId = */ eq(2));
+    }
+
+    private void setUpLaunchRootTaskView(TaskViewManager taskViewManager,
+            AtomicReference<ShellTaskOrganizer.TaskListener> listener,
+            int rootTaskId) throws Exception {
+        doAnswer(invocation -> {
+            listener.set(invocation.getArgument(2));
+            listener.get().onTaskAppeared(createMultiWindowTask(rootTaskId).getTaskInfo(), mLeash);
+            return null;
+        }).when(mOrganizer).createRootTask(eq(DEFAULT_DISPLAY),
+                eq(WINDOWING_MODE_MULTI_WINDOW),
+                any(ShellTaskOrganizer.TaskListener.class));
+        taskViewManager.createLaunchRootTaskView(
+                mActivity.getMainExecutor(),
+                mock(LaunchRootCarTaskViewCallbacks.class)
+        );
+        runOnMainAndWait(() -> {});
+        LaunchRootCarTaskView launchRootCarTaskView = taskViewManager.getLaunchRootCarTaskView();
+        launchRootCarTaskView.surfaceCreated(mock(SurfaceHolder.class));
+        runOnMainAndWait(() -> {});
+    }
+
+    @Test
+    public void testInit_registersTaskMonitor() throws Exception {
+        new TaskViewManager(mActivity, mShellExecutor, mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+
+        verify(mCarActivityManager).registerTaskMonitor();
+    }
+
+    @Test
+    public void testTaskAppeared_launchRootTaskView_updatesCarActivityManager() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+        // Set up a LaunchRootTaskView
+        AtomicReference<ShellTaskOrganizer.TaskListener> rootTaskListener = new AtomicReference<>();
+        setUpLaunchRootTaskView(taskViewManager, rootTaskListener, /* rootTaskId = */ 1);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+
+        // Act
+        rootTaskListener.get().onTaskAppeared(taskInfo, mLeash);
+        runOnMainAndWait(() -> {});
+
+        // Assert
+        verify(mCarActivityManager).onTaskAppeared(taskInfo);
+    }
+
+    @Test
+    public void testTaskInfoChanged_launchRootTaskView_updatesCarActivityManager()
+            throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+        // Set up a LaunchRootTaskView
+        AtomicReference<ShellTaskOrganizer.TaskListener> rootTaskListener = new AtomicReference<>();
+        setUpLaunchRootTaskView(taskViewManager, rootTaskListener, /* rootTaskId = */ 1);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+
+        // Act
+        rootTaskListener.get().onTaskInfoChanged(taskInfo);
+        runOnMainAndWait(() -> {});
+
+        // Assert
+        verify(mCarActivityManager).onTaskInfoChanged(taskInfo);
+    }
+
+    @Test
+    public void testTaskVanished_launchRootTaskView_updatesCarActivityManager() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+        // Set up a LaunchRootTaskView
+        AtomicReference<ShellTaskOrganizer.TaskListener> rootTaskListener = new AtomicReference<>();
+        setUpLaunchRootTaskView(taskViewManager, rootTaskListener, /* rootTaskId = */ 1);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+
+        // Act
+        rootTaskListener.get().onTaskVanished(taskInfo);
+        runOnMainAndWait(() -> {});
+
+        // Assert
+        verify(mCarActivityManager).onTaskVanished(taskInfo);
+    }
+
+    @Test
+    public void testHostActivityDestroyed_releasesAllTaskViews() throws Exception {
+        testReleaseAllTaskViews(() -> {
+            ActivityScenario<TestActivity> scenario = mActivityRule.getScenario();
+            scenario.moveToState(Lifecycle.State.DESTROYED);
+        });
+    }
+
+    private void setUpControlledTaskView(TaskViewManager taskViewManager, Intent activityIntent,
+            Set<String> packagesThatCanRestart) throws Exception {
+        ControlledCarTaskViewCallbacks controlledCarTaskViewCallbacks = mock(
+                ControlledCarTaskViewCallbacks.class);
+        when(controlledCarTaskViewCallbacks.getDependingPackageNames())
+                .thenReturn(packagesThatCanRestart);
+        taskViewManager.createControlledCarTaskView(
+                mActivity.getMainExecutor(),
+                activityIntent,
+                false,
+                controlledCarTaskViewCallbacks
+        );
+
+        int lastIndex = Math.min(0, taskViewManager.getControlledTaskViews().size() - 1);
+        ControlledCarTaskView taskView = spy(taskViewManager.getControlledTaskViews()
+                .get(lastIndex));
+        doNothing().when(taskView).startActivity();
+
+        taskView.surfaceCreated(mock(SurfaceHolder.class));
+        runOnMainAndWait(() -> {});
+    }
+
+    @Test
+    public void testRestartControlledTask_whenHostActivityFocussed() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+
+        // Send onTaskVanished to mimic the task removal behavior.
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.random.package2"));
+        ControlledCarTaskView controlledCarTaskView =
+                taskViewManager.getControlledTaskViews().get(0);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+        controlledCarTaskView.onTaskAppeared(taskInfo, mLeash);
+        controlledCarTaskView.onTaskVanished(taskInfo);
+        assertThat(controlledCarTaskView.getTaskId()).isEqualTo(INVALID_TASK_ID);
+
+        // Stub the taskview with a spy to assert on startActivity.
+        ControlledCarTaskView spiedTaskView = spy(controlledCarTaskView);
+        doNothing().when(spiedTaskView).startActivity();
+        taskViewManager.getControlledTaskViews().set(0, spiedTaskView);
+
+        // Act
+        mTaskStackListenerArgumentCaptor.getValue().onTaskFocusChanged(mActivity.getTaskId(),
+                /* focused = */ true);
+
+        // Assert
+        verify(spiedTaskView).startActivity();
+    }
+
+    @Test
+    public void testControlledTaskNotRestarted_ifAlreadyRunning_whenHostActivityFocussed()
+            throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.random.package2"));
+        ControlledCarTaskView controlledCarTaskView =
+                taskViewManager.getControlledTaskViews().get(0);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+        controlledCarTaskView.onTaskAppeared(taskInfo, mLeash);
+
+        // Stub the taskview with a spy to assert on startActivity.
+        ControlledCarTaskView spiedTaskView = spy(controlledCarTaskView);
+        doNothing().when(spiedTaskView).startActivity();
+        taskViewManager.getControlledTaskViews().set(0, spiedTaskView);
+
+        // Act
+        mTaskStackListenerArgumentCaptor.getValue().onTaskFocusChanged(mActivity.getTaskId(),
+                /* focused = */ true);
+
+        // Assert
+        verify(spiedTaskView, times(0)).startActivity();
+    }
+
+    @Test
+    public void testRestartControlledTask_whenHostActivityRestarted() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+
+        // Send onTaskVanished to mimic the task removal behavior.
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.random.package2"));
+        ControlledCarTaskView controlledCarTaskView =
+                taskViewManager.getControlledTaskViews().get(0);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+        controlledCarTaskView.onTaskAppeared(taskInfo, mLeash);
+        controlledCarTaskView.onTaskVanished(taskInfo);
+        assertThat(controlledCarTaskView.getTaskId()).isEqualTo(INVALID_TASK_ID);
+
+        // Stub the taskview with a spy to assert on startActivity.
+        ControlledCarTaskView spiedTaskView = spy(controlledCarTaskView);
+        doNothing().when(spiedTaskView).startActivity();
+        taskViewManager.getControlledTaskViews().set(0, spiedTaskView);
+
+        // Act
+        mTaskStackListenerArgumentCaptor.getValue().onActivityRestartAttempt(
+                createMultiWindowTask(mActivity.getTaskId()).getTaskInfo(),
+                /* homeTaskVisible = */ true, false,
+                /* focused = */ true);
+
+        // Assert
+        verify(spiedTaskView).startActivity();
+    }
+
+    @Test
+    public void testRestartControlledTask_whenPackageThatCanRestartChanged() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+
+        // Send onTaskVanished to mimic the task removal behavior.
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.relevant.package"));
+        ControlledCarTaskView controlledCarTaskView =
+                taskViewManager.getControlledTaskViews().get(0);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+        controlledCarTaskView.onTaskAppeared(taskInfo, mLeash);
+        controlledCarTaskView.onTaskVanished(taskInfo);
+        assertThat(controlledCarTaskView.getTaskId()).isEqualTo(INVALID_TASK_ID);
+
+        // Stub the taskview with a spy to assert on startActivity.
+        ControlledCarTaskView spiedTaskView = spy(controlledCarTaskView);
+        doNothing().when(spiedTaskView).startActivity();
+        taskViewManager.getControlledTaskViews().set(0, spiedTaskView);
+
+        // Act
+        taskViewManager.getPackageBroadcastReceiver().onReceive(mActivity,
+                new Intent().setData(Uri.parse("package:com.relevant.package")));
+
+        // Assert
+        verify(spiedTaskView).startActivity();
+    }
+
+    @Test
+    public void testControlledTaskNotRestarted_whenARandomPackageChanged() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+
+        // Send onTaskVanished to mimic the task removal behavior.
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.relevant.package"));
+        ControlledCarTaskView controlledCarTaskView =
+                taskViewManager.getControlledTaskViews().get(0);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+        controlledCarTaskView.onTaskAppeared(taskInfo, mLeash);
+        controlledCarTaskView.onTaskVanished(taskInfo);
+        assertThat(controlledCarTaskView.getTaskId()).isEqualTo(INVALID_TASK_ID);
+
+        // Stub the taskview with a spy to assert on startActivity.
+        ControlledCarTaskView spiedTaskView = spy(controlledCarTaskView);
+        doNothing().when(spiedTaskView).startActivity();
+        taskViewManager.getControlledTaskViews().set(0, spiedTaskView);
+
+        // Act
+        taskViewManager.getPackageBroadcastReceiver().onReceive(mActivity,
+                new Intent().setData(Uri.parse("package:com.random.package")));
+
+        // Assert
+        verify(spiedTaskView, times(0)).startActivity();
+    }
+
+    // User switch related tests.
+
+    @Test
+    public void testRestartControlledTask_onUserUnlocked() throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+
+        // Send onTaskVanished to mimic the task removal behavior.
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.random.package2"));
+        ControlledCarTaskView controlledCarTaskView =
+                taskViewManager.getControlledTaskViews().get(0);
+        ActivityManager.RunningTaskInfo taskInfo = createMultiWindowTask(2).getTaskInfo();
+        controlledCarTaskView.onTaskAppeared(taskInfo, mLeash);
+        controlledCarTaskView.onTaskVanished(taskInfo);
+        assertThat(controlledCarTaskView.getTaskId()).isEqualTo(INVALID_TASK_ID);
+
+        // Stub the taskview with a spy to assert on startActivity.
+        ControlledCarTaskView spiedTaskView = spy(controlledCarTaskView);
+        doNothing().when(spiedTaskView).startActivity();
+        taskViewManager.getControlledTaskViews().set(0, spiedTaskView);
+
+        // Act
+        mUserLifecycleListenerArgumentCaptor.getValue().onEvent(
+                new CarUserManager.UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED,
+                        mActivity.getUserId()));
+
+        // Assert
+        verify(spiedTaskView).startActivity();
+    }
+
+    @Test
+    public void testUserSwitch_releasesAllTaskViews() throws Exception {
+        testReleaseAllTaskViews(/* actionBlock= */ () ->
+                mUserLifecycleListenerArgumentCaptor.getValue().onEvent(
+                        new CarUserManager.UserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING,
+                                /* from= */ mActivity.getUserId(), /* to= */ 20))
+        );
+    }
+
+    private void testReleaseAllTaskViews(Runnable actionBlock) throws Exception {
+        TaskViewManager taskViewManager = new TaskViewManager(mActivity, mShellExecutor,
+                mOrganizer, mSyncQueue);
+        runOnMainAndWait(() -> {});
+        mCarServiceLifecycleListener.onLifecycleChanged(mCar, true);
+        // Create a few TaskViews
+        AtomicReference<ShellTaskOrganizer.TaskListener> listener = new AtomicReference<>();
+        setUpLaunchRootTaskView(taskViewManager, listener, /* rootTaskId = */ 1);
+        LaunchRootCarTaskView launchRootCarTaskView = taskViewManager.getLaunchRootCarTaskView();
+
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.random.package"));
+        ControlledCarTaskView controlledCarTaskView = taskViewManager.getControlledTaskViews()
+                .get(0);
+        setUpControlledTaskView(taskViewManager, new Intent("ACTION_VIEW"),
+                ImmutableSet.of("com.random.package2"));
+        ControlledCarTaskView controlledCarTaskView2 = taskViewManager.getControlledTaskViews()
+                .get(1);
+
+        SemiControlledCarTaskViewCallbacks taskViewCallbacks =
+                mock(SemiControlledCarTaskViewCallbacks.class);
+        when(taskViewCallbacks.shouldStartInTaskView(any())).thenReturn(true);
+        taskViewManager.createSemiControlledTaskView(
+                mActivity.getMainExecutor(),
+                taskViewCallbacks
+        );
+        runOnMainAndWait(() -> {});
+        taskViewManager.createSemiControlledTaskView(
+                mActivity.getMainExecutor(),
+                taskViewCallbacks
+        );
+        runOnMainAndWait(() -> {});
+        // Trigger surfaceCreated on SemiControlledTaskView.
+        SemiControlledCarTaskView semiControlledCarTaskView =
+                taskViewManager.getSemiControlledTaskViews().get(0);
+        semiControlledCarTaskView.surfaceCreated(mock(SurfaceHolder.class));
+        runOnMainAndWait(() -> {});
+        SemiControlledCarTaskView semiControlledCarTaskView2 =
+                taskViewManager.getSemiControlledTaskViews().get(1);
+        semiControlledCarTaskView2.surfaceCreated(mock(SurfaceHolder.class));
+        runOnMainAndWait(() -> {});
+
+        // Act
+        actionBlock.run();
+
+        // Assert
+        assertThat(launchRootCarTaskView.isInitialized()).isFalse();
+        assertThat(controlledCarTaskView.isInitialized()).isFalse();
+        assertThat(controlledCarTaskView2.isInitialized()).isFalse();
+        assertThat(semiControlledCarTaskView.isInitialized()).isFalse();
+        assertThat(semiControlledCarTaskView2.isInitialized()).isFalse();
+
+        assertThat(taskViewManager.getSemiControlledTaskViews()).isEmpty();
+        assertThat(taskViewManager.getLaunchRootCarTaskView()).isNull();
+        assertThat(taskViewManager.getControlledTaskViews()).isEmpty();
+
+        verify(mOrganizer).unregisterOrganizer();
+    }
+
+    private void runOnMainAndWait(Runnable r) throws Exception {
+        mActivity.getMainExecutor().execute(() -> {
+            r.run();
+            mIdleHandlerLatch.countDown();
+            mIdleHandlerLatch = new CountDownLatch(1);
+        });
+        mIdleHandlerLatch.await(5, TimeUnit.SECONDS);
+    }
+
+    public static class TestActivity extends Activity {}
+}
diff --git a/tests/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenterTest.java b/tests/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenterTest.java
index 602e364..b53d5bd 100644
--- a/tests/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenterTest.java
+++ b/tests/src/com/android/car/carlauncher/homescreen/audio/HomeAudioCardPresenterTest.java
@@ -27,6 +27,7 @@
 import com.android.car.carlauncher.homescreen.HomeCardInterface;
 import com.android.car.carlauncher.homescreen.ui.CardHeader;
 import com.android.car.carlauncher.homescreen.ui.DescriptiveTextView;
+import com.android.car.carlauncher.homescreen.ui.DescriptiveTextWithControlsView;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -35,8 +36,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Collections;
-
 @RunWith(JUnit4.class)
 public class HomeAudioCardPresenterTest {
 
@@ -92,6 +91,28 @@
     }
 
     @Test
+    public void onModelUpdated_activePhoneCall_doesNotUpdateFragment() {
+        //setUpActivePhoneCall in presenter
+        CardHeader callModelHeader = new CardHeader("dialer", /* appIcon = */
+                null);
+        DescriptiveTextWithControlsView callModelContent = new DescriptiveTextWithControlsView(
+                /* image = */ null, "callerNumber", "ongoingCall");
+        when(mOtherModel.getCardHeader()).thenReturn(callModelHeader);
+        when(mOtherModel.getCardContent()).thenReturn(callModelContent);
+        mPresenter.onModelUpdated(mOtherModel);
+
+        // send MediaModel update during ongoing call
+        mPresenter.onModelUpdated(mModel);
+
+        //verify call
+        verify(mView).updateHeaderView(callModelHeader);
+        verify(mView).updateContentView(callModelContent);
+        verify(mView, never()).hideCard();
+        verify(mView, never()).updateHeaderView(CARD_HEADER);
+        verify(mView, never()).updateContentView(CARD_CONTENT);
+    }
+
+    @Test
     public void onModelUpdated_nullSameModel_updatesFragment() {
         mPresenter.onModelUpdated(mModel);
         reset(mView);