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

am skip reason: subject contains skip directive

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

Change-Id: I2ee4e1c9c1b6e8af18cad7370cccc0659a438479
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/OWNERS b/OWNERS
index b459e37..777187a 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,13 +1 @@
-# Primary
-alexstetson@google.com
-
-# Secondary
-nehah@google.com
-
-# Owners from Core Android SystemUI in case quick approval is needed for simple refactoring.
-# But generally, someone from the AAOS SystemUI listed above should be included.
-dupin@google.com
-mankoff@google.com
-pixel@google.com
-dsandler@android.com
-adamcohen@google.com
\ No newline at end of file
+include platform/packages/apps/Car/SystemUI:master:/OWNERS
diff --git a/res/drawable/car_ic_managed_device.xml b/res/drawable/car_ic_managed_device.xml
new file mode 100644
index 0000000..fd333a7
--- /dev/null
+++ b/res/drawable/car_ic_managed_device.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="@*android:dimen/car_touch_target_size"
+        android:height="@*android:dimen/car_touch_target_size"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="@color/car_managed_device_icon_color"
+        android:pathData="M4 21Q3.175 21 2.588 20.413Q2 19.825 2 19V8Q2 7.175 2.588 6.588Q3.175 6 4 6H8V4Q8 3.175 8.588 2.587Q9.175 2 10 2H14Q14.825 2 15.413 2.587Q16 3.175 16 4V6H20Q20.825 6 21.413 6.588Q22 7.175 22 8V19Q22 19.825 21.413 20.413Q20.825 21 20 21ZM10 6H14V4Q14 4 14 4Q14 4 14 4H10Q10 4 10 4Q10 4 10 4ZM4 19H20Q20 19 20 19Q20 19 20 19V8Q20 8 20 8Q20 8 20 8H4Q4 8 4 8Q4 8 4 8V19Q4 19 4 19Q4 19 4 19ZM20 19H4Q4 19 4 19Q4 19 4 19V8Q4 8 4 8Q4 8 4 8H20Q20 8 20 8Q20 8 20 8V19Q20 19 20 19Q20 19 20 19Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/layout/device_management_dialog.xml b/res/layout/device_management_dialog.xml
new file mode 100644
index 0000000..f3516bf
--- /dev/null
+++ b/res/layout/device_management_dialog.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:id="@+id/scrollView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:clipToPadding="false">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="?android:attr/dialogPreferredPadding"
+        android:paddingRight="?android:attr/dialogPreferredPadding"
+        android:paddingLeft="?android:attr/dialogPreferredPadding"
+        android:orientation="vertical">
+        <LinearLayout
+            android:id="@+id/device_management_disclosures"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="?android:attr/dialogPreferredPadding"
+            android:orientation="vertical">
+            <TextView
+                android:id="@+id/device_management_subtitle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                style="@style/TextAppearance.CarUi.AlertDialog.Title"
+                android:paddingBottom="@dimen/device_management_dialog_subtitle_padding"
+            />
+            <TextView
+                android:id="@+id/device_management_warning"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.CarUi.AlertDialog.Subtitle"
+            />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/ca_certs_disclosures"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="?android:attr/dialogPreferredPadding"
+            android:orientation="vertical">
+            <TextView
+                android:id="@+id/ca_certs_subtitle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/monitoring_subtitle_ca_certificate"
+                style="@style/TextAppearance.CarUi.AlertDialog.Title"
+                android:paddingBottom="@dimen/device_management_dialog_subtitle_padding"
+            />
+            <TextView
+                android:id="@+id/ca_certs_warning"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.CarUi.AlertDialog.Subtitle"
+            />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/network_logging_disclosures"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="?android:attr/dialogPreferredPadding"
+            android:orientation="vertical">
+            <TextView
+                android:id="@+id/network_logging_subtitle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/monitoring_subtitle_network_logging"
+                style="@style/TextAppearance.CarUi.AlertDialog.Title"
+                android:paddingBottom="@dimen/device_management_dialog_subtitle_padding"
+            />
+            <TextView
+                android:id="@+id/network_logging_warning"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.CarUi.AlertDialog.Subtitle"
+            />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/vpn_disclosures"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="?android:attr/dialogPreferredPadding"
+            android:orientation="vertical">
+            <TextView
+                android:id="@+id/vpn_subtitle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/monitoring_subtitle_vpn"
+                style="@style/TextAppearance.CarUi.AlertDialog.Title"
+                android:paddingBottom="@dimen/device_management_dialog_subtitle_padding"
+            />
+            <TextView
+                android:id="@+id/vpn_warning"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.CarUi.AlertDialog.Subtitle"
+            />
+        </LinearLayout>
+    </LinearLayout>
+</ScrollView>
diff --git a/res/layout/hvac_panel_container.xml b/res/layout/hvac_panel_container.xml
index 7ed9ac4..284920d 100644
--- a/res/layout/hvac_panel_container.xml
+++ b/res/layout/hvac_panel_container.xml
@@ -46,7 +46,7 @@
             android:id="@+id/driver_hvac"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
             systemui:hvacAreaId="49">
@@ -58,8 +58,8 @@
             android:layout_height="@dimen/hvac_panel_group_height"
             android:background="@drawable/hvac_panel_button_bg"
             app:layout_constraintTop_toBottomOf="@+id/top_guideline"
-            app:layout_constraintStart_toEndOf="@+id/driver_hvac"
-            app:layout_constraintEnd_toStartOf="@+id/fan_control"
+            app:layout_constraintLeft_toRightOf="@+id/driver_hvac"
+            app:layout_constraintRight_toLeftOf="@+id/fan_control"
             systemui:hvacAreaId="117"
             systemui:hvacPropertyId="354419976"
             systemui:hvacTurnOffIfAutoOn="true"
@@ -71,8 +71,7 @@
             android:layout_width="@dimen/hvac_fan_speed_bar_width"
             android:layout_height="@dimen/hvac_panel_group_height"
             app:layout_constraintTop_toBottomOf="@+id/top_guideline"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintLeft_toRightOf="@+id/recycle_air_button"
             app:layout_constraintRight_toLeftOf="@+id/ac_button"
             android:layout_centerVertical="true"
             android:layout_centerHorizontal="true"
@@ -85,7 +84,8 @@
                 android:layout_weight="1"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
-                android:orientation="horizontal"/>
+                android:orientation="horizontal"
+                android:layoutDirection="ltr"/>
         </LinearLayout>
         <com.android.systemui.car.hvac.toggle.HvacBooleanToggleButton
             android:id="@+id/ac_button"
@@ -93,8 +93,8 @@
             android:layout_height="@dimen/hvac_panel_group_height"
             android:background="@drawable/hvac_panel_button_bg"
             app:layout_constraintTop_toBottomOf="@+id/top_guideline"
-            app:layout_constraintStart_toEndOf="@+id/fan_control"
-            app:layout_constraintEnd_toStartOf="@+id/passenger_hvac"
+            app:layout_constraintLeft_toRightOf="@+id/fan_control"
+            app:layout_constraintRight_toLeftOf="@+id/passenger_hvac"
             systemui:hvacAreaId="117"
             systemui:hvacPropertyId="354419973"
             systemui:hvacTurnOffIfAutoOn="true"
@@ -115,7 +115,7 @@
             android:background="@drawable/hvac_panel_button_bg"
             android:scaleType="center"
             style="@style/HvacButton"
-            app:layout_constraintStart_toEndOf="@+id/driver_hvac"
+            app:layout_constraintLeft_toRightOf="@+id/driver_hvac"
             app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
             systemui:hvacAreaId="117"
             systemui:hvacPropertyId="354419984"
@@ -126,7 +126,7 @@
             android:id="@+id/seat_heat_level_button_left"
             android:background="@drawable/hvac_panel_button_bg"
             style="@style/HvacButton"
-            app:layout_constraintStart_toEndOf="@+id/ac_master_switch"
+            app:layout_constraintLeft_toRightOf="@+id/ac_master_switch"
             app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
             systemui:hvacAreaId="1"
             systemui:seatTemperatureType="heating"
@@ -135,7 +135,7 @@
             android:id="@+id/defroster_button"
             android:background="@drawable/hvac_panel_button_bg"
             style="@style/HvacButton"
-            app:layout_constraintStart_toEndOf="@+id/seat_heat_level_button_left"
+            app:layout_constraintLeft_toRightOf="@+id/seat_heat_level_button_left"
             app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
             systemui:hvacAreaId="1"
             systemui:hvacPropertyId="320865540"
@@ -150,8 +150,8 @@
             android:layout_gravity="center"
             android:layout_width="0dp"
             style="@style/HvacButton"
-            app:layout_constraintStart_toEndOf="@+id/defroster_button"
-            app:layout_constraintEnd_toStartOf="@+id/rear_defroster_button"
+            app:layout_constraintLeft_toRightOf="@+id/defroster_button"
+            app:layout_constraintRight_toLeftOf="@+id/rear_defroster_button"
             app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
             systemui:hvacToggleOnButtonDrawable="@drawable/ic_auto_on"
             systemui:hvacToggleOffButtonDrawable="@drawable/ic_auto_off"/>
@@ -161,7 +161,7 @@
             style="@style/HvacButton"
             systemui:hvacAreaId="2"
             systemui:hvacPropertyId="320865540"
-            app:layout_constraintEnd_toStartOf="@+id/seat_heat_level_button_right"
+            app:layout_constraintRight_toLeftOf="@+id/seat_heat_level_button_right"
             app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
             systemui:hvacToggleOnButtonDrawable="@drawable/ic_rear_defroster_on"
             systemui:hvacToggleOffButtonDrawable="@drawable/ic_rear_defroster_off"/>
@@ -169,7 +169,7 @@
             android:id="@+id/seat_heat_level_button_right"
             android:background="@drawable/hvac_panel_button_bg"
             style="@style/HvacButton"
-            app:layout_constraintEnd_toStartOf="@+id/passenger_hvac"
+            app:layout_constraintRight_toLeftOf="@+id/passenger_hvac"
             app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline"
             systemui:hvacAreaId="4"
             systemui:seatTemperatureType="heating"
@@ -178,4 +178,4 @@
             layout="@layout/hvac_panel_handle_bar"
             app:layout_constraintTop_toTopOf="parent"/>
     </com.android.systemui.car.hvac.HvacPanelView>
-</com.android.car.ui.FocusArea>
\ No newline at end of file
+</com.android.car.ui.FocusArea>
diff --git a/res/layout/hvac_temperature_bar_overlay.xml b/res/layout/hvac_temperature_bar_overlay.xml
index 2644548..2ae3f0b 100644
--- a/res/layout/hvac_temperature_bar_overlay.xml
+++ b/res/layout/hvac_temperature_bar_overlay.xml
@@ -30,7 +30,6 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/temperature_bar_icon_margin"
-            android:layout_centerHorizontal="true"
             android:layout_alignParentTop="true"
             android:src="@drawable/ic_increase_icon"
             style="@style/HvacTemperatureControlIcon"/>
@@ -46,8 +45,8 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginBottom="@dimen/temperature_bar_icon_margin"
-            android:layout_centerHorizontal="true"
             android:layout_alignParentBottom="true"
-            android:src="@drawable/ic_decrease_icon" />
+            android:src="@drawable/ic_decrease_icon"
+            style="@style/HvacTemperatureControlIcon"/>
     </RelativeLayout>
 </FrameLayout>
\ No newline at end of file
diff --git a/res/layout/qc_bluetooth_panel.xml b/res/layout/qc_bluetooth_panel.xml
index 7cf88ba..0daff2f 100644
--- a/res/layout/qc_bluetooth_panel.xml
+++ b/res/layout/qc_bluetooth_panel.xml
@@ -13,33 +13,50 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
+<com.android.car.ui.FocusArea
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="vertical"
     android:background="@color/status_icon_panel_bg_color">
-    <com.android.car.ui.FocusArea
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:orientation="vertical">
-        <com.android.systemui.car.qc.SystemUIQCView
+        android:layout_height="wrap_content">
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:remoteQCProvider="content://com.android.car.settings.qc/bluetooth_switch"/>
-        <com.android.systemui.car.qc.SystemUIQCView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:remoteQCProvider="content://com.android.car.settings.qc/paired_bluetooth_devices"/>
+            android:layout_height="0dp"
+            app:layout_constraintHeight_default="wrap"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toTopOf="@+id/qc_bluetooth_footer_button">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:remoteQCProvider="content://com.android.car.settings.qc/bluetooth_switch"/>
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:remoteQCProvider="content://com.android.car.settings.qc/paired_bluetooth_devices"/>
+            </LinearLayout>
+        </ScrollView>
         <com.android.systemui.car.qc.QCFooterButton
+            android:id="@+id/qc_bluetooth_footer_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="start"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
             style="@style/QCFooterButtonStyle"
             android:text="@string/qc_footer_bluetooth_settings"
             app:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$BluetoothSettingsActivity;launchFlags=0x08080000;end"/>
-    </com.android.car.ui.FocusArea>
-</FrameLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.car.ui.FocusArea>
diff --git a/res/layout/qc_connectivity_panel.xml b/res/layout/qc_connectivity_panel.xml
index 42ae926..8371f70 100644
--- a/res/layout/qc_connectivity_panel.xml
+++ b/res/layout/qc_connectivity_panel.xml
@@ -13,38 +13,55 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
+<com.android.car.ui.FocusArea
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="vertical"
     android:background="@color/status_icon_panel_bg_color">
