Merge "Sets Storage Settings progress bar unselectable" into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index cb53a02..ce80fc5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1236,6 +1236,8 @@
                   android:label="@string/application_info_label"
                   android:exported="true">
             <intent-filter android:priority="1">
+                <action android:name="android.settings.APP_OPEN_BY_DEFAULT_SETTINGS" />
+                <!-- Also catch legacy "com." prefixed action. -->
                 <action android:name="com.android.settings.APP_OPEN_BY_DEFAULT_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:scheme="package" />
diff --git a/res/drawable/accessibility_magnification_full_screen.xml b/res/drawable/accessibility_magnification_full_screen.xml
deleted file mode 100644
index 09d1a7e..0000000
--- a/res/drawable/accessibility_magnification_full_screen.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?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:width="77dp"
-    android:height="134dp"
-    android:viewportWidth="77"
-    android:viewportHeight="134">
-  <path
-      android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
-      android:strokeWidth="1.8"
-      android:fillColor="#F2F3F4"
-      android:strokeColor="#DADCE0"/>
-  <group>
-    <clip-path
-        android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
-    <path
-        android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
-        android:fillColor="#ffffff"/>
-    <group>
-      <clip-path
-          android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
-      <path
-          android:pathData="M13,5L65,5A8,8 0,0 1,73 13L73,120A8,8 0,0 1,65 128L13,128A8,8 0,0 1,5 120L5,13A8,8 0,0 1,13 5z"
-          android:strokeLineJoin="bevel"
-          android:strokeWidth="10"
-          android:fillColor="#00000000"
-          android:strokeColor="#F29900"/>
-      <path
-          android:pathData="M51.077,14V18.314H56.612L50,24.958L53.037,28L59.692,21.334V26.921H64V14H51.077Z"
-          android:fillColor="#F29900"/>
-      <path
-          android:pathData="M25.963,104L19.308,110.655V105.077H15V118H27.923V113.692H22.366L29,107.037L25.963,104Z"
-          android:fillColor="#F29900"/>
-    </group>
-  </group>
-</vector>
diff --git a/res/drawable/accessibility_magnification_switch.xml b/res/drawable/accessibility_magnification_switch.xml
deleted file mode 100644
index 21e0cef..0000000
--- a/res/drawable/accessibility_magnification_switch.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?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:width="77dp"
-    android:height="134dp"
-    android:viewportWidth="77"
-    android:viewportHeight="134">
-  <path
-      android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
-      android:strokeWidth="1.8"
-      android:fillColor="#F2F3F4"
-      android:strokeColor="#DADCE0"/>
-  <group>
-    <clip-path
-        android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
-    <path
-        android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
-        android:fillColor="#ffffff"/>
-    <group>
-      <clip-path
-          android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
-      <path
-          android:pathData="M39,94h24v24h-24z"
-          android:fillColor="#000000"
-          android:fillAlpha="0.7"/>
-      <path
-          android:pathData="M51.414,98.138H45.138C44.033,98.138 43.138,99.033 43.138,100.138V112.689C43.138,113.794 44.033,114.689 45.138,114.689H57.69C58.794,114.689 59.69,113.794 59.69,112.689L59.69,106.414H57.69L57.69,112.689L45.138,112.689V100.138H51.414V98.138ZM49.414,108.414H48.448V109.379H49.414V108.414ZM48.448,106.414H46.448V108.414V109.379V111.379H48.448H49.414H51.414V109.379V108.414V106.414H49.414H48.448ZM55.891,103.103L58.035,103.103V104.758L53.069,104.758V99.793L54.724,99.793V101.936L58.275,98.378L59.45,99.553L55.891,103.103Z"
-          android:fillColor="#ffffff"
-          android:fillType="evenOdd"/>
-      <path
-          android:pathData="M13,5L65,5A8,8 0,0 1,73 13L73,120A8,8 0,0 1,65 128L13,128A8,8 0,0 1,5 120L5,13A8,8 0,0 1,13 5z"
-          android:strokeLineJoin="bevel"
-          android:strokeWidth="10"
-          android:fillColor="#00000000"
-          android:strokeColor="#F29900"/>
-    </group>
-  </group>
-</vector>
diff --git a/res/drawable/accessibility_magnification_window_screen.xml b/res/drawable/accessibility_magnification_window_screen.xml
deleted file mode 100644
index d7e164c..0000000
--- a/res/drawable/accessibility_magnification_window_screen.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?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:width="77dp"
-    android:height="134dp"
-    android:viewportWidth="77"
-    android:viewportHeight="134">
-  <path
-      android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
-      android:strokeWidth="1.8"
-      android:fillColor="#F2F3F4"
-      android:strokeColor="#DADCE0"/>
-  <group>
-    <clip-path
-        android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
-    <path
-        android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
-        android:fillColor="#ffffff"/>
-    <group>
-      <clip-path
-          android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
-      <path
-          android:pathData="M15,47L64,47A2,2 0,0 1,66 49L66,84A2,2 0,0 1,64 86L15,86A2,2 0,0 1,13 84L13,49A2,2 0,0 1,15 47z"
-          android:strokeLineJoin="bevel"
-          android:strokeWidth="5"
-          android:fillColor="#00000000"
-          android:strokeColor="#F29900"/>
-      <path
-          android:pathData="M47.077,53V57.314H52.612L46,63.958L49.037,67L55.692,60.334V65.921H60V53H47.077Z"
-          android:fillColor="#F29900"/>
-      <path
-          android:pathData="M29.963,66L23.308,72.655V67.077H19V80H31.923V75.692H26.366L33,69.037L29.963,66Z"
-          android:fillColor="#F29900"/>
-    </group>
-  </group>
-</vector>
diff --git a/res/drawable/ic_emergency_gesture_24dp.xml b/res/drawable/ic_emergency_gesture_24dp.xml
new file mode 100644
index 0000000..ceeacf0
--- /dev/null
+++ b/res/drawable/ic_emergency_gesture_24dp.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ 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="24dp"
+        android:height="24dp"
+        android:tint="?android:attr/colorControlNormal"
+        android:viewportHeight="48"
+        android:viewportWidth="48">
+    <path
+        android:fillColor="#000000"
+        android:fillType="evenOdd"
+        android:pathData="M4,34L5,30H12V26H8C5.79,26 4,24.21 4,22V18C4,15.79 5.79,14 8,14H16L15,18H8V22H12C14.21,22 16,23.79 16,26V30C16,32.21 14.21,34 12,34H4Z" />
+    <path
+        android:fillColor="#000000"
+        android:fillType="evenOdd"
+        android:pathData="M32,34L33,30H40V26H36C33.79,26 32,24.21 32,22V18C32,15.79 33.79,14 36,14H44L43,18H36V22H40C42.21,22 44,23.79 44,26V30C44,32.21 42.21,34 40,34H32Z" />
+    <path
+        android:fillColor="#000000"
+        android:fillType="evenOdd"
+        android:pathData="M22,30H26V18H22V30ZM18,30C18,32.21 19.79,34 22,34H26C28.21,34 30,32.21 30,30V18C30,15.79 28.21,14 26,14H22C19.79,14 18,15.79 18,18V30Z" />
+</vector>
diff --git a/res/drawable/ic_illustration_fullscreen.xml b/res/drawable/ic_illustration_fullscreen.xml
new file mode 100644
index 0000000..fbb62bf
--- /dev/null
+++ b/res/drawable/ic_illustration_fullscreen.xml
@@ -0,0 +1,39 @@
+<?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:width="77dp"
+    android:height="134dp"
+    android:viewportWidth="77"
+    android:viewportHeight="134">
+  <path
+      android:pathData="M69.6,1.1H7.4C3.921,1.1 1.1,3.921 1.1,7.4V126.6C1.1,130.079 3.921,132.9 7.4,132.9H69.6C73.079,132.9 75.9,130.079 75.9,126.6V7.4C75.9,3.921 73.079,1.1 69.6,1.1Z"
+      android:strokeWidth="1.8"
+      android:fillColor="#F2F3F4"
+      android:strokeColor="#DADCE0"/>
+  <path
+      android:pathData="M66.642,5H10.358C7.399,5 5,7.418 5,10.4V123.6C5,126.582 7.399,129 10.358,129H66.642C69.601,129 72,126.582 72,123.6V10.4C72,7.418 69.601,5 66.642,5Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M66,10H11C10.448,10 10,10.448 10,11V123C10,123.552 10.448,124 11,124H66C66.552,124 67,123.552 67,123V11C67,10.448 66.552,10 66,10ZM11,5C7.686,5 5,7.686 5,11V123C5,126.314 7.686,129 11,129H66C69.314,129 72,126.314 72,123V11C72,7.686 69.314,5 66,5H11Z"
+      android:fillColor="#F29900"
+      android:fillType="evenOdd"/>
+  <path
+      android:pathData="M49.077,15V19.314H54.612L48,25.958L51.037,29L57.692,22.334V27.921H62V15H49.077Z"
+      android:fillColor="#F29900"/>
+  <path
+      android:pathData="M25.963,105L19.308,111.655V106.077H15V119H27.923V114.692H22.366L29,108.037L25.963,105Z"
+      android:fillColor="#F29900"/>
+</vector>
diff --git a/res/drawable/ic_illustration_switch.xml b/res/drawable/ic_illustration_switch.xml
new file mode 100644
index 0000000..9d3990b
--- /dev/null
+++ b/res/drawable/ic_illustration_switch.xml
@@ -0,0 +1,46 @@
+<?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:width="77dp"
+    android:height="134dp"
+    android:viewportWidth="77"
+    android:viewportHeight="134">
+  <path
+      android:pathData="M69.6,1.1H7.4C3.921,1.1 1.1,3.921 1.1,7.4V126.6C1.1,130.079 3.921,132.9 7.4,132.9H69.6C73.079,132.9 75.9,130.079 75.9,126.6V7.4C75.9,3.921 73.079,1.1 69.6,1.1Z"
+      android:strokeWidth="1.8"
+      android:fillColor="#F2F3F4"
+      android:strokeColor="#DADCE0"/>
+  <path
+      android:pathData="M66.642,5H10.358C7.399,5 5,7.418 5,10.4V123.6C5,126.582 7.399,129 10.358,129H66.642C69.601,129 72,126.582 72,123.6V10.4C72,7.418 69.601,5 66.642,5Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M63,94H39V118H63V94Z"
+      android:fillColor="#000000"
+      android:fillAlpha="0.7"/>
+  <path
+      android:pathData="M43,106V114H59V98H51V99.6H57.4V112.4H44.6V106H43Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M49.4,98H43V104.4H49.4V98Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M55.8,105.2V106.8H52.928L56.56,110.432L55.432,111.56L51.8,107.928V110.8H50.2V105.2H55.8Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M66,10H11C10.448,10 10,10.448 10,11V123C10,123.552 10.448,124 11,124H66C66.552,124 67,123.552 67,123V11C67,10.448 66.552,10 66,10ZM11,5C7.686,5 5,7.686 5,11V123C5,126.314 7.686,129 11,129H66C69.314,129 72,126.314 72,123V11C72,7.686 69.314,5 66,5H11Z"
+      android:fillColor="#F29900"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/res/drawable/ic_illustration_window.xml b/res/drawable/ic_illustration_window.xml
new file mode 100644
index 0000000..1b87d7d
--- /dev/null
+++ b/res/drawable/ic_illustration_window.xml
@@ -0,0 +1,41 @@
+<?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:width="77dp"
+    android:height="134dp"
+    android:viewportWidth="77"
+    android:viewportHeight="134">
+  <path
+      android:pathData="M69.6,1.1H7.4C3.921,1.1 1.1,3.921 1.1,7.4V126.6C1.1,130.079 3.921,132.9 7.4,132.9H69.6C73.079,132.9 75.9,130.079 75.9,126.6V7.4C75.9,3.921 73.079,1.1 69.6,1.1Z"
+      android:strokeWidth="1.8"
+      android:fillColor="#F2F3F4"
+      android:strokeColor="#DADCE0"/>
+  <path
+      android:pathData="M66.642,5H10.358C7.399,5 5,7.418 5,10.4V123.6C5,126.582 7.399,129 10.358,129H66.642C69.601,129 72,126.582 72,123.6V10.4C72,7.418 69.601,5 66.642,5Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M63,48H14C12.895,48 12,48.895 12,50V85C12,86.105 12.895,87 14,87H63C64.105,87 65,86.105 65,85V50C65,48.895 64.105,48 63,48Z"
+      android:strokeLineJoin="bevel"
+      android:strokeWidth="5"
+      android:fillColor="#00000000"
+      android:strokeColor="#F29900"/>
+  <path
+      android:pathData="M46.077,54V58.314H51.612L45,64.958L48.037,68L54.692,61.334V66.921H59V54H46.077Z"
+      android:fillColor="#F29900"/>
+  <path
+      android:pathData="M28.963,67L22.308,73.655V68.077H18V81H30.923V76.692H25.366L32,70.037L28.963,67Z"
+      android:fillColor="#F29900"/>
+</vector>
diff --git a/res/layout/battery_usage_graph.xml b/res/layout/battery_chart_graph.xml
similarity index 60%
rename from res/layout/battery_usage_graph.xml
rename to res/layout/battery_chart_graph.xml
index 93001c3..6187d07 100644
--- a/res/layout/battery_usage_graph.xml
+++ b/res/layout/battery_chart_graph.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<!-- 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.
@@ -18,36 +18,25 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingTop="16dp"
-    android:paddingStart="@dimen/preference_no_icon_padding_start"
+    android:paddingStart="?android:attr/listPreferredItemPaddingEnd"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
     android:orientation="vertical">
 
     <TextView
