Merge "[RESTRICT AUTOMERGE] Replace SharedPrefs with flat file persistable bundle" into sc-v2-dev
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/ic_minimize.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/ic_minimize.xml
new file mode 100644
index 0000000..721cec4
--- /dev/null
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/ic_minimize.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <vector
+            android:width="@dimen/system_bar_icon_drawing_size"
+            android:height="@dimen/system_bar_icon_drawing_size"
+            android:viewportWidth="24"
+            android:viewportHeight="24">
+            <path
+                android:pathData="M12,15.375l-6,-6 1.4,-1.4 4.6,4.6 4.6,-4.6 1.4,1.4z"
+                android:fillColor="@color/car_nav_minimize_icon_fill_color"/>
+        </vector>
+    </item>
+</selector>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml
index de76f55..7c8b669 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/drawable/nav_bar_button_background.xml
@@ -15,19 +15,9 @@
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:aapt="http://schemas.android.com/aapt">
-    <item android:state_activated="true">
+    <item android:state_selected="true">
         <layer-list>
             <item>
-                <shape android:shape="rectangle">
-                    <size android:width="@dimen/system_bar_button_size"
-                          android:height="@dimen/system_bar_button_size"/>
-                    <corners
-                        android:radius="@dimen/system_bar_button_corner_radius"/>
-                    <solid
-                        android:color="@color/car_nav_icon_fill_color"/>
-                </shape>
-            </item>
-            <item>
                 <ripple android:color="@color/car_ui_ripple_color">
                     <item>
                         <shape android:shape="rectangle">
@@ -36,26 +26,18 @@
                             <corners
                                 android:radius="@dimen/system_bar_button_corner_radius"/>
                             <solid
-                                android:color="@color/car_nav_icon_fill_color"/>
+                                android:color="?android:attr/colorAccent"/>
                         </shape>
                     </item>
                 </ripple>
             </item>
+            <item android:drawable="@drawable/ic_minimize"
+                  android:gravity="center"/>
         </layer-list>
     </item>
     <item>
         <layer-list>
             <item>
-                <shape android:shape="rectangle">
-                    <size android:width="@dimen/system_bar_button_size"
-                          android:height="@dimen/system_bar_button_size"/>
-                    <corners
-                        android:radius="@dimen/system_bar_button_corner_radius"/>
-                    <solid
-                        android:color="@color/car_nav_icon_background_color"/>
-                </shape>
-            </item>
-            <item>
                 <ripple android:color="@color/car_ui_ripple_color">
                     <item>
                         <shape android:shape="rectangle">
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
index 557547a..69c3d30 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/layout/car_bottom_system_bar.xml
@@ -52,8 +52,9 @@
                 android:id="@+id/grid_nav"
                 style="@style/SystemBarButton"
                 systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
-                systemui:highlightWhenSelected="true"
                 systemui:icon="@drawable/car_ic_apps"
+                systemui:highlightWhenSelected="true"
+                systemui:toggleSelected="true"
                 systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"
                 systemui:clearBackStack="true"/>
 
@@ -61,23 +62,25 @@
                 android:id="@+id/standalone_notifications"
                 style="@style/SystemBarButton"
                 systemui:componentNames="com.android.car.notification/.CarNotificationCenterActivity"
-                systemui:highlightWhenSelected="true"
+                systemui:packages="com.android.car.notification"
                 systemui:icon="@drawable/car_ic_notification"
+                systemui:highlightWhenSelected="true"
+                systemui:toggleSelected="true"
                 systemui:intent="intent:#Intent;component=com.android.car.notification/.CarNotificationCenterActivity;launchFlags=0x24000000;end"
                 systemui:longIntent="intent:#Intent;component=com.android.car.bugreport/.BugReportActivity;end"/>
 
             <com.android.systemui.car.systembar.CarSystemBarButton
                 android:id="@+id/hvac"
                 style="@style/SystemBarButton"
-                systemui:highlightWhenSelected="true"
                 systemui:icon="@drawable/car_ic_hvac"
+                systemui:highlightWhenSelected="true"
                 systemui:broadcast="true"/>
 
             <com.android.systemui.car.systembar.AssitantButton
                 android:id="@+id/assist"
                 style="@style/SystemBarButton"
-                systemui:highlightWhenSelected="true"
                 systemui:icon="@drawable/car_ic_mic"
+                systemui:highlightWhenSelected="true"
                 systemui:useDefaultAppIconForRole="true"/>
         </LinearLayout>
 
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
index 8792680..3f62d35 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/colors.xml
@@ -20,6 +20,7 @@
 
     <color name="car_nav_icon_fill_color">#FFFFFF</color>
     <color name="car_nav_icon_background_color">#282A2D</color>
+    <color name="car_nav_minimize_icon_fill_color">@android:color/black</color>
 
     <drawable name="system_bar_background">#000000</drawable>
     <color name="system_bar_text_color">#E8EAED</color>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml
index 8ed622b..f900e57 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/dimens.xml
@@ -42,6 +42,9 @@
     <dimen name="system_bar_user_icon_drawing_size">44dp</dimen>
     <dimen name="status_bar_system_icon_spacing">32dp</dimen>
 
+    <dimen name="system_bar_minimize_icon_height">17dp</dimen>
+    <dimen name="system_bar_minimize_icon_width">28dp</dimen>
+
     <dimen name="hvac_panel_handle_bar_container_height">64dp</dimen>
     <dimen name="hvac_panel_handle_bar_container_width">728dp</dimen>
     <dimen name="hvac_panel_handle_bar_height">6dp</dimen>
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
index 6e400e5..b5f46f8 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitSystemUI/res/values/styles.xml
@@ -17,12 +17,19 @@
 <resources
     xmlns:android="http://schemas.android.com/apk/res/android">
 
+    <!--
+        Note on selected/unselected icons:
+        The icon is always tinted with @color/car_nav_icon_fill_color_selected in @layout/car_system_bar_button
+        Unselected: keep this behavior so all icons have consistent color (eg. tint a multi-colored default app icon)
+        Selected: set selected alpha 0, making icon transparent. Use state list nav_bar_button_background to show selected icon (in addition to background).
+    -->
     <style name="SystemBarButton">
         <item name="android:layout_width">@dimen/system_bar_button_size</item>
         <item name="android:layout_height">@dimen/system_bar_button_size</item>
         <item name="android:background">@drawable/nav_bar_button_background</item>
         <item name="android:gravity">center</item>
         <item name="unselectedAlpha">1.0</item>
+        <item name="selectedAlpha">0</item>
     </style>
 
     <style name="TextAppearance.SystemBar.Username"
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp
index fecf167..92bd722 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/Android.bp
@@ -25,5 +25,7 @@
     static_libs: [
         "androidx-constraintlayout_constraintlayout",
         "androidx-constraintlayout_constraintlayout-solver",
+        "car-apps-common",
+        "car-ui-lib",
     ],
 }
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/dialer_ripple_background.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/dialer_ripple_background.xml
new file mode 100644
index 0000000..131afd5
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/dialer_ripple_background.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <shape
+            android:shape="oval">
+            <solid
+                android:color="@color/keypad_background_color" />
+            <size
+                android:width="@dimen/dialer_keypad_button_size"
+                android:height="@dimen/dialer_keypad_button_size"/>
+        </shape>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_arrow_right.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_arrow_right.xml
new file mode 100644
index 0000000..f1210dc
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_arrow_right.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:viewportWidth="48"
+        android:viewportHeight="48"
+        android:width="44dp"
+        android:height="44dp"
+        android:tint="?attr/colorControlNormal"
+        android:autoMirrored="true">
+
+    <path android:pathData="M0-.25h48v48H0z"/>
+    <path
+        android:fillColor="?android:attr/textColorPrimary"
+        android:pathData="M17.17 32.92l9.17-9.17-9.17-9.17L20 11.75l12 12-12 12z"/>
+</vector>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_backspace.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_backspace.xml
new file mode 100644
index 0000000..6b4f369
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_backspace.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="44dp"
+        android:height="32dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M22,3L7,3c-0.69,0 -1.23,0.35 -1.59,0.88L0,12l5.41,8.11c0.36,0.53 0.9,0.89 1.59,0.89h15c1.1,0 2,-0.9 2,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM22,19L7.07,19L2.4,12l4.66,-7L22,5v14zM10.41,17L14,13.41 17.59,17 19,15.59 15.41,12 19,8.41 17.59,7 14,10.59 10.41,7 9,8.41 12.59,12 9,15.59z"/>
+</vector>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml
index b659da1..3e2e824 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/ic_phone.xml
@@ -22,7 +22,7 @@
     <path
         android:pathData="M0 0h24v24H0z" />
     <path