-    <com.android.car.ui.FocusArea
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:orientation="vertical">
-        <com.android.systemui.car.qc.SystemUIQCView
+        android:layout_height="wrap_content">
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:remoteQCProvider="content://com.android.car.settings.qc/mobile_data_row"/>
-        <com.android.systemui.car.qc.SystemUIQCView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:remoteQCProvider="content://com.android.car.settings.qc/hotspot_row"/>
-        <com.android.systemui.car.qc.SystemUIQCView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:remoteQCProvider="content://com.android.car.settings.qc/wifi_row"/>
+            android:layout_height="0dp"
+            app:layout_constraintHeight_default="wrap"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toTopOf="@+id/qc_connectivity_footer_button">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:remoteQCProvider="content://com.android.car.settings.qc/mobile_data_row"/>
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:remoteQCProvider="content://com.android.car.settings.qc/hotspot_row"/>
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:remoteQCProvider="content://com.android.car.settings.qc/wifi_row"/>
+            </LinearLayout>
+        </ScrollView>
         <com.android.systemui.car.qc.QCFooterButton
+            android:id="@+id/qc_connectivity_footer_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="start"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
             style="@style/QCFooterButtonStyle"
             android:text="@string/qc_footer_network_internet_settings"
             app:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$NetworkAndInternetActivity;launchFlags=0x08080000;end"/>
-    </com.android.car.ui.FocusArea>
-</FrameLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.car.ui.FocusArea>
diff --git a/res/layout/qc_display_panel.xml b/res/layout/qc_display_panel.xml
index 19776c0..8eaa6b9 100644
--- a/res/layout/qc_display_panel.xml
+++ b/res/layout/qc_display_panel.xml
@@ -13,33 +13,50 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
+<com.android.car.ui.FocusArea
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="vertical"
     android:background="@color/status_icon_panel_bg_color">
-    <com.android.car.ui.FocusArea
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:orientation="vertical">
-        <com.android.systemui.car.qc.SystemUIQCView
+        android:layout_height="wrap_content">
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:remoteQCProvider="content://com.android.car.settings.qc/brightness_slider"/>
-        <com.android.systemui.car.qc.SystemUIQCView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:remoteQCProvider="content://com.android.car.settings.qc/adaptive_brightness_switch"/>
+            android:layout_height="0dp"
+            app:layout_constraintHeight_default="wrap"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toTopOf="@+id/qc_display_footer_button">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:remoteQCProvider="content://com.android.car.settings.qc/brightness_slider"/>
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:remoteQCProvider="content://com.android.car.settings.qc/adaptive_brightness_switch"/>
+            </LinearLayout>
+        </ScrollView>
         <com.android.systemui.car.qc.QCFooterButton
+            android:id="@+id/qc_display_footer_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="start"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
             style="@style/QCFooterButtonStyle"
             android:text="@string/qc_footer_display_settings"
             app:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$DisplaySettingsActivity;launchFlags=0x08080000;end"/>
-    </com.android.car.ui.FocusArea>
-</FrameLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.car.ui.FocusArea>
diff --git a/res/layout/qc_mic_panel.xml b/res/layout/qc_mic_panel.xml
index 71f4a07..e4724f9 100644
--- a/res/layout/qc_mic_panel.xml
+++ b/res/layout/qc_mic_panel.xml
@@ -13,30 +13,41 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
+<com.android.car.ui.FocusArea
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/mic_privacy_panel"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="vertical"
     android:background="@color/status_icon_panel_bg_color">
-    <com.android.car.ui.FocusArea
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:orientation="vertical">
-        <com.android.systemui.car.qc.SystemUIQCView
+        android:layout_height="wrap_content">
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:localQCProvider="com.android.systemui.car.privacy.MicQcPanel"/>
+            android:layout_height="0dp"
+            app:layout_constraintHeight_default="wrap"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toTopOf="@+id/qc_mic_footer_button">
+            <com.android.systemui.car.qc.SystemUIQCView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                app:localQCProvider="com.android.systemui.car.privacy.MicQcPanel"/>
+        </ScrollView>
         <com.android.systemui.car.qc.QCFooterButton
+            android:id="@+id/qc_mic_footer_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="start"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
             style="@style/QCFooterButtonStyle"
             android:text="@string/mic_privacy_chip_microphone_settings"
             app:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$PrivacySettingsActivity;launchFlags=0x08080000;end"
             app:disableWhileDriving="true"/>
-    </com.android.car.ui.FocusArea>
-</FrameLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.car.ui.FocusArea>
diff --git a/res/layout/qc_profile_switcher.xml b/res/layout/qc_profile_switcher.xml
index 2367bb8..ab0f974 100644
--- a/res/layout/qc_profile_switcher.xml
+++ b/res/layout/qc_profile_switcher.xml
@@ -24,17 +24,33 @@
         android:layout_height="wrap_content"
         android:gravity="center"
         android:orientation="vertical">
-        <com.android.systemui.car.qc.SystemUIQCView
+        <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            app:localQCProvider="com.android.systemui.car.qc.ProfileSwitcher"/>
-        <com.android.systemui.car.qc.QCFooterButton
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="start"
-            style="@style/QCFooterButtonStyle"
-            android:text="@string/qc_footer_profiles_accounts_settings"
-            app:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$ProfileDetailsActivity;launchFlags=0x08080000;end"/>
+            android:layout_height="wrap_content">
+            <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                app:layout_constraintHeight_default="wrap"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@+id/qc_profile_footer_button">
+                <com.android.systemui.car.qc.SystemUIQCView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    app:localQCProvider="com.android.systemui.car.qc.ProfileSwitcher"/>
+            </ScrollView>
+            <com.android.systemui.car.qc.QCFooterButton
+                android:id="@+id/qc_profile_footer_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="start"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                style="@style/QCFooterButtonStyle"
+                android:text="@string/qc_footer_profiles_accounts_settings"
+                app:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$ProfileDetailsActivity;launchFlags=0x08080000;end"/>
+        </androidx.constraintlayout.widget.ConstraintLayout>
     </com.android.car.ui.FocusArea>
 </FrameLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index d48c9ba..44d268d 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -20,6 +20,7 @@
     <color name="car_user_switcher_name_text_color">@*android:color/car_body1_light</color>
     <color name="car_user_switcher_add_user_background_color">#131313</color>
     <color name="car_user_switcher_add_user_add_sign_color">@*android:color/car_body1_light</color>
+    <color name="car_managed_device_icon_color">@android:color/white</color>
     <color name="car_nav_icon_fill_color">#8F8F8F</color>
     <color name="car_nav_icon_fill_color_selected">#ffffff</color>
     <!-- colors for seekbar -->
diff --git a/res/values/config.xml b/res/values/config.xml
index a6b7736..03b6746 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -117,6 +117,7 @@
         <item>@string/config_notificationPanelViewMediator</item>
         <item>com.android.systemui.car.hvac.HvacPanelOverlayViewMediator</item>
         <item>com.android.systemui.car.keyguard.CarKeyguardViewMediator</item>
+        <item>com.android.systemui.car.systemdialogs.SystemDialogsViewMediator</item>
         <item>com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator</item>
         <item>com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator</item>
     </string-array>
@@ -183,6 +184,7 @@
         <item>android.server.wm.app</item>
         <item>android.server.wm.cts</item>
         <item>android.server.wm.second</item>
+        <item>com.android.cts.verifier</item>
     </string-array>
 
     <!-- Specifies the component name of the app grid activity -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 5439b38..14999c1 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -101,6 +101,8 @@
     <dimen name="car_keyline_2">96dp</dimen>
     <dimen name="car_keyline_3">128dp</dimen>
 
+    <dimen name="device_management_dialog_subtitle_padding">20dp</dimen>
+
     <!-- Height of icons in Privacy chip dialog. Both App Op icon and application icon -->
     <dimen name="privacy_chip_dialog_icon_height">48dp</dimen>
     <!-- Icon size for Privacy chip -->
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
index 07bc358..cbe8929 100644
--- a/res/values/overlayable.xml
+++ b/res/values/overlayable.xml
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Copyright (C) 2021 The Android Open Source Project
+<!-- 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
@@ -98,6 +98,7 @@
       <item type="color" name="activity_blocking_activity_background"/>
       <item type="color" name="blocking_text"/>
       <item type="color" name="car_accent"/>
+      <item type="color" name="car_managed_device_icon_color"/>
       <item type="color" name="car_nav_icon_fill_color"/>
       <item type="color" name="car_nav_icon_fill_color_selected"/>
       <item type="color" name="car_nav_unseen_indicator_color"/>
@@ -244,6 +245,7 @@
       <item type="dimen" name="car_volume_item_seekbar_margin_vertical"/>
       <item type="dimen" name="car_volume_item_seekbar_padding_vertical"/>
       <item type="dimen" name="close_handle_underlap"/>
+      <item type="dimen" name="device_management_dialog_subtitle_padding"/>
       <item type="dimen" name="hvac_button_margin_bottom"/>
       <item type="dimen" name="hvac_button_margin_end"/>
       <item type="dimen" name="hvac_button_margin_start"/>
@@ -385,6 +387,7 @@
       <item type="drawable" name="car_ic_hvac"/>
       <item type="drawable" name="car_ic_hvac_selected"/>
       <item type="drawable" name="car_ic_keyboard_arrow_down"/>
+      <item type="drawable" name="car_ic_managed_device"/>
       <item type="drawable" name="car_ic_music"/>
       <item type="drawable" name="car_ic_music_mute"/>
       <item type="drawable" name="car_ic_music_selected"/>
@@ -467,6 +470,9 @@
       <item type="id" name="active_background"/>
       <item type="id" name="auto_button"/>
       <item type="id" name="bottom_guideline"/>
+      <item type="id" name="ca_certs_disclosures"/>
+      <item type="id" name="ca_certs_subtitle"/>
+      <item type="id" name="ca_certs_warning"/>
       <item type="id" name="car_nav_button_icon"/>
       <item type="id" name="car_nav_button_icon_image"/>
       <item type="id" name="car_nav_button_more_icon"/>
@@ -480,6 +486,9 @@
       <item type="id" name="dark_icon"/>
       <item type="id" name="dark_muted_icon"/>
       <item type="id" name="defroster_button"/>
+      <item type="id" name="device_management_disclosures"/>
+      <item type="id" name="device_management_subtitle"/>
+      <item type="id" name="device_management_warning"/>
       <item type="id" name="direction_defrost"/>
       <item type="id" name="direction_face"/>
       <item type="id" name="direction_face_and_floor"/>
@@ -520,8 +529,10 @@
       <item type="id" name="lock_screen_nav_buttons"/>
       <item type="id" name="manage_button"/>
       <item type="id" name="max_width_guideline"/>
-      <item type="id" name="mic_privacy_panel"/>
       <item type="id" name="nav_buttons"/>
+      <item type="id" name="network_logging_disclosures"/>
+      <item type="id" name="network_logging_subtitle"/>
+      <item type="id" name="network_logging_warning"/>
       <item type="id" name="note"/>
       <item type="id" name="notification_container"/>
       <item type="id" name="notification_panel_stub"/>
@@ -532,11 +543,17 @@
       <item type="id" name="phone_nav"/>
       <item type="id" name="primary_icon"/>
       <item type="id" name="privacy_chip"/>
+      <item type="id" name="qc_bluetooth_footer_button"/>
+      <item type="id" name="qc_connectivity_footer_button"/>
+      <item type="id" name="qc_display_footer_button"/>
       <item type="id" name="qc_entry_points_container"/>
+      <item type="id" name="qc_mic_footer_button"/>
+      <item type="id" name="qc_profile_footer_button"/>
       <item type="id" name="qs_car_top_bar"/>
       <item type="id" name="read_only_icons_container"/>
       <item type="id" name="rear_defroster_button"/>
       <item type="id" name="recycle_air_button"/>
+      <item type="id" name="scrollView"/>
       <item type="id" name="seat_heat_level_button_left"/>
       <item type="id" name="seat_heat_level_button_right"/>
       <item type="id" name="segment_container"/>
@@ -558,6 +575,9 @@
       <item type="id" name="user_switching_dialog_stub"/>
       <item type="id" name="volume_list"/>
       <item type="id" name="volume_seek_bar"/>
+      <item type="id" name="vpn_disclosures"/>
+      <item type="id" name="vpn_subtitle"/>
+      <item type="id" name="vpn_warning"/>
       <item type="id" name="wifi_airplane_spacer"/>
       <item type="id" name="wifi_combo"/>
       <item type="id" name="wifi_group"/>
@@ -610,6 +630,7 @@
       <item type="layout" name="car_volume_dialog"/>
       <item type="layout" name="car_volume_item"/>
       <item type="layout" name="default_status_icon"/>
+      <item type="layout" name="device_management_dialog"/>
       <item type="layout" name="fan_direction"/>
       <item type="layout" name="fan_speed"/>
       <item type="layout" name="hvac_panel_container"/>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 7d3fa00..619fd61 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -81,10 +81,7 @@
 
     <style name="HvacTemperatureControlIcon">
         <item name="android:scaleType">center</item>
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">@dimen/temperature_control_arrow_height</item>
         <item name="android:layout_centerHorizontal">true</item>
-        <item name="android:background">?android:attr/selectableItemBackgroundBorderless</item>
     </style>
 
     <style name="HvacFanSpeedBar">
diff --git a/src/com/android/systemui/car/CarServiceProvider.java b/src/com/android/systemui/car/CarServiceProvider.java
index 5778d66..69c6b42 100644
--- a/src/com/android/systemui/car/CarServiceProvider.java
+++ b/src/com/android/systemui/car/CarServiceProvider.java
@@ -19,8 +19,10 @@
 import android.car.Car;
 import android.content.Context;
 