-        android:id="@+id/charge"
+        android:id="@+id/chart_summary"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="16dp"
-        android:fontFamily="@*android:string/config_headlineFontFamily"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:textSize="36sp"
-        android:textColor="?android:attr/colorAccent" />
+        android:layout_marginBottom="45dp"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        settings:textColor="?android:attr/textColorSecondary"
+        android:text="@string/battery_usage_chart_graph_hint" />
 
-    <com.android.settings.widget.UsageView
-        android:id="@+id/battery_usage"
+    <com.android.settings.fuelgauge.BatteryChartView
+        android:id="@+id/battery_chart"
         android:layout_width="match_parent"
         android:layout_height="141dp"
         android:layout_marginBottom="16dp"
-        settings:sideLabels="@array/battery_labels"
-        android:colorAccent="?android:attr/colorAccent"
-        android:gravity="end"
+        android:textAppearance="?android:attr/textAppearanceSmall"
         settings:textColor="?android:attr/textColorSecondary" />
 
-    <TextView
-        android:id="@+id/bottom_summary"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="16dp"
-        android:textAppearance="?android:attr/textAppearanceSmall" />
-
 </LinearLayout>
diff --git a/res/layout/more_settings_button.xml b/res/layout/more_settings_button.xml
index 4bbe119..84ef75a 100644
--- a/res/layout/more_settings_button.xml
+++ b/res/layout/more_settings_button.xml
@@ -14,22 +14,20 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<LinearLayout
+<FrameLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:settings="http://schemas.android.com/apk/res-auto"
       android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:orientation="vertical">
+      android:layout_height="wrap_content">
 
       <Button
          android:id="@+id/button"
+         style="@style/ActionPrimaryButton"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
-         android:layout_gravity="center_horizontal"
-         android:layout_marginTop="20dip"
-         android:layout_marginBottom="20dip"
-         style="@style/ActionPrimaryButton"
-         settings:allowDividerBelow="true"
-         android:gravity="center" />
+         android:layout_marginVertical="8dp"
+         android:layout_marginHorizontal="16dp"
+         android:theme="@style/RoundedCornerThemeOverlay"
+         settings:allowDividerBelow="true"/>
 
-</LinearLayout>
+</FrameLayout>
diff --git a/res/layout/verified_links_widget.xml b/res/layout/verified_links_widget.xml
index 322ddd5..03951ff 100644
--- a/res/layout/verified_links_widget.xml
+++ b/res/layout/verified_links_widget.xml
@@ -18,6 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
+    android:contentDescription="@string/app_launch_verified_links_info_description"
     android:orientation="horizontal">
 
     <include layout="@layout/preference_widget_info"
diff --git a/res/layout/wifi_add_network_view.xml b/res/layout/wifi_add_network_view.xml
index 33154f6..6af46cf 100644
--- a/res/layout/wifi_add_network_view.xml
+++ b/res/layout/wifi_add_network_view.xml
@@ -15,25 +15,26 @@
      limitations under the License.
 -->
 
-<RelativeLayout
+<androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:clipToPadding="true"
-    android:clipChildren="true"
-    android:orientation="vertical">
+    android:clipChildren="true">
 
         <include
+            android:id="@+id/wifi_dialog_frame"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_above="@id/add_network_button_bar"
-            android:layout_alignParentTop="true"
+            app:layout_constraintTop_toTopOf="parent"
             layout="@layout/wifi_dialog"/>
 
         <include
             android:id="@+id/add_network_button_bar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true"
+            app:layout_constraintTop_toBottomOf="@id/wifi_dialog_frame"
             layout="@*android:layout/alert_dialog_button_bar_material"/>
-</RelativeLayout>
\ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e0e0219..aca3322 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -446,4 +446,11 @@
 
     <!--  Choose SIM Activity dimens  -->
     <dimen name="subtitle_bottom_padding">24dp</dimen>
+
+    <!-- Battery usage chart view component -->
+    <dimen name="chartview_divider_width">1dp</dimen>
+    <dimen name="chartview_divider_height">4dp</dimen>
+    <dimen name="chartview_trapezoid_radius">2dp</dimen>
+    <dimen name="chartview_trapezoid_margin_start">1dp</dimen>
+    <dimen name="chartview_trapezoid_margin_bottom">2dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 15b9054..ce266e2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2508,9 +2508,11 @@
     <!-- Summary for the toggle to turn off hotspot automatically [CHAR LIMIT=NONE]-->
     <string name="wifi_hotspot_auto_off_summary">When no devices are connected</string>
     <!-- Title for the toggle to enable/disable the maximize compatibility [CHAR LIMIT=NONE]-->
-    <string name="wifi_hotspot_maximize_compatibility">Maximize compatibility</string>
-    <!-- Summary for the toggle to show the maximize compatibility warning message [CHAR LIMIT=NONE]-->
-    <string name="wifi_hotspot_maximize_compatibility_summary">This may reduce speed for devices connected to this hotspot and use more power</string>
+    <string name="wifi_hotspot_maximize_compatibility">Extend compatibility</string>
+    <!-- Summary for the toggle to show the maximize compatibility warning message in single AP device [CHAR LIMIT=NONE]-->
+    <string name="wifi_hotspot_maximize_compatibility_single_ap_summary">Helps other devices find this hotspot. Reduces hotspot connection speed.</string>
+    <!-- Summary for the toggle to show the maximize compatibility warning message in dual AP device [CHAR LIMIT=NONE]-->
+    <string name="wifi_hotspot_maximize_compatibility_dual_ap_summary">Helps other devices find this hotspot. Increases battery usage.</string>
 
     <!-- Summary text when turning hotspot on -->
     <string name="wifi_tether_starting">Turning hotspot on\u2026</string>
@@ -2942,6 +2944,10 @@
     <string name="adaptive_sleep_contextual_slice_title">Turn on screen attention</string>
     <!-- Description about the contextual adaptive sleep card [CHAR LIMIT=NONE]-->
     <string name="adaptive_sleep_contextual_slice_summary">Keep screen on when looking at it</string>
+    <!-- auto_rotate settings screen, title about the camera privacy lock enabled [CHAR LIMIT=NONE]-->
+    <string name="auto_rotate_camera_lock_title">Camera is locked</string>
+    <!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
+    <string name="auto_rotate_camera_lock_summary">Camera must be unlocked for Face Detection</string>
     <!-- auto_rotate settings screen, title about the required permission is missing [CHAR LIMIT=NONE]-->
     <string name="auto_rotate_summary_no_permission">Camera access is required for Face Detection. Tap to manage permissions for Device Personalization Services</string>
     <!-- auto_rotate settings screen, text for the camera permission button [CHAR LIMIT=NONE]-->
@@ -5467,7 +5473,7 @@
     <!-- Summary shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
     <string name="daltonizer_mode_tritanomaly_summary">Blue-yellow</string>
 
-    <!-- Title for the accessibility preference of the Reduce Brightness feature. [CHAR LIMIT=NONE] -->
+    <!-- Title for the accessibility preference of the Extra Dim/Reduce Brightness feature that dims your screen. [CHAR LIMIT=NONE] -->
     <string name="reduce_bright_colors_preference_title">Extra dim</string>
     <!-- Title for the activation switch of the Reduce Brightness feature. [CHAR LIMIT=NONE] -->
     <string name="reduce_bright_colors_switch_title">Make screen extra dim</string>
@@ -6348,6 +6354,21 @@
     <!-- [CHAR_LIMIT=NONE] Battery percentage: Description for preference -->
     <string name="battery_percentage_description">Show battery percentage in status bar</string>
 
+    <!-- [CHAR_LIMIT=NONE] Battery usage main screen chart graph hint -->
+    <string name="battery_usage_chart_graph_hint">Battery level for past 24 hr</string>
+    <!-- [CHAR_LIMIT=NONE] Battery app usage section header for past 24 hour -->
+    <string name="battery_app_usage_for_past_24">App usage for past 24 hr</string>
+    <!-- [CHAR_LIMIT=NONE] Battery system usage section header for past 24 hour -->
+    <string name="battery_system_usage_for_past_24">System usage for past 24 hr</string>
+    <!-- [CHAR_LIMIT=NONE] Battery system usage section header -->
+    <string name="battery_system_usage_for">System usage for</string>
+    <!-- [CHAR_LIMIT=NONE] Battery app usage section header -->
+    <string name="battery_app_usage_for">App usage for</string>
+    <!-- [CHAR_LIMIT=NONE] Battery usage section header for a specific time slot -->
+    <string name="battery_usage_time_am">am</string>
+    <!-- [CHAR_LIMIT=NONE] Battery usage section header for a specific time slot -->
+    <string name="battery_usage_time_pm">pm</string>
+
     <!-- Process Stats strings -->
     <skip />
 
@@ -7880,7 +7901,7 @@
     <!-- Toast shown when an app in the work profile attempts to open notification settings. The apps in the work profile cannot access notification settings. [CHAR LIMIT=NONE] -->
     <string name="notification_settings_work_profile">Notification access is not available for apps in the work profile.</string>
     <!-- Title for setting tile leading to saved autofill passwords, autofill, and account settings [CHAR LIMIT=40]-->
-    <string name="account_dashboard_title">Passwords and accounts</string>
+    <string name="account_dashboard_title">Passwords &amp; accounts</string>
     <!-- Summary for setting tile leading to saved autofill passwords, autofill, and account settings [CHAR LIMIT=NONE]-->
     <string name="account_dashboard_default_summary">Saved passwords, autofill, synced accounts</string>
     <!-- Title for setting tile leading to setting UI which allows user set default app to
@@ -8053,6 +8074,9 @@
     <!-- List of synonyms for the font size, used to match in settings search [CHAR LIMIT=NONE] -->
     <string name="keywords_font_size">text size</string>
 
+    <!-- List of synonyms used in the settings search bar to find the “Extra Dim” setting, which dims your screen. Title name is located at strings/reduce_bright_colors_preference_title. [CHAR LIMIT=NONE] -->
+    <string name="keywords_reduce_bright_colors">light sensitivity, photophobia, dark theme, migraine, headache, reading mode, night mode, reduce brightness, white point</string>
+
     <!-- Option title for the default sound, context based on screen -->
     <string name="default_sound">Default sound</string>
 
@@ -9874,6 +9898,8 @@
     </plurals>
     <!-- OK button for verified links dialog. [CHAR LIMIT=20] -->
     <string name="app_launch_dialog_ok">OK</string>
+    <!-- Info icon description of the verified links. [CHAR LIMIT=NONE] -->
+    <string name="app_launch_verified_links_info_description">Show verified links list</string>
 
     <!-- Title for Checking other supported links dialog. [CHAR LIMIT=50] -->
     <string name="app_launch_checking_links_title">Checking for other supported links\u2026</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8ca72db..078c6b6 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -421,6 +421,10 @@
     <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored"/>
     <style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
 
+    <style name="RoundedCornerThemeOverlay">
+        <item name="android:buttonCornerRadius">24dp</item>
+    </style>
+
     <style name="LockPatternContainerStyle">
         <item name="android:maxHeight">400dp</item>
         <item name="android:maxWidth">420dp</item>
diff --git a/res/xml/auto_rotate_settings.xml b/res/xml/auto_rotate_settings.xml
index 7c46d29..bc47b81 100644
--- a/res/xml/auto_rotate_settings.xml
+++ b/res/xml/auto_rotate_settings.xml
@@ -26,6 +26,12 @@
         android:summary="@string/auto_rotate_summary_no_permission"
         settings:controller="com.android.settings.display.SmartAutoRotatePermissionController" />
 