-        android:fillColor="#fffafafa"
+        android:fillColor="?android:attr/textColorPrimary"
         android:pathData="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27 .67 -.36 1.02-.24 1.12
 .37 2.33 .57 3.57 .57 .55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17
 0-.55 .45 -1 1-1h3.5c.55 0 1 .45 1 1 0 1.25 .2 2.45 .57 3.57 .11 .35 .03 .74-.25
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml
index 748a1d0..d048af9 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/icon_call_button.xml
@@ -19,11 +19,11 @@
         <shape
             android:shape="rectangle">
             <solid
-                android:color="#52CCB0" />
+                android:color="#29cb86" />
             <corners android:radius="100dp"/>
             <size
-                android:width="424dp"
-                android:height="120dp"/>
+                android:width="416dp"
+                android:height="@dimen/dialer_keypad_button_size"/>
         </shape>
     </item>
     <item android:drawable="@drawable/ic_phone" android:gravity="center"/>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml
index bf49159..131afd5 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/keypad_default_background.xml
@@ -19,10 +19,10 @@
         <shape
             android:shape="oval">
             <solid
-                android:color="#282A2D" />
+                android:color="@color/keypad_background_color" />
             <size
-                android:width="120dp"
-                android:height="120dp"/>
+                android:width="@dimen/dialer_keypad_button_size"
+                android:height="@dimen/dialer_keypad_button_size"/>
         </shape>
     </item>
 </layer-list>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/restricted_dialing_mode_label_background.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/restricted_dialing_mode_label_background.xml
new file mode 100644
index 0000000..ea5a715
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/drawable/restricted_dialing_mode_label_background.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <corners android:radius="4dp"/>
+    <solid android:color="@color/car_red_500a"/>
+</shape>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_fragment_with_type_down.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_fragment_with_type_down.xml
new file mode 100644
index 0000000..0185f23
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_fragment_with_type_down.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginLeft="100dp">
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="45dp"
+        android:maxLines="1"
+        android:layout_marginBottom="48dp"
+        android:textAppearance="@style/TextAppearance.DialNumber"
+        android:autoSizeMinTextSize="24sp"
+        android:autoSizeMaxTextSize="28sp"
+        android:layout_marginLeft="150dp"
+        android:layout_alignParentTop="true"/>
+
+    <com.android.car.ui.recyclerview.CarUiRecyclerView
+        android:id="@+id/list_view"
+        android:layout_width="536dp"
+        android:layout_height="266dp"
+        android:layout_marginBottom="10dp"
+        android:layout_marginLeft="70dp"
+        android:layout_below="@id/title"/>
+    <fragment
+        android:id="@+id/dialpad_fragment"
+        android:name="com.android.car.dialer.ui.dialpad.KeypadFragment"
+        android:layout_height="456dp"
+        android:layout_width="416dp"
+        android:layout_marginLeft="120dp"
+        android:layout_below="@id/list_view"/>
+
+    <RelativeLayout
+        android:layout_height="@dimen/dialer_keypad_button_size"
+        android:layout_width="0dp"
+        android:layout_below="@id/dialpad_fragment"
+        android:layout_marginTop="38dp"
+        android:layout_alignLeft="@id/dialpad_fragment"
+        android:layout_alignRight="@id/dialpad_fragment">
+
+        <ImageView
+            android:id="@+id/call_button"
+            android:layout_height="match_parent"
+            android:layout_width="match_parent"
+            android:adjustViewBounds="true"
+            android:scaleType="fitXY"
+            android:src="@drawable/icon_call_button"
+            android:layout_toLeftOf="@id/delete_button"/>
+
+        <ImageButton
+            android:id="@+id/delete_button"
+            android:layout_width="@dimen/dialer_keypad_button_size"
+            android:layout_height="match_parent"
+            style="@style/DialpadSecondaryButton"
+            android:src="@drawable/ic_backspace"
+            android:layout_marginLeft="64dp"
+            android:visibility="gone"
+            android:layout_alignParentRight="true"/>
+    </RelativeLayout>
+
+    <include
+        layout="@layout/dialpad_user_profile"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginTop="10dp"
+        android:layout_below="@id/title"
+        android:layout_centerHorizontal="true"/>
+
+    <include
+        layout="@layout/restricted_dialing_mode_label"
+        android:id="@+id/restricted_dialing_mode_label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="8dp"
+        android:layout_below="@id/title"
+        android:visibility="invisible"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_user_profile.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_user_profile.xml
new file mode 100644
index 0000000..bb4e11f
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/dialpad_user_profile.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/display_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.DialpadDisplayName"
+        android:singleLine="true"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentTop="true"/>
+
+    <TextView
+        android:id="@+id/label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:singleLine="true"
+        android:layout_marginTop="12dp"
+        android:layout_below="@id/display_name"
+        android:layout_centerHorizontal="true"/>
+
+    <ImageView
+        android:id="@+id/dialpad_contact_avatar"
+        android:layout_height="@dimen/dialpad_contact_avatar_size"
+        android:layout_width="@dimen/dialpad_contact_avatar_size"
+        android:layout_below="@id/label"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"/>
+
+    <TextView
+        android:id="@+id/dialpad_contact_initials"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:layout_width="10dp"
+        android:layout_height="10dp"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/restricted_dialing_mode_label.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/restricted_dialing_mode_label.xml
new file mode 100644
index 0000000..6a23fd5
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/restricted_dialing_mode_label.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ 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.
+  -->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/restricted_dialing_mode_label"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="8dp"
+    android:padding="8dp"
+    android:textAppearance="@style/TextAppearance.Body2"
+    android:text="@string/restricted_dialing_mode_label"
+    android:alpha="0.8"
+    android:background="@drawable/restricted_dialing_mode_label_background"/>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/type_down_list_item.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/type_down_list_item.xml
new file mode 100644
index 0000000..68cf567
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/layout/type_down_list_item.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contact_result"
+    android:foreground="?android:attr/selectableItemBackground"
+    android:layout_width="match_parent"
+    android:layout_height="112dp">
+
+    <ImageView
+        android:id="@+id/contact_picture"
+        android:layout_width="72dp"
+        android:layout_height="72dp"
+        android:scaleType="centerCrop"
+        android:layout_centerVertical="true"
+        android:layout_alignParentLeft="true"/>
+
+    <TextView
+        android:id="@+id/contact_name"
+        android:layout_marginStart="24dp"
+        android:layout_marginTop="14dp"
+        android:layout_marginBottom="8dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:textAppearance="@style/TextAppearance.ContactResultTitle"
+        android:duplicateParentState="true"
+        android:layout_alignParentTop="true"
+        android:layout_toRightOf="@id/contact_picture"/>
+
+    <TextView
+        android:id="@+id/phone_number"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="14dp"
+        android:theme="@style/Theme.CarUi.WithToolbar"
+        android:singleLine="true"
+        android:layout_alignParentBottom="true"
+        android:layout_alignLeft="@id/contact_name"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values-night/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values-night/colors.xml
new file mode 100644
index 0000000..929bfe2
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values-night/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <color name="keypad_background_color">#282A2D</color>
+</resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/colors.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/colors.xml
new file mode 100644
index 0000000..5452e77
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <color name="keypad_background_color">#E8EAED</color>
+</resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/dimens.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/dimens.xml
new file mode 100644
index 0000000..108cfb1
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <dimen name="dialer_keypad_button_size">96dp</dimen>
+    <dimen name="dialpad_contact_avatar_size">64dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/strings.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/strings.xml
new file mode 100644
index 0000000..88b64b6
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="restricted_dialing_mode_label">Dialpad usage is restricted while driving</string>
+</resources>
\ No newline at end of file
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml
index 678cf0c..d67d485 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/values/styles.xml
@@ -20,18 +20,53 @@
         <item name="android:clickable">true</item>
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_marginTop">16dp</item>
-        <item name="android:layout_marginRight">16dp</item>
-        <item name="android:layout_marginBottom">16dp</item>
-        <item name="android:layout_marginLeft">16dp</item>
+        <item name="android:layout_marginTop">12dp</item>
+        <item name="android:layout_marginRight">32dp</item>
+        <item name="android:layout_marginBottom">12dp</item>
+        <item name="android:layout_marginLeft">32dp</item>
         <item name="android:background">@drawable/keypad_default_background</item>
         <item name="android:focusable">true</item>
     </style>
 