+import androidx.annotation.AnyThread;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.dagger.SysUISingleton;
 
 import java.util.ArrayList;
@@ -33,7 +35,18 @@
 public class CarServiceProvider {
 
     private final Context mContext;
+    /**
+     * mListeners is guarded by itself - when requiring locks on both mListeners and mCar, always
+     * obtain the car lock before the listeners.
+     */
+    @GuardedBy("mListeners")
     private final List<CarServiceOnConnectedListener> mListeners = new ArrayList<>();
+    private final Object mCarLock = new Object();
+    /**
+     * mCar is guarded by mCarLock - when requiring locks on both mListeners and mCar, always
+     * obtain the car lock before the listeners.
+     */
+    @GuardedBy("mCarLock")
     private Car mCar;
 
     @Inject
@@ -41,16 +54,18 @@
         mContext = context;
         mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
                 (car, ready) -> {
-                    mCar = car;
-
-                    synchronized (mListeners) {
-                        for (CarServiceOnConnectedListener listener : mListeners) {
+                    synchronized (mCarLock) {
+                        synchronized (mListeners) {
+                            mCar = car;
                             if (ready) {
-                                listener.onConnected(mCar);
+                                for (CarServiceOnConnectedListener listener : mListeners) {
+                                    listener.onConnected(mCar);
+                                }
                             }
                         }
                     }
                 });
+
     }
 
     @VisibleForTesting
@@ -63,11 +78,16 @@
      * Let's other components hook into the connection to the car service. If we're already
      * connected to the car service, the callback is immediately triggered.
      */
+    @AnyThread
     public void addListener(CarServiceOnConnectedListener listener) {
-        if (mCar.isConnected()) {
-            listener.onConnected(mCar);
+        synchronized (mCarLock) {
+            if (mCar.isConnected()) {
+                listener.onConnected(mCar);
+            }
         }
-        mListeners.add(listener);
+        synchronized (mListeners) {
+            mListeners.add(listener);
+        }
     }
 
     /**
diff --git a/src/com/android/systemui/car/qc/ProfileSwitcher.java b/src/com/android/systemui/car/qc/ProfileSwitcher.java
index 920bd7d..8f0a85f 100644
--- a/src/com/android/systemui/car/qc/ProfileSwitcher.java
+++ b/src/com/android/systemui/car/qc/ProfileSwitcher.java
@@ -16,6 +16,7 @@
 package com.android.systemui.car.qc;
 
 import static android.os.UserManager.SWITCHABILITY_STATUS_OK;
+import static android.provider.Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS;
 import static android.view.WindowInsets.Type.statusBars;
 
 import static com.android.car.ui.utils.CarUiUtils.drawableToBitmap;
@@ -24,6 +25,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
 import android.car.Car;
 import android.car.user.CarUserManager;
 import android.car.user.UserCreationResult;
@@ -43,6 +45,7 @@
 import android.view.Window;
 import android.view.WindowManager;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
 import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
@@ -67,6 +70,7 @@
     private static final int TIMEOUT_MS = CarProperties.user_hal_timeout().orElse(5_000) + 500;
 
     private final UserManager mUserManager;
+    private final DevicePolicyManager mDevicePolicyManager;
     private final UserIconProvider mUserIconProvider;
     private final Car mCar;
     private final CarUserManager mCarUserManager;
@@ -75,15 +79,18 @@
     public ProfileSwitcher(Context context) {
         super(context);
         mUserManager = context.getSystemService(UserManager.class);
+        mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
         mUserIconProvider = new UserIconProvider();
-        mCar = Car.createCar(mContext);
+        mCar = Car.createCar(context);
         mCarUserManager = (CarUserManager) mCar.getCarManager(Car.CAR_USER_SERVICE);
     }
 
     @VisibleForTesting
-    ProfileSwitcher(Context context, UserManager userManager, CarUserManager carUserManager) {
+    ProfileSwitcher(Context context, UserManager userManager,
+            DevicePolicyManager devicePolicyManager, CarUserManager carUserManager) {
         super(context);
         mUserManager = userManager;
+        mDevicePolicyManager = devicePolicyManager;
         mUserIconProvider = new UserIconProvider();
         mCar = null;
         mCarUserManager = carUserManager;
@@ -93,6 +100,11 @@
     public QCItem getQCItem() {
         QCList.Builder listBuilder = new QCList.Builder();
 
+        if (mDevicePolicyManager.isDeviceManaged()
+                || mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()) {
+            listBuilder.addRow(createOrganizationOwnedDeviceRow());
+        }
+
         int fgUserId = ActivityManager.getCurrentUser();
         UserHandle fgUserHandle = UserHandle.of(fgUserId);
         // If the foreground user CANNOT switch to other users, only display the foreground user.
@@ -106,7 +118,9 @@
             listBuilder.addRow(createUserProfileRow(profile));
         }
         listBuilder.addRow(createGuestProfileRow());
-        listBuilder.addRow(createAddProfileRow());
+        if (!hasAddUserRestriction(fgUserHandle)) {
+            listBuilder.addRow(createAddProfileRow());
+        }
         return listBuilder.build();
     }
 
@@ -125,6 +139,29 @@
                 .collect(Collectors.toList());
     }
 
+    private QCRow createOrganizationOwnedDeviceRow() {
+        Icon icon = Icon.createWithBitmap(
+                drawableToBitmap(mContext.getDrawable(R.drawable.car_ic_managed_device)));
+        QCRow row = new QCRow.Builder()
+                .setIcon(icon)
+                .setSubtitle(mContext.getString(R.string.do_disclosure_generic))
+                .build();
+        row.setActionHandler(new QCItem.ActionHandler() {
+            @Override
+            public void onAction(@NonNull QCItem item, @NonNull Context context,
+                    @NonNull Intent intent) {
+                mContext.startActivityAsUser(new Intent(ACTION_ENTERPRISE_PRIVACY_SETTINGS),
+                        UserHandle.CURRENT);
+            }
+
+            @Override
+            public boolean isActivity() {
+                return true;
+            }
+        });
+        return row;
+    }
+
     private QCRow createUserProfileRow(UserInfo userInfo) {
         QCItem.ActionHandler actionHandler = (item, context, intent) -> {
             if (mPendingUserAdd) {
@@ -134,7 +171,7 @@
         };
 
         return createProfileRow(userInfo.name,
-                mUserIconProvider.getRoundedUserIcon(userInfo, mContext), actionHandler);
+                mUserIconProvider.getDrawableWithBadge(mContext, userInfo), actionHandler);
     }
 
     private QCRow createGuestProfileRow() {
@@ -165,7 +202,8 @@
             }
         };
 
-        return createProfileRow(mContext.getString(R.string.car_add_user), getCircularAddUserIcon(),
+        return createProfileRow(mContext.getString(R.string.car_add_user),
+                mUserIconProvider.getDrawableWithBadge(mContext, getCircularAddUserIcon()),
                 actionHandler);
     }
 
@@ -248,6 +286,10 @@
         return circleIcon;
     }
 
+    private boolean hasAddUserRestriction(UserHandle userHandle) {
+        return mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_ADD_USER, userHandle);
+    }
+
     private int getMaxSupportedRealUsers() {
         int maxSupportedUsers = UserManager.getMaxSupportedUsers();
         if (UserManager.isHeadlessSystemUserMode()) {
diff --git a/src/com/android/systemui/car/statusicon/StatusIconPanelController.java b/src/com/android/systemui/car/statusicon/StatusIconPanelController.java
index 0b71756..feb3233 100644
--- a/src/com/android/systemui/car/statusicon/StatusIconPanelController.java
+++ b/src/com/android/systemui/car/statusicon/StatusIconPanelController.java
@@ -16,14 +16,16 @@
 
 package com.android.systemui.car.statusicon;
 
-import static android.content.Intent.ACTION_USER_FOREGROUND;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 import static android.widget.ListPopupWindow.WRAP_CONTENT;
 
 import android.annotation.ColorInt;
 import android.annotation.DimenRes;
 import android.annotation.LayoutRes;
+import android.app.PendingIntent;
+import android.car.Car;
 import android.car.drivingstate.CarUxRestrictions;
+import android.car.user.CarUserManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -42,6 +44,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.car.qc.QCItem;
+import com.android.car.qc.view.QCView;
 import com.android.car.ui.FocusParkingView;
 import com.android.car.ui.utils.CarUxRestrictionsUtil;
 import com.android.car.ui.utils.ViewUtils;
@@ -58,8 +62,6 @@
  */
 public class StatusIconPanelController {
     private static final int DEFAULT_POPUP_WINDOW_ANCHOR_GRAVITY = Gravity.TOP | Gravity.START;
-    private static final IntentFilter INTENT_FILTER_USER_CHANGED = new IntentFilter(
-            ACTION_USER_FOREGROUND);
 
     private final Context mContext;
     private final String mIdentifier;
@@ -77,10 +79,10 @@
     private ImageView mStatusIconView;
     private CarUxRestrictionsUtil mCarUxRestrictionsUtil;
     private float mDimValue = -1.0f;
+    private boolean mUserSwitchEventRegistered;
 
-    private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
+    private final CarUserManager.UserLifecycleListener mUserLifecycleListener = event -> {
+        if (event.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
             reset();
         }
     };
@@ -100,7 +102,7 @@
                 public void onRestrictionsChanged(@NonNull CarUxRestrictions carUxRestrictions) {
                     if (mIsDisabledWhileDriving
                             && carUxRestrictions.isRequiresDistractionOptimization()
-                            && mPanel != null) {
+                            && isPanelShowing()) {
                         mPanel.dismiss();
                     }
                 }
@@ -114,7 +116,7 @@
                     intent.getIdentifier() != null && intent.getIdentifier().equals(mIdentifier);
 
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) && !isIntentFromSelf
-                    && mPanel != null && mPanel.isShowing()) {
+                    && isPanelShowing()) {
                 mPanel.dismiss();
             }
         }
@@ -122,7 +124,7 @@
 
     private final ViewTreeObserver.OnGlobalFocusChangeListener mFocusChangeListener =
             (oldFocus, newFocus) -> {
-                if (mPanel != null && oldFocus != null && newFocus instanceof FocusParkingView) {
+                if (isPanelShowing() && oldFocus != null && newFocus instanceof FocusParkingView) {
                     // When nudging out of the panel, RotaryService will focus on the
                     // FocusParkingView to clear the focus highlight. When this occurs, dismiss the
                     // panel.
@@ -130,6 +132,21 @@
                 }
             };
 
+    private final QCView.QCActionListener mQCActionListener = (item, action) -> {
+        if (!isPanelShowing()) {
+            return;
+        }
+        if (action instanceof PendingIntent) {
+            if (((PendingIntent) action).isActivity()) {
+                mPanel.dismiss();
+            }
+        } else if (action instanceof QCItem.ActionHandler) {
+            if (((QCItem.ActionHandler) action).isActivity()) {
+                mPanel.dismiss();
+            }
+        }
+    };
+
     public StatusIconPanelController(
             Context context,
             CarServiceProvider carServiceProvider,
@@ -164,8 +181,14 @@
                 UserHandle.ALL);
         configurationController.addCallback(mConfigurationListener);
 
-        context.registerReceiverForAllUsers(mUserChangeReceiver, INTENT_FILTER_USER_CHANGED,
-                /* broadcastPermission= */ null, /* scheduler= */ null);
+        carServiceProvider.addListener(car -> {
+            CarUserManager carUserManager = (CarUserManager) car.getCarManager(
+                    Car.CAR_USER_SERVICE);
+            if (!mUserSwitchEventRegistered) {
+                carUserManager.addListener(Runnable::run, mUserLifecycleListener);
+                mUserSwitchEventRegistered = true;
+            }
+        });
 
         mIsDisabledWhileDriving = isDisabledWhileDriving;
         if (mIsDisabledWhileDriving) {
@@ -405,7 +428,9 @@
         for (int i = 0; i < rootView.getChildCount(); i++) {
             View v = rootView.getChildAt(i);
             if (v instanceof SystemUIQCView) {
-                mQCViews.add((SystemUIQCView) v);
+                SystemUIQCView qcv = (SystemUIQCView) v;
+                mQCViews.add(qcv);
+                qcv.setActionListener(mQCActionListener);
             } else if (v instanceof ViewGroup) {
                 this.findQcViews((ViewGroup) v);
             }
@@ -428,4 +453,8 @@
                     isHighlighted ? mIconHighlightedColor : mIconNotHighlightedColor);
         }
     }
+
+    private boolean isPanelShowing() {
+        return mPanel != null && mPanel.isShowing();
+    }
 }
diff --git a/src/com/android/systemui/car/statusicon/ui/LocationStatusIconController.java b/src/com/android/systemui/car/statusicon/ui/LocationStatusIconController.java
index 5ceeb65..2c49007 100644
--- a/src/com/android/systemui/car/statusicon/ui/LocationStatusIconController.java
+++ b/src/com/android/systemui/car/statusicon/ui/LocationStatusIconController.java
@@ -16,9 +16,9 @@
 
 package com.android.systemui.car.statusicon.ui;
 
-import static android.content.Intent.ACTION_USER_FOREGROUND;
-
 import android.app.ActivityManager;
+import android.car.Car;
+import android.car.user.CarUserManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -26,6 +26,7 @@
 import android.content.res.Resources;
 import android.location.LocationManager;
 import android.os.UserHandle;