+    <com.android.settingslib.widget.BannerMessagePreference
+        android:key="camera_lock_state"
+        android:title="@string/auto_rotate_camera_lock_title"
+        android:summary="@string/auto_rotate_camera_lock_summary"
+        settings:controller="com.android.settings.display.SmartAutoRotateCameraStateController" />
+
     <SwitchPreference
         android:key="face_based_rotate"
         android:title="@string/auto_rotate_switch_face_based"
diff --git a/res/xml/conversation_list_settings.xml b/res/xml/conversation_list_settings.xml
index 86b4f81..040a968 100644
--- a/res/xml/conversation_list_settings.xml
+++ b/res/xml/conversation_list_settings.xml
@@ -34,6 +34,7 @@
         settings:allowDividerBelow="true" >
         <Preference
             android:key="behavior"
+            android:selectable="false"
             android:summary="@string/important_conversation_behavior_summary"/>
         <!-- Important conversations added here -->
         <PreferenceCategory
diff --git a/res/xml/emergency_settings.xml b/res/xml/emergency_settings.xml
index 80d6ac0..66c5fd1 100644
--- a/res/xml/emergency_settings.xml
+++ b/res/xml/emergency_settings.xml
@@ -20,29 +20,28 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="safety_and_emergency_screen"
     android:title="@string/emergency_settings_preference_title">
-    <Preference
-        android:key="emergency_info"
-        android:title="@string/emergency_info_title"
-        android:summary="@string/summary_placeholder"
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="more_emergency_settings"
+        android:layout="@layout/more_settings_button"
         android:order="0"
-        settings:controller="com.android.settings.accounts.EmergencyInfoPreferenceController"/>
+        android:selectable="false"
+        settings:controller="com.android.settings.emergency.MoreSettingsPreferenceController" />
     <Preference
         android:key="gesture_emergency_summary"
         android:title="@string/emergency_gesture_screen_title"
+        android:icon="@drawable/ic_emergency_gesture_24dp"
         android:order="100"
         android:fragment="com.android.settings.emergency.EmergencyGestureSettings"
         settings:controller="com.android.settings.emergency.EmergencyGestureEntrypointPreferenceController" />
-    <com.android.settingslib.widget.LayoutPreference
-        android:key="more_settings"
-        android:layout="@layout/more_settings_button"
-        android:order="180"
-        android:selectable="false"
-        settings:allowDividerBelow="true"
-        settings:controller="com.android.settings.emergency.MoreSettingsPreferenceController" />
+    <PreferenceCategory
+        android:order="170"
+        android:layout="@layout/preference_category_no_label"
+        settings:allowDividerAbove="true"/>
     <com.android.settingslib.RestrictedPreference
         android:key="app_and_notif_cell_broadcast_settings"
         android:title="@string/cell_broadcast_settings"
         android:order="200"
+        settings:iconSpaceReserved="true"
         settings:useAdminDisabledSummary="true">
         <intent
             android:action="android.intent.action.MAIN"
diff --git a/res/xml/wifi_tether_settings.xml b/res/xml/wifi_tether_settings.xml
index 8648cff..21f347b 100644
--- a/res/xml/wifi_tether_settings.xml
+++ b/res/xml/wifi_tether_settings.xml
@@ -44,6 +44,5 @@
 
     <SwitchPreference
         android:key="wifi_tether_maximize_compatibility"
-        android:title="@string/wifi_hotspot_maximize_compatibility"
-        android:summary="@string/wifi_hotspot_maximize_compatibility_summary"/>
+        android:title="@string/wifi_hotspot_maximize_compatibility"/>
 </PreferenceScreen>
diff --git a/src/com/android/settings/ActivityPicker.java b/src/com/android/settings/ActivityPicker.java
index f75ce37..ae61944 100644
--- a/src/com/android/settings/ActivityPicker.java
+++ b/src/com/android/settings/ActivityPicker.java
@@ -16,8 +16,6 @@
 
 package com.android.settings;
 
-import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-
 import android.app.Activity;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -73,8 +71,6 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-
-        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         
         final Intent intent = getIntent();
         
diff --git a/src/com/android/settings/SettingsInitialize.java b/src/com/android/settings/SettingsInitialize.java
index 5157033..cd949de 100644
--- a/src/com/android/settings/SettingsInitialize.java
+++ b/src/com/android/settings/SettingsInitialize.java
@@ -39,6 +39,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.Settings.CreateShortcutActivity;
+import com.android.settingslib.utils.ThreadUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -62,7 +63,7 @@
         final PackageManager pm = context.getPackageManager();
         managedProfileSetup(context, pm, broadcast, userInfo);
         webviewSettingSetup(context, pm, userInfo);
-        refreshExistingShortcuts(context);
+        ThreadUtils.postOnBackgroundThread(() -> refreshExistingShortcuts(context));
     }
 
     private void managedProfileSetup(Context context, final PackageManager pm, Intent broadcast,
@@ -142,5 +143,4 @@
         }
         shortcutManager.updateShortcuts(updates);
     }
-
 }
diff --git a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
index c4d6fd5..520de01 100644
--- a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
@@ -209,15 +209,15 @@
         mModeInfos.clear();
         mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
                 R.string.accessibility_magnification_mode_dialog_option_full_screen), null,
-                R.drawable.accessibility_magnification_full_screen, MagnificationMode.FULLSCREEN));
+                R.drawable.ic_illustration_fullscreen, MagnificationMode.FULLSCREEN));
         mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
                 R.string.accessibility_magnification_mode_dialog_option_window), null,
-                R.drawable.accessibility_magnification_window_screen, MagnificationMode.WINDOW));
+                R.drawable.ic_illustration_window, MagnificationMode.WINDOW));
         mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
                 R.string.accessibility_magnification_mode_dialog_option_switch),
                 getPrefContext().getText(
                         R.string.accessibility_magnification_area_settings_mode_switch_summary),
-                R.drawable.accessibility_magnification_switch, MagnificationMode.ALL));
+                R.drawable.ic_illustration_switch, MagnificationMode.ALL));
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java b/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java
index d8c190f..2c76f05 100644
--- a/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java
@@ -19,29 +19,29 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.hardware.usb.IUsbManager;
-import android.os.ServiceManager;
+import android.content.pm.verify.domain.DomainVerificationManager;
+import android.content.pm.verify.domain.DomainVerificationUserState;
 import android.os.UserHandle;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.applications.intentpicker.AppLaunchSettings;
+import com.android.settings.applications.intentpicker.IntentPickerUtils;
+import com.android.settingslib.R;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 
 public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceControllerBase {
 
-    private IUsbManager mUsbManager;
-    private PackageManager mPackageManager;
+    private final DomainVerificationManager mDomainVerificationManager;
     private String mPackageName;
 
     public AppOpenByDefaultPreferenceController(Context context, String key) {
         super(context, key);
-        mUsbManager = IUsbManager.Stub.asInterface(ServiceManager.getService(Context.USB_SERVICE));
-        mPackageManager = context.getPackageManager();
+        mDomainVerificationManager = context.getSystemService(DomainVerificationManager.class);
     }
 
     /** Set a package name for this controller. */
@@ -69,8 +69,7 @@
                 && !AppUtils.isBrowserApp(mContext, packageInfo.packageName,
                 UserHandle.myUserId())) {
             preference.setVisible(true);
-            preference.setSummary(AppUtils.getLaunchByDefaultSummary(mParent.getAppEntry(),
-                    mUsbManager, mPackageManager, mContext));
+            preference.setSummary(getSubtext());
         } else {
             preference.setVisible(false);
         }
@@ -80,4 +79,18 @@
     protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
         return AppLaunchSettings.class;
     }
+
+    @VisibleForTesting
+    CharSequence getSubtext() {
+        return mContext.getText(isLinkHandlingAllowed()
+                ? R.string.app_link_open_always : R.string.app_link_open_never);
+    }
+
+    @VisibleForTesting
+    boolean isLinkHandlingAllowed() {
+        final DomainVerificationUserState userState =
+                IntentPickerUtils.getDomainVerificationUserState(mDomainVerificationManager,
+                        mPackageName);
+        return userState == null ? false : userState.isLinkHandlingAllowed();
+    }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java b/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java
index 3173a34..416e805 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java
@@ -20,6 +20,8 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Bundle;
 
+import androidx.fragment.app.FragmentManager;
+
 import com.android.settings.R;
 import com.android.settings.biometrics.BiometricEnrollBase;
 import com.android.settings.biometrics.BiometricErrorDialog;