-    <style name="DialpadPrimaryButton">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">150dp</item>
-        <item name="android:layout_marginBottom">180dp</item>
-        <item name="android:scaleType">center</item>
+    <style name="TextAppearance.DialNumber" parent="android:style/TextAppearance">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textSize">32sp</item>
+    </style>
+
+    <style name="SubheaderText" parent="android:style/TextAppearance">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textSize">24sp</item>
+        <item name="android:textFontWeight">500</item>
+        <item name="android:textStyle">normal</item>
+    </style>
+
+    <style name="AddFavoriteText">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+    </style>
+
+    <!-- Call history -->
+    <style name="TextAppearance.CallLogTitleDefault" parent="TextAppearance.Body1">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+    </style>
+    <!-- Customized text color for missed calls can be added here -->
+    <style name="TextAppearance.CallLogTitleMissedCall" parent="TextAppearance.Body1">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+    </style>
+
+    <style name="DialpadSecondaryButton">
+        <item name="android:background">@drawable/dialer_ripple_background</item>
+        <item name="android:scaleType">centerInside</item>
+        <item name="android:tint">?android:attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.DialpadDisplayName" parent="TextAppearance.Body1"/>
+
+    <style name="TextAppearance.ContactResultTitle" parent="TextAppearance.Body1">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.TypeDownListSpan" parent="TextAppearance.Body3">
+        <item name="android:textSize">32sp</item>
+        <item name="android:textColor">#29cb86</item>
     </style>
 </resources>
diff --git a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml
index a404157..b75bc81 100644
--- a/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml
+++ b/car_product/car_ui_portrait/rro/CarUiPortraitDialerRRO/res/xml/overlays.xml
@@ -15,9 +15,40 @@
   ~ limitations under the License.
   -->
 <overlay>
-    <item target="style/KeypadButtonStyle" value="@style/KeypadButtonStyle"/>
-    <item target="style/DialpadPrimaryButton" value="@style/DialpadPrimaryButton"/>
-
     <item target="drawable/ic_phone" value="@drawable/ic_phone"/>
     <item target="drawable/icon_call_button" value="@drawable/icon_call_button"/>
+    <item target="drawable/ic_backspace" value="@drawable/ic_backspace"/>
+    <item target="drawable/dialer_ripple_background" value="@drawable/dialer_ripple_background"/>
+    <item target="drawable/restricted_dialing_mode_label_background" value="@drawable/restricted_dialing_mode_label_background"/>
+    <item target="drawable/ic_arrow_right" value="@drawable/ic_arrow_right"/>
+
+    <item target="id/dialpad_fragment" value="@id/dialpad_fragment" />
+    <item target="id/call_button" value="@id/call_button" />
+    <item target="id/title" value="@id/title" />
+    <item target="id/delete_button" value="@id/delete_button" />
+    <item target="id/display_name" value="@id/display_name" />
+    <item target="id/label" value="@id/label" />
+    <item target="id/dialpad_contact_avatar" value="@id/dialpad_contact_avatar" />
+    <item target="id/dialpad_contact_initials" value="@id/dialpad_contact_initials" />
+    <item target="id/list_view" value="@id/list_view" />
+    <item target="id/restricted_dialing_mode_label" value="@id/restricted_dialing_mode_label" />
+    <item target="id/contact_picture" value="@id/contact_picture" />
+    <item target="id/contact_result" value="@id/contact_result" />
+    <item target="id/contact_name" value="@id/contact_name" />
+    <item target="id/phone_number" value="@id/phone_number" />
+
+    <item target="layout/dialpad_fragment_with_type_down" value="@layout/dialpad_fragment_with_type_down"/>
+    <item target="layout/dialpad_user_profile" value="@layout/dialpad_user_profile"/>
+    <item target="layout/type_down_list_item" value="@layout/type_down_list_item"/>
+    <item target="layout/restricted_dialing_mode_label" value="@layout/restricted_dialing_mode_label"/>
+
+    <item target="style/KeypadButtonStyle" value="@style/KeypadButtonStyle"/>
+    <item target="style/TextAppearance.DialNumber" value="@style/TextAppearance.DialNumber"/>
+    <item target="style/SubheaderText" value="@style/SubheaderText"/>
+    <item target="style/AddFavoriteText" value="@style/AddFavoriteText"/>
+    <item target="style/TextAppearance.CallLogTitleDefault" value="@style/TextAppearance.CallLogTitleDefault"/>
+    <item target="style/TextAppearance.DialpadDisplayName" value="@style/TextAppearance.DialpadDisplayName"/>
+    <item target="style/TextAppearance.ContactResultTitle" value="@style/TextAppearance.ContactResultTitle"/>
+    <item target="style/TextAppearance.TypeDownListSpan" value="@style/TextAppearance.TypeDownListSpan"/>
+
 </overlay>
diff --git a/car_product/car_ui_portrait/rro/android/res/values/colors_device_default.xml b/car_product/car_ui_portrait/rro/android/res/values/colors_device_default.xml
index e9c768b..6258766 100644
--- a/car_product/car_ui_portrait/rro/android/res/values/colors_device_default.xml
+++ b/car_product/car_ui_portrait/rro/android/res/values/colors_device_default.xml
@@ -63,8 +63,8 @@
     <color name="surface_highlight_light">@*android:color/system_neutral1_1000</color>
 
     <!-- Please refer to text_color_[primary]_device_default_[light].xml for text colors-->
-    <color name="foreground_device_default_light">@*android:color/text_color_primary_device_default_dark</color>
-    <color name="foreground_device_default_dark">@*android:color/text_color_primary_device_default_light</color>
+    <color name="foreground_device_default_light">@*android:color/text_color_primary_device_default_light</color>
+    <color name="foreground_device_default_dark">@*android:color/text_color_primary_device_default_dark</color>
 
     <color name="list_divider_color_light">@*android:color/system_neutral1_700</color>
     <color name="list_divider_color_dark">@*android:color/system_neutral1_200</color>
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml
index 0162e5b..ffbeb18 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/drawable/tab_background.xml
@@ -17,7 +17,7 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_activated="true">
         <shape android:shape="rectangle">