+import android.util.Log;
 
 import com.android.systemui.R;
 import com.android.systemui.car.CarServiceProvider;
@@ -42,14 +43,13 @@
     private static final String TAG = LocationStatusIconController.class.getSimpleName();
     private static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED = new IntentFilter(
             LocationManager.MODE_CHANGED_ACTION);
-    private static final IntentFilter INTENT_FILTER_USER_CHANGED = new IntentFilter(
-            ACTION_USER_FOREGROUND);
 
     private final Context mContext;
     private final LocationManager mLocationManager;
     private final CarServiceProvider mCarServiceProvider;
 
     private boolean mIsLocationActive;
+    private boolean mUserLifecycleListenerRegistered;
 
     private final BroadcastReceiver mLocationReceiver = new BroadcastReceiver() {
         @Override
@@ -58,12 +58,18 @@
         }
     };
 
-    private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            updateIconVisibilityForCurrentUser();
-        }
-    };
+    private final CarUserManager.UserLifecycleListener mUserLifecycleListener =
+            new CarUserManager.UserLifecycleListener() {
+                @Override
+                public void onEvent(CarUserManager.UserLifecycleEvent event) {
+                    mContext.getMainExecutor().execute(() -> {
+                        if (event.getEventType()
+                                == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
+                            updateIconVisibilityForCurrentUser();
+                        }
+                    });
+                }
+            };
 
     @Inject
     LocationStatusIconController(
@@ -77,9 +83,7 @@
 
         context.registerReceiverForAllUsers(mLocationReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED,
                 /* broadcastPermission= */ null, /* scheduler= */ null);
-        context.registerReceiverForAllUsers(mUserChangeReceiver, INTENT_FILTER_USER_CHANGED,
-                /* broadcastPermission= */ null,
-                /* scheduler= */ null);
+        registerForUserChangeEvents();
         setIconDrawableToDisplay(resources.getDrawable(R.drawable.ic_location, context.getTheme()));
         updateIconVisibilityForCurrentUser();
     }
@@ -96,4 +100,17 @@
         mIsLocationActive = mLocationManager.isLocationEnabledForUser(fgUserHandle);
         updateStatus();
     }
+
+    private void registerForUserChangeEvents() {
+        mCarServiceProvider.addListener(car -> {
+            CarUserManager carUserManager = (CarUserManager) car.getCarManager(
+                    Car.CAR_USER_SERVICE);
+            if (carUserManager != null && !mUserLifecycleListenerRegistered) {
+                carUserManager.addListener(Runnable::run, mUserLifecycleListener);
+                mUserLifecycleListenerRegistered = true;
+            } else {
+                Log.e(TAG, "CarUserManager could not be obtained.");
+            }
+        });
+    }
 }
diff --git a/src/com/android/systemui/car/systembar/ButtonSelectionStateController.java b/src/com/android/systemui/car/systembar/ButtonSelectionStateController.java
index 3c4b604..19e5846 100644
--- a/src/com/android/systemui/car/systembar/ButtonSelectionStateController.java
+++ b/src/com/android/systemui/car/systembar/ButtonSelectionStateController.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
 
 import android.app.ActivityTaskManager;
 import android.app.ActivityTaskManager.RootTaskInfo;
@@ -29,7 +30,6 @@
 import android.content.pm.ResolveInfo;
 import android.os.RemoteException;
 import android.util.Log;
-import android.view.Display;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -115,7 +115,7 @@
             // Find the first stack info with a topActivity in the primary display.
             // TODO: We assume that CarFacetButton will launch an app only in the primary display.
             // We need to extend the functionality to handle the multiple display properly.