@@ -31,7 +33,10 @@
     public static void showErrorDialog(BiometricEnrollBase host, int errMsgId) {
         final CharSequence errMsg = host.getText(getErrorMessage(errMsgId));
         final FingerprintErrorDialog dialog = newInstance(errMsg, errMsgId);
-        dialog.show(host.getSupportFragmentManager(), FingerprintErrorDialog.class.getName());
+        final FragmentManager fragmentManager = host.getSupportFragmentManager();
+        if (!fragmentManager.isDestroyed()) {
+            dialog.show(fragmentManager, FingerprintErrorDialog.class.getName());
+        }
     }
 
     private static int getErrorMessage(int errMsgId) {
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
index 4c30baa..e502d65 100644
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
@@ -364,7 +364,12 @@
             final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction);
             if (estimateReady == 1) {
                 textView.setVisibility(View.VISIBLE);
-                textView.setText(StringUtil.formatElapsedTime(mContext, batteryEstimate, false));
+                textView.setText(
+                        StringUtil.formatElapsedTime(
+                                mContext,
+                                batteryEstimate,
+                                /* withSeconds */ false,
+                                /* collapseTimeUnit */  false));
             } else {
                 textView.setVisibility(View.GONE);
             }
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java
index 9cbb921..f1728b6 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java
@@ -318,7 +318,10 @@
                     textResourceId = R.string.no_carrier_update_text;
                 }
                 updateTime = StringUtil.formatElapsedTime(
-                        getContext(), updateAgeMillis, false /* withSeconds */);
+                        getContext(),
+                        updateAgeMillis,
+                        false /* withSeconds */,
+                        false /* collapseTimeUnit */);
             }
             carrierInfo.setText(TextUtils.expandTemplate(
                     getContext().getText(textResourceId),
diff --git a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
index 05a542d..3035b8c 100644
--- a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
+++ b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
@@ -17,10 +17,10 @@
 package com.android.settings.datetime.timezone.model;
 
 import android.util.ArraySet;
+import android.util.TimeUtils;
 
 import com.android.i18n.timezone.CountryTimeZones;
 
-import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -31,21 +31,6 @@
  */
 public class FilteredCountryTimeZones {
 
-    /**
-     * The timestamp used to determine which time zones to show to users by using the notUsedAfter
-     * metadata Android holds for each time zone.
-     *
-     * notUsedAfter exists because some time zones effectively "merge" with other time zones after
-     * a given point in time (i.e. they have identical transitions, offsets, etc.). After that
-     * point we only need to show one of the functionally identical ones.
-     *
-     * Rather than using System.currentTimeMillis(), UX folks asked for consistent behavior and so
-     * a timestamp known to be in the recent past is used. This should be updated occasionally but
-     * it doesn't have to be very often.
-     */
-    private static final Instant MIN_USE_DATE_OF_TIMEZONE =
-            Instant.ofEpochMilli(1546300800000L); // 1/1/2019 00:00 UTC
-
     private final CountryTimeZones mCountryTimeZones;
     private final List<String> mPreferredTimeZoneIds;
     private final Set<String> mAlternativeTimeZoneIds;
@@ -56,7 +41,7 @@
         Set<String> alternativeTimeZoneIds = new ArraySet<>();
         for (CountryTimeZones.TimeZoneMapping timeZoneMapping :
                 countryTimeZones.getTimeZoneMappings()) {
-            if (timeZoneMapping.isShownInPickerAt(MIN_USE_DATE_OF_TIMEZONE)) {
+            if (timeZoneMapping.isShownInPickerAt(TimeUtils.MIN_USE_DATE_OF_TIMEZONE)) {
                 String timeZoneId = timeZoneMapping.getTimeZoneId();
                 timeZoneIds.add(timeZoneId);
                 alternativeTimeZoneIds.addAll(timeZoneMapping.getAlternativeIds());
diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
index a0af268..6b243c6 100644
--- a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
+++ b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
@@ -61,14 +61,6 @@
     }
 
     @Override
-    public void onHDAudioEnabled(boolean enabled) {
-        if (!enabled) {
-            // If option codec is disabled, SBC is the only only one available codec.
-            onIndexUpdated(convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC));
-        }
-    }
-
-    @Override
     public List<Integer> getSelectableIndex() {
         List<Integer> index = new ArrayList<>();
         final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp;
diff --git a/src/com/android/settings/display/SmartAutoRotateCameraStateController.java b/src/com/android/settings/display/SmartAutoRotateCameraStateController.java
new file mode 100644
index 0000000..1480785
--- /dev/null
+++ b/src/com/android/settings/display/SmartAutoRotateCameraStateController.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.settings.display;
+
+import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
+
+import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable;
+
+import android.content.Context;
+import android.hardware.SensorPrivacyManager;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.BannerMessagePreference;
+
+/**
+ * The controller of camera based rotate privacy sensor warning preference. The preference appears
+ * when the privacy sensor service disables camera functionality completely.
+ */
+public class SmartAutoRotateCameraStateController extends BasePreferenceController {
+
+    private final SensorPrivacyManager mPrivacyManager;
+    private Preference mPreference;
+
+    public SmartAutoRotateCameraStateController(Context context, String key) {
+        super(context, key);
+        mPrivacyManager = SensorPrivacyManager.getInstance(context);
+        mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> {
+            mPreference.setVisible(enabled);
+            updateState(mPreference);
+        });
+    }
+
+    @VisibleForTesting
+    boolean isCameraLocked() {
+        return mPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+        ((BannerMessagePreference) mPreference)
+                .setPositiveButtonText(R.string.allow)
+                .setPositiveButtonOnClickListener(v -> {
+                    mPrivacyManager.setSensorPrivacy(CAMERA, false);
+                });
+    }
+
+    @Override
+    @AvailabilityStatus
+    public int getAvailabilityStatus() {
+        return isRotationResolverServiceAvailable(mContext)
+                && isCameraLocked() ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
+    }
+}
diff --git a/src/com/android/settings/display/SmartAutoRotateController.java b/src/com/android/settings/display/SmartAutoRotateController.java
index ca196ba..e3b2665 100644
--- a/src/com/android/settings/display/SmartAutoRotateController.java
+++ b/src/com/android/settings/display/SmartAutoRotateController.java
@@ -15,6 +15,7 @@
  */
 package com.android.settings.display;
 
+import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
 import static android.provider.Settings.Secure.CAMERA_AUTOROTATE;
 
 import android.Manifest;
@@ -23,12 +24,15 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.hardware.SensorPrivacyManager;
 import android.provider.Settings;
 import android.service.rotationresolver.RotationResolverService;
 import android.text.TextUtils;
 
 import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.view.RotationPolicy;
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
@@ -41,10 +45,14 @@
         Preference.OnPreferenceChangeListener {
 
     private final MetricsFeatureProvider mMetricsFeatureProvider;
+    private final SensorPrivacyManager mPrivacyManager;
+    private Preference mPreference;
 
     public SmartAutoRotateController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        mPrivacyManager = SensorPrivacyManager.getInstance(context);
+        mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> updateState(mPreference));
     }
 
     @Override
@@ -53,17 +61,40 @@
             return UNSUPPORTED_ON_DEVICE;
         }
         return !RotationPolicy.isRotationLocked(mContext) && hasSufficientPermission(mContext)
-                ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
+                && !isCameraLocked() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        if (preference != null) {
+            preference.setEnabled(getAvailabilityStatus() == AVAILABLE);
+        }
+    }
+
+    /**
+     * Need this because all controller tests use RoboElectric. No easy way to mock this service,
+     * so we mock the call we need
+     */
+    @VisibleForTesting
+    boolean isCameraLocked() {
+        return mPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA);
     }
 
     @Override
     public boolean isChecked() {
-        return hasSufficientPermission(mContext) && Settings.Secure.getInt(
+        return hasSufficientPermission(mContext) && !isCameraLocked() && Settings.Secure.getInt(
                 mContext.getContentResolver(),
                 CAMERA_AUTOROTATE, 0) == 1;
     }
 
     @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
     public boolean setChecked(boolean isChecked) {
         mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CAMERA_ROTATE_TOGGLE,
                 isChecked);
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
index 130bbd8..1a91775 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
@@ -19,6 +19,7 @@
 import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable;
 
 import android.app.settings.SettingsEnums;
+import android.hardware.SensorPrivacyManager;
 import android.os.Bundle;
 import android.text.Html;
 import android.view.LayoutInflater;
@@ -47,6 +48,7 @@
     private static final String TAG = "SmartAutoRotatePreferenceFragment";
 
     private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
+    private SensorPrivacyManager mPrivacyManager;
     private AutoRotateSwitchBarController mSwitchBarController;
     private static final String FACE_SWITCH_PREFERENCE_ID = "face_based_rotate";
 
@@ -66,6 +68,7 @@
         switchBar.show();
         mSwitchBarController = new AutoRotateSwitchBarController(activity, switchBar,
                 getSettingsLifecycle());
+        mPrivacyManager = SensorPrivacyManager.getInstance(activity);
         final Preference footerPreference = findPreference(FooterPreference.KEY_FOOTER);
         if (footerPreference != null) {
             footerPreference.setTitle(Html.fromHtml(getString(R.string.smart_rotate_text_headline),
@@ -84,9 +87,11 @@
                 public void onChange() {
                     mSwitchBarController.onChange();
                     final boolean isLocked = RotationPolicy.isRotationLocked(getContext());
+                    final boolean isCameraLocked = mPrivacyManager.isSensorPrivacyEnabled(
+                            SensorPrivacyManager.Sensors.CAMERA);
                     final Preference preference = findPreference(FACE_SWITCH_PREFERENCE_ID);
                     if (preference != null && hasSufficientPermission(getContext())) {
-                        preference.setEnabled(!isLocked);
+                        preference.setEnabled(!isLocked && !isCameraLocked);
                     }
                 }
             };
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 399a84d..f4bdfb3 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -229,10 +229,18 @@
         final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
         mForegroundPreference.setSummary(
                 TextUtils.expandTemplate(getText(R.string.battery_used_for),
-                        StringUtil.formatElapsedTime(context, foregroundTimeMs, false)));
+                        StringUtil.formatElapsedTime(
+                                context,
+                                foregroundTimeMs,
+                                /* withSeconds */ false,
+                                /* collapseTimeUnit */ false)));
         mBackgroundPreference.setSummary(
                 TextUtils.expandTemplate(getText(R.string.battery_active_for),
-                        StringUtil.formatElapsedTime(context, backgroundTimeMs, false)));
+                        StringUtil.formatElapsedTime(
+                                context,
+                                backgroundTimeMs,
+                                /* withSeconds */ false,
+                                /* collapseTimeUnit */ false)));
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index a55d0d3..4053e86 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -380,7 +380,7 @@
         final long usageTimeMs = entry.getTimeInForegroundMs();
         if (shouldShowSummary(entry) && usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) {
             final CharSequence timeSequence =
-                    StringUtil.formatElapsedTime(mContext, usageTimeMs, false);
+                    StringUtil.formatElapsedTime(mContext, usageTimeMs, false, false);
             preference.setSummary(
                     entry.isHidden()
                             ? timeSequence
diff --git a/src/com/android/settings/fuelgauge/BatteryChartView.java b/src/com/android/settings/fuelgauge/BatteryChartView.java
new file mode 100644
index 0000000..47333aa
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatteryChartView.java
@@ -0,0 +1,269 @@
+/*
+ * 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.settings.fuelgauge;
+
+import static java.lang.Math.round;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.CornerPathEffect;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.appcompat.widget.AppCompatImageView;
+
+import com.android.settings.R;
+import com.android.settingslib.Utils;
+
+import java.util.Locale;
+
+/** A widget component to draw chart graph. */
+public class BatteryChartView extends AppCompatImageView implements View.OnClickListener {
+    private static final String TAG = "BatteryChartView";
+    private static final int DEFAULT_TRAPEZOID_COUNT = 12;
+    /** Selects all trapezoid shapes. */
+    public static final int SELECTED_INDEX_ALL = -1;
+    public static final int SELECTED_INDEX_INVALID = -2;
+
+    /** A callback listener for selected group index is updated. */
+    public interface OnSelectListener {
+        void onSelect(int trapezoidIndex);
+    }
+
+    private int mDividerWidth;
+    private int mDividerHeight;
+    private int mTrapezoidCount;
+    private int mSelectedIndex;
+    private float mTrapezoidVOffset;
+    private float mTrapezoidHOffset;
+    // Colors for drawing the trapezoid shape and dividers.
+    private int mTrapezoidColor;
+    private int mTrapezoidSolidColor;
+    private final int mDividerColor = Color.parseColor("#CDCCC5");
+
+    private int[] mLevels;
+    private Paint mDividerPaint;
+    private Paint mTrapezoidPaint;
+    private TrapezoidSlot[] mTrapezoidSlot;
+    // Records the location to calculate selected index.
+    private MotionEvent mTouchUpEvent;
+    private BatteryChartView.OnSelectListener mOnSelectListener;
+
+    public BatteryChartView(Context context) {
+        super(context, null);
+    }
+
+    public BatteryChartView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initializeColors(context);
+        setOnClickListener(this);
+        setSelectedIndex(SELECTED_INDEX_ALL);
+        setTrapezoidCount(DEFAULT_TRAPEZOID_COUNT);
+    }
+
+    /** Sets the total trapezoid count for drawing. */
+    public void setTrapezoidCount(int trapezoidCount) {
+        Log.i(TAG, "trapezoidCount:" + trapezoidCount);
+        mTrapezoidCount = trapezoidCount;
+        mTrapezoidSlot = new TrapezoidSlot[trapezoidCount];
+        // Allocates the trapezoid slot array.
+        for (int index = 0; index < trapezoidCount; index++) {
+            mTrapezoidSlot[index] = new TrapezoidSlot();
+        }
+        invalidate();
+    }
+
+    /** Sets all levels value to draw the trapezoid shape */
+    public void setLevels(int[] levels) {
+        // We should provide trapezoid count + 1 data to draw all trapezoids.
+        mLevels = levels.length == mTrapezoidCount + 1 ? levels : null;
+        setClickable(mLevels != null);
+        invalidate();
+    }
+
+    /** Sets the selected group index to draw highlight effect. */
+    public void setSelectedIndex(int index) {
+        if (mSelectedIndex != index) {
+            mSelectedIndex = index;
+            invalidate();
+            // Callbacks to the listener if we have.
+            if (mOnSelectListener != null) {
+                mOnSelectListener.onSelect(mSelectedIndex);
+            }
+        }
+    }
+
+    /** Sets the callback to monitor the selected group index. */
+    public void setOnSelectListener(BatteryChartView.OnSelectListener listener) {
+        mOnSelectListener = listener;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+        drawHorizontalDividers(canvas);
+        drawVerticalDividers(canvas);
+        drawTrapezoids(canvas);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        // Caches the location to calculate selected trapezoid index.
+        final int action = event.getAction();
+        if (action == MotionEvent.ACTION_UP) {
+            mTouchUpEvent = MotionEvent.obtain(event);
+        } else if (action == MotionEvent.ACTION_CANCEL) {
+            mTouchUpEvent = null; // reset
+        }
+        return super.onTouchEvent(event);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (mTouchUpEvent == null) {
+            Log.w(TAG, "invalid motion event for onClick() callback");
+            return;
+        }
+        final int trapezoidIndex = getTrapezoidIndex(mTouchUpEvent.getX());
+        // Selects all if users click the same trapezoid item two times.
+        if (trapezoidIndex == mSelectedIndex) {
+            setSelectedIndex(SELECTED_INDEX_ALL);
+        } else {
+            setSelectedIndex(trapezoidIndex);
+        }
+        view.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
+    }
+
+    private void initializeColors(Context context) {
+        setBackgroundColor(Color.TRANSPARENT);
+        mTrapezoidSolidColor = Utils.getColorAccentDefaultColor(context);
+        mTrapezoidColor = Utils.getDisabled(context, mTrapezoidSolidColor);
+        // Initializes the divider line paint.
+        final Resources resources = getContext().getResources();
+        mDividerWidth = resources.getDimensionPixelSize(R.dimen.chartview_divider_width);
+        mDividerHeight = resources.getDimensionPixelSize(R.dimen.chartview_divider_height);
+        mDividerPaint = new Paint();
+        mDividerPaint.setAntiAlias(true);
+        mDividerPaint.setColor(mDividerColor);
+        mDividerPaint.setStyle(Paint.Style.STROKE);
+        mDividerPaint.setStrokeWidth(mDividerWidth);
+        Log.i(TAG, "mDividerWidth:" + mDividerWidth);
+        Log.i(TAG, "mDividerHeight:" + mDividerHeight);
+        // Initializes the trapezoid paint.
+        mTrapezoidHOffset = resources.getDimension(R.dimen.chartview_trapezoid_margin_start);
+        mTrapezoidVOffset = resources.getDimension(R.dimen.chartview_trapezoid_margin_bottom);
+        mTrapezoidPaint = new Paint();
+        mTrapezoidPaint.setAntiAlias(true);
+        mTrapezoidPaint.setColor(mTrapezoidSolidColor);
+        mTrapezoidPaint.setStyle(Paint.Style.FILL);
+        mTrapezoidPaint.setPathEffect(
+            new CornerPathEffect(
+                resources.getDimensionPixelSize(R.dimen.chartview_trapezoid_radius)));
+    }
+
+    private void drawHorizontalDividers(Canvas canvas) {
+        // Draws the top divider line for 100% curve.
+        float offsetY = mDividerWidth * 0.5f;
+        canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint);
+        // Draws the center divider line for 50% curve.
+        final float availableSpace =
+                getHeight() - mDividerWidth * 2 - mTrapezoidVOffset - mDividerHeight;
+        offsetY = mDividerWidth + availableSpace * 0.5f;
+        canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint);
+        // Draws the center divider line for 0% curve.
+        offsetY = getHeight() - mDividerHeight - mDividerWidth * 0.5f;
+        canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint);
+    }
+
+    private void drawVerticalDividers(Canvas canvas) {
+        final int dividerCount = mTrapezoidCount + 1;
+        final float dividerSpace = dividerCount * mDividerWidth;
+        final float unitWidth = (getWidth() - dividerSpace) / (float) mTrapezoidCount;
+        final float startY = getHeight() - mDividerHeight;
+        final float trapezoidSlotOffset = mTrapezoidHOffset + mDividerWidth * 0.5f;
+        // Draws each vertical dividers.
+        float startX = mDividerWidth * 0.5f;
+        for (int index = 0; index < dividerCount; index++) {
+            canvas.drawLine(startX, startY, startX, getHeight(), mDividerPaint);
+            final float nextX = startX + mDividerWidth + unitWidth;
+            // Updates the trapezoid slots for drawing.
+            if (index < mTrapezoidSlot.length) {
+                mTrapezoidSlot[index].mLeft = round(startX + trapezoidSlotOffset);
+                mTrapezoidSlot[index].mRight = round(nextX - trapezoidSlotOffset);
+            }
+            startX = nextX;
+        }
+    }
+
+    private void drawTrapezoids(Canvas canvas) {
+        // Ignores invalid trapezoid data.
+        if (mLevels == null) {
+            return;
+        }
+        final float trapezoidBottom =
+            getHeight() - mDividerHeight - mDividerWidth - mTrapezoidVOffset;
+        final float availableSpace = trapezoidBottom - mDividerWidth;
+        final float unitHeight = availableSpace / 100f;
+        // Draws all trapezoid shapes into the canvas.
+        final Path trapezoidPath = new Path();
+        for (int index = 0; index < mTrapezoidCount; index++) {
+            // Configures the trapezoid paint color.
+            mTrapezoidPaint.setColor(
+                mSelectedIndex == index || mSelectedIndex == SELECTED_INDEX_ALL
+                ? mTrapezoidSolidColor
+                : mTrapezoidColor);
+            final float leftTop = round(trapezoidBottom - mLevels[index] * unitHeight);
+            final float rightTop = round(trapezoidBottom - mLevels[index + 1] * unitHeight);
+            trapezoidPath.reset();
+            trapezoidPath.moveTo(mTrapezoidSlot[index].mLeft, trapezoidBottom);
+            trapezoidPath.lineTo(mTrapezoidSlot[index].mLeft, leftTop);
+            trapezoidPath.lineTo(mTrapezoidSlot[index].mRight, rightTop);
+            trapezoidPath.lineTo(mTrapezoidSlot[index].mRight, trapezoidBottom);
+            // A tricky way to make the trapezoid shape drawing the rounded corner.
+            trapezoidPath.lineTo(mTrapezoidSlot[index].mLeft, trapezoidBottom);
+            trapezoidPath.lineTo(mTrapezoidSlot[index].mLeft, leftTop);
+            // Draws the trapezoid shape into canvas.
+            canvas.drawPath(trapezoidPath, mTrapezoidPaint);
+        }
+    }
+
+    // Searches the corresponding trapezoid index from x location.
+    private int getTrapezoidIndex(float x) {
+        for (int index = 0; index < mTrapezoidSlot.length; index++) {
+            final TrapezoidSlot slot = mTrapezoidSlot[index];
+            if (x >= slot.mLeft && x <= slot.mRight) {
+                return index;
+            }
+        }
+        return SELECTED_INDEX_INVALID;
+    }
+
+    // A container class for each trapezoid left and right location.
+    private static final class TrapezoidSlot {
+        public float mLeft;
+        public float mRight;
+
+        @Override
+        public String toString() {
+            return String.format(Locale.US, "TrapezoidSlot[%f,%f]", mLeft, mRight);
+        }
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/BatteryHistEntry.java b/src/com/android/settings/fuelgauge/BatteryHistEntry.java
new file mode 100644
index 0000000..b2c8eec
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatteryHistEntry.java
@@ -0,0 +1,112 @@
+/*
+ * 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.settings.fuelgauge;
+
+import android.content.ContentValues;
+
+/** A container class to carry data from {@link ContentValues}. */
+public final class BatteryHistEntry {
+    private static final String TAG = "BatteryHistEntry";
+
+    public final long mUid;
+    public final long mUserId;
+    public final String mAppLabel;
+    public final String mPackageName;
+    // Whether the data is represented as system component or not?
+    public final boolean mIsHidden;
+    // Records the timestamp relative information.
+    public final long mTimestamp;
+    public final String mZoneId;
+    // Records the battery usage relative information.
+    public final double mTotalPower;
+    public final double mConsumePower;
+    public final double mPercentOfTotal;
+    public final long mForegroundUsageTimeInMs;
+    public final long mBackgroundUsageTimeInMs;
+    public final int mDrainType;
+    public final int mConsumerType;
+    // Records the battery intent relative information.
+    public final int mBatteryLevel;
+    public final int mBatteryStatus;
+    public final int mBatteryHealth;
+
+    private boolean mIsValidEntry = true;
+    private ContentValues mContentValues;
+
+    public BatteryHistEntry(ContentValues contentValues) {
+        mContentValues = contentValues;
+        mUid = getLong("uid");
+        mUserId = getLong("userId");
+        mAppLabel = getString("appLabel");
+        mPackageName = getString("packageName");
+        mIsHidden = getBoolean("isHidden");
+        mTimestamp = getLong("timestamp");
+        mZoneId = getString("zoneId");
+        mTotalPower = getDouble("totalPower");
+        mConsumePower = getDouble("consumePower");
+        mPercentOfTotal = getDouble("percentOfTotal");
+        mForegroundUsageTimeInMs = getLong("foregroundUsageTimeInMs");
+        mBackgroundUsageTimeInMs = getLong("backgroundUsageTimeInMs");
+        mDrainType = getInteger("drainType");
+        mConsumerType = getInteger("consumerType");
+        mBatteryLevel = getInteger("batteryLevel");
+        mBatteryStatus = getInteger("batteryStatus");
+        mBatteryHealth = getInteger("batteryHealth");
+    }
+
+    /** Whether this {@link BatteryHistEntry} is valid or not? */
+    public boolean isValidEntry() {
+        return mIsValidEntry;
+    }
+
+    private int getInteger(String key) {
+        if (mContentValues != null && mContentValues.containsKey(key)) {
+            return mContentValues.getAsInteger(key);
+        };
+        mIsValidEntry = false;
+        return -1;
+    }
+
+    private long getLong(String key) {
+        if (mContentValues != null && mContentValues.containsKey(key)) {
+            return mContentValues.getAsLong(key);
+        }
+        mIsValidEntry = false;
+        return -1L;
+    }
+
+    private double getDouble(String key) {
+        if (mContentValues != null && mContentValues.containsKey(key)) {
+            return mContentValues.getAsDouble(key);
+        }
+        mIsValidEntry = false;
+        return 0f;
+    }
+
+    private String getString(String key) {
+        if (mContentValues != null && mContentValues.containsKey(key)) {
+            return mContentValues.getAsString(key);
+        }
+        mIsValidEntry = false;
+        return null;
+    }
+
+    private boolean getBoolean(String key) {
+        if (mContentValues != null && mContentValues.containsKey(key)) {
+            return mContentValues.getAsBoolean(key);
+        }
+        mIsValidEntry = false;
+        return false;
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
index 4d3b9cd..cb22ff3 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
@@ -19,8 +19,8 @@
 import android.content.Context;
 import android.os.BatteryUsageStats;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.View;
-import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
@@ -28,26 +28,26 @@
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
-import com.android.settings.widget.UsageView;
+import com.android.settings.overlay.FeatureFactory;
 
 /**
- * Custom preference for displaying power consumption as a bar and an icon on the left for the
- * subsystem/app type.
+ * Custom preference for displaying the battery level as chart graph.
  */
 public class BatteryHistoryPreference extends Preference {
     private static final String TAG = "BatteryHistoryPreference";
 
-    private CharSequence mSummary;
-    private TextView mSummaryView;
-
-    @VisibleForTesting
-    boolean hideSummary;
     @VisibleForTesting
     BatteryInfo mBatteryInfo;
 
     public BatteryHistoryPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
-        setLayoutResource(R.layout.battery_usage_graph);
+        final boolean isChartGraphEnabled =
+            FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context)
+                   .isChartGraphEnabled(context);
+        Log.i(TAG, "isChartGraphEnabled: " + isChartGraphEnabled);
+        if (isChartGraphEnabled) {
+            setLayoutResource(R.layout.battery_chart_graph);
+        }
         setSelectable(false);
     }
 
@@ -58,22 +58,6 @@
         }, batteryUsageStats, false);
     }
 