-            <solid android:color="#2E3134"/>
+            <solid android:color="@color/tab_background_color"/>
         </shape>
     </item>
     <item android:state_activated="false">
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
index 39d910c..02a7320 100644
--- a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/layout/car_ui_base_layout_toolbar.xml
@@ -75,7 +75,7 @@
                     android:layout_gravity="center"
                     android:scaleType="fitXY"
                     android:background="@drawable/car_ui_toolbar_menu_item_icon_ripple"
-                    android:tint="@color/car_ui_text_color_primary"/>
+                    android:tint="?android:attr/textColorPrimary"/>
 
                 <ImageView
                     android:id="@+id/car_ui_toolbar_logo"
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values-night/colors.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values-night/colors.xml
new file mode 100644
index 0000000..9134d34
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values-night/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <color name="tab_background_color">#282A2D</color>
+</resources>
diff --git a/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values/colors.xml b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values/colors.xml
new file mode 100644
index 0000000..fca1ab1
--- /dev/null
+++ b/car_product/car_ui_portrait/rro/car-ui-toolbar-customizations/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <color name="tab_background_color">#E8EAED</color>
+</resources>
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/config.xml b/car_product/overlay/frameworks/base/core/res/res/values/config.xml
index a1b0cd2..73326f1 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values/config.xml
@@ -156,4 +156,10 @@
      This flag should be enabled only when the product does not have any UI to toggle airplane
      mode like automotive devices.-->
     <bool name="config_autoResetAirplaneMode">true</bool>
+
+    <!-- The component name of the activity for the companion-device-manager notification access
+         confirmation. -->
+    <string name="config_notificationAccessConfirmationActivity" translatable="false">
+        com.android.car.settings/com.android.car.settings.notifications.NotificationAccessConfirmationActivity
+    </string>
 </resources>