-            if (taskInfo.topActivity != null && taskInfo.displayId == validDisplay) {
+            if (taskInfo.topActivity != null && taskInfo.displayAreaFeatureId == validDisplay) {
                 validTaskInfo = taskInfo;
                 break;
             }
@@ -153,7 +153,7 @@
      * @param taskInfoList
      */
     protected void taskChanged(List<RootTaskInfo> taskInfoList) {
-        taskChanged(taskInfoList, Display.DEFAULT_DISPLAY);
+        taskChanged(taskInfoList, FEATURE_DEFAULT_TASK_CONTAINER);
     }
 
     /**
diff --git a/src/com/android/systemui/car/systembar/CarSystemBar.java b/src/com/android/systemui/car/systembar/CarSystemBar.java
index bdc6d05..f423489 100644
--- a/src/com/android/systemui/car/systembar/CarSystemBar.java
+++ b/src/com/android/systemui/car/systembar/CarSystemBar.java
@@ -258,7 +258,7 @@
         mActivityManagerWrapper.registerTaskStackListener(new TaskStackChangeListener() {
             @Override
             public void onLockTaskModeChanged(int mode) {
-                mCarSystemBarController.refreshSystemBarByLockTaskFeatures();
+                mCarSystemBarController.refreshSystemBar();
             }
         });
 
@@ -477,7 +477,7 @@
             mAppearanceRegions = appearanceRegions;
             updateStatusBarAppearance();
         }
-        mCarSystemBarController.refreshSystemBarByLockTaskFeatures();
+        mCarSystemBarController.refreshSystemBar();
     }
 
     @Override
@@ -486,7 +486,7 @@
         if (displayId != mDisplayId) {
             return;
         }
-        mCarSystemBarController.setStatusBarState(state1);
+        mCarSystemBarController.setSystemBarStates(state1, state2);
     }
 
     private void updateStatusBarAppearance() {
diff --git a/src/com/android/systemui/car/systembar/CarSystemBarController.java b/src/com/android/systemui/car/systembar/CarSystemBarController.java
index d8ae28a..0fcdebd 100644
--- a/src/com/android/systemui/car/systembar/CarSystemBarController.java
+++ b/src/com/android/systemui/car/systembar/CarSystemBarController.java
@@ -85,7 +85,11 @@
     private CarSystemBarView mLeftView;
     private CarSystemBarView mRightView;
 
+    // Saved StatusBarManager.DisableFlags
     private int mStatusBarState;
+    // Saved StatusBarManager.Disable2Flags
+    private int mStatusBarState2;
+    private int mLockTaskMode;
 
     @Inject
     public CarSystemBarController(Context context,
@@ -208,19 +212,27 @@
     }
 
     /**
-     * Sets the status bar state and refreshes the system bar when the state was changed.
+     * Sets the system bar states - {@code StatusBarManager.DisableFlags},
+     * {@code StatusBarManager.Disable2Flags}, lock task mode. When there is a change in state,
+     * and refreshes the system bars.
+     *
+     * @param state {@code StatusBarManager.DisableFlags}
+     * @param state2 {@code StatusBarManager.Disable2Flags}
      */
-    public void setStatusBarState(int state) {
-        int diff = state ^ mStatusBarState;
-        if (diff == 0) {
+    public void setSystemBarStates(int state, int state2) {
+        int diff = (state ^ mStatusBarState) | (state2 ^ mStatusBarState2);
+        int lockTaskMode = getLockTaskModeState();
+        if (diff == 0 && mLockTaskMode == lockTaskMode) {
             if (DEBUG) {
-                Log.d(TAG, "setStatusBarState(): status bar states unchanged: "
-                        + state);
+                Log.d(TAG, "setSystemBarStates(): status bar states unchanged: state: "
+                        + state + " state2: " +  state2 + " lockTaskMode: " + mLockTaskMode);
             }
             return;
         }
         mStatusBarState = state;
-        refreshSystemBarByLockTaskFeatures();
+        mStatusBarState2 = state2;
+        mLockTaskMode = lockTaskMode;
+        refreshSystemBar();
     }
 
     @VisibleForTesting
@@ -228,47 +240,77 @@
         return mStatusBarState;
     }
 
+    @VisibleForTesting
+    protected int getStatusBarState2() {
+        return mStatusBarState2;
+    }
+
+    @VisibleForTesting
+    protected int getLockTaskMode() {
+        return mLockTaskMode;
+    }
+
     /**
-     * Refreshes certain system bar views when lock task mode feature is changed based on
-     * {@link StatusBarManager} flags.
+     * Refreshes system bar views and sets the visibility of certain components based on
+     * {@link StatusBarManager} flags and lock task mode.
+     * <ul>
+     * <li>Home button will be disabled when {@code StatusBarManager.DISABLE_HOME} is set.
+     * <li>Phone call button will be disable in lock task mode.
+     * <li>App grid button will be disable when {@code StatusBarManager.DISABLE_HOME} is set.
+     * <li>Notification button will be disable when
+     * {@code StatusBarManager.DISABLE_NOTIFICATION_ICONS} is set.
+     * <li>Quick settings and user switcher will be hidden when in lock task mode or when
+     * {@code StatusBarManager.DISABLE2_QUICK_SETTINGS} is set.
+     * </ul>
      */
-    public void refreshSystemBarByLockTaskFeatures() {
-        boolean locked = isLockTaskModeLocked();
-        int lockTaskModeVisibility = locked ? View.GONE : View.VISIBLE;
+    public void refreshSystemBar() {
         boolean homeDisabled = ((mStatusBarState & StatusBarManager.DISABLE_HOME) > 0);
         boolean notificationDisabled =
                 ((mStatusBarState & StatusBarManager.DISABLE_NOTIFICATION_ICONS) > 0);
+        boolean locked = (mLockTaskMode == ActivityManager.LOCK_TASK_MODE_LOCKED);
+        boolean qcDisabled =
+                ((mStatusBarState2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) > 0) || locked;
+        boolean systemIconsDisabled =
+                ((mStatusBarState2 & StatusBarManager.DISABLE2_SYSTEM_ICONS) > 0) || locked;
+
+        setDisabledSystemBarButton(R.id.home, homeDisabled, "home");
+        setDisabledSystemBarButton(R.id.phone_nav, locked, "phone_nav");
+        setDisabledSystemBarButton(R.id.grid_nav, homeDisabled, "grid_nav");
+        setDisabledSystemBarButton(R.id.notifications, notificationDisabled, "notifications");
+
+        setDisabledSystemBarContainer(R.id.qc_entry_points_container, qcDisabled,
+                "qc_entry_points_container");
+        setDisabledSystemBarContainer(R.id.user_name_container, qcDisabled,
+                "user_name_container");
+        setDisabledSystemBarContainer(R.id.read_only_icons_container, systemIconsDisabled,
+                "read_only_icons_container");
+
         if (DEBUG) {
-            Log.d(TAG, "refreshSystemBarByLockTaskFeatures: locked?: " + locked
+            Log.d(TAG, "refreshSystemBar: locked?: " + locked
                     + " homeDisabled: " + homeDisabled
-                    + " notificationDisabled: " + notificationDisabled);
-        }
-
-        setLockTaskDisabledContainer(R.id.qc_entry_points_container, lockTaskModeVisibility);
-        setLockTaskDisabledContainer(R.id.user_name_container, lockTaskModeVisibility);
-
-        // Check navigation icons
-        setLockTaskDisabledButton(R.id.home, homeDisabled);
-        setLockTaskDisabledButton(R.id.phone_nav, locked);
-        setLockTaskDisabledButton(R.id.grid_nav, homeDisabled);
-        setLockTaskDisabledButton(R.id.notifications, notificationDisabled);
-    }
-
-    private boolean isLockTaskModeLocked() {
-        return mContext.getSystemService(ActivityManager.class).getLockTaskModeState()
-                == ActivityManager.LOCK_TASK_MODE_LOCKED;
-    }
-
-    private void setLockTaskDisabledButton(int viewId, boolean disabled) {
-        for (CarSystemBarView barView : getAllAvailableSystemBarViews()) {
-            barView.setLockTaskDisabledButton(viewId, disabled, () ->
-                    showAdminSupportDetailsDialog());
+                    + " notificationDisabled: " + notificationDisabled
+                    + " qcDisabled: " + qcDisabled
+                    + " systemIconsDisabled: " + systemIconsDisabled);
         }
     }
 
-    private void setLockTaskDisabledContainer(int viewId, @View.Visibility int visibility) {
+    private int getLockTaskModeState() {
+        return mContext.getSystemService(ActivityManager.class).getLockTaskModeState();
+    }
+
+    private void setDisabledSystemBarButton(int viewId, boolean disabled,
+                @Nullable String buttonName) {
         for (CarSystemBarView barView : getAllAvailableSystemBarViews()) {
-            barView.setLockTaskDisabledContainer(viewId, visibility);
+            barView.setDisabledSystemBarButton(viewId, disabled,
+                    () -> showAdminSupportDetailsDialog(), buttonName);
+        }
+    }
+
+    private void setDisabledSystemBarContainer(int viewId, boolean disabled,
+                @Nullable String viewName) {
+        for (CarSystemBarView barView : getAllAvailableSystemBarViews()) {
+            barView.setVisibilityByViewId(viewId, viewName,
+                    disabled ? View.INVISIBLE : View.VISIBLE);
         }
     }
 
diff --git a/src/com/android/systemui/car/systembar/CarSystemBarView.java b/src/com/android/systemui/car/systembar/CarSystemBarView.java
index 9d2def2..ea4bafb 100644
--- a/src/com/android/systemui/car/systembar/CarSystemBarView.java
+++ b/src/com/android/systemui/car/systembar/CarSystemBarView.java
@@ -17,6 +17,7 @@
 package com.android.systemui.car.systembar;
 
 import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -51,6 +52,7 @@
     }
 
     private static final String TAG = CarSystemBarView.class.getSimpleName();
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     public static final int BUTTON_TYPE_NAVIGATION = 0;
     public static final int BUTTON_TYPE_KEYGUARD = 1;
@@ -241,30 +243,28 @@
     /**
      * Sets the system bar view's disabled state and runnable when disabled.
      */
-    public void setLockTaskDisabledButton(int viewId, boolean disabled, Runnable runnable) {
+    public void setDisabledSystemBarButton(int viewId, boolean disabled, Runnable runnable,
+                @Nullable String buttonName) {
         CarSystemBarButton button = findViewById(viewId);
         if (button != null) {
+            if (DEBUG) {
+                Log.d(TAG, "setDisabledSystemBarButton for: " + buttonName + " to: " + disabled);
+            }
             button.setDisabled(disabled, runnable);
         }
     }
 
     /**
-     * Sets the system bar ViewGroup container's visibility
+     * Sets the system bar specific View container's visibility. ViewName is used just for
+     * debugging.
      */
-    public void setLockTaskDisabledContainer(int viewId, @View.Visibility int visibility) {
+    public void setVisibilityByViewId(int viewId, @Nullable String viewName,
+                @View.Visibility int visibility) {
         View v = findViewById(viewId);
-        if (v == null) {
-            Log.e(TAG, "setLockTaskViewVisibility for: " + viewId + " not found");
-            return;
+        if (v != null) {
+            if (DEBUG) Log.d(TAG, "setVisibilityByViewId for: " + viewName + " to: " + visibility);
+            v.setVisibility(visibility);
         }
-        if (v instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) v;
-            for (int i = 0; i < group.getChildCount(); i++) {
-                group.getChildAt(i).setVisibility(visibility);
-            }
-            return;
-        }
-        v.setVisibility(visibility);
     }
 
     /**
diff --git a/src/com/android/systemui/car/systembar/PrivacyChipViewController.java b/src/com/android/systemui/car/systembar/PrivacyChipViewController.java
index 48a5b4d..f6a8ee7 100644
--- a/src/com/android/systemui/car/systembar/PrivacyChipViewController.java
+++ b/src/com/android/systemui/car/systembar/PrivacyChipViewController.java
@@ -19,6 +19,8 @@
 import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE;
 import static android.hardware.SensorPrivacyManager.Sources.QS_TILE;
 
+import android.car.Car;
+import android.car.user.CarUserManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -64,6 +66,7 @@
 
     private Context mContext;
     private MicPrivacyChip mPrivacyChip;
+    private CarUserManager mCarUserManager;
     private Runnable mQsTileNotifyUpdateRunnable;
     private final SensorPrivacyManager.OnSensorPrivacyChangedListener
             mOnSensorPrivacyChangedListener = (sensor, sensorPrivacyEnabled) -> {
@@ -125,6 +128,7 @@
                     }
                 }
             };
+    private boolean mUserLifecycleListenerRegistered;
     private int mCurrentUserId;
     private final BroadcastReceiver mUserUpdateReceiver = new BroadcastReceiver() {
         @Override
@@ -143,19 +147,19 @@
             setUser(currentUserId);
         }
     };
-    private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mPrivacyChip == null) {
-                return;
-            }
-            int currentUserId = mCarDeviceProvisionedController.getCurrentUser();
-            if (mCurrentUserId == currentUserId) {
-                return;
-            }
-            setUser(currentUserId);
-        }
-    };
+    private final CarUserManager.UserLifecycleListener mUserLifecycleListener =
+            new CarUserManager.UserLifecycleListener() {
+                @Override
+                public void onEvent(CarUserManager.UserLifecycleEvent event) {
+                    if (mPrivacyChip == null) {
+                        return;
+                    }
+                    if (event.getEventType()
+                            == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
+                        setUser(event.getUserHandle().getIdentifier());
+                    }
+                }
+            };
 
     @Inject
     public PrivacyChipViewController(Context context, PrivacyItemController privacyItemController,
@@ -214,6 +218,7 @@
         mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable();
         mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
         mPrivacyItemController.addCallback(mPicCallback);
+        mUserLifecycleListenerRegistered = false;
         registerForUserChangeEvents();
         setUser(mCarDeviceProvisionedController.getCurrentUser());
     }
@@ -228,7 +233,12 @@
 
         mPrivacyItemController.removeCallback(mPicCallback);
         mBroadcastDispatcher.unregisterReceiver(mUserUpdateReceiver);
-        mBroadcastDispatcher.unregisterReceiver(mUserChangeReceiver);
+        if (mUserLifecycleListenerRegistered) {
+            if (mCarUserManager != null) {
+                mCarUserManager.removeListener(mUserLifecycleListener);
+            }
+            mUserLifecycleListenerRegistered = false;
+        }
         mSensorPrivacyManager.removeSensorPrivacyListener(MICROPHONE,
                 mOnSensorPrivacyChangedListener);
         mPrivacyChip = null;
@@ -256,9 +266,15 @@
 
     private void registerForUserChangeEvents() {
         // Register for user switching
-        IntentFilter userChangeFilter = new IntentFilter(Intent.ACTION_USER_FOREGROUND);
-        mBroadcastDispatcher.registerReceiver(mUserChangeReceiver, userChangeFilter,
-                /* executor= */ null, UserHandle.ALL);
+        mCarServiceProvider.addListener(car -> {
+            mCarUserManager = (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
+            if (mCarUserManager != null && !mUserLifecycleListenerRegistered) {
+                mCarUserManager.addListener(Runnable::run, mUserLifecycleListener);
+                mUserLifecycleListenerRegistered = true;
+            } else {
+                Log.e(TAG, "CarUserManager could not be obtained.");
+            }
+        });
 
         // Also register for user info changing
         IntentFilter filter = new IntentFilter();
diff --git a/src/com/android/systemui/car/systemdialogs/SystemDialogsViewController.java b/src/com/android/systemui/car/systemdialogs/SystemDialogsViewController.java
new file mode 100644
index 0000000..56cd49d
--- /dev/null
+++ b/src/com/android/systemui/car/systemdialogs/SystemDialogsViewController.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.car.systemdialogs;
+
+import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
+import static android.view.WindowInsets.Type.statusBars;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.systemui.R;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.policy.SecurityController;
+
+import javax.inject.Inject;
+
+/**
+ * A controller that can create and control the visibility of various system dialogs.
+ */
+@SysUISingleton
+public class SystemDialogsViewController {
+    private final Context mContext;
+    private final SecurityController mSecurityController;
+    private final AlertDialog.OnClickListener mOnDeviceMonitoringConfirmed;
+
+    @Inject
+    public SystemDialogsViewController(
+            Context context,
+            SecurityController securityController) {
+        mContext = context;
+        mSecurityController = securityController;
+        mOnDeviceMonitoringConfirmed = (dialog, which) -> {
+            if (which == DialogInterface.BUTTON_POSITIVE) {
+                Intent intent = new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS);
+                dialog.dismiss();
+                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+            }
+        };
+    }
+
+    protected void showDeviceMonitoringDialog() {
+        AlertDialog dialog = new AlertDialog.Builder(mContext,
+                com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert)
+                .setView(createDialogView())
+                .setPositiveButton(R.string.ok, mOnDeviceMonitoringConfirmed)
+                .create();
+
+        applyCarSysUIDialogFlags(dialog);
+        dialog.show();
+    }
+
+    private View createDialogView() {
+        View dialogView = LayoutInflater.from(mContext)
+                .inflate(R.layout.device_management_dialog, null, false);
+
+        CharSequence deviceOwnerOrganization = mSecurityController.getDeviceOwnerOrganizationName();
+        boolean isDeviceManaged = mSecurityController.isDeviceManaged();
+
+        // device management section
+        TextView deviceManagementSubtitle =
+                dialogView.requireViewById(R.id.device_management_subtitle);
+        deviceManagementSubtitle.setText(getDeviceMonitoringTitle(deviceOwnerOrganization));
+
+        CharSequence managementMessage = getDeviceMonitoringMessage(deviceOwnerOrganization);
+        if (managementMessage == null) {
+            dialogView.requireViewById(R.id.device_management_disclosures).setVisibility(View.GONE);
+        } else {
+            dialogView.requireViewById(R.id.device_management_disclosures)
+                    .setVisibility(View.VISIBLE);
+            TextView deviceManagementWarning =
+                    dialogView.requireViewById(R.id.device_management_warning);
+            deviceManagementWarning.setText(managementMessage);
+        }
+
+        // CA certificate section
+        CharSequence caCertsMessage = getCaCertsMessage(isDeviceManaged);
+        if (caCertsMessage == null) {
+            dialogView.requireViewById(R.id.ca_certs_disclosures).setVisibility(View.GONE);
+        } else {
+            dialogView.requireViewById(R.id.ca_certs_disclosures).setVisibility(View.VISIBLE);
+            TextView caCertsWarning = dialogView.requireViewById(R.id.ca_certs_warning);
+            caCertsWarning.setText(caCertsMessage);
+        }
+
+        // network logging section
+        CharSequence networkLoggingMessage = getNetworkLoggingMessage(isDeviceManaged);
+        if (networkLoggingMessage == null) {
+            dialogView.requireViewById(R.id.network_logging_disclosures).setVisibility(View.GONE);
+        } else {
+            dialogView.requireViewById(R.id.network_logging_disclosures)
+                    .setVisibility(View.VISIBLE);
+            TextView networkLoggingWarning =
+                    dialogView.requireViewById(R.id.network_logging_warning);
+            networkLoggingWarning.setText(networkLoggingMessage);
+        }
+
+        // VPN section
+        CharSequence vpnMessage = getVpnMessage(isDeviceManaged);
+        if (vpnMessage == null) {
+            dialogView.requireViewById(R.id.vpn_disclosures).setVisibility(View.GONE);
+        } else {
+            dialogView.requireViewById(R.id.vpn_disclosures).setVisibility(View.VISIBLE);
+            TextView vpnWarning = dialogView.requireViewById(R.id.vpn_warning);
+            vpnWarning.setText(vpnMessage);
+        }
+
+        return dialogView;
+    }
+
+    private CharSequence getDeviceMonitoringTitle(CharSequence deviceOwnerOrganization) {
+        if (deviceOwnerOrganization != null && isFinancedDevice()) {
+            return mContext.getString(R.string.monitoring_title_financed_device,
+                    deviceOwnerOrganization);
+        } else {
+            return mContext.getString(R.string.monitoring_title_device_owned);
+        }
+    }
+
+    private CharSequence getDeviceMonitoringMessage(CharSequence deviceOwnerOrganization) {
+        if (deviceOwnerOrganization != null) {
+            if (isFinancedDevice()) {
+                return mContext.getString(R.string.monitoring_financed_description_named_management,
+                        deviceOwnerOrganization, deviceOwnerOrganization);
+            } else {
+                return mContext.getString(
+                        R.string.monitoring_description_named_management, deviceOwnerOrganization);
+            }
+        }
+        return mContext.getString(R.string.monitoring_description_management);
+    }
+
+    @Nullable
+    private CharSequence getCaCertsMessage(boolean isDeviceManaged) {
+        boolean hasCACerts = mSecurityController.hasCACertInCurrentUser();
+        boolean hasCACertsInWorkProfile = mSecurityController.hasCACertInWorkProfile();
+        if (!(hasCACerts || hasCACertsInWorkProfile)) return null;
+        if (isDeviceManaged) {
+            return mContext.getString(R.string.monitoring_description_management_ca_certificate);
+        }
+        if (hasCACertsInWorkProfile) {
+            return mContext.getString(
+                    R.string.monitoring_description_managed_profile_ca_certificate);
+        }
+        return mContext.getString(R.string.monitoring_description_ca_certificate);
+    }
+
+    @Nullable
+    private CharSequence getNetworkLoggingMessage(boolean isDeviceManaged) {
+        boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled();
+        if (!isNetworkLoggingEnabled) return null;
+        if (isDeviceManaged) {
+            return mContext.getString(R.string.monitoring_description_management_network_logging);
+        } else {
+            return mContext.getString(
+                    R.string.monitoring_description_managed_profile_network_logging);
+        }
+    }
+
+    @Nullable
+    private CharSequence getVpnMessage(boolean isDeviceManaged) {
+        boolean hasWorkProfile = mSecurityController.hasWorkProfile();
+        String vpnName = mSecurityController.getPrimaryVpnName();
+        String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName();
+        if (vpnName == null && vpnNameWorkProfile == null) return null;
+        if (isDeviceManaged) {
+            if (vpnName != null && vpnNameWorkProfile != null) {
+                return mContext.getString(R.string.monitoring_description_two_named_vpns,
+                        vpnName, vpnNameWorkProfile);
+            } else {
+                return mContext.getString(R.string.monitoring_description_named_vpn,
+                        vpnName != null ? vpnName : vpnNameWorkProfile);
+            }
+        } else {
+            if (vpnName != null && vpnNameWorkProfile != null) {
+                return mContext.getString(R.string.monitoring_description_two_named_vpns,
+                        vpnName, vpnNameWorkProfile);
+            } else if (vpnNameWorkProfile != null) {
+                return mContext.getString(R.string.monitoring_description_managed_profile_named_vpn,
+                        vpnNameWorkProfile);
+            } else if (hasWorkProfile) {
+                return mContext.getString(
+                        R.string.monitoring_description_personal_profile_named_vpn, vpnName);
+            } else {
+                return mContext.getString(R.string.monitoring_description_named_vpn, vpnName);
+            }
+        }
+    }
+
+    private boolean isFinancedDevice() {
+        return mSecurityController.isDeviceManaged()
+                && mSecurityController.getDeviceOwnerType(
+                mSecurityController.getDeviceOwnerComponentOnAnyUser())
+                == DEVICE_OWNER_TYPE_FINANCED;
+    }
+
+    private void applyCarSysUIDialogFlags(AlertDialog dialog) {
+        Window window = dialog.getWindow();
+        window.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+        window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        window.getAttributes().setFitInsetsTypes(
+                window.getAttributes().getFitInsetsTypes() & ~statusBars());
+    }
+}
diff --git a/src/com/android/systemui/car/systemdialogs/SystemDialogsViewMediator.java b/src/com/android/systemui/car/systemdialogs/SystemDialogsViewMediator.java
new file mode 100644
index 0000000..727cf38
--- /dev/null
+++ b/src/com/android/systemui/car/systemdialogs/SystemDialogsViewMediator.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.car.systemdialogs;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
+
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.car.window.OverlayViewMediator;
+import com.android.systemui.dagger.SysUISingleton;
+
+import javax.inject.Inject;
+
+/**
+ * A view mediator that listens to events that trigger various system dialogs.
+ *
+ * NOTE: Even though {@link com.android.systemui.statusbar.phone.StatusBar} listens to these
+ * events in core Android, a separate view mediator is created in AAOS since the event listeners
+ * need to exist independent of OEM SystemBar configuration (that is, we cannot assume the existence
+ * of any particular SystemBars in AAOS).
+ */
+@SysUISingleton
+public class SystemDialogsViewMediator implements OverlayViewMediator {
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final SystemDialogsViewController mSystemDialogsViewController;
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
+                mSystemDialogsViewController.showDeviceMonitoringDialog();
+            }
+        }
+    };
+
+    @Inject
+    public SystemDialogsViewMediator(
+            BroadcastDispatcher broadcastDispatcher,
+            SystemDialogsViewController systemDialogsViewController) {
+        mBroadcastDispatcher = broadcastDispatcher;
+        mSystemDialogsViewController = systemDialogsViewController;
+    }
+
+    @Override
+    public void registerListeners() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
+        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, /* executor= */ null,
+                UserHandle.ALL);
+    }
+
+    @Override
+    public void setUpOverlayContentViewControllers() {
+        // no-op.
+    }
+}
diff --git a/src/com/android/systemui/car/userswitcher/UserIconProvider.java b/src/com/android/systemui/car/userswitcher/UserIconProvider.java
index 9b938b3..679c9de 100644
--- a/src/com/android/systemui/car/userswitcher/UserIconProvider.java
+++ b/src/com/android/systemui/car/userswitcher/UserIconProvider.java
@@ -16,9 +16,7 @@
 
 package com.android.systemui.car.userswitcher;
 
