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 & 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();