diff --git a/cpp/libsysfsmonitor/Android.bp b/cpp/libsysfsmonitor/Android.bp
new file mode 100644
index 0000000..545255b
--- /dev/null
+++ b/cpp/libsysfsmonitor/Android.bp
@@ -0,0 +1,60 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "libsysfsmonitor_defaults",
+    cflags: [
+        "-Wall",
+        "-Wno-missing-field-initializers",
+        "-Werror",
+        "-Wno-unused-variable",
+        "-Wunused-parameter",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libutils",
+    ],
+}
+
+cc_library {
+    name: "libsysfsmonitor",
+    srcs: [
+        "src/SysfsMonitor.cpp",
+    ],
+    defaults: [
+        "libsysfsmonitor_defaults",
+    ],
+    export_include_dirs: [
+        "src",
+    ],
+}
+
+cc_test {
+    name: "libsysfsmonitor_test",
+    srcs: [
+        "tests/SysfsMonitorTest.cpp",
+    ],
+    defaults: [
+        "libsysfsmonitor_defaults",
+    ],
+    static_libs: [
+        "libgtest",
+        "libsysfsmonitor",
+    ],
+}
diff --git a/cpp/libsysfsmonitor/src/SysfsMonitor.cpp b/cpp/libsysfsmonitor/src/SysfsMonitor.cpp
new file mode 100644
index 0000000..ee89ec0
--- /dev/null
+++ b/cpp/libsysfsmonitor/src/SysfsMonitor.cpp
@@ -0,0 +1,135 @@
+/**
+ * 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.
+ */
+
+#define LOG_TAG "libsysfsmonitor"
+#define DEBUG false
+
+#include "SysfsMonitor.h"
+
+#include <android-base/stringprintf.h>
+#include <log/log.h>
+
+#include <sys/epoll.h>
+
+namespace {
+
+using ::android::base::Error;
+using ::android::base::Result;
+using ::android::base::StringPrintf;
+
+// The maximum number of sysfs files to monitor.
+constexpr int32_t EPOLL_MAX_EVENTS = 10;
+
+}  // namespace
+
+namespace android {
+namespace automotive {
+
+Result<void> SysfsMonitor::init(CallbackFunc callback) {
+    if (mEpollFd >= 0) {
+        return Error() << "Epoll instance was already created";
+    }
+    if (mEpollFd.reset(epoll_create1(EPOLL_CLOEXEC)); mEpollFd < 0) {
+        return Error() << "Cannot create epoll instance: errno = " << errno;
+    }
+    mCallback = callback;
+    return {};
+}
+
+Result<void> SysfsMonitor::release() {
+    if (mEpollFd < 0) {
+        return Error() << "Epoll instance wasn't created";
+    }
+    for (const int32_t fd : mMonitoringFds) {
+        if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, /*event=*/nullptr)) {
+            ALOGW("Failed to deregister fd(%d) from epoll instance: errno = %d", fd, errno);
+        }
+    }
+    mMonitoringFds.clear();
+    mEpollFd.reset();
+    mCallback = nullptr;
+    return {};
+}
+
+Result<void> SysfsMonitor::registerFd(int32_t fd) {
+    if (fd < 0) {
+        return Error() << StringPrintf("fd(%d) is invalid", fd);
+    }
+    if (mMonitoringFds.count(fd) > 0) {
+        return Error() << StringPrintf("fd(%d) is already being monitored", fd);
+    }
+    if (mMonitoringFds.size() == EPOLL_MAX_EVENTS) {
+        return Error() << "Cannot monitor more than " << EPOLL_MAX_EVENTS << " sysfs files";
+    }
+    struct epoll_event eventItem = {};
+    eventItem.events = EPOLLIN | EPOLLPRI | EPOLLET;
+    eventItem.data.fd = fd;
+    if (int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem); result != 0) {
+        return Error() << StringPrintf("Failed to add fd(%d) to epoll instance: errno = %d", fd,
+                                       errno);
+    }
+    mMonitoringFds.insert(fd);
+    return {};
+}
+
+Result<void> SysfsMonitor::unregisterFd(int32_t fd) {
+    if (fd < 0) {
+        return Error() << StringPrintf("fd(%d) is invalid", fd);
+    }
+    if (mMonitoringFds.count(fd) == 0) {
+        return Error() << StringPrintf("fd(%d) is not being monitored", fd);
+    }
+    // Even when epoll_ctl() fails, we proceed to handle the request.
+    if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, /*event=*/nullptr)) {
+        ALOGW("Failed to deregister fd(%d) from epoll instance: errno = %d", fd, errno);
+    }
+    mMonitoringFds.erase(fd);
+    return {};
+}
+
+Result<void> SysfsMonitor::observe() {
+    if (mEpollFd < 0) {
+        return Error() << "Epoll instance is not initialized";
+    }
+
+    struct epoll_event events[EPOLL_MAX_EVENTS];
+    while (true) {
+        int pollResult = epoll_wait(mEpollFd, events, EPOLL_MAX_EVENTS, /*timeout=*/-1);
+        if (pollResult < 0) {
+            ALOGW("Polling sysfs failed, but continue polling: errno = %d", errno);
+            continue;
+        }
+        std::vector<int32_t> fds;
+        for (int i = 0; i < pollResult; i++) {
+            int fd = events[i].data.fd;
+            if (mMonitoringFds.count(fd) == 0) {
+                continue;
+            }
+            if (events[i].events & EPOLLIN) {
+                fds.push_back(fd);
+            } else if (events[i].events & EPOLLERR) {
+                ALOGW("An error occurred when polling fd(%d)", fd);
+            }
+        }
+        if (mCallback && fds.size() > 0) {
+            mCallback(fds);
+        }
+    }
+    return {};
+}
+
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/libsysfsmonitor/src/SysfsMonitor.h b/cpp/libsysfsmonitor/src/SysfsMonitor.h
new file mode 100644
index 0000000..f941041
--- /dev/null
+++ b/cpp/libsysfsmonitor/src/SysfsMonitor.h
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+#ifndef CPP_LIBSYSFSMONITOR_SRC_SYSFSMONITOR_H_
+#define CPP_LIBSYSFSMONITOR_SRC_SYSFSMONITOR_H_
+
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+#include <utils/RefBase.h>
+
+#include <functional>
+#include <string>
+#include <unordered_set>
+
+namespace android {
+namespace automotive {
+
+using CallbackFunc = ::std::function<void(const std::vector<int32_t>&)>;
+
+/**
+ * SysfsMonitor monitors sysfs file changes and invokes the registered callback when there is a
+ * change at the sysfs files to monitor.
+ */
+class SysfsMonitor final : public RefBase {
+public:
+    // Initializes SysfsMonitor instance.
+    android::base::Result<void> init(CallbackFunc callback);
+    // Releases resources used for monitoring.
+    android::base::Result<void> release();
+    // Registers a sysfs file to monitor.
+    android::base::Result<void> registerFd(int32_t fd);
+    // Unregisters a sysfs file to monitor.
+    android::base::Result<void> unregisterFd(int32_t fd);
+    // Starts observing sysfs file changes.
+    android::base::Result<void> observe();
+
+private:
+    android::base::unique_fd mEpollFd;
+    std::unordered_set<int32_t> mMonitoringFds;
+    CallbackFunc mCallback;
+};
+
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_LIBSYSFSMONITOR_SRC_SYSFSMONITOR_H_
diff --git a/cpp/libsysfsmonitor/tests/SysfsMonitorTest.cpp b/cpp/libsysfsmonitor/tests/SysfsMonitorTest.cpp
new file mode 100644
index 0000000..f6dda6c
--- /dev/null
+++ b/cpp/libsysfsmonitor/tests/SysfsMonitorTest.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+#include "SysfsMonitor.h"
+
+#include <gtest/gtest.h>
+#include <utils/StrongPointer.h>
+
+#include <sys/socket.h>
+
+#include <vector>
+
+namespace android {
+namespace automotive {
+
+class SysfsMonitorTest : public ::testing::Test {
+public:
+    void SetUp() override { mSysfsMonitor = sp<SysfsMonitor>::make(); }
+    void TearDown() override { mSysfsMonitor = nullptr; }
+
+protected:
+    sp<SysfsMonitor> mSysfsMonitor;
+};
+
+TEST_F(SysfsMonitorTest, TestDuplicateInitialize) {
+    auto ret = mSysfsMonitor->init([](const std::vector<int32_t>&) {});
+    ASSERT_TRUE(ret.ok()) << "First initialization should be successful: " << ret.error().message();
+    ASSERT_FALSE(mSysfsMonitor->init([](const std::vector<int32_t>&) {}).ok())
+            << "Initialization cannot be done twice";
+}
+
+TEST_F(SysfsMonitorTest, TestDuplicateRelease) {
+    auto ret = mSysfsMonitor->init([](const std::vector<int32_t>&) {});
+    ASSERT_TRUE(ret.ok()) << "First initialization should be successful: " << ret.error().message();
+    ret = mSysfsMonitor->release();
+    ASSERT_TRUE(ret.ok()) << "Releasing the initialized instance should be successful: "
+                          << ret.error().message();
+    ASSERT_FALSE(mSysfsMonitor->release().ok()) << "Released instance cannot be released";
+}
+
+TEST_F(SysfsMonitorTest, TestNoInitRelease) {
+    ASSERT_FALSE(mSysfsMonitor->release().ok()) << "Uninitailized instance cannot be released";
+}
+
+TEST_F(SysfsMonitorTest, TestUnregisterNotRegisteredFd) {
+    // A regular file cannot be registered to epoll instance. So, the test is using a socket file.
+    int32_t fd = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
+    mSysfsMonitor->init([](const std::vector<int32_t>&) {});
+
+    ASSERT_FALSE(mSysfsMonitor->unregisterFd(fd).ok())
+            << "Unregistered file description cannot be unregistered";
+    close(fd);
+}
+
+TEST_F(SysfsMonitorTest, TestDuplicateRegister) {
+    int32_t fd = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
+    mSysfsMonitor->init([](const std::vector<int32_t>&) {});
+
+    auto ret = mSysfsMonitor->registerFd(fd);
+    ASSERT_TRUE(ret.ok()) << "Registering a file descriptor first time should be successful: "
+                          << ret.error().message();
+    ASSERT_FALSE(mSysfsMonitor->registerFd(fd).ok())
+            << "Registering a file descriptor twice cannot be done";
+    close(fd);
+}
+
+TEST_F(SysfsMonitorTest, TestDuplicateUnregister) {
+    int32_t fd = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
+    mSysfsMonitor->init([](const std::vector<int32_t>&) {});
+
+    auto ret = mSysfsMonitor->registerFd(fd);
+    ASSERT_TRUE(ret.ok()) << "Registering a file descriptor first time should be successful: "
+                          << ret.error().message();
+    ret = mSysfsMonitor->unregisterFd(fd);
+    ASSERT_TRUE(ret.ok()) << "The registered file descriptor should be unregistered: "
+                          << ret.error().message();
+    ASSERT_FALSE(mSysfsMonitor->unregisterFd(fd).ok())
+            << "Unregistering the unregistered file descriptor cannot be done";
+    close(fd);
+}
+
+TEST_F(SysfsMonitorTest, TestRegisterInvalidFd) {
+    const int32_t invalidFd = -1;
+    ASSERT_FALSE(mSysfsMonitor->registerFd(invalidFd).ok())
+            << "fd(-1) cannot be registered to SysfsMonitor";
+}
+
+TEST_F(SysfsMonitorTest, TestUnregisterInvalidFd) {
+    const int32_t invalidFd = -1;
+    ASSERT_FALSE(mSysfsMonitor->unregisterFd(invalidFd).ok())
+            << "fd(-1) cannot be given to unregisterFd";
+}
+
+TEST_F(SysfsMonitorTest, TestRegisterMultipleFds) {
+    const int32_t maxFdCount = 10;
+    int32_t fdsToMonitor[maxFdCount + 1];
+
+    mSysfsMonitor->init([](const std::vector<int32_t>&) {});
+    for (int i = 0; i < maxFdCount; i++) {
+        fdsToMonitor[i] = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
+        auto ret = mSysfsMonitor->registerFd(fdsToMonitor[i]);
+        ASSERT_TRUE(ret.ok()) << "Registering a file descriptor first time should be successful: "
+                              << ret.error().message();
+    }
+    fdsToMonitor[maxFdCount] = socket(AF_UNIX, SOCK_DGRAM, /*protocol=*/0);
+    ASSERT_FALSE(mSysfsMonitor->registerFd(fdsToMonitor[maxFdCount]).ok())
+            << "Registering more than " << maxFdCount << " files cannot be done";
+
+    mSysfsMonitor->release();
+    for (int i = 0; i <= maxFdCount; i++) {
+        close(fdsToMonitor[i]);
+    }
+}
+
+TEST_F(SysfsMonitorTest, TestObserveWithoutInitialization) {
+    ASSERT_FALSE(mSysfsMonitor->observe().ok()) << "Uninitialized instance cannot observe";
+}
+
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/powerpolicy/server/Android.bp b/cpp/powerpolicy/server/Android.bp
index 094a3f5..2dd40bd 100644
--- a/cpp/powerpolicy/server/Android.bp
+++ b/cpp/powerpolicy/server/Android.bp
@@ -36,6 +36,9 @@
         "libtinyxml2",
         "libutils",
     ],
+    static_libs: [
+        "libsysfsmonitor",
+    ],
 }
 
 cc_library {
diff --git a/cpp/powerpolicy/server/src/SilentModeHandler.cpp b/cpp/powerpolicy/server/src/SilentModeHandler.cpp
index c57b6fa..79d78be 100644
--- a/cpp/powerpolicy/server/src/SilentModeHandler.cpp
+++ b/cpp/powerpolicy/server/src/SilentModeHandler.cpp
@@ -25,7 +25,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 
-#include <sys/inotify.h>
+#include <sys/epoll.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
@@ -35,6 +35,7 @@
 namespace powerpolicy {
 
 using ::android::Mutex;
+using ::android::automotive::SysfsMonitor;
 using ::android::base::Error;
 using ::android::base::GetProperty;
 using ::android::base::ReadFileToString;
@@ -49,12 +50,11 @@
 
 constexpr const char kPropertySystemBootReason[] = "sys.boot.reason";
 constexpr const char kSilentModeHwStateFilename[] = "/sys/power/pm_silentmode_hw_state";
-constexpr const char kKernelSilentModeFilename[] = "/sys/power/pm_silentmode_kernel";
+constexpr const char kKernelSilentModeFilename[] = "/sys/power/pm_silentmode_kernel_state";
 // To prevent boot animation from being started.
 constexpr const char kPropertyNoBootAnimation[] = "debug.sf.nobootanimation";
 // To stop boot animation while it is being played.
 constexpr const char kPropertyBootAnimationExit[] = "service.bootanim.exit";
-constexpr int kEventBufferSize = 512;
 
 bool fileExists(const char* filename) {
     struct stat buffer;
@@ -68,7 +68,7 @@
       mSilentModeHwStateFilename(kSilentModeHwStateFilename),
       mKernelSilentModeFilename(kKernelSilentModeFilename),
       mSilentModeChangeHandler(handler),
-      mFdInotify(-1) {
+      mSysfsMonitor(sp<SysfsMonitor>::make()) {
     mBootReason = GetProperty(kPropertySystemBootReason, "");
 }
 
@@ -83,7 +83,7 @@
     if (mForcedMode) {
         handleSilentModeChange(mSilentModeByHwState);
         mSilentModeChangeHandler->notifySilentModeChange(mSilentModeByHwState);
-        ALOGI("Now in forced mode: monitoring %s is disabled", kSilentModeHwStateFilename);
+        ALOGI("Now in forced mode: monitoring %s is disabled", mSilentModeHwStateFilename.c_str());
     } else {
         startMonitoringSilentModeHwState();
     }
@@ -101,13 +101,15 @@
 void SilentModeHandler::stopMonitoringSilentModeHwState(bool shouldWaitThread) {
     if (mIsMonitoring) {
         mIsMonitoring = false;
-        inotify_rm_watch(mFdInotify, mWdSilentModeHwState);
-        mWdSilentModeHwState = -1;
+        if (auto ret = mSysfsMonitor->unregisterFd(mFdSilentModeHwState.get()); !ret.ok()) {
+            ALOGW("Unregistering %s from SysfsMonitor failed", mSilentModeHwStateFilename.c_str());
+        }
         if (shouldWaitThread && mSilentModeMonitoringThread.joinable()) {
             mSilentModeMonitoringThread.join();
         }
     }
-    mFdInotify.reset(-1);
+    mFdSilentModeHwState.reset();
+    mSysfsMonitor->release();
 }
 
 Result<void> SilentModeHandler::dump(int fd, const Vector<String16>& /*args*/) {
@@ -132,56 +134,38 @@
         ALOGW("Silent Mode monitoring is already started");
         return;
     }
-    if (mFdInotify < 0) {
-        mFdInotify.reset(inotify_init1(IN_CLOEXEC));
-        if (mFdInotify < 0) {
-            ALOGE("Failed to start monitoring Silent Mode HW state: creating inotify instance "
-                  "failed (errno = %d)",
-                  errno);
-            return;
-        }
-    }
     const char* filename = mSilentModeHwStateFilename.c_str();
     if (!fileExists(filename)) {
         ALOGW("Failed to start monitoring Silent Mode HW state: %s doesn't exist", filename);
-        mFdInotify.reset(-1);
         return;
     }
-    // TODO(b/178843534): Additional masks might be needed to detect sysfs change.
-    const uint32_t masks = IN_MODIFY;
-    mWdSilentModeHwState = inotify_add_watch(mFdInotify, filename, masks);
+    if (mFdSilentModeHwState == -1) {
+        if (mFdSilentModeHwState.reset(open(filename, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
+            mFdSilentModeHwState == -1) {
+            ALOGW("Failed to open %s for monitoring: errno = %d", filename, errno);
+            return;
+        }
+    }
+    auto ret = mSysfsMonitor->init([this](const std::vector<int32_t>& fileDescriptors) {
+        // Only one sysfs file is registered.
+        if (mFdSilentModeHwState != fileDescriptors[0]) {
+            return;
+        }
+        handleSilentModeHwStateChange();
+    });
+    if (!ret.ok()) {
+        ALOGW("Failed to initialize SysfsMonitor: %s", ret.error().message().c_str());
+        return;
+    }
+    if (auto ret = mSysfsMonitor->registerFd(mFdSilentModeHwState.get()); !ret.ok()) {
+        ALOGW("Failed to register %s to SysfsMonitor: %s", filename, ret.error().message().c_str());
+        return;
+    }
     mIsMonitoring = true;
-    mSilentModeMonitoringThread = std::thread([this]() {
-        char eventBuf[kEventBufferSize];
-        struct inotify_event* event;
-        constexpr size_t inotifyEventSize = sizeof(*event);
-        ALOGI("Monitoring %s started", mSilentModeHwStateFilename.c_str());
-        while (mIsMonitoring) {
-            int eventPos = 0;
-            int numBytes = read(mFdInotify, eventBuf, sizeof(eventBuf));
-            if (numBytes < static_cast<int>(inotifyEventSize)) {
-                if (errno == EINTR) {
-                    ALOGW("System call interrupted. Wait for inotify event again.");
-                    continue;
-                }
-                mIsMonitoring = false;
-                inotify_rm_watch(mFdInotify, mWdSilentModeHwState);
-                mWdSilentModeHwState = -1;
-                mFdInotify.reset(-1);
-                ALOGW("Failed to wait for change at %s (errno = %d)",
-                      mSilentModeHwStateFilename.c_str(), errno);
-                return;
-            }
-            while (numBytes >= static_cast<int>(inotifyEventSize)) {
-                int eventSize;
-                event = (struct inotify_event*)(eventBuf + eventPos);
-                if (event->wd == mWdSilentModeHwState && (event->mask & masks)) {
-                    handleSilentModeHwStateChange();
-                }
-                eventSize = inotifyEventSize + event->len;
-                numBytes -= eventSize;
-                eventPos += eventSize;
-            }
+    mSilentModeMonitoringThread = std::thread([this, filename]() {
+        if (auto ret = mSysfsMonitor->observe(); !ret.ok()) {
+            ALOGI("Failed to observe %s", filename);
+            return;
         }
         ALOGI("Monitoring %s ended", mSilentModeHwStateFilename.c_str());
     });
diff --git a/cpp/powerpolicy/server/src/SilentModeHandler.h b/cpp/powerpolicy/server/src/SilentModeHandler.h
index 9fae109..96074f8 100644
--- a/cpp/powerpolicy/server/src/SilentModeHandler.h
+++ b/cpp/powerpolicy/server/src/SilentModeHandler.h
@@ -21,8 +21,11 @@
 #include <android-base/unique_fd.h>
 #include <utils/Mutex.h>
 #include <utils/String16.h>
+#include <utils/StrongPointer.h>
 #include <utils/Vector.h>
 
+#include <SysfsMonitor.h>
+
 #include <atomic>
 #include <thread>  // NOLINT(build/c++11)
 
@@ -47,8 +50,8 @@
 
 /**
  * SilentModeHandler monitors {@code /sys/power/pm_silentmode_hw_state} in sysfs to detect Silent
- * Mode change by a vehicle processor. Also, it updates {@code /sys/power/pm_silentmode_kernel} in
- * sysfs to tell kernel the current Silent Mode.
+ * Mode change by a vehicle processor. Also, it updates
+ * {@code /sys/power/pm_silentmode_kernel_state} in sysfs to tell kernel the current Silent Mode.
  */
 class SilentModeHandler final {
 public:
@@ -80,9 +83,9 @@
     std::string mKernelSilentModeFilename;
     ISilentModeChangeHandler* mSilentModeChangeHandler;
     std::thread mSilentModeMonitoringThread;
-    android::base::unique_fd mFdInotify;
-    int mWdSilentModeHwState = -1;
     std::atomic_bool mIsMonitoring = false;
+    android::sp<android::automotive::SysfsMonitor> mSysfsMonitor;
+    android::base::unique_fd mFdSilentModeHwState;
 
     // For unit tests.
     friend class internal::SilentModeHandlerPeer;
diff --git a/cpp/powerpolicy/server/tests/SilentModeHandlerTest.cpp b/cpp/powerpolicy/server/tests/SilentModeHandlerTest.cpp
index 1eaec81..6548cf1 100644
--- a/cpp/powerpolicy/server/tests/SilentModeHandlerTest.cpp
+++ b/cpp/powerpolicy/server/tests/SilentModeHandlerTest.cpp
@@ -46,20 +46,6 @@
 constexpr int kMaxPollingAttempts = 5;
 constexpr std::chrono::microseconds kPollingDelayUs = 50ms;
 
-bool waitForSilentMode(SilentModeHandler* handler, bool expectedSilentMode) {
-    int count = 0;
-    while (true) {
-        if (handler->isSilentMode() == expectedSilentMode) {
-            return true;
-        }
-        if (count++; count == kMaxPollingAttempts) {
-            break;
-        }
-        usleep(kPollingDelayUs.count());
-    }
-    return false;
-}
-
 }  // namespace
 
 namespace internal {
@@ -124,23 +110,6 @@
     sp<MockCarPowerPolicyServer> carPowerPolicyServer;
 };
 
-TEST_F(SilentModeHandlerTest, TestSilentModeHwStateMonitoring) {
-    SilentModeHandler handler(carPowerPolicyServer.get());
-    internal::SilentModeHandlerPeer handlerPeer(&handler);
-    handlerPeer.injectBootReason(kBootReasonNormal);
-    handlerPeer.init();
-
-    handlerPeer.updateSilentModeHwState(/*isSilent=*/true);
-
-    ASSERT_TRUE(waitForSilentMode(&handler, /*expectedSilentMode=*/true))
-            << "It should be silent mode when HW state is on";
-
-    handlerPeer.updateSilentModeHwState(/*isSilent=*/false);
-
-    ASSERT_TRUE(waitForSilentMode(&handler, /*expectedSilentMode=*/false))
-            << "It should be non-silent mode when HW state is off";
-}
-
 TEST_F(SilentModeHandlerTest, TestRebootForForcedSilentMode) {
     SilentModeHandler handler(carPowerPolicyServer.get());
     internal::SilentModeHandlerPeer handlerPeer(&handler);
diff --git a/service/src/com/android/car/power/SilentModeHandler.java b/service/src/com/android/car/power/SilentModeHandler.java
index 2631c01..bb78810 100644
--- a/service/src/com/android/car/power/SilentModeHandler.java
+++ b/service/src/com/android/car/power/SilentModeHandler.java
@@ -39,9 +39,9 @@
  * Class to handle Silent Mode and Non-Silent Mode.
  *
  * <p>This monitors {@code /sys/power/pm_silentmode_hw_state} to figure out when to switch to Silent
- * Mode and updates {@code /sys/power/pm_silentmode_kernel} to tell early-init services about Silent
- * Mode change. Also, it handles forced Silent Mode for testing purpose, which is given through
- * reboot reason.
+ * Mode and updates {@code /sys/power/pm_silentmode_kernel_state} to tell early-init services about
+ * Silent Mode change. Also, it handles forced Silent Mode for testing purpose, which is given
+ * through reboot reason.
  */
 final class SilentModeHandler {
     static final String SILENT_MODE_FORCED_SILENT = "forced-silent";
@@ -53,7 +53,7 @@
     private static final String SYSFS_FILENAME_HW_STATE_MONITORING =
             "/sys/power/pm_silentmode_hw_state";
     private static final String SYSFS_FILENAME_KERNEL_SILENTMODE =
-            "/sys/power/pm_silentmode_kernel";
+            "/sys/power/pm_silentmode_kernel_state";
     private static final String VALUE_SILENT_MODE = "1";
     private static final String VALUE_NON_SILENT_MODE = "0";
     private static final String SYSTEM_BOOT_REASON = "sys.boot.reason";
diff --git a/service/src/com/android/car/watchdog/PackageInfoHandler.java b/service/src/com/android/car/watchdog/PackageInfoHandler.java
index 5ee811d..e3f4bb8 100644
--- a/service/src/com/android/car/watchdog/PackageInfoHandler.java
+++ b/service/src/com/android/car/watchdog/PackageInfoHandler.java
@@ -292,4 +292,10 @@
         }
         return ComponentType.THIRD_PARTY;
     }
+
+    void setVendorPackagePrefixes(List<String> vendorPackagePrefixes) {
+        synchronized (mLock) {
+            mVendorPackagePrefixes = vendorPackagePrefixes;
+        }
+    }
 }
diff --git a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
index fee73b9..e83288b 100644
--- a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
+++ b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
@@ -797,6 +797,8 @@
                         break;
                     case ComponentType.VENDOR:
                         mSafeToKillVendorPackages.addAll(internalConfigs.get(i).safeToKillPackages);
+                        mPackageInfoHandler.setVendorPackagePrefixes(
+                                internalConfigs.get(i).vendorPackagePrefixes);
                         break;
                     default:
                         // All third-party apps are killable.
@@ -804,7 +806,7 @@
                 }
             }
             if (DEBUG) {
-                Slogf.d(TAG, "Fetched and synced safe to kill packages.");
+                Slogf.d(TAG, "Fetched and synced resource overuse configs.");
             }
         }
     }
@@ -1705,12 +1707,14 @@
     }
     /** Defines I/O usage fields for a package. */
     public static final class PackageIoUsage {
+        private static final android.automotive.watchdog.PerStateBytes DEFAULT_PER_STATE_BYTES =
+                new android.automotive.watchdog.PerStateBytes();
         private android.automotive.watchdog.IoOveruseStats mIoOveruseStats;
         private android.automotive.watchdog.PerStateBytes mForgivenWriteBytes;
         private int mTotalTimesKilled;
 
         private PackageIoUsage() {
-            mForgivenWriteBytes = new android.automotive.watchdog.PerStateBytes();
+            mForgivenWriteBytes = DEFAULT_PER_STATE_BYTES;
             mTotalTimesKilled = 0;
         }
 
@@ -1777,7 +1781,7 @@
 
         void resetStats() {
             mIoOveruseStats = null;
-            mForgivenWriteBytes = null;
+            mForgivenWriteBytes = DEFAULT_PER_STATE_BYTES;
             mTotalTimesKilled = 0;
         }
     }
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
index f97965e..a3914d7 100644
--- a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
@@ -1211,10 +1211,6 @@
     @Test
     public void testGetPackageKillableStatesAsUserWithSafeToKillPackages() throws Exception {
         mockUmGetAliveUsers(mMockUserManager, 11, 12);
-        List<android.automotive.watchdog.internal.ResourceOveruseConfiguration> configs =
-                sampleInternalResourceOveruseConfigurations();
-        injectResourceOveruseConfigsAndWait(configs);
-
         injectPackageInfos(Arrays.asList(
                 constructPackageManagerPackageInfo("system_package.non_critical.A", 1102459, null),
                 constructPackageManagerPackageInfo("third_party_package", 1103456, null),
@@ -1223,6 +1219,10 @@
                 constructPackageManagerPackageInfo("third_party_package", 1203456, null),
                 constructPackageManagerPackageInfo("vendor_package.critical.B", 1201278, null)));
 
+        List<android.automotive.watchdog.internal.ResourceOveruseConfiguration> configs =
+                sampleInternalResourceOveruseConfigurations();
+        injectResourceOveruseConfigsAndWait(configs);
+
         PackageKillableStateSubject.assertThat(
                 mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL))
                 .containsExactly(
@@ -1241,6 +1241,37 @@
     }
 
     @Test
+    public void testGetPackageKillableStatesAsUserWithVendorPackagePrefixes() throws Exception {
+        mockUmGetAliveUsers(mMockUserManager, 11);
+        /* Package names which start with "system" are constructed as system packages. */
+        injectPackageInfos(Arrays.asList(
+                constructPackageManagerPackageInfo("system_package_as_vendor", 1102459, null)));
+
+        android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
+                new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+        vendorConfig.componentType = ComponentType.VENDOR;
+        vendorConfig.safeToKillPackages = Collections.singletonList("system_package_as_vendor");
+        vendorConfig.vendorPackagePrefixes = Collections.singletonList(
+                "system_package_as_vendor");
+        injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
+
+        List<PackageKillableState> killableStates =
+                mCarWatchdogService.getPackageKillableStatesAsUser(new UserHandle(11));
+
+        /* When CarWatchdogService connects with the watchdog daemon, CarWatchdogService fetches
+         * resource overuse configs from watchdog daemon. The vendor package prefixes in the
+         * configs help identify vendor packages. The safe-to-kill list in the configs helps
+         * identify safe-to-kill vendor packages. |system_package_as_vendor| is a critical system
+         * package by default but with the latest resource overuse configs, this package should be
+         * classified as a safe-to-kill vendor package.
+         */
+        PackageKillableStateSubject.assertThat(killableStates)
+                .containsExactly(
+                        new PackageKillableState("system_package_as_vendor", 11,
+                                PackageKillableState.KILLABLE_STATE_YES));
+    }
+
+    @Test
     public void testGetPackageKillableStatesAsUserWithSharedUids() throws Exception {
         mockUmGetAliveUsers(mMockUserManager, 11, 12);
         injectPackageInfos(Arrays.asList(
@@ -1274,13 +1305,6 @@
     public void testGetPackageKillableStatesAsUserWithSharedUidsAndSafeToKillPackages()
             throws Exception {
         mockUmGetAliveUsers(mMockUserManager, 11);
-        android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
-                new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
-        vendorConfig.componentType = ComponentType.VENDOR;
-        vendorConfig.safeToKillPackages = Collections.singletonList(
-                "vendor_package.non_critical.A");
-        injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
-
         injectPackageInfos(Arrays.asList(
                 constructPackageManagerPackageInfo(
                         "vendor_package.non_critical.A", 1103456, "vendor_shared_package.A"),
@@ -1293,6 +1317,14 @@
                 constructPackageManagerPackageInfo(
                         "third_party_package.D", 1105678, "third_party_shared_package")));
 
+        android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
+                new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+        vendorConfig.componentType = ComponentType.VENDOR;
+        vendorConfig.safeToKillPackages = Collections.singletonList(
+                "vendor_package.non_critical.A");
+        vendorConfig.vendorPackagePrefixes = new ArrayList<>();
+        injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
+
         PackageKillableStateSubject.assertThat(
                 mCarWatchdogService.getPackageKillableStatesAsUser(new UserHandle(11)))
                 .containsExactly(
@@ -1312,13 +1344,6 @@
     public void testGetPackageKillableStatesAsUserWithSharedUidsAndSafeToKillSharedPackage()
             throws Exception {
         mockUmGetAliveUsers(mMockUserManager, 11);
-        android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
-                new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
-        vendorConfig.componentType = ComponentType.VENDOR;
-        vendorConfig.safeToKillPackages = Collections.singletonList(
-                "shared:vendor_shared_package.B");
-        injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
-
         injectPackageInfos(Arrays.asList(
                 constructPackageManagerPackageInfo(
                         "vendor_package.non_critical.A", 1103456, "vendor_shared_package.B"),
@@ -1327,6 +1352,15 @@
                 constructPackageManagerPackageInfo(
                         "vendor_package.non_critical.B", 1103456, "vendor_shared_package.B")));
 
+        android.automotive.watchdog.internal.ResourceOveruseConfiguration vendorConfig =
+                new android.automotive.watchdog.internal.ResourceOveruseConfiguration();
+        vendorConfig.componentType = ComponentType.VENDOR;
+        vendorConfig.safeToKillPackages = Collections.singletonList(
+                "shared:vendor_shared_package.B");
+        vendorConfig.vendorPackagePrefixes = new ArrayList<>();
+        injectResourceOveruseConfigsAndWait(Collections.singletonList(vendorConfig));
+
+
         PackageKillableStateSubject.assertThat(
                 mCarWatchdogService.getPackageKillableStatesAsUser(new UserHandle(11)))
                 .containsExactly(
@@ -2013,6 +2047,37 @@
     }
 
     @Test
+    public void testSaveToStorageAfterResetResourceOveruseStats() throws Exception {
+        setDate(1);
+        mGenericPackageNameByUid.put(1011200, "system_package");
+        SparseArray<PackageIoOveruseStats> stats = injectIoOveruseStatsForPackages(
+                mGenericPackageNameByUid, /* killablePackages= */ new ArraySet<>(),
+                /* shouldNotifyPackages= */ new ArraySet<>());
+
+        mWatchdogServiceForSystemImpl.resetResourceOveruseStats(
+                Collections.singletonList("system_package"));
+
+        /* |resetResourceOveruseStats| sets the package's IoOveruseStats to null, packages with
+         * null I/O stats are not written to disk. Push new IoOveruseStats to the |system_package|
+         * so that the package can be written to the database when date changes.
+         */
+        pushLatestIoOveruseStatsAndWait(Collections.singletonList(stats.get(1011200)));
+
+        /* Force write to disk by changing the date and pushing new I/O overuse stats. */
+        setDate(0);
+        pushLatestIoOveruseStatsAndWait(Collections.singletonList(new PackageIoOveruseStats()));
+
+        WatchdogStorage.IoUsageStatsEntry expectedSavedEntries =
+                new WatchdogStorage.IoUsageStatsEntry(/* userId= */ 10, "system_package",
+                        new WatchdogPerfHandler.PackageIoUsage(stats.get(1011200).ioOveruseStats,
+                                /* forgivenWriteBytes= */ constructPerStateBytes(0, 0, 0),
+                                /* totalTimesKilled= */ 0));
+
+        IoUsageStatsEntrySubject.assertThat(mIoUsageStatsEntries)
+                .containsExactlyElementsIn(Collections.singletonList(expectedSavedEntries));
+    }
+
+    @Test
     public void testGetPackageInfosForUids() throws Exception {
         injectPackageInfos(Arrays.asList(
                 constructPackageManagerPackageInfo(
@@ -2432,6 +2497,11 @@
          */
         crashWatchdogDaemon();
         restartWatchdogDaemonAndAwait();
+
+        /* Method should be invoked 2 times. Once at test setup and once more after the daemon
+         * crashes and reconnects.
+         */
+        verify(mMockCarWatchdogDaemon, times(2)).getResourceOveruseConfigurations();
     }
 
     private SparseArray<PackageIoOveruseStats> injectIoOveruseStatsForPackages(