-import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
@@ -29,11 +27,9 @@
 import android.os.UserManager;
 
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
-import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
 
+import com.android.car.admin.ui.UserAvatarView;
 import com.android.internal.util.UserIcons;
-import com.android.settingslib.Utils;
-import com.android.settingslib.drawable.UserIconDrawable;
 import com.android.systemui.R;
 
 /**
@@ -60,6 +56,51 @@
         return new BitmapDrawable(res, icon);
     }
 
+    /**
+     * Gets a user icon with badge if the user profile is managed.
+     *
+     * @param context to use for the avatar view
+     * @param userInfo User for which the icon is requested and badge is set
+     * @return {@link Drawable} with badge
+     */
+    public Drawable getDrawableWithBadge(Context context, UserInfo userInfo) {
+        return addBadge(context, getRoundedUserIcon(userInfo, context), userInfo.id);
+    }
+
+    /**
+     * Gets an icon with badge if the device is managed.
+     *
+     * @param context context
+     * @param drawable icon without badge
+     * @return {@link Drawable} with badge
+     */
+    public Drawable getDrawableWithBadge(Context context, Drawable drawable) {
+        return addBadge(context, drawable, UserHandle.USER_NULL);
+    }
+
+    private static Drawable addBadge(Context context, Drawable drawable, @UserIdInt int userId) {
+        int iconSize = drawable.getIntrinsicWidth();
+        UserAvatarView userAvatarView = new UserAvatarView(context);
+        float badgeToIconSizeRatio =
+                context.getResources().getDimension(R.dimen.car_user_switcher_managed_badge_size)
+                        / context.getResources().getDimension(
+                        R.dimen.car_user_switcher_image_avatar_size);
+        userAvatarView.setBadgeDiameter(iconSize * badgeToIconSizeRatio);
+        float badgePadding = context.getResources().getDimension(
+                R.dimen.car_user_switcher_managed_badge_margin);
+        userAvatarView.setBadgeMargin(badgePadding);
+        if (userId != UserHandle.USER_NULL) {
+            // When the userId is valid, add badge if the user is managed.
+            userAvatarView.setDrawableWithBadge(drawable, userId);
+        } else {
+            // When the userId is not valid, add badge if the device is managed.
+            userAvatarView.setDrawableWithBadge(drawable);
+        }
+        Drawable badgedIcon = userAvatarView.getUserIconDrawable();
+        badgedIcon.setBounds(0, 0, iconSize, iconSize);
+        return badgedIcon;
+    }
+
     /** Returns a scaled, rounded, default icon for the Guest user */
     public Drawable getRoundedGuestDefaultIcon(Resources resources) {
         Bitmap icon = getGuestUserDefaultIcon(resources);
diff --git a/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java b/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
index 1e604bd..2e73c21 100644
--- a/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
+++ b/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
@@ -19,10 +19,10 @@
 import static android.car.settings.CarSettings.Global.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE;
 
 import android.annotation.UserIdInt;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.os.Handler;
+import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -34,7 +34,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.settingslib.drawable.CircleFramedDrawable;
 import com.android.systemui.R;
 import com.android.systemui.car.window.OverlayViewController;
 import com.android.systemui.car.window.OverlayViewGlobalStateController;
@@ -56,8 +55,10 @@
     private final Context mContext;
     private final Resources mResources;
     private final DelayableExecutor mMainExecutor;
+    private final ActivityManager mActivityManager;
     private final UserManager mUserManager;
     private final IWindowManager mWindowManagerService;
+    private final UserIconProvider mUserIconProvider = new UserIconProvider();
     private final int mWindowShownTimeoutMs;
     private final Runnable mWindowShownTimeoutCallback = () -> {
         if (DEBUG) {
@@ -78,6 +79,7 @@
             Context context,
             @Main Resources resources,
             @Main DelayableExecutor delayableExecutor,
+            ActivityManager activityManager,
             UserManager userManager,
             IWindowManager windowManagerService,
             OverlayViewGlobalStateController overlayViewGlobalStateController) {
@@ -87,6 +89,7 @@
         mContext = context;
         mResources = resources;
         mMainExecutor = delayableExecutor;
+        mActivityManager = activityManager;
         mUserManager = userManager;
         mWindowManagerService = windowManagerService;
         mWindowShownTimeoutMs = mResources.getInteger(
@@ -147,12 +150,10 @@
     }
 
     private void drawUserIcon(int newUserId) {
-        Bitmap bitmap = mUserManager.getUserIcon(newUserId);
-        if (bitmap != null) {
-            CircleFramedDrawable drawable = CircleFramedDrawable.getInstance(mContext, bitmap);
-            ((ImageView) getLayout().findViewById(R.id.user_loading_avatar))
-                    .setImageDrawable(drawable);
-        }
+        Drawable userIcon = mUserIconProvider.getDrawableWithBadge(mContext,
+                mUserManager.getUserInfo(newUserId));
+        ((ImageView) getLayout().findViewById(R.id.user_loading_avatar))
+                .setImageDrawable(userIcon);
     }
 
     private void populateLoadingText(@UserIdInt int previousUserId, @UserIdInt int newUserId) {
@@ -167,7 +168,10 @@
                     mResources.getString(R.string.car_loading_profile_developer_message,
                             previousUserId, newUserId));
         } else {
-            msgView.setText(mResources.getString(R.string.car_loading_profile));
+            // Show the switchingFromUserMessage if it was set.
+            String switchingFromUserMessage = mActivityManager.getSwitchingFromUserMessage();
+            msgView.setText(switchingFromUserMessage != null ? switchingFromUserMessage
+                    : mResources.getString(R.string.car_loading_profile));
         }
     }
 }
diff --git a/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java b/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
index cdf572b..b90f342 100644
--- a/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
+++ b/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
@@ -114,7 +114,6 @@
     private boolean mHovering;
     private int mCurrentlyDisplayingGroupId;
     private int mPreviouslyDisplayingGroupId;
-    private boolean mShowing;
     private boolean mDismissing;
     private boolean mExpanded;
     private View mExpandIcon;
@@ -267,7 +266,6 @@
         mDialog = new CustomDialog(mContext);
 
         mHovering = false;
-        mShowing = false;
         mDismissing = false;
         mExpanded = false;
         mWindow = mDialog.getWindow();
@@ -332,7 +330,7 @@
         // Refresh the data set before showing.
         mVolumeItemsAdapter.notifyDataSetChanged();
 
-        if (mShowing) {
+        if (mDialog.isShowing()) {
             if (mPreviouslyDisplayingGroupId == mCurrentlyDisplayingGroupId || mExpanded) {
                 return;
             }
@@ -341,8 +339,8 @@
             return;
         }
 
-        mShowing = true;
         clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
+        mDismissing = false;
         mDialog.show();
         Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
     }
@@ -381,7 +379,7 @@
 
         mHandler.removeMessages(H.DISMISS);
         mHandler.removeMessages(H.SHOW);
-        if (!mShowing || mDismissing) {
+        if (!mDialog.isShowing() || mDismissing) {
             return;
         }
 
@@ -396,7 +394,6 @@
                         Log.d(TAG, "mDialog.dismiss()");
                     }
                     mDialog.dismiss();
-                    mShowing = false;
                     mDismissing = false;
                     // if mExpandIcon is null that means user never clicked on the expanded arrow
                     // which implies that the dialog is still not expanded. In that case we do
diff --git a/src/com/android/systemui/car/window/OverlayPanelViewController.java b/src/com/android/systemui/car/window/OverlayPanelViewController.java
index 9ab6669..34cb557 100644
--- a/src/com/android/systemui/car/window/OverlayPanelViewController.java
+++ b/src/com/android/systemui/car/window/OverlayPanelViewController.java
@@ -96,10 +96,10 @@
     private boolean mPanelVisible;
     private boolean mPanelExpanded;
 
-    private float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
-    private float mClosingVelocity = DEFAULT_FLING_VELOCITY;
+    protected float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
+    protected float mClosingVelocity = DEFAULT_FLING_VELOCITY;
 
-    private boolean mIsAnimating;
+    protected boolean mIsAnimating;
     private boolean mIsTracking;
 
     public OverlayPanelViewController(
@@ -342,7 +342,7 @@
     }
 
     /** Returns the start position if we are in the middle of swiping. */
-    private int getCurrentStartPosition(Rect clipBounds) {
+    protected int getCurrentStartPosition(Rect clipBounds) {
         return mAnimateDirection > 0 ? clipBounds.bottom : clipBounds.top;
     }
 
@@ -352,7 +352,7 @@
                 : 0;
     }
 