-    public void setBottomSummary(CharSequence text) {
-        mSummary = text;
-        if (mSummaryView != null) {
-            mSummaryView.setVisibility(View.VISIBLE);
-            mSummaryView.setText(mSummary);
-        }
-        hideSummary = false;
-    }
-
-    public void hideBottomSummary() {
-        if (mSummaryView != null) {
-            mSummaryView.setVisibility(View.GONE);
-        }
-        hideSummary = true;
-    }
-
     @Override
     public void onBindViewHolder(PreferenceViewHolder view) {
         super.onBindViewHolder(view);
@@ -81,18 +65,6 @@
         if (mBatteryInfo == null) {
             return;
         }
-
-        ((TextView) view.findViewById(R.id.charge)).setText(mBatteryInfo.batteryPercentString);
-        mSummaryView = (TextView) view.findViewById(R.id.bottom_summary);
-        if (mSummary != null) {
-            mSummaryView.setText(mSummary);
-        }
-        if (hideSummary) {
-            mSummaryView.setVisibility(View.GONE);
-        }
-        UsageView usageView = (UsageView) view.findViewById(R.id.battery_usage);
-        usageView.findViewById(R.id.label_group).setAlpha(.7f);
-        mBatteryInfo.bindHistory(usageView);
         BatteryUtils.logRuntime(TAG, "onBindViewHolder", startTime);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java
index a4dd86c..832936c 100644
--- a/src/com/android/settings/fuelgauge/BatteryInfo.java
+++ b/src/com/android/settings/fuelgauge/BatteryInfo.java
@@ -263,8 +263,11 @@
                 context.getString(chargingLimitedResId, info.batteryPercentString);
         } else if (chargeTimeMs > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
             info.remainingTimeUs = PowerUtil.convertMsToUs(chargeTimeMs);
-            CharSequence timeString = StringUtil.formatElapsedTime(context,
-                    PowerUtil.convertUsToMs(info.remainingTimeUs), false /* withSeconds */);
+            final CharSequence timeString = StringUtil.formatElapsedTime(
+                    context,
+                    PowerUtil.convertUsToMs(info.remainingTimeUs),
+                    false /* withSeconds */,
+                    true /* collapseTimeUnit */);
             int resId = R.string.power_charging_duration;
             info.remainingLabel = context.getString(
                     R.string.power_remaining_charging_duration_only, timeString);
@@ -287,7 +290,7 @@
                     context,
                     PowerUtil.convertUsToMs(drainTimeUs),
                     null /* percentageString */,
-                    estimate.isBasedOnUsage() && !shortString
+                    false /* basedOnUsage */
             );
             info.chargeLabel = PowerUtil.getBatteryRemainingStringFormatted(
                     context,
diff --git a/src/com/android/settings/fuelgauge/ConvertUtils.java b/src/com/android/settings/fuelgauge/ConvertUtils.java
new file mode 100644
index 0000000..30ac7bf
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/ConvertUtils.java
@@ -0,0 +1,105 @@
+/*
+ * 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.settings.fuelgauge;
+
+import android.annotation.IntDef;
+import android.content.ContentValues;
+import android.os.BatteryConsumer;
+import android.os.BatteryUsageStats;
+import android.os.SystemBatteryConsumer;
+import android.os.UidBatteryConsumer;
+import android.os.UserBatteryConsumer;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.TimeZone;
+
+/** A utility class to convert data into another types. */
+public final class ConvertUtils {
+    private static final String TAG = "ConvertUtils";
+    /** Invalid system battery consumer drain type. */
+    public static final int INVALID_DRAIN_TYPE = -1;
+
+    @IntDef(prefix = {"CONSUMER_TYPE"}, value = {
+        CONSUMER_TYPE_UNKNOWN,
+        CONSUMER_TYPE_UID_BATTERY,
+        CONSUMER_TYPE_USER_BATTERY,
+        CONSUMER_TYPE_SYSTEM_BATTERY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public static @interface ConsumerType {}
+
+    public static final int CONSUMER_TYPE_UNKNOWN = 0;
+    public static final int CONSUMER_TYPE_UID_BATTERY = 1;
+    public static final int CONSUMER_TYPE_USER_BATTERY = 2;
+    public static final int CONSUMER_TYPE_SYSTEM_BATTERY = 3;
+
+    /** Gets consumer type from {@link BatteryConsumer}. */
+    @ConsumerType
+    public static int getConsumerType(BatteryConsumer consumer) {
+        if (consumer instanceof UidBatteryConsumer) {
+            return CONSUMER_TYPE_UID_BATTERY;
+        } else if (consumer instanceof UserBatteryConsumer) {
+            return CONSUMER_TYPE_USER_BATTERY;
+        } else if (consumer instanceof SystemBatteryConsumer) {
+            return CONSUMER_TYPE_SYSTEM_BATTERY;
+        } else {
+          return CONSUMER_TYPE_UNKNOWN;
+        }
+    }
+
+    /** Gets battery drain type for {@link SystemBatteryConsumer}. */
+    public static int getDrainType(BatteryConsumer consumer) {
+        if (consumer instanceof SystemBatteryConsumer) {
+            return ((SystemBatteryConsumer) consumer).getDrainType();
+        }
+        return INVALID_DRAIN_TYPE;
+    }
+
+    public static ContentValues convert(
+            BatteryEntry entry,
+            BatteryUsageStats batteryUsageStats,
+            int batteryLevel,
+            int batteryStatus,
+            int batteryHealth,
+            long timestamp) {
+        final ContentValues values = new ContentValues();
+        values.put("uid", Long.valueOf(entry.getUid()));
+        values.put("userId",
+            Long.valueOf(UserHandle.getUserId(entry.getUid())));
+        values.put("appLabel", entry.getLabel());
+        values.put("packageName", entry.getDefaultPackageName());
+        values.put("isHidden", Boolean.valueOf(entry.isHidden()));
+        values.put("timestamp", Long.valueOf(timestamp));
+        values.put("zoneId", TimeZone.getDefault().getID());
+        values.put("totalPower",
+            Double.valueOf(batteryUsageStats.getConsumedPower()));
+        values.put("consumePower", Double.valueOf(entry.getConsumedPower()));
+        values.put("percentOfTotal", Double.valueOf(entry.percent));
+        values.put("foregroundUsageTimeInMs",
+            Long.valueOf(entry.getTimeInForegroundMs()));
+        values.put("backgroundUsageTimeInMs",
+            Long.valueOf(entry.getTimeInBackgroundMs()));
+        values.put("drainType", getDrainType(entry.getBatteryConsumer()));
+        values.put("consumerType", getConsumerType(entry.getBatteryConsumer()));
+        values.put("batteryLevel", Integer.valueOf(batteryLevel));
+        values.put("batteryStatus", Integer.valueOf(batteryStatus));
+        values.put("batteryHealth", Integer.valueOf(batteryHealth));
+        return values;
+    }
+
+    private ConvertUtils() {}
+}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index 9279e5d..0727e48 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -17,14 +17,9 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.os.BatteryManager;
 import android.os.Bundle;
 import android.provider.SearchIndexableResource;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -44,16 +39,11 @@
     private static final String TAG = "AdvancedBatteryUsage";
     private static final String KEY_BATTERY_GRAPH = "battery_graph";
     private static final String KEY_APP_LIST = "app_list";
-    private static final String KEY_SHOW_ALL_APPS = "show_all_apps";
-    @VisibleForTesting
-    static final int MENU_TOGGLE_APPS = Menu.FIRST + 1;
 
     @VisibleForTesting
     BatteryHistoryPreference mHistPref;
     private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
     private BatteryAppListPreferenceController mBatteryAppListPreferenceController;
-    @VisibleForTesting
-    boolean mShowAllApps = false;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -63,10 +53,6 @@
         mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH);
         mPowerUsageFeatureProvider = FeatureFactory.getFactory(context)
                 .getPowerUsageFeatureProvider(context);
-
-        // init the summary so other preferences won't have unnecessary move
-        updateHistPrefSummary(context);
-        restoreSavedInstance(icicle);
     }
 
     @Override
@@ -93,42 +79,6 @@
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        menu.add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE,
-                mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
-        super.onCreateOptionsMenu(menu, inflater);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case MENU_TOGGLE_APPS:
-                mShowAllApps = !mShowAllApps;
-                item.setTitle(mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
-                mMetricsFeatureProvider.action(getContext(),
-                        SettingsEnums.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE,
-                        mShowAllApps);
-                restartBatteryStatsLoader(BatteryUpdateType.MANUAL);
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-    }
-
-    @VisibleForTesting
-    void restoreSavedInstance(Bundle savedInstance) {
-        if (savedInstance != null) {
-            mShowAllApps = savedInstance.getBoolean(KEY_SHOW_ALL_APPS, false);
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_SHOW_ALL_APPS, mShowAllApps);
-    }
-
-    @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
 
@@ -151,22 +101,7 @@
             return;
         }
         updatePreference(mHistPref);