-    private void animate(float from, float to, float velocity, boolean isClosing) {
+    protected void animate(float from, float to, float velocity, boolean isClosing) {
         if (mIsAnimating) {
             return;
         }
@@ -384,7 +384,7 @@
         animator.start();
     }
 
-    private void resetPanelVisibility() {
+    protected void resetPanelVisibility() {
         setPanelVisible(false);
         getLayout().setClipBounds(null);
         onCollapseAnimationEnd();
diff --git a/src/com/android/systemui/car/window/OverlayWindowModule.java b/src/com/android/systemui/car/window/OverlayWindowModule.java
index 9361c76..fc48ff8 100644
--- a/src/com/android/systemui/car/window/OverlayWindowModule.java
+++ b/src/com/android/systemui/car/window/OverlayWindowModule.java
@@ -21,6 +21,7 @@
 import com.android.systemui.car.notification.BottomNotificationPanelViewMediator;
 import com.android.systemui.car.notification.NotificationPanelViewMediator;
 import com.android.systemui.car.notification.TopNotificationPanelViewMediator;
+import com.android.systemui.car.systemdialogs.SystemDialogsViewMediator;
 import com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator;
 import com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator;
 
@@ -83,4 +84,11 @@
     @ClassKey(HvacPanelOverlayViewMediator.class)
     public abstract OverlayViewMediator bindHvacPanelOverlayViewMediator(
             HvacPanelOverlayViewMediator overlayViewMediator);
+
+    /** Inject SystemDialogsViewMediator. */
+    @Binds
+    @IntoMap
+    @ClassKey(SystemDialogsViewMediator.class)
+    public abstract OverlayViewMediator bindSystemDialogsViewMediator(
+            SystemDialogsViewMediator sysui);
 }
diff --git a/tests/res/layout/car_top_system_bar.xml b/tests/res/layout/car_top_system_bar.xml
index 98ec85a..55e1b9f 100644
--- a/tests/res/layout/car_top_system_bar.xml
+++ b/tests/res/layout/car_top_system_bar.xml
@@ -30,11 +30,18 @@
         android:layout_weight="1"
         android:layoutDirection="ltr">
 
-        <com.android.systemui.car.systembar.CarSystemBarButton
+        <LinearLayout
+            android:id="@+id/qc_entry_points_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            android:layout_alignParentStart="true"
+            />
+
+        <FrameLayout
             android:id="@+id/clock_container"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:background="@drawable/system_bar_pill_rotary_background"
             android:paddingStart="@dimen/car_padding_2"
             android:paddingEnd="@dimen/car_padding_2"
             android:layout_centerInParent="true">
@@ -47,13 +54,31 @@
                 android:singleLine="true"
                 android:textAppearance="@style/TextAppearance.SystemBar.Clock"
                 systemui:amPmStyle="normal"
+                />
+        </FrameLayout>
+
+        <LinearLayout
+            android:id="@+id/read_only_icons_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            android:layout_toRightOf="@id/clock_container"
             />
-        </com.android.systemui.car.systembar.CarSystemBarButton>
+
+        <include layout="@layout/mic_privacy_chip"
+            android:layout_width="@dimen/privacy_chip_width"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            android:layout_toRightOf="@id/read_only_icons_container"
+            android:layout_toLeftOf="@id/user_name_container" />
+
+        <FrameLayout
+            android:id="@+id/user_name_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_centerVertical="true"
+            android:layout_marginTop="@dimen/car_padding_2"
+            />
     </RelativeLayout>
-    <include layout="@layout/mic_privacy_chip"
-             android:layout_width="@dimen/privacy_chip_width"
-             android:layout_height="match_parent"
-             android:layout_centerVertical="true"
-             android:layout_toRightOf="@id/clock_container"
-             android:layout_toLeftOf="@id/user_name_container" />
 </com.android.systemui.car.systembar.CarSystemBarView>
diff --git a/tests/src/com/android/systemui/car/qc/ProfileSwitcherTest.java b/tests/src/com/android/systemui/car/qc/ProfileSwitcherTest.java
index 939253a..e07d2a4 100644
--- a/tests/src/com/android/systemui/car/qc/ProfileSwitcherTest.java
+++ b/tests/src/com/android/systemui/car/qc/ProfileSwitcherTest.java
@@ -24,11 +24,13 @@
 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.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.app.admin.DevicePolicyManager;
 import android.car.user.CarUserManager;
 import android.car.user.UserCreationResult;
 import android.car.user.UserSwitchResult;
@@ -71,6 +73,8 @@
     @Mock
     private UserManager mUserManager;
     @Mock
+    private DevicePolicyManager mDevicePolicyManager;
+    @Mock
     private CarUserManager mCarUserManager;
 
     @Before
@@ -79,6 +83,8 @@
 
         when(mUserManager.getAliveUsers()).thenReturn(mAliveUsers);
         when(mUserManager.getUserSwitchability(any())).thenReturn(SWITCHABILITY_STATUS_OK);
+        when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
+        when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false);
 
         AsyncFuture<UserSwitchResult> switchResultFuture = mock(AsyncFuture.class);
         UserSwitchResult switchResult = mock(UserSwitchResult.class);
@@ -86,7 +92,8 @@
         when(switchResultFuture.get(anyLong(), any())).thenReturn(switchResult);
         when(mCarUserManager.switchUser(anyInt())).thenReturn(switchResultFuture);
 
-        mProfileSwitcher = new ProfileSwitcher(mContext, mUserManager, mCarUserManager);
+        mProfileSwitcher = new ProfileSwitcher(mContext, mUserManager, mDevicePolicyManager,
+                mCarUserManager);
     }
 
     @Test
@@ -100,9 +107,9 @@
         UserInfo otherUser = generateUser(1001, "Other User", /* supportsSwitch= */ true,
                 /* isGuest= */ false);
         mAliveUsers.add(otherUser);
-        QCList list = getQCList();
-        assertThat(list.getRows().size()).isEqualTo(1);
-        assertThat(list.getRows().get(0).getTitle()).isEqualTo("Current User");
+        List<QCRow> rows = getProfileRows();
+        assertThat(rows).hasSize(1);
+        assertThat(rows.get(0).getTitle()).isEqualTo("Current User");
     }
 
     @Test
@@ -113,14 +120,14 @@
                 /* isGuest= */ false);
         mAliveUsers.add(user1);
         mAliveUsers.add(user2);
-        QCList list = getQCList();
+        List<QCRow> rows = getProfileRows();
         // Expect four rows - one for each user, one for the guest user, and one for add user
-        assertThat(list.getRows().size()).isEqualTo(4);
-        assertThat(list.getRows().get(0).getTitle()).isEqualTo("User1");
-        assertThat(list.getRows().get(1).getTitle()).isEqualTo("User2");
-        assertThat(list.getRows().get(2).getTitle()).isEqualTo(
+        assertThat(rows).hasSize(4);
+        assertThat(rows.get(0).getTitle()).isEqualTo("User1");
+        assertThat(rows.get(1).getTitle()).isEqualTo("User2");
+        assertThat(rows.get(2).getTitle()).isEqualTo(
                 mContext.getString(R.string.car_guest));
-        assertThat(list.getRows().get(3).getTitle()).isEqualTo(
+        assertThat(rows.get(3).getTitle()).isEqualTo(
                 mContext.getString(R.string.car_add_user));
     }
 
@@ -132,13 +139,13 @@
                 /* isGuest= */ false);
         mAliveUsers.add(user1);
         mAliveUsers.add(user2);
-        QCList list = getQCList();
+        List<QCRow> rows = getProfileRows();
         // Expect three rows - one for the valid user, one for the guest user, and one for add user
-        assertThat(list.getRows().size()).isEqualTo(3);
-        assertThat(list.getRows().get(0).getTitle()).isEqualTo("User1");
-        assertThat(list.getRows().get(1).getTitle()).isEqualTo(
+        assertThat(rows).hasSize(3);
+        assertThat(rows.get(0).getTitle()).isEqualTo("User1");
+        assertThat(rows.get(1).getTitle()).isEqualTo(
                 mContext.getString(R.string.car_guest));
-        assertThat(list.getRows().get(2).getTitle()).isEqualTo(
+        assertThat(rows.get(2).getTitle()).isEqualTo(
                 mContext.getString(R.string.car_add_user));
     }
 
@@ -150,13 +157,51 @@
                 /* isGuest= */ true);
         mAliveUsers.add(user1);
         mAliveUsers.add(user2);
-        QCList list = getQCList();
+        List<QCRow> rows = getProfileRows();
         // Expect three rows - one for the valid user, one for the guest user, and one for add user
-        assertThat(list.getRows().size()).isEqualTo(3);
-        assertThat(list.getRows().get(0).getTitle()).isEqualTo("User1");
-        assertThat(list.getRows().get(1).getTitle()).isEqualTo(
+        assertThat(rows).hasSize(3);
+        assertThat(rows.get(0).getTitle()).isEqualTo("User1");
+        assertThat(rows.get(1).getTitle()).isEqualTo(
                 mContext.getString(R.string.car_guest));
-        assertThat(list.getRows().get(2).getTitle()).isEqualTo(
+        assertThat(rows.get(2).getTitle()).isEqualTo(
+                mContext.getString(R.string.car_add_user));
+    }
+
+    @Test
+    public void switchAllowed_addUserDisallowed_returnsValidRows() {
+        when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_USER),
+                any())).thenReturn(true);
+        UserInfo user1 = generateUser(1000, "User1", /* supportsSwitch= */ true,
+                /* isGuest= */ false);
+        UserInfo user2 = generateUser(1001, "User2", /* supportsSwitch= */ true,
+                /* isGuest= */ false);
+        mAliveUsers.add(user1);
+        mAliveUsers.add(user2);
+        List<QCRow> rows = getProfileRows();
+        // Expect three rows - one for each user and one for the guest user
+        assertThat(rows).hasSize(3);
+        assertThat(rows.get(0).getTitle()).isEqualTo("User1");
+        assertThat(rows.get(1).getTitle()).isEqualTo("User2");
+        assertThat(rows.get(2).getTitle()).isEqualTo(
+                mContext.getString(R.string.car_guest));
+    }
+
+    @Test
+    public void switchAllowed_deviceManaged_returnsValidRows() {
+        when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+        UserInfo user1 = generateUser(1000, "User1", /* supportsSwitch= */ true,
+                /* isGuest= */ false);
+        mAliveUsers.add(user1);
+        List<QCRow> rows = getProfileRows();
+        // Expect four rows - one for the device owner message, one for the user,
+        // one for the guest user, and one for add user
+        assertThat(rows).hasSize(4);
+        assertThat(rows.get(0).getSubtitle()).isEqualTo(
+                mContext.getString(R.string.do_disclosure_generic));
+        assertThat(rows.get(1).getTitle()).isEqualTo("User1");
+        assertThat(rows.get(2).getTitle()).isEqualTo(
+                mContext.getString(R.string.car_guest));
+        assertThat(rows.get(3).getTitle()).isEqualTo(
                 mContext.getString(R.string.car_add_user));
     }
 
@@ -170,10 +215,10 @@
                 /* isGuest= */ false);
         mAliveUsers.add(user1);
         mAliveUsers.add(user2);
-        QCList list = getQCList();
+        List<QCRow> rows = getProfileRows();
         // Expect four rows - one for each user, one for the guest user, and one for add user
-        assertThat(list.getRows().size()).isEqualTo(4);
-        QCRow otherUserRow = list.getRows().get(1);
+        assertThat(rows).hasSize(4);
+        QCRow otherUserRow = rows.get(1);
         otherUserRow.getActionHandler().onAction(otherUserRow, mContext, new Intent());
         verify(mCarUserManager).switchUser(otherUserId);
     }
@@ -194,20 +239,20 @@
         UserInfo user1 = generateUser(currentUserId, "User1", /* supportsSwitch= */ true,
                 /* isGuest= */ false);
         mAliveUsers.add(user1);
-        QCList list = getQCList();
+        List<QCRow> rows = getProfileRows();
         // Expect 3 rows - one for the user, one for the guest user, and one for add user
-        assertThat(list.getRows().size()).isEqualTo(3);
-        QCRow guestRow = list.getRows().get(1);
+        assertThat(rows).hasSize(3);
+        QCRow guestRow = rows.get(1);
         guestRow.getActionHandler().onAction(guestRow, mContext, new Intent());
         verify(mCarUserManager).createGuest(any());
         verify(mCarUserManager).switchUser(guestUserId);
     }
 