-        updateHistPrefSummary(context);
-
-        mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, mShowAllApps);
-    }
-
-    private void updateHistPrefSummary(Context context) {
-        Intent batteryIntent =
-                context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
-        final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0;
-
-        if (mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(context) && !plugged) {
-            mHistPref.setBottomSummary(
-                    mPowerUsageFeatureProvider.getAdvancedUsageScreenInfoString());
-        } else {
-            mHistPref.hideBottomSummary();
-        }
+        mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, true);
     }
 
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index 6a22ed4..8557bf7 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -124,4 +124,9 @@
      * Checks whether smart battery feature is supported in this device
      */
     boolean isSmartBatterySupported();
+
+    /**
+     * Checks whether we should enable chart graph design or not
+     */
+    boolean isChartGraphEnabled(Context context);
 }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index cb83d80..a3e9aec 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -150,4 +150,9 @@
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_smart_battery_available);
     }
+
+    @Override
+    public boolean isChartGraphEnabled(Context context) {
+        return false;
+    }
 }
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index be8f257..4ba7fc9 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -256,7 +256,7 @@
                 .map(i -> {
                     DisplayInfo info = new DisplayInfo();
                     info.subscriptionInfo = i;
-                    info.originalName = i.getDisplayName();
+                    info.originalName = i.getDisplayName().toString().trim();
                     return info;
                 });
 
diff --git a/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java b/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java
index d00efc7..2b07b5d 100644
--- a/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java
@@ -149,9 +149,15 @@
 
     private boolean hasBackupCallingFeature(int subscriptionId) {
         PersistableBundle carrierConfig = getCarrierConfigForSubId(subscriptionId);
-        return (carrierConfig != null)
-                && carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false);
+        Boolean featureEnableStatus = null;
+        if (carrierConfig != null) {
+            featureEnableStatus = carrierConfig.getBoolean(
+                    CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false);
+        }
+        // TODO: remove log after fixing b/182326102
+        Log.d(LOG_TAG, "config " + CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL
+                + "=" + featureEnableStatus + " for subId=" + mSubId);
+        return (featureEnableStatus != null) && featureEnableStatus.booleanValue();
     }
 
     private ImsMmTelManager getImsMmTelManager(int subId) {
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 9a4cb40..6e89c8a 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -214,6 +214,8 @@
     @Override
     public void onResume() {
         super.onResume();
+        // TODO: remove log after fixing b/182326102
+        Log.d(LOG_TAG, "onResume() subId=" + mSubId);
         if (mActiveSubsciptionsListener == null) {
             mActiveSubsciptionsListener = new ActiveSubsciptionsListener(
                     getContext().getMainLooper(), getContext(), mSubId) {
diff --git a/src/com/android/settings/notification/app/AllConversationsPreferenceController.java b/src/com/android/settings/notification/app/AllConversationsPreferenceController.java
index 4b28b11..03e321b 100644
--- a/src/com/android/settings/notification/app/AllConversationsPreferenceController.java
+++ b/src/com/android/settings/notification/app/AllConversationsPreferenceController.java
@@ -55,6 +55,7 @@
         Preference pref = new Preference(mContext);
         pref.setOrder(1);
         pref.setSummary(R.string.other_conversations_summary);
+        pref.setSelectable(false);
         return pref;
     }
 
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index 90c9859..9093b97 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -248,10 +248,8 @@
             if (savedInstanceState != null) {
                 mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
                 mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
-                if (mUserPassword == null) {
-                    mUserPassword = savedInstanceState.getParcelable(
-                            ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
-                }
+                mUserPassword = savedInstanceState.getParcelable(
+                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
             }
 
             // a) If this is started from other user, use that user id.
@@ -512,7 +510,8 @@
             outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
             outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
             if (mUserPassword != null) {
-                outState.putParcelable(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mUserPassword);
+                outState.putParcelable(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
+                        mUserPassword.duplicate());
             }
         }
 
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index 35d624b..7b6bc0c 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -567,9 +567,7 @@
                     updateStage(mUiStage);
                 }
 
-                if (mCurrentCredential == null) {
-                    mCurrentCredential = savedInstanceState.getParcelable(KEY_CURRENT_CREDENTIAL);
-                }
+                mCurrentCredential = savedInstanceState.getParcelable(KEY_CURRENT_CREDENTIAL);
 
                 // Re-attach to the exiting worker if there is one.
                 mSaveAndFinishWorker = (SaveAndFinishWorker) getFragmentManager().findFragmentByTag(
@@ -646,7 +644,9 @@
             super.onSaveInstanceState(outState);
             outState.putString(KEY_UI_STAGE, mUiStage.name());
             outState.putParcelable(KEY_FIRST_PASSWORD, mFirstPassword);
-            outState.putParcelable(KEY_CURRENT_CREDENTIAL, mCurrentCredential);
+            if (mCurrentCredential != null) {
+                outState.putParcelable(KEY_CURRENT_CREDENTIAL, mCurrentCredential.duplicate());
+            }
         }
 
         @Override
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index 4b9883a..a3c91cf 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -611,10 +611,8 @@
             } else {
                 // restore from previous state
                 mChosenPattern = savedInstanceState.getParcelable(KEY_PATTERN_CHOICE);
+                mCurrentCredential = savedInstanceState.getParcelable(KEY_CURRENT_PATTERN);
 
-                if (mCurrentCredential == null) {
-                    mCurrentCredential = savedInstanceState.getParcelable(KEY_CURRENT_PATTERN);
-                }
                 updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
 
                 // Re-attach to the exiting worker if there is one.
@@ -729,7 +727,7 @@
             }
 
             if (mCurrentCredential != null) {
-                outState.putParcelable(KEY_CURRENT_PATTERN, mCurrentCredential);
+                outState.putParcelable(KEY_CURRENT_PATTERN, mCurrentCredential.duplicate());
             }
         }
 
diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
index b3ae609..82b9e76 100644
--- a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
+++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
@@ -149,6 +149,8 @@
 
         root.postDelayed(() -> {
             mHighlightRequested = true;
+            // Remove the animator to avoid a RecyclerView crash.
+            recyclerView.setItemAnimator(null);
             recyclerView.smoothScrollToPosition(position);
             mHighlightPosition = position;
             notifyItemChanged(position);
diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
index 0c3f42d..3c312b8 100644
--- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
@@ -480,7 +480,7 @@
             return mContext.getString(R.string.wifi_time_remaining, StringUtil.formatElapsedTime(
                     mContext,
                     Duration.between(now, expiryTime).getSeconds() * 1000,
-                    false /* withSeconds */));
+                    false /* withSeconds */, false /* collapseTimeUnit */));
         }
 
         // For more than 2 days, show the expiry date
diff --git a/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java
index 41532d0..67d1f49 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java
@@ -24,6 +24,8 @@
 import androidx.preference.Preference;
 import androidx.preference.SwitchPreference;
 
+import com.android.settings.R;
+
 /**
  * This controller helps to manage the state of maximize compatibility switch preference.
  */
@@ -53,6 +55,9 @@
         }
         mPreference.setEnabled(is5GhzBandSupported());
         ((SwitchPreference) mPreference).setChecked(mIsChecked);