-    private QCList getQCList() {
+    private List<QCRow> getProfileRows() {
         QCItem item = mProfileSwitcher.getQCItem();
         assertThat(item).isNotNull();
         assertThat(item instanceof QCList).isTrue();
-        return (QCList) item;
+        return ((QCList) item).getRows();
     }
 
     private UserInfo generateUser(int id, String name, boolean supportsSwitch, boolean isGuest) {
diff --git a/tests/src/com/android/systemui/car/systembar/CarSystemBarControllerTest.java b/tests/src/com/android/systemui/car/systembar/CarSystemBarControllerTest.java
index afbd5e7..4c888f4 100644
--- a/tests/src/com/android/systemui/car/systembar/CarSystemBarControllerTest.java
+++ b/tests/src/com/android/systemui/car/systembar/CarSystemBarControllerTest.java
@@ -16,11 +16,19 @@
 
 package com.android.systemui.car.systembar;
 
+import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
+import static android.app.StatusBarManager.DISABLE_HOME;
+import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
+import android.content.Context;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableResources;
@@ -62,8 +70,11 @@
     private CarSystemBarController mCarSystemBar;
     private CarSystemBarViewFactory mCarSystemBarViewFactory;
     private TestableResources mTestableResources;
+    private Context mSpiedContext;
 
     @Mock
+    private ActivityManager mActivityManager;
+    @Mock
     private ButtonSelectionStateController mButtonSelectionStateController;
     @Mock
     private ButtonRoleHolderController mButtonRoleHolderController;
@@ -89,9 +100,11 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mCarSystemBarViewFactory = new CarSystemBarViewFactory(mContext, mFeatureFlags,
-                mQuickControlsEntryPointsController, mReadOnlyIconsController);
         mTestableResources = mContext.getOrCreateTestableResources();
+        mSpiedContext = spy(mContext);
+        when(mSpiedContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
+        mCarSystemBarViewFactory = new CarSystemBarViewFactory(mSpiedContext, mFeatureFlags,
+                mQuickControlsEntryPointsController, mReadOnlyIconsController);
 
         // Needed to inflate top navigation bar.
         mDependency.injectMockDependency(DarkIconDispatcher.class);
@@ -99,8 +112,9 @@
     }
 
     private CarSystemBarController createSystemBarController() {
-        return new CarSystemBarController(mContext, mCarSystemBarViewFactory, mCarServiceProvider,
-                mBroadcastDispatcher, mConfigurationController, mButtonSelectionStateController,
+        return new CarSystemBarController(mSpiedContext, mCarSystemBarViewFactory,
+                mCarServiceProvider, mBroadcastDispatcher, mConfigurationController,
+                mButtonSelectionStateController,
                 () -> mUserNameViewController, () -> mPrivacyChipViewController,
                 mButtonRoleHolderController,
                 new SystemBarConfigs(mTestableResources.getResources()),
@@ -573,4 +587,154 @@
 
         assertThat(notifications.getUnseen()).isFalse();
     }
+
+    @Test
+    public void testSetSystemBarStates_stateUpdated() {
+        mTestableResources.addOverride(R.bool.config_enableBottomSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        clearSystemBarStates();
+
+        mCarSystemBar.setSystemBarStates(DISABLE_HOME, /* state2= */ 0);
+
+        assertThat(mCarSystemBar.getStatusBarState()).isEqualTo(DISABLE_HOME);
+    }
+
+    @Test
+    public void testSetSystemBarStates_state2Updated() {
+        mTestableResources.addOverride(R.bool.config_enableBottomSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        clearSystemBarStates();
+
+        mCarSystemBar.setSystemBarStates(0, DISABLE2_QUICK_SETTINGS);
+
+        assertThat(mCarSystemBar.getStatusBarState2()).isEqualTo(DISABLE2_QUICK_SETTINGS);
+    }
+
+    @Test
+    public void testRefreshSystemBar_homeDisabled() {
+        mTestableResources.addOverride(R.bool.config_enableBottomSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        CarSystemBarView bottomBar = mCarSystemBar.getBottomBar(/* isSetUp= */ true);
+        clearSystemBarStates();
+        CarSystemBarButton button = bottomBar.findViewById(R.id.home);
+        assertThat(button.getDisabled()).isFalse();
+
+        mCarSystemBar.setSystemBarStates(DISABLE_HOME, /* state2= */ 0);
+
+        assertThat(button.getDisabled()).isTrue();
+    }
+
+    @Test
+    public void testRefreshSystemBar_phoneNavDisabled() {
+        mTestableResources.addOverride(R.bool.config_enableBottomSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        CarSystemBarView bottomBar = mCarSystemBar.getBottomBar(/* isSetUp= */ true);
+        clearSystemBarStates();
+        CarSystemBarButton button = bottomBar.findViewById(R.id.phone_nav);
+        assertThat(button.getDisabled()).isFalse();
+
+        setLockTaskModeLocked(/* locked= */true);
+
+        assertThat(button.getDisabled()).isTrue();
+    }
+
+    @Test
+    public void testRefreshSystemBar_appGridisabled() {
+        mTestableResources.addOverride(R.bool.config_enableBottomSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        CarSystemBarView bottomBar = mCarSystemBar.getBottomBar(/* isSetUp= */ true);
+        clearSystemBarStates();
+        CarSystemBarButton button = bottomBar.findViewById(R.id.grid_nav);
+        assertThat(button.getDisabled()).isFalse();
+
+        mCarSystemBar.setSystemBarStates(DISABLE_HOME, /* state2= */ 0);
+
+        assertThat(button.getDisabled()).isTrue();
+    }
+
+    @Test
+    public void testRefreshSystemBar_notificationDisabled() {
+        mTestableResources.addOverride(R.bool.config_enableBottomSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        CarSystemBarView bottomBar = mCarSystemBar.getBottomBar(/* isSetUp= */ true);
+        clearSystemBarStates();
+        CarSystemBarButton button = bottomBar.findViewById(R.id.notifications);
+        assertThat(button.getDisabled()).isFalse();
+
+        mCarSystemBar.setSystemBarStates(DISABLE_NOTIFICATION_ICONS, /* state2= */ 0);
+
+        assertThat(button.getDisabled()).isTrue();
+    }
+
+    @Test
+    public void testRefreshSystemBar_disableQcFlagOn_qcHidden() {
+        mTestableResources.addOverride(R.bool.config_enableTopSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+
+        CarSystemBarView topBar = mCarSystemBar.getTopBar(/* isSetUp= */ true);
+        View qcView = topBar.findViewById(R.id.qc_entry_points_container);
+        clearSystemBarStates();
+        assertThat(qcView.getVisibility()).isEqualTo(View.VISIBLE);
+
+        mCarSystemBar.setSystemBarStates(0, DISABLE2_QUICK_SETTINGS);
+
+        assertThat(qcView.getVisibility()).isEqualTo(View.INVISIBLE);
+    }
+
+    @Test
+    public void testRefreshSystemBar_lockTaskModeOn_qcHidden() {
+        mTestableResources.addOverride(R.bool.config_enableTopSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        CarSystemBarView topBar = mCarSystemBar.getTopBar(/* isSetUp= */ true);
+        View qcView = topBar.findViewById(R.id.qc_entry_points_container);
+        clearSystemBarStates();
+        assertThat(qcView.getVisibility()).isEqualTo(View.VISIBLE);
+
+        setLockTaskModeLocked(/* locked= */ true);
+
+        assertThat(qcView.getVisibility()).isEqualTo(View.INVISIBLE);
+    }
+
+    @Test
+    public void testRefreshSystemBar_disableQcFlagOn_userSwitcherHidden() {
+        mTestableResources.addOverride(R.bool.config_enableTopSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        CarSystemBarView topBar = mCarSystemBar.getTopBar(/* isSetUp= */ true);
+
+        View userSwitcher = topBar.findViewById(R.id.user_name_container);
+        clearSystemBarStates();
+        assertThat(userSwitcher.getVisibility()).isEqualTo(View.VISIBLE);
+
+        mCarSystemBar.setSystemBarStates(0, DISABLE2_QUICK_SETTINGS);
+
+        assertThat(userSwitcher.getVisibility()).isEqualTo(View.INVISIBLE);
+    }
+
+    @Test
+    public void testRefreshSystemBar_lockTaskModeOn_userSwitcherHidden() {
+        mTestableResources.addOverride(R.bool.config_enableTopSystemBar, true);
+        mCarSystemBar = createSystemBarController();
+        CarSystemBarView topBar = mCarSystemBar.getTopBar(/* isSetUp= */ true);
+        View userSwitcher = topBar.findViewById(R.id.user_name_container);
+        clearSystemBarStates();
+        assertThat(userSwitcher.getVisibility()).isEqualTo(View.VISIBLE);
+
+        setLockTaskModeLocked(/* locked= */ true);
+
+        assertThat(userSwitcher.getVisibility()).isEqualTo(View.INVISIBLE);
+    }
+
+    private void clearSystemBarStates() {
+        if (mCarSystemBar != null) {
+            mCarSystemBar.setSystemBarStates(/* state= */ 0, /* state2= */ 0);
+        }
+        setLockTaskModeLocked(false);
+    }
+
+    private void setLockTaskModeLocked(boolean locked) {
+        when(mActivityManager.getLockTaskModeState()).thenReturn(locked
+                ? ActivityManager.LOCK_TASK_MODE_LOCKED
+                : ActivityManager.LOCK_TASK_MODE_NONE);
+        mCarSystemBar.setSystemBarStates(/* state= */ 0, /* state2= */ 0);
+    }
 }
diff --git a/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java b/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
index eadb323..d101395 100644
--- a/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
+++ b/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
@@ -25,6 +25,8 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -379,6 +381,22 @@
         assertThat(mCarSystemBar.isNavBarTransientShown()).isFalse();
     }
 
+    @Test
+    public void disable_wrongDisplayId_notSetStatusBarState() {
+        int randomDisplay = Display.DEFAULT_DISPLAY + 10;
+
+        mCarSystemBar.disable(randomDisplay, 0, 0, false);
+
+        verify(mCarSystemBarController, never()).setSystemBarStates(anyInt(), anyInt());
+    }
+
+    @Test
+    public void disable_correctDisplayId_setSystemBarStates() {
+        mCarSystemBar.disable(Display.DEFAULT_DISPLAY, 0, 0, false);
+
+        verify(mCarSystemBarController).setSystemBarStates(0, 0);
+    }
+
     private void waitForDelayableExecutor() {
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
diff --git a/tests/src/com/android/systemui/car/systembar/PrivacyChipViewControllerTest.java b/tests/src/com/android/systemui/car/systembar/PrivacyChipViewControllerTest.java
index d751ac8..6baae34 100644
--- a/tests/src/com/android/systemui/car/systembar/PrivacyChipViewControllerTest.java
+++ b/tests/src/com/android/systemui/car/systembar/PrivacyChipViewControllerTest.java
@@ -23,7 +23,6 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -36,7 +35,6 @@
 import android.car.user.CarUserManager;
 import android.content.BroadcastReceiver;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.hardware.SensorPrivacyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -300,8 +298,7 @@
                 .thenReturn(true);
         mPrivacyChipViewController.addPrivacyChipView(mFrameLayout);
         verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
-                argThat((IntentFilter filter) -> filter.hasAction(Intent.ACTION_USER_INFO_CHANGED)),
-                any(), any());
+                any(), any(), any());
         reset(mExecutor);
         when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(1);
         mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext,
@@ -318,13 +315,15 @@
         when(mSensorPrivacyManager.isSensorPrivacyEnabled(MICROPHONE, /* userId= */ 1))
                 .thenReturn(false);
         mPrivacyChipViewController.addPrivacyChipView(mFrameLayout);
-        verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
-                argThat((IntentFilter filter) -> filter.hasAction(Intent.ACTION_USER_FOREGROUND)),
-                any(), any());
+        verify(mCarUserManager).addListener(any(), mUserLifecycleListenerArgumentCaptor.capture());
+        CarUserManager.UserLifecycleEvent event = new CarUserManager.UserLifecycleEvent(
+                CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, /* from= */ 0,
+                /* to= */ 1);
+        CarUserManager.UserLifecycleListener userLifecycleListener =
+                mUserLifecycleListenerArgumentCaptor.getValue();
+        assertThat(userLifecycleListener).isNotNull();
         reset(mExecutor);
-        when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(1);
-        mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext,
-                new Intent(Intent.ACTION_USER_FOREGROUND));
+        userLifecycleListener.onEvent(event);
         verify(mExecutor).execute(mRunnableArgumentCaptor.capture());
 
         mRunnableArgumentCaptor.getValue().run();
diff --git a/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java b/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
index afd22b5..ed7c60b 100644
--- a/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
+++ b/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
@@ -16,13 +16,17 @@
 
 package com.android.systemui.car.userswitcher;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
-import android.content.Context;
+import android.app.ActivityManager;
+import android.content.pm.UserInfo;
 import android.os.UserManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -31,6 +35,7 @@
 import android.view.IWindowManager;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
+import android.widget.TextView;
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -56,10 +61,16 @@
     private UserSwitchTransitionViewController mCarUserSwitchingDialogController;
     private TestableResources mTestableResources;
     private FakeExecutor mExecutor;
+    private FakeSystemClock mClock;
+    private ViewGroup mViewGroup;
+    @Mock
+    private ActivityManager mMockActivityManager;
     @Mock
     private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
     @Mock
     private IWindowManager mWindowManagerService;
+    @Mock
+    private UserManager mMockUserManager;
 
     @Before
     public void setUp() {
@@ -70,18 +81,22 @@
                 mContext,
                 mTestableResources.getResources(),
                 mExecutor,
-                (UserManager) mContext.getSystemService(Context.USER_SERVICE),
+                mMockActivityManager,
+                mMockUserManager,
                 mWindowManagerService,
                 mOverlayViewGlobalStateController
         );
 
-        mCarUserSwitchingDialogController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
-                R.layout.sysui_overlay_window, /* root= */ null));
+        mockGetUserInfo(TEST_USER_1);
+        mockGetUserInfo(TEST_USER_2);
+        mViewGroup = (ViewGroup) LayoutInflater.from(mContext).inflate(
+                R.layout.sysui_overlay_window, /* root= */ null);
+        mCarUserSwitchingDialogController.inflate(mViewGroup);
     }
 
     @Test
     public void onHandleShow_newUserSelected_showsDialog() {
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
 
@@ -90,11 +105,35 @@
     }
 
     @Test
-    public void onHandleShow_alreadyShowing_ignoresRequest() {
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+    public void onHandleShow_showsDefaultLoadingMessage() {
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_2);
+
+        TextView textView = mViewGroup.findViewById(R.id.user_loading);
+        assertThat(textView.getText().toString()).isEqualTo(
+                mTestableResources.getResources().getString(R.string.car_loading_profile));
+    }
+
+    @Test
+    public void onHandleShow_showsUserSwitchingMessage() {
+        String message = "Hello world!";
+        when(mMockActivityManager.getSwitchingFromUserMessage()).thenReturn(message);
+
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
+        mExecutor.advanceClockToLast();
+        mExecutor.runAllReady();
+
+        TextView textView = mViewGroup.findViewById(R.id.user_loading);
+        assertThat(textView.getText().toString()).isEqualTo(message);
+    }
+
+    @Test
+    public void onHandleShow_alreadyShowing_ignoresRequest() {
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
+        mExecutor.advanceClockToLast();
+        mExecutor.runAllReady();
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_2);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
 
@@ -105,13 +144,13 @@
 
     @Test
     public void onHandleShow_sameUserSelected_ignoresRequest() {
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
         mCarUserSwitchingDialogController.handleHide();
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
 
@@ -122,7 +161,7 @@
 
     @Test
     public void onHide_currentlyShowing_hidesDialog() {
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
         mCarUserSwitchingDialogController.handleHide();
@@ -135,7 +174,7 @@
 
     @Test
     public void onHide_notShowing_ignoresRequest() {
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
         mCarUserSwitchingDialogController.handleHide();
@@ -152,7 +191,7 @@
 
     @Test
     public void onWindowShownTimeoutPassed_viewNotHidden_hidesUserSwitchTransitionView() {
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
         reset(mOverlayViewGlobalStateController);
@@ -165,7 +204,7 @@
 
     @Test
     public void onWindowShownTimeoutPassed_viewHidden_doesNotHideUserSwitchTransitionViewAgain() {
-        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* newUserId= */ TEST_USER_1);
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
         mCarUserSwitchingDialogController.handleHide();
@@ -178,4 +217,9 @@
                     eq(mCarUserSwitchingDialogController), any());
         }, mCarUserSwitchingDialogController.getWindowShownTimeoutMs() + 10);
     }
+
+    private void mockGetUserInfo(int userId) {
+        when(mMockUserManager.getUserInfo(userId))
+                .thenReturn(new UserInfo(userId, "USER_" + userId, /* flags= */ 0));
+    }
 }