+        mPreference.setSummary(mWifiManager.isBridgedApConcurrencySupported()
+                ? R.string.wifi_hotspot_maximize_compatibility_dual_ap_summary
+                : R.string.wifi_hotspot_maximize_compatibility_single_ap_summary);
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java
index 1073256..e329dcc 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -33,6 +34,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.verify.domain.DomainVerificationManager;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
@@ -66,6 +68,8 @@
     private Preference mPreference;
     @Mock
     private PackageManager mPackageManager;
+    @Mock
+    private DomainVerificationManager mDomainVerificationManager;
 
     private Context mContext;
     private AppOpenByDefaultPreferenceController mController;
@@ -78,6 +82,8 @@
         mController.setParentFragment(mFragment);
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getSystemService(DomainVerificationManager.class)).thenReturn(
+                mDomainVerificationManager);
     }
 
     @Test
@@ -194,10 +200,27 @@
         final AppEntry appEntry = mock(AppEntry.class);
         appEntry.info = new ApplicationInfo();
         when(mFragment.getAppEntry()).thenReturn(appEntry);
+        doReturn(true).when(mController).isLinkHandlingAllowed();
 
         mController.updateState(mPreference);
 
         verify(mPreference).setVisible(true);
         verify(mPreference).setSummary(any());
     }
+
+    @Test
+    public void getSubtext_allowedLinkHandling_returnAllowedString() {
+        final String allowdedString = "Allow app to open supported links";
+        doReturn(true).when(mController).isLinkHandlingAllowed();
+
+        assertThat(mController.getSubtext()).isEqualTo(allowdedString);
+    }
+
+    @Test
+    public void getSubtext_notAllowedLinkHandling_returnNotAllowedString() {
+        final String notAllowdedString = "Don’t allow app to open links";
+        doReturn(false).when(mController).isLinkHandlingAllowed();
+
+        assertThat(mController.getSubtext()).isEqualTo(notAllowdedString);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
index c5ea21f..197fdff 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
@@ -34,6 +34,7 @@
 
 import com.google.common.collect.ImmutableList;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -79,6 +80,7 @@
     }
 
     @Test
+    @Ignore
     public void getPreferenceSummary_appOpNotAllowed_returnsNotAllowed() {
         shadowOf(mUserManager).addUser(
                 PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
index 215cddb..5350d45 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
@@ -473,9 +473,9 @@
     @Test
     public void showBatteryPredictionIfNecessary_estimateReadyIsAvailable_showCorrectValue() {
         final String leftBatteryPrediction =
-                StringUtil.formatElapsedTime(mContext, 12000000, false).toString();
+                StringUtil.formatElapsedTime(mContext, 12000000, false, false).toString();
         final String rightBatteryPrediction =
-                StringUtil.formatElapsedTime(mContext, 1200000, false).toString();
+                StringUtil.formatElapsedTime(mContext, 1200000, false, false).toString();
 
         mController.showBatteryPredictionIfNecessary(1, 12000000,
                 mLayoutPreference.findViewById(R.id.layout_left));
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotateCameraStateControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotateCameraStateControllerTest.java
new file mode 100644
index 0000000..ffd6411
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotateCameraStateControllerTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.settings.display;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+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.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+
+import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowSensorPrivacyManager.class)
+public class SmartAutoRotateCameraStateControllerTest {
+
+    private static final String PACKAGE_NAME = "package_name";
+
+    private SmartAutoRotateCameraStateController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        final Context context = Mockito.spy(RuntimeEnvironment.application);
+        final ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver();
+        when(context.getContentResolver()).thenReturn(contentResolver);
+        final PackageManager packageManager = Mockito.mock(PackageManager.class);
+        when(context.getPackageManager()).thenReturn(packageManager);
+        doReturn(PACKAGE_NAME).when(packageManager).getRotationResolverPackageName();
+        mController = new SmartAutoRotateCameraStateController(context, "smart_auto_rotate");
+        when(mController.isCameraLocked()).thenReturn(false);
+
+        final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
+        resolveInfo.serviceInfo = new ServiceInfo();
+        when(packageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo);
+    }
+
+    @Test
+    public void getAvailabilityStatus_returnUnsupportedOnDevice() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_cameraNotEnabled_returnAvailableUnSearchAble() {
+        when(mController.isCameraLocked()).thenReturn(true);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
index 2d56c0e..a65d880 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
@@ -39,6 +39,7 @@
 import androidx.preference.Preference;
 
 import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,8 +49,10 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowSensorPrivacyManager.class)
 public class SmartAutoRotateControllerTest {
 
     private static final String PACKAGE_NAME = "package_name";
@@ -72,6 +75,7 @@
         doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
                 Manifest.permission.CAMERA, PACKAGE_NAME);
         mController = new SmartAutoRotateController(context, "test_key");
+        when(mController.isCameraLocked()).thenReturn(false);
         doReturn(mController.getPreferenceKey()).when(mPreference).getKey();
 
         final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
@@ -105,6 +109,12 @@
         assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
     }
 
+    @Test
+    public void getAvailabilityStatus_cameraDisabled_returnDisableDependentSetting() {
+        when(mController.isCameraLocked()).thenReturn(true);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
+    }
+
     private void enableAutoRotation() {
         Settings.System.putIntForUser(mContentResolver,
                 Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java
new file mode 100644
index 0000000..234f6ce
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.settings.fuelgauge;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentValues;
+import android.os.BatteryConsumer;
+import android.os.BatteryManager;
+import android.os.BatteryUsageStats;
+import android.os.SystemBatteryConsumer;
+import android.os.UserHandle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.TimeZone;
+
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryHistEntryTest {
+
+    @Mock
+    private BatteryEntry mockBatteryEntry;
+    @Mock
+    private BatteryUsageStats mBatteryUsageStats;
+    @Mock
+    private SystemBatteryConsumer mockSystemBatteryConsumer;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testConstructor_returnsExpectedResult() {
+        final int expectedType = 3;
+        when(mockBatteryEntry.getUid()).thenReturn(1001);
+        when(mockBatteryEntry.getLabel()).thenReturn("Settings");
+        when(mockBatteryEntry.getDefaultPackageName())
+            .thenReturn("com.google.android.settings.battery");
+        when(mockBatteryEntry.isHidden()).thenReturn(true);
+        when(mBatteryUsageStats.getConsumedPower()).thenReturn(5.1);
+        when(mockBatteryEntry.getConsumedPower()).thenReturn(1.1);
+        mockBatteryEntry.percent = 0.3;
+        when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
+        when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
+        when(mockBatteryEntry.getBatteryConsumer())
+            .thenReturn(mockSystemBatteryConsumer);
+        when(mockSystemBatteryConsumer.getDrainType()).thenReturn(expectedType);
+        final ContentValues values =
+            ConvertUtils.convert(
+                mockBatteryEntry,
+                mBatteryUsageStats,
+                /*batteryLevel=*/ 12,
+                /*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL,
+                /*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD,
+                /*timestamp=*/ 10001L);
+
+        final BatteryHistEntry entry = new BatteryHistEntry(values);
+
+        assertThat(entry.isValidEntry()).isTrue();
+        assertThat(entry.mUid).isEqualTo(1001);
+        assertThat(entry.mUserId).isEqualTo(UserHandle.getUserId(1001));
+        assertThat(entry.mAppLabel).isEqualTo("Settings");
+        assertThat(entry.mPackageName)
+            .isEqualTo("com.google.android.settings.battery");
+        assertThat(entry.mIsHidden).isTrue();
+        assertThat(entry.mTimestamp).isEqualTo(10001L);
+        assertThat(entry.mZoneId).isEqualTo(TimeZone.getDefault().getID());
+        assertThat(entry.mTotalPower).isEqualTo(5.1);
+        assertThat(entry.mConsumePower).isEqualTo(1.1);
+        assertThat(entry.mPercentOfTotal).isEqualTo(mockBatteryEntry.percent);
+        assertThat(entry.mForegroundUsageTimeInMs).isEqualTo(1234L);
+        assertThat(entry.mBackgroundUsageTimeInMs).isEqualTo(5689L);
+        assertThat(entry.mDrainType).isEqualTo(expectedType);
+        assertThat(entry.mConsumerType)
+            .isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
+        assertThat(entry.mBatteryLevel).isEqualTo(12);
+        assertThat(entry.mBatteryStatus)
+            .isEqualTo(BatteryManager.BATTERY_STATUS_FULL);
+        assertThat(entry.mBatteryHealth)
+            .isEqualTo(BatteryManager.BATTERY_HEALTH_COLD);
+    }
+
+    @Test
+    public void testConstructor_invalidField_returnsInvalidEntry() {
+        final BatteryHistEntry entry = new BatteryHistEntry(new ContentValues());
+        assertThat(entry.isValidEntry()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistoryPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistoryPreferenceTest.java
deleted file mode 100644
index fc8e994..0000000
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistoryPreferenceTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 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.settings.fuelgauge;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settings.widget.UsageView;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class BatteryHistoryPreferenceTest {
-
-    private static final String TEST_STRING = "test";
-    @Mock
-    private PreferenceViewHolder mViewHolder;
-    @Mock
-    private BatteryInfo mBatteryInfo;
-    @Mock
-    private TextView mTextView;
-    @Mock
-    private UsageView mUsageView;
-    @Mock
-    private View mLabelView;
-    private BatteryHistoryPreference mBatteryHistoryPreference;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        final Context context = RuntimeEnvironment.application;
-        final View itemView =
-                LayoutInflater.from(context).inflate(R.layout.battery_usage_graph, null);
-
-        mBatteryHistoryPreference = new BatteryHistoryPreference(context, null);
-        mBatteryHistoryPreference.mBatteryInfo = mBatteryInfo;
-        mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(itemView));
-        when(mViewHolder.findViewById(R.id.battery_usage)).thenReturn(mUsageView);
-        when(mViewHolder.findViewById(R.id.charge)).thenReturn(mTextView);
-        when(mUsageView.findViewById(anyInt())).thenReturn(mLabelView);
-    }
-
-    @Test
-    public void testOnBindViewHolder_updateBatteryUsage() {
-        mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
-
-        verify(mViewHolder).findViewById(R.id.battery_usage);
-        verify(mTextView).setText(nullable(String.class));
-        verify(mBatteryInfo).bindHistory(mUsageView);
-    }
-
-    @Test
-    public void testSetBottomSummary_updatesBottomSummaryTextIfSet() {
-        mBatteryHistoryPreference.setBottomSummary(TEST_STRING);
-        mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
-
-        TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
-        assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(view.getText()).isEqualTo(TEST_STRING);
-        assertThat(mBatteryHistoryPreference.hideSummary).isFalse();
-    }
-
-    @Test
-    public void testSetBottomSummary_leavesBottomSummaryTextBlankIfNotSet() {
-        mBatteryHistoryPreference.hideBottomSummary();
-        mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
-
-        TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
-        assertThat(view.getVisibility()).isEqualTo(View.GONE);
-        assertThat(view.getText()).isEqualTo("");
-        assertThat(mBatteryHistoryPreference.hideSummary).isTrue();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
index afec5cb..8eed2cb 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
@@ -150,10 +150,9 @@
                 mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
                 true /* shortString */);
 
-        // We only add special mention for the long string
-        assertThat(info.remainingLabel.toString()).contains(ENHANCED_STRING_SUFFIX);
+        // Both long and short strings should not have extra text
+        assertThat(info.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX);
         assertThat(info.suggestionLabel).contains(BATTERY_RUN_OUT_PREFIX);
-        // shortened string should not have extra text
         assertThat(info2.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX);
         assertThat(info2.suggestionLabel).contains(BATTERY_RUN_OUT_PREFIX);
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
new file mode 100644
index 0000000..70a4914
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.settings.fuelgauge;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentValues;
+import android.os.BatteryConsumer;
+import android.os.BatteryManager;
+import android.os.BatteryUsageStats;
+import android.os.SystemBatteryConsumer;
+import android.os.UidBatteryConsumer;
+import android.os.UserBatteryConsumer;
+import android.os.UserHandle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.TimeZone;
+
+@RunWith(RobolectricTestRunner.class)
+public final class ConvertUtilsTest {
+
+    @Mock
+    private BatteryUsageStats mBatteryUsageStats;
+    @Mock
+    private BatteryEntry mockBatteryEntry;
+    @Mock
+    private BatteryConsumer mockBatteryConsumer;
+    @Mock
+    private UidBatteryConsumer mockUidBatteryConsumer;
+    @Mock
+    private UserBatteryConsumer mockUserBatteryConsumer;
+    @Mock
+    private SystemBatteryConsumer mockSystemBatteryConsumer;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testConvert_returnsExpectedContentValues() {
+        final int expectedType = 3;
+        when(mockBatteryEntry.getUid()).thenReturn(1001);
+        when(mockBatteryEntry.getLabel()).thenReturn("Settings");
+        when(mockBatteryEntry.getDefaultPackageName())
+            .thenReturn("com.google.android.settings.battery");
+        when(mockBatteryEntry.isHidden()).thenReturn(true);
+        when(mBatteryUsageStats.getConsumedPower()).thenReturn(5.1);
+        when(mockBatteryEntry.getConsumedPower()).thenReturn(1.1);
+        mockBatteryEntry.percent = 0.3;
+        when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
+        when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
+        when(mockBatteryEntry.getBatteryConsumer())
+            .thenReturn(mockSystemBatteryConsumer);
+        when(mockSystemBatteryConsumer.getDrainType()).thenReturn(expectedType);
+
+        final ContentValues values =
+            ConvertUtils.convert(
+                mockBatteryEntry,
+                mBatteryUsageStats,
+                /*batteryLevel=*/ 12,
+                /*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL,
+                /*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD,
+                /*timestamp=*/ 10001L);
+
+        assertThat(values.getAsLong("uid")).isEqualTo(1001L);
+        assertThat(values.getAsLong("userId"))
+            .isEqualTo(UserHandle.getUserId(1001));
+        assertThat(values.getAsString("appLabel")).isEqualTo("Settings");
+        assertThat(values.getAsString("packageName"))
+            .isEqualTo("com.google.android.settings.battery");
+        assertThat(values.getAsBoolean("isHidden")).isTrue();
+        assertThat(values.getAsLong("timestamp")).isEqualTo(10001L);
+        assertThat(values.getAsString("zoneId"))
+            .isEqualTo(TimeZone.getDefault().getID());
+        assertThat(values.getAsDouble("totalPower")).isEqualTo(5.1);
+        assertThat(values.getAsDouble("consumePower")).isEqualTo(1.1);
+        assertThat(values.getAsDouble("percentOfTotal")).isEqualTo(0.3);
+        assertThat(values.getAsLong("foregroundUsageTimeInMs")).isEqualTo(1234L);
+        assertThat(values.getAsLong("backgroundUsageTimeInMs")).isEqualTo(5689L);
+        assertThat(values.getAsInteger("drainType")).isEqualTo(expectedType);
+        assertThat(values.getAsInteger("consumerType"))
+            .isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
+        assertThat(values.getAsInteger("batteryLevel")).isEqualTo(12);
+        assertThat(values.getAsInteger("batteryStatus"))
+            .isEqualTo(BatteryManager.BATTERY_STATUS_FULL);
+        assertThat(values.getAsInteger("batteryHealth"))
+            .isEqualTo(BatteryManager.BATTERY_HEALTH_COLD);
+    }
+
+    @Test
+    public void testGetDrainType_returnsExpetcedResult() {
+        final int expectedType = 3;
+        when(mockSystemBatteryConsumer.getDrainType())
+            .thenReturn(expectedType);
+
+        assertThat(ConvertUtils.getDrainType(mockSystemBatteryConsumer))
+            .isEqualTo(expectedType);
+    }
+
+    @Test
+    public void testGetDrainType_notValidConsumer_returnsInvalidTypeValue() {
+        assertThat(ConvertUtils.getDrainType(mockUserBatteryConsumer))
+            .isEqualTo(ConvertUtils.INVALID_DRAIN_TYPE);
+    }
+
+    @Test
+    public void testGetConsumerType_returnsExpetcedResult() {
+        assertThat(ConvertUtils.getConsumerType(mockUidBatteryConsumer))
+            .isEqualTo(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        assertThat(ConvertUtils.getConsumerType(mockUserBatteryConsumer))
+            .isEqualTo(ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
+        assertThat(ConvertUtils.getConsumerType(mockSystemBatteryConsumer))
+            .isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
+    }
+
+    @Test
+    public void testGetConsumeType_invalidConsumer_returnsInvalidType() {
+          assertThat(ConvertUtils.getConsumerType(mockBatteryConsumer))
+              .isEqualTo(ConvertUtils.CONSUMER_TYPE_UNKNOWN);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
deleted file mode 100644
index c9b1a00..0000000
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2017 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.settings.fuelgauge;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class PowerUsageAdvancedTest {
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Menu mMenu;
-    @Mock
-    private MenuInflater mMenuInflater;
-    @Mock
-    private MenuItem mToggleAppsMenu;
-    private Context mContext;
-    private PowerUsageAdvanced mFragment;
-    private FakeFeatureFactory mFeatureFactory;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mContext = RuntimeEnvironment.application;
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
-        when(mToggleAppsMenu.getItemId()).thenReturn(PowerUsageAdvanced.MENU_TOGGLE_APPS);
-
-        BatteryAppListPreferenceController.sConfig =
-                new BatteryAppListPreferenceController.Config() {
-                    @Override
-                    public boolean shouldShowBatteryAttributionList(Context context) {
-                        return true;
-                    }
-                };
-
-        mFragment = spy(new PowerUsageAdvanced());
-        mFragment.onAttach(mContext);
-    }
-
-    @Test
-    public void testSaveInstanceState_showAllAppsRestored() {
-        Bundle bundle = new Bundle();
-        mFragment.mShowAllApps = true;
-        doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
-
-        mFragment.onSaveInstanceState(bundle);
-        mFragment.restoreSavedInstance(bundle);
-
-        assertThat(mFragment.mShowAllApps).isTrue();
-    }
-
-    @Test
-    public void testOptionsMenu_menuAppToggle_metricEventInvoked() {
-        mFragment.mShowAllApps = false;
-        doNothing().when(mFragment).restartBatteryStatsLoader(anyInt());
-
-        mFragment.onOptionsItemSelected(mToggleAppsMenu);
-
-        verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
-                eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE), eq(true));
-    }
-
-    @Test
-    public void testOptionsMenu_toggleAppsEnabled() {
-        when(mFeatureFactory.powerUsageFeatureProvider.isPowerAccountingToggleEnabled())
-                .thenReturn(true);
-        mFragment.mShowAllApps = false;
-
-        mFragment.onCreateOptionsMenu(mMenu, mMenuInflater);
-
-        verify(mMenu).add(Menu.NONE, PowerUsageAdvanced.MENU_TOGGLE_APPS, Menu.NONE,
-                R.string.show_all_apps);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSensorPrivacyManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSensorPrivacyManager.java
new file mode 100644
index 0000000..b153110
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSensorPrivacyManager.java
@@ -0,0 +1,34 @@
+/*
+ * 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.settings.testutils.shadow;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.hardware.SensorPrivacyManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(value = SensorPrivacyManager.class)
+public class ShadowSensorPrivacyManager {
+
+    @Implementation
+    public static SensorPrivacyManager getInstance(Context context) {
+        return mock(SensorPrivacyManager.class);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
index 3e0e22f..4360a09 100644
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java
@@ -579,7 +579,11 @@
                 ZoneId.of("Europe/London"));
         doShouldShowRemainingTimeTest(fakeNow, timeRemainingMs);
         final String expectedSummary = mContext.getString(R.string.wifi_time_remaining,
-                StringUtil.formatElapsedTime(mContext, timeRemainingMs, false /* withSeconds */));
+                StringUtil.formatElapsedTime(
+                        mContext,
+                        timeRemainingMs,
+                        false /* withSeconds */,
+                        false /* collapseTimeUnit */));
         final InOrder inOrder = inOrder(mMockHeaderController);
         inOrder.verify(mMockHeaderController).setSecondSummary(expectedSummary);
 
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
index c0e5205..3d192cf 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -48,7 +48,8 @@
     private static final int SUBID_1 = 1;
     private static final int SUBID_2 = 2;
     private static final int SUBID_3 = 3;
-    private static final CharSequence CARRIER_1 = "carrier1111111";
+    private static final CharSequence CARRIER_1 = "carrier1";
+    private static final CharSequence CARRIER_1_SPACE = " carrier1       ";
     private static final CharSequence CARRIER_2 = "carrier2";
 
     private Context mContext;
@@ -196,6 +197,35 @@
     }
 
     @Test
+    public void getUniqueDisplayNames_identicalCarriersAfterTrim_fourDigitsUsed() {
+        // Both subscriptoins have the same display name.
+        final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
+        final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
+        when(info1.getSubscriptionId()).thenReturn(SUBID_1);
+        when(info2.getSubscriptionId()).thenReturn(SUBID_2);
+        when(info1.getDisplayName()).thenReturn(CARRIER_1);
+        when(info2.getDisplayName()).thenReturn(CARRIER_1_SPACE);
+        when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(
+                Arrays.asList(info1, info2));
+
+        // Each subscription has a unique last 4 digits of the phone number.
+        TelephonyManager sub1Telmgr = mock(TelephonyManager.class);
+        TelephonyManager sub2Telmgr = mock(TelephonyManager.class);
+        when(sub1Telmgr.getLine1Number()).thenReturn("1112223333");
+        when(sub2Telmgr.getLine1Number()).thenReturn("2223334444");
+        when(mTelMgr.createForSubscriptionId(SUBID_1)).thenReturn(sub1Telmgr);
+        when(mTelMgr.createForSubscriptionId(SUBID_2)).thenReturn(sub2Telmgr);
+
+        final Map<Integer, CharSequence> idNames =
+                SubscriptionUtil.getUniqueSubscriptionDisplayNames(mContext);
+
+        assertThat(idNames).isNotNull();
+        assertThat(idNames).hasSize(2);
+        assertEquals(CARRIER_1 + " 3333", idNames.get(SUBID_1));
+        assertEquals(CARRIER_1 + " 4444", idNames.get(SUBID_2));
+    }
+
+    @Test
     public void getUniqueDisplayNames_phoneNumberBlocked_subscriptoinIdFallback() {
         // Both subscriptoins have the same display name.
         final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java
index 0729780..0ee9e70 100644
--- a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java
@@ -34,6 +34,8 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.settings.testutils.ResourcesUtils;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -52,29 +54,30 @@
     @Mock
     private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener;
 
+    private Context mContext;
     private WifiTetherMaximizeCompatibilityPreferenceController mController;
     private SwitchPreference mPreference;
     private SoftApConfiguration mConfig;
 
     @Before
     public void setUp() {
-        final Context context = spy(ApplicationProvider.getApplicationContext());
+        mContext = spy(ApplicationProvider.getApplicationContext());
         mConfig = new SoftApConfiguration.Builder()
                 .setSsid("test_Ssid")
                 .setPassphrase(null, SoftApConfiguration.SECURITY_TYPE_OPEN)
                 .setBridgedModeOpportunisticShutdownEnabled(true)
                 .build();
-        doReturn(mWifiManager).when(context).getSystemService(Context.WIFI_SERVICE);
+        doReturn(mWifiManager).when(mContext).getSystemService(Context.WIFI_SERVICE);
         doReturn(true).when(mWifiManager).isBridgedApConcurrencySupported();
         doReturn(mConfig).when(mWifiManager).getSoftApConfiguration();
 
-        mController = new WifiTetherMaximizeCompatibilityPreferenceController(context, mListener);
+        mController = new WifiTetherMaximizeCompatibilityPreferenceController(mContext, mListener);
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
-        final PreferenceManager preferenceManager = new PreferenceManager(context);
-        final PreferenceScreen screen = preferenceManager.createPreferenceScreen(context);
-        mPreference = new SwitchPreference(context);
+        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
+        mPreference = new SwitchPreference(mContext);
         mPreference.setKey(WifiTetherMaximizeCompatibilityPreferenceController.PREF_KEY);
         screen.addPreference(mPreference);
         mController.displayPreference(screen);
@@ -105,6 +108,26 @@
     }
 
     @Test
+    public void updateDisplay_notSupportedBridgedApConcurrency_setSingleApSummary() {
+        doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported();
+
+        mController.updateDisplay();
+
+        assertThat(mPreference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(mContext,
+                "wifi_hotspot_maximize_compatibility_single_ap_summary"));
+    }
+
+    @Test
+    public void updateDisplay_supportedBridgedApConcurrency_setDualApSummary() {
+        doReturn(true).when(mWifiManager).isBridgedApConcurrencySupported();
+
+        mController.updateDisplay();
+
+        assertThat(mPreference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(mContext,
+                "wifi_hotspot_maximize_compatibility_dual_ap_summary"));
+    }
+
+    @Test
     public void updateDisplay_supported5GHzBandAndCountryCodeIsNotNull_setPreferenceEnabled() {
         doReturn(true).when(mWifiManager).is5GHzBandSupported();
         doReturn("US").when(mWifiManager).getCountryCode();